Skip to content

Commit 768c343

Browse files
committed
tapchannel: update signSweepVpackets to be 2nd level HTLC aware
In this commit, we update `signSweepVpackets` to be 2nd level HTLC aware. If we have an auxSigDesc, then that means we're spending a 2nd level HTLC txn. To spend this properly, we'll need to insert the remote party's signature at the proper location, as it's a 2-of-2 multi-sig.
1 parent 66ea173 commit 768c343

File tree

1 file changed

+55
-5
lines changed

1 file changed

+55
-5
lines changed

tapchannel/aux_sweeper.go

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"math"
88
"net/url"
9+
"slices"
910
"sync"
1011
"sync/atomic"
1112

@@ -327,12 +328,14 @@ func (a *AuxSweeper) createSweepVpackets(sweepInputs []*cmsg.AssetOutput,
327328
// signSweepVpackets attempts to sign the vPackets specified using the passed
328329
// sign desc and script tree.
329330
func (a *AuxSweeper) signSweepVpackets(vPackets []*tappsbt.VPacket,
330-
signDesc input.SignDescriptor, tapscriptDesc tapscriptSweepDesc) error {
331+
signDesc input.SignDescriptor, tapTweak, ctrlBlock []byte,
332+
auxSigDesc lfn.Option[lnwallet.AuxSigDesc],
333+
secondLevelSigIndex lfn.Option[uint32]) error {
331334

332335
// Before we sign below, we also need to generate the tapscript With
333336
// the vPackets prepared, we can now sign the output asset we'll create
334337
// at a later step.
335-
for _, vPacket := range vPackets {
338+
for vPktIndex, vPacket := range vPackets {
336339
if len(vPacket.Inputs) != 1 {
337340
return fmt.Errorf("expected single input, got %v",
338341
len(vPacket.Inputs))
@@ -348,12 +351,12 @@ func (a *AuxSweeper) signSweepVpackets(vPackets []*tappsbt.VPacket,
348351
// signature.
349352
signingKey, leafToSign := applySignDescToVIn(
350353
signDesc, vIn, &a.cfg.ChainParams,
351-
tapscriptDesc.scriptTree.TapTweak(),
354+
tapTweak,
352355
)
353356

354357
// In this case, the witness isn't special, so we'll set the
355358
// control block now for it.
356-
ctrlBlock := tapscriptDesc.ctrlBlockBytes
359+
ctrlBlock := ctrlBlock
357360
vIn.TaprootLeafScript[0].ControlBlock = ctrlBlock
358361

359362
log.Debugf("signing vPacket for input=%v",
@@ -378,6 +381,50 @@ func (a *AuxSweeper) signSweepVpackets(vPackets []*tappsbt.VPacket,
378381
return fmt.Errorf("error signing virtual packet, " +
379382
"got no sig")
380383
}
384+
385+
// At this point, the witness looks like: <sig> <witnessScript>
386+
// <ctrlBlock>. This is a second level transaction, so we have
387+
// another signature that we need to add to the witness this
388+
// additional signature for the multi-sig.
389+
err = lfn.MapOptionZ(
390+
auxSigDesc,
391+
func(aux lnwallet.AuxSigDesc) error {
392+
assetSigs, err := cmsg.DecodeAssetSigListRecord(
393+
aux.AuxSig,
394+
)
395+
if err != nil {
396+
return fmt.Errorf("error "+
397+
"decoding asset sig list "+
398+
"record: %w", err)
399+
}
400+
auxSig := assetSigs.Sigs[vPktIndex]
401+
402+
// With the sig obtained, we'll now insert the
403+
// signature at the specified index.
404+
sigIndex, err := secondLevelSigIndex.UnwrapOrErr( //nolint:lll
405+
fmt.Errorf("no sig index"),
406+
)
407+
if err != nil {
408+
return err
409+
}
410+
411+
auxSigBytes := append(
412+
auxSig.Sig.Val.RawBytes(),
413+
byte(auxSig.SigHashType.Val),
414+
)
415+
416+
newAsset := vPacket.Outputs[0].Asset
417+
418+
prevWitness := newAsset.PrevWitnesses[0].TxWitness //nolint:lll
419+
prevWitness = slices.Insert(
420+
prevWitness, int(sigIndex), auxSigBytes,
421+
)
422+
return newAsset.UpdateTxWitness(0, prevWitness)
423+
},
424+
)
425+
if err != nil {
426+
return err
427+
}
381428
}
382429

383430
return nil
@@ -400,7 +447,10 @@ func (a *AuxSweeper) createAndSignSweepVpackets(
400447
signPkts := func(vPkts []*tappsbt.VPacket,
401448
desc tapscriptSweepDesc) lfn.Result[[]*tappsbt.VPacket] {
402449

403-
err := a.signSweepVpackets(vPkts, resReq.SignDesc, desc)
450+
err := a.signSweepVpackets(
451+
vPkts, resReq.SignDesc, nil, nil,
452+
lfn.None[lnwallet.AuxSigDesc](), lfn.None[uint32](),
453+
)
404454
if err != nil {
405455
return lfn.Err[returnType](err)
406456
}

0 commit comments

Comments
 (0)