diff --git a/htlcswitch/link.go b/htlcswitch/link.go index ad37ac1782..25c971308c 100644 --- a/htlcswitch/link.go +++ b/htlcswitch/link.go @@ -698,7 +698,6 @@ func (l *channelLink) syncChanStates() error { return fmt.Errorf("unable to generate chan sync message for "+ "ChannelPoint(%v)", l.channel.ChannelPoint()) } - if err := l.cfg.Peer.SendMessage(true, localChanSyncMsg); err != nil { return fmt.Errorf("unable to send chan sync message for "+ "ChannelPoint(%v): %v", l.channel.ChannelPoint(), err) @@ -738,6 +737,13 @@ func (l *channelLink) syncChanStates() error { l.ChanID(), nextRevocation, ) + // If this is a taproot channel, then we'll send the + // very same nonce that we sent above, as they should + // take the latest verification nonce we send. + if chanState.ChanType.IsTaproot() { + fundingLockedMsg.NextLocalNonce = localChanSyncMsg.LocalNonce + } + // For channels that negotiated the option-scid-alias // feature bit, ensure that we send over the alias in // the funding_locked message. We'll send the first @@ -1930,8 +1936,8 @@ func (l *channelLink) handleUpstreamMsg(msg lnwire.Message) { // chain, validate this new commitment, closing the link if // invalid. err = l.channel.ReceiveNewCommitment(&lnwallet.CommitSigs{ - CommitSig: msg.CommitSig, - HtlcSigs: msg.HtlcSigs, + CommitSig: msg.CommitSig, + HtlcSigs: msg.HtlcSigs, }) if err != nil { // If we were unable to reconstruct their proposed @@ -2309,9 +2315,9 @@ func (l *channelLink) updateCommitTx() error { } commitSig := &lnwire.CommitSig{ - ChanID: l.ChanID(), - CommitSig: newCommit.CommitSig, - HtlcSigs: newCommit.HtlcSigs, + ChanID: l.ChanID(), + CommitSig: newCommit.CommitSig, + HtlcSigs: newCommit.HtlcSigs, } l.cfg.Peer.SendMessage(false, commitSig) diff --git a/lnwallet/channel.go b/lnwallet/channel.go index dc3734778a..3ca8e3ee4d 100644 --- a/lnwallet/channel.go +++ b/lnwallet/channel.go @@ -4094,8 +4094,6 @@ func (lc *LightningChannel) ProcessChanSyncMsg( msg *lnwire.ChannelReestablish) ([]lnwire.Message, []models.CircuitKey, []models.CircuitKey, error) { - // TODO(roasbeef): need to replace w/ received nonces - // Now we'll examine the state we have, vs what was contained in the // chain sync message. If we're de-synchronized, then we'll send a // batch of messages which when applied will kick start the chain @@ -4135,6 +4133,25 @@ func (lc *LightningChannel) ProcessChanSyncMsg( } } + // If this is a taproot channel, then we expect that the remote party + // has sent the next verification nonce. If they haven't, then we'll + // bail out, otherwise we'll init our local session then continue as + // normal. + switch { + case lc.channelState.ChanType.IsTaproot() && msg.LocalNonce == nil: + return nil, nil, nil, fmt.Errorf("remote verification nonce " + + "not sent") + + case lc.channelState.ChanType.IsTaproot() && msg.LocalNonce != nil: + err := lc.InitRemoteMusigNonces(&musig2.Nonces{ + PubNonce: *msg.LocalNonce, + }) + if err != nil { + return nil, nil, nil, fmt.Errorf("unable to init "+ + "remote nonce: %w", err) + } + } + // If we detect that this is is a restored channel, then we can skip a // portion of the verification, as we already know that we're unable to // proceed with any updates. @@ -4212,12 +4229,12 @@ func (lc *LightningChannel) ProcessChanSyncMsg( "while we have %v, we owe them a revocation", msg.RemoteCommitTailHeight, localTailHeight) - revocationMsg, err := lc.generateRevocation( - localTailHeight - 1, - ) + heightToRetransmit := localTailHeight - 1 + revocationMsg, err := lc.generateRevocation(heightToRetransmit) if err != nil { return nil, nil, nil, err } + updates = append(updates, revocationMsg) // Next, as a precaution, we'll check a special edge case. If