Skip to content

Commit 86fb985

Browse files
committed
tapchannel: tweak HTLC second level transaction internal key
1 parent 645b950 commit 86fb985

File tree

4 files changed

+28
-20
lines changed

4 files changed

+28
-20
lines changed

tapchannel/aux_leaf_creator.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ func FetchLeavesFromCommit(chainParams *address.ChainParams,
129129
leaf, err := CreateSecondLevelHtlcTx(
130130
chanState, com.CommitTx, htlc.Amt.ToSatoshis(),
131131
keys, chainParams, htlcOutputs, cltvTimeout,
132+
htlc.HtlcIndex,
132133
)
133134
if err != nil {
134135
return lfn.Err[returnType](fmt.Errorf("unable "+
@@ -169,6 +170,7 @@ func FetchLeavesFromCommit(chainParams *address.ChainParams,
169170
leaf, err := CreateSecondLevelHtlcTx(
170171
chanState, com.CommitTx, htlc.Amt.ToSatoshis(),
171172
keys, chainParams, htlcOutputs, cltvTimeout,
173+
htlc.HtlcIndex,
172174
)
173175
if err != nil {
174176
return lfn.Err[returnType](fmt.Errorf("unable "+

tapchannel/aux_leaf_signer.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ func verifyHtlcSignature(chainParams *address.ChainParams,
369369

370370
vPackets, err := htlcSecondLevelPacketsFromCommit(
371371
chainParams, chanState, commitTx, baseJob.KeyRing, htlcOutputs,
372-
baseJob, htlcTimeout,
372+
baseJob, htlcTimeout, baseJob.HTLC.HtlcIndex,
373373
)
374374
if err != nil {
375375
return fmt.Errorf("error generating second level packets: %w",
@@ -513,7 +513,7 @@ func (s *AuxLeafSigner) generateHtlcSignature(chanState lnwallet.AuxChanState,
513513

514514
vPackets, err := htlcSecondLevelPacketsFromCommit(
515515
s.cfg.ChainParams, chanState, commitTx, baseJob.KeyRing,
516-
htlcOutputs, baseJob, htlcTimeout,
516+
htlcOutputs, baseJob, htlcTimeout, baseJob.HTLC.HtlcIndex,
517517
)
518518
if err != nil {
519519
return lnwallet.AuxSigJobResp{}, fmt.Errorf("error generating "+
@@ -601,12 +601,12 @@ func (s *AuxLeafSigner) generateHtlcSignature(chanState lnwallet.AuxChanState,
601601
func htlcSecondLevelPacketsFromCommit(chainParams *address.ChainParams,
602602
chanState lnwallet.AuxChanState, commitTx *wire.MsgTx,
603603
keyRing lnwallet.CommitmentKeyRing, htlcOutputs []*cmsg.AssetOutput,
604-
baseJob lnwallet.BaseAuxJob,
605-
htlcTimeout fn.Option[uint32]) ([]*tappsbt.VPacket, error) {
604+
baseJob lnwallet.BaseAuxJob, htlcTimeout fn.Option[uint32],
605+
htlcIndex uint64) ([]*tappsbt.VPacket, error) {
606606

607607
packets, _, err := CreateSecondLevelHtlcPackets(
608608
chanState, commitTx, baseJob.HTLC.Amount.ToSatoshis(),
609-
keyRing, chainParams, htlcOutputs, htlcTimeout,
609+
keyRing, chainParams, htlcOutputs, htlcTimeout, htlcIndex,
610610
)
611611
if err != nil {
612612
return nil, fmt.Errorf("error creating second level HTLC "+

tapchannel/aux_sweeper.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,12 @@ func (a *AuxSweeper) createSweepVpackets(sweepInputs []*cmsg.AssetOutput,
217217
cltvTimeout = fn.Some(uint32(delay))
218218
})
219219

220+
htlcIndex := resReq.HtlcID.UnwrapOr(math.MaxUint64)
220221
alloc, err := createSecondLevelHtlcAllocations(
221222
resReq.ChanType, resReq.Initiator, sweepInputs,
222223
resReq.HtlcAmt, resReq.CommitCsvDelay, *resReq.KeyRing,
223224
fn.Some(resReq.ContractPoint.Index), cltvTimeout,
225+
htlcIndex,
224226
)
225227
if err != nil {
226228
return lfn.Err[returnType](err)
@@ -364,8 +366,7 @@ func (a *AuxSweeper) signSweepVpackets(vPackets []*tappsbt.VPacket,
364366
// tweaks to generate the key we'll use to verify the
365367
// signature.
366368
signingKey, leafToSign := applySignDescToVIn(
367-
signDesc, vIn, &a.cfg.ChainParams,
368-
tapTweak,
369+
signDesc, vIn, &a.cfg.ChainParams, tapTweak,
369370
)
370371

371372
// In this case, the witness isn't special, so we'll set the
@@ -876,7 +877,7 @@ func localHtlcTimeoutSweepDesc(req lnwallet.ResolutionReq,
876877
// As this is an HTLC on our local commitment transaction, we'll also
877878
// need to generate a sweep desc for second level HTLC.
878879
secondLevelScriptTree, err := input.TaprootSecondLevelScriptTree(
879-
req.KeyRing.RevocationKey, req.KeyRing.ToLocalKey,
880+
tweakedKeyRing.RevocationKey, req.KeyRing.ToLocalKey,
880881
req.CommitCsvDelay, lfn.None[txscript.TapLeaf](),
881882
)
882883
if err != nil {
@@ -978,7 +979,7 @@ func localHtlcSuccessSweepDesc(req lnwallet.ResolutionReq,
978979
// As this is an HTLC on our local commitment transaction, we'll also
979980
// need to generate a sweep desc for second level HTLC.
980981
secondLevelScriptTree, err := input.TaprootSecondLevelScriptTree(
981-
req.KeyRing.RevocationKey, req.KeyRing.ToLocalKey,
982+
tweakedKeyRing.RevocationKey, req.KeyRing.ToLocalKey,
982983
req.CommitCsvDelay, lfn.None[txscript.TapLeaf](),
983984
)
984985
if err != nil {
@@ -2408,9 +2409,7 @@ func (a *AuxSweeper) registerAndBroadcastSweep(req *sweep.BumpRequest,
24082409
}
24092410

24102411
// Now that we have our vPkts, we'll re-create the output commitments.
2411-
outCommitments, err := tapsend.CreateOutputCommitments(
2412-
vPkts.allPkts(),
2413-
)
2412+
outCommitments, err := tapsend.CreateOutputCommitments(vPkts.allPkts())
24142413
if err != nil {
24152414
return fmt.Errorf("unable to create output "+
24162415
"commitments: %w", err)

tapchannel/commitment.go

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,7 +1260,7 @@ func createSecondLevelHtlcAllocations(chanType channeldb.ChannelType,
12601260
initiator bool, htlcOutputs []*cmsg.AssetOutput, htlcAmt btcutil.Amount,
12611261
commitCsvDelay uint32, keys lnwallet.CommitmentKeyRing,
12621262
outputIndex fn.Option[uint32], htlcTimeout fn.Option[uint32],
1263-
) ([]*Allocation, error) {
1263+
htlcIndex uint64) ([]*Allocation, error) {
12641264

12651265
// TODO(roasbeef): thaw height not implemented for taproot chans rn
12661266
// (lease expiry)
@@ -1281,6 +1281,13 @@ func createSecondLevelHtlcAllocations(chanType channeldb.ChannelType,
12811281
"script sibling: %w", err)
12821282
}
12831283

1284+
// To ensure uniqueness of the script key across HTLCs with the same
1285+
// payment hash and timeout (which would be equal otherwise), we tweak
1286+
// the asset level internal key of the second-level script key as well
1287+
// with the HTLC index. We'll ONLY use this for the asset level, NOT for
1288+
// the BTC level.
1289+
tweakedTree := TweakHtlcTree(htlcTree, htlcIndex)
1290+
12841291
allocations := []*Allocation{{
12851292
Type: SecondLevelHtlcAllocation,
12861293
// If we're making the second-level transaction just to sign,
@@ -1296,12 +1303,12 @@ func createSecondLevelHtlcAllocations(chanType channeldb.ChannelType,
12961303
),
12971304
InternalKey: htlcTree.InternalKey,
12981305
NonAssetLeaves: sibling,
1299-
ScriptKey: asset.NewScriptKey(htlcTree.TaprootKey),
1306+
ScriptKey: asset.NewScriptKey(tweakedTree.TaprootKey),
13001307
SortTaprootKeyBytes: schnorr.SerializePubKey(
13011308
htlcTree.TaprootKey,
13021309
),
1303-
// TODO(roasbeef): don't need it here?
1304-
CLTV: htlcTimeout.UnwrapOr(0),
1310+
CLTV: htlcTimeout.UnwrapOr(0),
1311+
HtlcIndex: htlcIndex,
13051312
}}
13061313

13071314
return allocations, nil
@@ -1313,12 +1320,12 @@ func CreateSecondLevelHtlcPackets(chanState lnwallet.AuxChanState,
13131320
commitTx *wire.MsgTx, htlcAmt btcutil.Amount,
13141321
keys lnwallet.CommitmentKeyRing, chainParams *address.ChainParams,
13151322
htlcOutputs []*cmsg.AssetOutput, htlcTimeout fn.Option[uint32],
1316-
) ([]*tappsbt.VPacket, []*Allocation, error) {
1323+
htlcIndex uint64) ([]*tappsbt.VPacket, []*Allocation, error) {
13171324

13181325
allocations, err := createSecondLevelHtlcAllocations(
13191326
chanState.ChanType, chanState.IsInitiator,
13201327
htlcOutputs, htlcAmt, uint32(chanState.LocalChanCfg.CsvDelay),
1321-
keys, fn.None[uint32](), htlcTimeout,
1328+
keys, fn.None[uint32](), htlcTimeout, htlcIndex,
13221329
)
13231330
if err != nil {
13241331
return nil, nil, err
@@ -1364,13 +1371,13 @@ func CreateSecondLevelHtlcTx(chanState lnwallet.AuxChanState,
13641371
commitTx *wire.MsgTx, htlcAmt btcutil.Amount,
13651372
keys lnwallet.CommitmentKeyRing, chainParams *address.ChainParams,
13661373
htlcOutputs []*cmsg.AssetOutput, htlcTimeout fn.Option[uint32],
1367-
) (input.AuxTapLeaf, error) {
1374+
htlcIndex uint64) (input.AuxTapLeaf, error) {
13681375

13691376
none := input.NoneTapLeaf()
13701377

13711378
vPackets, allocations, err := CreateSecondLevelHtlcPackets(
13721379
chanState, commitTx, htlcAmt, keys, chainParams, htlcOutputs,
1373-
htlcTimeout,
1380+
htlcTimeout, htlcIndex,
13741381
)
13751382
if err != nil {
13761383
return none, fmt.Errorf("error creating second level HTLC "+

0 commit comments

Comments
 (0)