Skip to content

Commit 571e532

Browse files
committed
tapchannel: add 2nd level information to tapscriptSweepDesc
In this commit, we add two fields to the tapscriptSweepDesc struct related to 2nd level HTLCs. First, we add the second level sig index, which is needed to be able to know where to insert our signature after we generate it. We also add an optional lnwallet.AuxSigDesc, which contains the remote party's signature, and also the sighash needed for it and a sign desc to generate it with.
1 parent 6877f4c commit 571e532

File tree

1 file changed

+55
-34
lines changed

1 file changed

+55
-34
lines changed

tapchannel/aux_sweeper.go

Lines changed: 55 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -382,26 +382,37 @@ func (a *AuxSweeper) createAndSignSweepVpackets(
382382

383383
// tapscriptSweepDesc is a helper struct that contains the tapscript tree and
384384
// the control block needed to generate a valid spend.
385-
//
386-
// TODO(roasbeef): only needs the merkle root?
387385
type tapscriptSweepDesc struct {
386+
auxSigInfo lfn.Option[lnwallet.AuxSigDesc]
387+
388388
scriptTree input.TapscriptDescriptor
389389

390390
ctrlBlockBytes []byte
391391

392-
relativeDelay fn.Option[uint64]
392+
relativeDelay lfn.Option[uint64]
393+
394+
absoluteDelay lfn.Option[uint64]
395+
396+
secondLevelSigIndex lfn.Option[uint32]
397+
}
398+
399+
// tapscriptSweepDescs contains the sweep decs for the first and second level.
400+
// Most outputs only go to the first level, but HTLCs on our local commitment
401+
// transaction go to the second level.
402+
type tapscriptSweepDescs struct {
403+
firstLevel tapscriptSweepDesc
393404

394-
absoluteDelay fn.Option[uint64] //nolint:unused
405+
secondLevel lfn.Option[tapscriptSweepDesc]
395406
}
396407

397408
// commitNoDelaySweepDesc creates a sweep desc for a commitment output that
398409
// resides on the remote party's commitment transaction. This output is a
399410
// non-delay output, so we don't need to worry about the CSV delay when
400411
// sweeping it.
401412
func commitNoDelaySweepDesc(keyRing *lnwallet.CommitmentKeyRing,
402-
csvDelay uint32) lfn.Result[tapscriptSweepDesc] {
413+
csvDelay uint32) lfn.Result[tapscriptSweepDescs] {
403414

404-
type returnType = tapscriptSweepDesc
415+
type returnType = tapscriptSweepDescs
405416

406417
// We'll make the script tree for the to remote script (we're remote as
407418
// this is their commitment transaction). We don't have an auxLeaf here
@@ -410,8 +421,8 @@ func commitNoDelaySweepDesc(keyRing *lnwallet.CommitmentKeyRing,
410421
keyRing.ToRemoteKey, input.NoneTapLeaf(),
411422
)
412423
if err != nil {
413-
return lfn.Errf[returnType]("unable to make remote script "+
414-
"tree: %w", err)
424+
return lfn.Errf[returnType]("unable to make remote "+
425+
"script tree: %w", err)
415426
}
416427

417428
// Now that we have the script tree, we'll make the control block
@@ -420,29 +431,29 @@ func commitNoDelaySweepDesc(keyRing *lnwallet.CommitmentKeyRing,
420431
input.ScriptPathSuccess,
421432
)
422433
if err != nil {
423-
return lfn.Errf[returnType]("unable to make ctrl block: %w",
424-
err)
425434
}
426435
ctrlBlockBytes, err := ctrlBlock.ToBytes()
427436
if err != nil {
428-
return lfn.Errf[returnType]("unable to encode ctrl block: %w",
429-
err)
437+
return lfn.Errf[returnType]("unable to encode ctrl "+
438+
"block: %w", err)
430439
}
431440

432-
return lfn.Ok(tapscriptSweepDesc{
433-
scriptTree: toRemoteScriptTree,
434-
relativeDelay: fn.Some(uint64(csvDelay)),
435-
ctrlBlockBytes: ctrlBlockBytes,
441+
return lfn.Ok(tapscriptSweepDescs{
442+
firstLevel: tapscriptSweepDesc{
443+
scriptTree: toRemoteScriptTree,
444+
relativeDelay: lfn.Some(uint64(csvDelay)),
445+
ctrlBlockBytes: ctrlBlockBytes,
446+
},
436447
})
437448
}
438449

439450
// commitDelaySweepDesc creates a sweep desc for a commitment output that
440451
// resides on our local commitment transaction. This output is a delay output,
441452
// so we need to mind the CSV delay when sweeping it.
442453
func commitDelaySweepDesc(keyRing *lnwallet.CommitmentKeyRing,
443-
csvDelay uint32) lfn.Result[tapscriptSweepDesc] {
454+
csvDelay uint32) lfn.Result[tapscriptSweepDescs] {
444455

445-
type returnType = tapscriptSweepDesc
456+
type returnType = tapscriptSweepDescs
446457

447458
// We'll make the script tree for the to remote script (we're remote as
448459
// this is their commitment transaction). We don't have an auxLeaf here
@@ -461,27 +472,28 @@ func commitDelaySweepDesc(keyRing *lnwallet.CommitmentKeyRing,
461472
input.ScriptPathSuccess,
462473
)
463474
if err != nil {
464-
return lfn.Err[returnType](err)
465475
}
466476
ctrlBlockBytes, err := ctrlBlock.ToBytes()
467477
if err != nil {
468478
return lfn.Err[returnType](err)
469479
}
470480

471-
return lfn.Ok(tapscriptSweepDesc{
472-
scriptTree: toLocalScriptTree,
473-
relativeDelay: fn.Some(uint64(csvDelay)),
474-
ctrlBlockBytes: ctrlBlockBytes,
481+
return lfn.Ok(tapscriptSweepDescs{
482+
firstLevel: tapscriptSweepDesc{
483+
scriptTree: toLocalScriptTree,
484+
relativeDelay: lfn.Some(uint64(csvDelay)),
485+
ctrlBlockBytes: ctrlBlockBytes,
486+
},
475487
})
476488
}
477489

478490
// commitRevokeSweepDesc creates a sweep desc for a commitment output that is
479491
// the local output on the remote party's commitment transaction. We can seep
480492
// this in the case of a revoked commitment.
481493
func commitRevokeSweepDesc(keyRing *lnwallet.CommitmentKeyRing,
482-
csvDelay uint32) lfn.Result[tapscriptSweepDesc] {
494+
csvDelay uint32) lfn.Result[tapscriptSweepDescs] {
483495

484-
type returnType = tapscriptSweepDesc
496+
type returnType = tapscriptSweepDescs
485497

486498
// To sweep their revoked output, we'll make the script tree for the
487499
// local tree of their commitment transaction, which is actually their
@@ -504,12 +516,14 @@ func commitRevokeSweepDesc(keyRing *lnwallet.CommitmentKeyRing,
504516
}
505517
ctrlBlockBytes, err := ctrlBlock.ToBytes()
506518
if err != nil {
507-
return lfn.Err[returnType](err)
519+
return lfn.Err[tapscriptSweepDescs](err)
508520
}
509521

510-
return lfn.Ok(tapscriptSweepDesc{
511-
scriptTree: toLocalScriptTree,
512-
ctrlBlockBytes: ctrlBlockBytes,
522+
return lfn.Ok(tapscriptSweepDescs{
523+
firstLevel: tapscriptSweepDesc{
524+
scriptTree: toLocalScriptTree,
525+
ctrlBlockBytes: ctrlBlockBytes,
526+
},
513527
})
514528
}
515529

@@ -1159,7 +1173,7 @@ func (a *AuxSweeper) resolveContract(
11591173
}
11601174

11611175
var (
1162-
sweepDesc lfn.Result[tapscriptSweepDesc]
1176+
sweepDesc lfn.Result[tapscriptSweepDescs]
11631177
assetOutputs []*cmsg.AssetOutput
11641178
)
11651179

@@ -1192,13 +1206,13 @@ func (a *AuxSweeper) resolveContract(
11921206
// The remote party has breached the channel. We'll sweep the revoked
11931207
// key that we learned in the past.
11941208
case input.TaprootCommitmentRevoke:
1195-
// In this case, we'll be sweeping the remote party's asset
11961209
// outputs, as they broadcast a revoked commitment. For the
1210+
// In this case, we'll be sweeping the remote party's asset
11971211
// remote party, this is actually their local output.
11981212
assetOutputs = commitState.LocalAssets.Val.Outputs
11991213

1200-
// As we have multiple outputs to sweep above, we'll also have
1201-
// two sweep descs.
1214+
// Next, we'll make a sweep desk capable of sweeping the remote
1215+
// party's local output.
12021216
sweepDesc = commitRevokeSweepDesc(req.KeyRing, req.CsvDelay)
12031217

12041218
default:
@@ -1216,10 +1230,17 @@ func (a *AuxSweeper) resolveContract(
12161230
log.Infof("Sweeping %v asset outputs: %v", len(assetOutputs),
12171231
limitSpewer.Sdump(assetOutputs))
12181232

1233+
firstLevelSweepDesc := lfn.AndThen(
1234+
sweepDesc,
1235+
func(sweepDesc tapscriptSweepDescs) lfn.Result[tapscriptSweepDesc] { //nolint:lll
1236+
return lfn.Ok(sweepDesc.firstLevel)
1237+
},
1238+
)
1239+
12191240
// With the sweep desc constructed above, we'll create vPackets for
12201241
// each of the local assets, then sign them all.
12211242
sPkts := a.createAndSignSweepVpackets(
1222-
assetOutputs, req.SignDesc, sweepDesc,
1243+
assetOutputs, req.SignDesc, firstLevelSweepDesc,
12231244
)
12241245

12251246
// With the vPackets fully generated and signed above, we'll serialize

0 commit comments

Comments
 (0)