Skip to content

Commit fb66bd2

Browse files
authored
Merge pull request #9032 from lightningnetwork/htlc-aux-sig-retransmission
lnwallet: properly set aux HTLC blob on retransmission
2 parents e78b0bb + 5058432 commit fb66bd2

File tree

12 files changed

+643
-112
lines changed

12 files changed

+643
-112
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ require (
6262
google.golang.org/protobuf v1.33.0
6363
gopkg.in/macaroon-bakery.v2 v2.0.1
6464
gopkg.in/macaroon.v2 v2.0.0
65+
pgregory.net/rapid v1.1.0
6566
)
6667

6768
require (

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,6 +1070,8 @@ modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
10701070
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
10711071
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
10721072
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
1073+
pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw=
1074+
pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=
10731075
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
10741076
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
10751077
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

htlcswitch/link.go

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2164,11 +2164,21 @@ func (l *channelLink) handleUpstreamMsg(msg lnwire.Message) {
21642164
// We just received a new updates to our local commitment
21652165
// chain, validate this new commitment, closing the link if
21662166
// invalid.
2167+
auxSigBlob, err := msg.CustomRecords.Serialize()
2168+
if err != nil {
2169+
l.fail(
2170+
LinkFailureError{code: ErrInternalError},
2171+
"unable to serialize custom records: %v",
2172+
err,
2173+
)
2174+
2175+
return
2176+
}
21672177
err = l.channel.ReceiveNewCommitment(&lnwallet.CommitSigs{
21682178
CommitSig: msg.CommitSig,
21692179
HtlcSigs: msg.HtlcSigs,
21702180
PartialSig: msg.PartialSig,
2171-
AuxSigBlob: msg.ExtraData,
2181+
AuxSigBlob: auxSigBlob,
21722182
})
21732183
if err != nil {
21742184
// If we were unable to reconstruct their proposed
@@ -2577,12 +2587,17 @@ func (l *channelLink) updateCommitTx() error {
25772587
default:
25782588
}
25792589

2590+
auxBlobRecords, err := lnwire.ParseCustomRecords(newCommit.AuxSigBlob)
2591+
if err != nil {
2592+
return fmt.Errorf("error parsing aux sigs: %w", err)
2593+
}
2594+
25802595
commitSig := &lnwire.CommitSig{
2581-
ChanID: l.ChanID(),
2582-
CommitSig: newCommit.CommitSig,
2583-
HtlcSigs: newCommit.HtlcSigs,
2584-
PartialSig: newCommit.PartialSig,
2585-
ExtraData: newCommit.AuxSigBlob,
2596+
ChanID: l.ChanID(),
2597+
CommitSig: newCommit.CommitSig,
2598+
HtlcSigs: newCommit.HtlcSigs,
2599+
PartialSig: newCommit.PartialSig,
2600+
CustomRecords: auxBlobRecords,
25862601
}
25872602
l.cfg.Peer.SendMessage(false, commitSig)
25882603

lnwallet/channel.go

Lines changed: 65 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)