diff --git a/contractcourt/chain_watcher.go b/contractcourt/chain_watcher.go index 0c522aa3..7ea3da14 100644 --- a/contractcourt/chain_watcher.go +++ b/contractcourt/chain_watcher.go @@ -331,7 +331,7 @@ func (c *chainWatcher) SubscribeChannelEvents() *ChainEventSubscription { // based off of only the set of outputs included. func isOurCommitment(localChanCfg, remoteChanCfg channeldb.ChannelConfig, commitSpend *chainntnfs.SpendDetail, broadcastStateNum uint64, - revocationProducer shachain.Producer) (bool, error) { + revocationProducer shachain.Producer, tweakless bool) (bool, error) { // First, we'll re-derive our commitment point for this state since // this is what we use to randomize each of the keys for this state. @@ -344,14 +344,15 @@ func isOurCommitment(localChanCfg, remoteChanCfg channeldb.ChannelConfig, // Now that we have the commit point, we'll derive the tweaked local // and remote keys for this state. We use our point as only we can // revoke our own commitment. - localDelayBasePoint := localChanCfg.DelayBasePoint.PubKey - localDelayKey := input.TweakPubKey(localDelayBasePoint, commitPoint) - remoteNonDelayPoint := remoteChanCfg.PaymentBasePoint.PubKey - remotePayKey := input.TweakPubKey(remoteNonDelayPoint, commitPoint) + commitKeyRing := lnwallet.DeriveCommitmentKeys( + commitPoint, true, tweakless, &localChanCfg, &remoteChanCfg, + ) // With the keys derived, we'll construct the remote script that'll be // present if they have a non-dust balance on the commitment. - remotePkScript, err := input.CommitScriptUnencumbered(remotePayKey) + remotePkScript, err := input.CommitScriptUnencumbered( + commitKeyRing.NoDelayKey, + ) if err != nil { return false, err } @@ -359,11 +360,9 @@ func isOurCommitment(localChanCfg, remoteChanCfg channeldb.ChannelConfig, // Next, we'll derive our script that includes the revocation base for // the remote party allowing them to claim this output before the CSV // delay if we breach. - revocationKey := input.DeriveRevocationPubkey( - remoteChanCfg.RevocationBasePoint.PubKey, commitPoint, - ) localScript, err := input.CommitScriptToSelf( - uint32(localChanCfg.CsvDelay), localDelayKey, revocationKey, + uint32(localChanCfg.CsvDelay), commitKeyRing.DelayKey, + commitKeyRing.RevocationKey, ) if err != nil { return false, err @@ -423,6 +422,11 @@ func (c *chainWatcher) closeObserver(spendNtfn *chainntnfs.SpendEvent) { // revoked state...!!! commitTxBroadcast := commitSpend.SpendingTx + // An additional piece of information we need to properly + // dispatch a close event if is this channel was using the + // tweakless remove key format or not. + tweaklessCommit := c.cfg.chanState.ChanType.IsTweakless() + localCommit, remoteCommit, err := c.cfg.chanState.LatestCommitments() if err != nil { log.Errorf("Unable to fetch channel state for "+ @@ -480,6 +484,7 @@ func (c *chainWatcher) closeObserver(spendNtfn *chainntnfs.SpendEvent) { c.cfg.chanState.LocalChanCfg, c.cfg.chanState.RemoteChanCfg, commitSpend, broadcastStateNum, c.cfg.chanState.RevocationProducer, + tweaklessCommit, ) if err != nil { log.Errorf("unable to determine self commit for "+ @@ -584,9 +589,6 @@ func (c *chainWatcher) closeObserver(spendNtfn *chainntnfs.SpendEvent) { "state #%v!!! Attempting recovery...", broadcastStateNum, remoteStateNum) - tweaklessCommit := (c.cfg.chanState.ChanType == - channeldb.SingleFunderTweakless) - // If this isn't a tweakless commitment, then we'll // need to wait for the remote party's latest unrevoked // commitment point to be presented to us as we need diff --git a/lnwallet/channel.go b/lnwallet/channel.go index dbf44324..720f5d0d 100644 --- a/lnwallet/channel.go +++ b/lnwallet/channel.go @@ -876,13 +876,13 @@ func (lc *LightningChannel) diskCommitToMemCommit(isLocal bool, // haven't yet received a responding commitment from the remote party. var localCommitKeys, remoteCommitKeys *CommitmentKeyRing if localCommitPoint != nil { - localCommitKeys = deriveCommitmentKeys( + localCommitKeys = DeriveCommitmentKeys( localCommitPoint, true, tweaklessCommit, lc.localChanCfg, lc.remoteChanCfg, ) } if remoteCommitPoint != nil { - remoteCommitKeys = deriveCommitmentKeys( + remoteCommitKeys = DeriveCommitmentKeys( remoteCommitPoint, false, tweaklessCommit, lc.localChanCfg, lc.remoteChanCfg, ) @@ -981,10 +981,10 @@ type CommitmentKeyRing struct { RevocationKey *btcec.PublicKey } -// deriveCommitmentKey generates a new commitment key set using the base points +// DeriveCommitmentKey generates a new commitment key set using the base points // and commitment point. The keys are derived differently depending whether the // commitment transaction is ours or the remote peer's. -func deriveCommitmentKeys(commitPoint *btcec.PublicKey, +func DeriveCommitmentKeys(commitPoint *btcec.PublicKey, isOurCommit, tweaklessCommit bool, localChanCfg, remoteChanCfg *channeldb.ChannelConfig) *CommitmentKeyRing { @@ -1711,9 +1711,8 @@ func (lc *LightningChannel) restoreCommitState( // We'll also re-create the set of commitment keys needed to // fully re-derive the state. - tweaklessCommit := (lc.channelState.ChanType == - channeldb.SingleFunderTweakless) - pendingRemoteKeyChain = deriveCommitmentKeys( + tweaklessCommit := lc.channelState.ChanType.IsTweakless() + pendingRemoteKeyChain = DeriveCommitmentKeys( pendingCommitPoint, false, tweaklessCommit, lc.localChanCfg, lc.remoteChanCfg, ) @@ -1999,8 +1998,8 @@ func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64, // With the commitment point generated, we can now generate the four // keys we'll need to reconstruct the commitment state, - tweaklessCommit := chanState.ChanType == channeldb.SingleFunderTweakless - keyRing := deriveCommitmentKeys( + tweaklessCommit := chanState.ChanType.IsTweakless() + keyRing := DeriveCommitmentKeys( commitmentPoint, false, tweaklessCommit, &chanState.LocalChanCfg, &chanState.RemoteChanCfg, ) @@ -3258,11 +3257,9 @@ func (lc *LightningChannel) SignNextCommitment() (lnwire.Sig, []lnwire.Sig, []ch // Grab the next commitment point for the remote party. This will be // used within fetchCommitmentView to derive all the keys necessary to // construct the commitment state. - tweaklessCommit := (lc.channelState.ChanType == - channeldb.SingleFunderTweakless) - keyRing := deriveCommitmentKeys( - commitPoint, false, tweaklessCommit, lc.localChanCfg, - lc.remoteChanCfg, + keyRing := DeriveCommitmentKeys( + commitPoint, false, lc.channelState.ChanType.IsTweakless(), + lc.localChanCfg, lc.remoteChanCfg, ) // Create a new commitment view which will calculate the evaluated @@ -4017,11 +4014,9 @@ func (lc *LightningChannel) ReceiveNewCommitment(commitSig lnwire.Sig, return err } commitPoint := input.ComputeCommitmentPoint(commitSecret[:]) - tweaklessCommit := (lc.channelState.ChanType == - channeldb.SingleFunderTweakless) - keyRing := deriveCommitmentKeys( - commitPoint, true, tweaklessCommit, lc.localChanCfg, - lc.remoteChanCfg, + keyRing := DeriveCommitmentKeys( + commitPoint, true, lc.channelState.ChanType.IsTweakless(), + lc.localChanCfg, lc.remoteChanCfg, ) // With the current commitment point re-calculated, construct the new @@ -5050,8 +5045,8 @@ func NewUnilateralCloseSummary(chanState *channeldb.OpenChannel, signer input.Si // First, we'll generate the commitment point and the revocation point // so we can re-construct the HTLC state and also our payment key. - tweaklessCommit := chanState.ChanType == channeldb.SingleFunderTweakless - keyRing := deriveCommitmentKeys( + tweaklessCommit := chanState.ChanType.IsTweakless() + keyRing := DeriveCommitmentKeys( commitPoint, false, tweaklessCommit, &chanState.LocalChanCfg, &chanState.RemoteChanCfg, ) @@ -5706,10 +5701,9 @@ func NewLocalForceCloseSummary(chanState *channeldb.OpenChannel, signer input.Si return nil, err } commitPoint := input.ComputeCommitmentPoint(revocation[:]) - tweaklessCommit := chanState.ChanType == channeldb.SingleFunderTweakless - keyRing := deriveCommitmentKeys( - commitPoint, true, tweaklessCommit, &chanState.LocalChanCfg, - &chanState.RemoteChanCfg, + keyRing := DeriveCommitmentKeys( + commitPoint, true, chanState.ChanType.IsTweakless(), + &chanState.LocalChanCfg, &chanState.RemoteChanCfg, ) selfScript, err := input.CommitScriptToSelf(csvTimeout, keyRing.DelayKey, keyRing.RevocationKey) diff --git a/lnwallet/wallet.go b/lnwallet/wallet.go index 0e75e585..02321baf 100644 --- a/lnwallet/wallet.go +++ b/lnwallet/wallet.go @@ -663,11 +663,11 @@ func CreateCommitmentTxns(localBalance, remoteBalance btcutil.Amount, fundingTxIn wire.TxIn, tweaklessCommit bool) (*wire.MsgTx, *wire.MsgTx, error) { - localCommitmentKeys := deriveCommitmentKeys( + localCommitmentKeys := DeriveCommitmentKeys( localCommitPoint, true, tweaklessCommit, ourChanCfg, theirChanCfg, ) - remoteCommitmentKeys := deriveCommitmentKeys( + remoteCommitmentKeys := DeriveCommitmentKeys( remoteCommitPoint, false, tweaklessCommit, ourChanCfg, theirChanCfg, )