@@ -4028,16 +4028,20 @@ func (lc *LightningChannel) createCommitDiff(newCommit *commitment,
40284028 if err != nil {
40294029 return nil , fmt .Errorf ("error packing aux sigs: %w" , err )
40304030 }
4031+ auxBlobRecords , err := lnwire .ParseCustomRecords (auxSigBlob )
4032+ if err != nil {
4033+ return nil , fmt .Errorf ("error parsing aux sigs: %w" , err )
4034+ }
40314035
40324036 return & channeldb.CommitDiff {
40334037 Commitment : * diskCommit ,
40344038 CommitSig : & lnwire.CommitSig {
40354039 ChanID : lnwire .NewChanIDFromOutPoint (
40364040 lc .channelState .FundingOutpoint ,
40374041 ),
4038- CommitSig : commitSig ,
4039- HtlcSigs : htlcSigs ,
4040- ExtraData : auxSigBlob ,
4042+ CommitSig : commitSig ,
4043+ HtlcSigs : htlcSigs ,
4044+ CustomRecords : auxBlobRecords ,
40414045 },
40424046 LogUpdates : logUpdates ,
40434047 OpenedCircuitKeys : openCircuitKeys ,
@@ -4737,17 +4741,44 @@ func (lc *LightningChannel) SignNextCommitment() (*NewCommitState, error) {
47374741 // latest commitment update.
47384742 lc .remoteCommitChain .addCommitment (newCommitView )
47394743
4744+ auxSigBlob , err := commitDiff .CommitSig .CustomRecords .Serialize ()
4745+ if err != nil {
4746+ return nil , fmt .Errorf ("unable to serialize aux sig " +
4747+ "blob: %v" , err )
4748+ }
4749+
47404750 return & NewCommitState {
47414751 CommitSigs : & CommitSigs {
47424752 CommitSig : sig ,
47434753 HtlcSigs : htlcSigs ,
47444754 PartialSig : lnwire .MaybePartialSigWithNonce (partialSig ),
4745- AuxSigBlob : commitDiff . CommitSig . ExtraData ,
4755+ AuxSigBlob : auxSigBlob ,
47464756 },
47474757 PendingHTLCs : commitDiff .Commitment .Htlcs ,
47484758 }, nil
47494759}
47504760
4761+ // resignMusigCommit is used to resign a commitment transaction for taproot
4762+ // channels when we need to retransmit a signature after a channel reestablish
4763+ // message. Taproot channels use musig2, which means we must use fresh nonces
4764+ // each time. After we receive the channel reestablish message, we learn the
4765+ // nonce we need to use for the remote party. As a result, we need to generate
4766+ // the partial signature again with the new nonce.
4767+ func (lc * LightningChannel ) resignMusigCommit (commitTx * wire.MsgTx ,
4768+ ) (lnwire.OptPartialSigWithNonceTLV , error ) {
4769+
4770+ remoteSession := lc .musigSessions .RemoteSession
4771+ musig , err := remoteSession .SignCommit (commitTx )
4772+ if err != nil {
4773+ var none lnwire.OptPartialSigWithNonceTLV
4774+ return none , err
4775+ }
4776+
4777+ partialSig := lnwire .MaybePartialSigWithNonce (musig .ToWireSig ())
4778+
4779+ return partialSig , nil
4780+ }
4781+
47514782// ProcessChanSyncMsg processes a ChannelReestablish message sent by the remote
47524783// connection upon re establishment of our connection with them. This method
47534784// will return a single message if we are currently out of sync, otherwise a
@@ -4939,13 +4970,23 @@ func (lc *LightningChannel) ProcessChanSyncMsg(
49394970 // If we signed this state, then we'll accumulate
49404971 // another update to send over.
49414972 case err == nil :
4973+ blobRecords , err := lnwire .ParseCustomRecords (
4974+ newCommit .AuxSigBlob ,
4975+ )
4976+ if err != nil {
4977+ sErr := fmt .Errorf ("error parsing " +
4978+ "aux sigs: %w" , err )
4979+ return nil , nil , nil , sErr
4980+ }
4981+
49424982 commitSig := & lnwire.CommitSig {
49434983 ChanID : lnwire .NewChanIDFromOutPoint (
49444984 lc .channelState .FundingOutpoint ,
49454985 ),
4946- CommitSig : newCommit .CommitSig ,
4947- HtlcSigs : newCommit .HtlcSigs ,
4948- PartialSig : newCommit .PartialSig ,
4986+ CommitSig : newCommit .CommitSig ,
4987+ HtlcSigs : newCommit .HtlcSigs ,
4988+ PartialSig : newCommit .PartialSig ,
4989+ CustomRecords : blobRecords ,
49494990 }
49504991
49514992 updates = append (updates , commitSig )
@@ -5025,12 +5066,23 @@ func (lc *LightningChannel) ProcessChanSyncMsg(
50255066 commitUpdates = append (commitUpdates , logUpdate .UpdateMsg )
50265067 }
50275068
5069+ // If this is a taproot channel, then we need to regenerate the
5070+ // musig2 signature for the remote party, using their fresh
5071+ // nonce.
5072+ if lc .channelState .ChanType .IsTaproot () {
5073+ partialSig , err := lc .resignMusigCommit (
5074+ commitDiff .Commitment .CommitTx ,
5075+ )
5076+ if err != nil {
5077+ return nil , nil , nil , err
5078+ }
5079+
5080+ commitDiff .CommitSig .PartialSig = partialSig
5081+ }
5082+
50285083 // With the batch of updates accumulated, we'll now re-send the
50295084 // original CommitSig message required to re-sync their remote
50305085 // commitment chain with our local version of their chain.
5031- //
5032- // TODO(roasbeef): need to re-sign commitment states w/
5033- // fresh nonce
50345086 commitUpdates = append (commitUpdates , commitDiff .CommitSig )
50355087
50365088 // NOTE: If a revocation is not owed, then updates is empty.
@@ -5500,9 +5552,9 @@ func genHtlcSigValidationJobs(chanState *channeldb.OpenChannel,
55005552 // store in the custom records map so we can write to
55015553 // disk later.
55025554 sigType := htlcCustomSigType .TypeVal ()
5503- htlc . CustomRecords [ uint64 ( sigType )] = auxSig . UnwrapOr (
5504- nil ,
5505- )
5555+ auxSig . WhenSome ( func ( sigB tlv. Blob ) {
5556+ htlc . CustomRecords [ uint64 ( sigType )] = sigB
5557+ } )
55065558
55075559 auxVerifyJobs = append (auxVerifyJobs , auxVerifyJob )
55085560 }
0 commit comments