Skip to content

Commit a05313d

Browse files
committed
tapchannel: update registerAndBroadcastSweep for HTLC sweeps
In this commit, we update `registerAndBroadcastSweep` to be able to handle HTLC sweeps. First, we only need to set the anchor for first level sweeps. We weren't able to sign the 2nd level sweeps earlier as we didn't know the txid of the transaction that swept them. Now that we're about to broadcast, we know the sweeping transaction so we can set the prevID properly, then sign the sweeping transaction. If the sweeper is broadcasting _just_ a second level txn with an asset, then we won't have an extra change output. This transaction also already has its internal key bound.
1 parent 9fdac50 commit a05313d

File tree

1 file changed

+71
-17
lines changed

1 file changed

+71
-17
lines changed

tapchannel/aux_sweeper.go

Lines changed: 71 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1758,6 +1758,7 @@ func (a *AuxSweeper) resolveContract(
17581758
default:
17591759
return lfn.Errf[returnType]("unknown resolution type: %v",
17601760
req.Type)
1761+
// TODO(roasbeef): need to do HTLC revocation casesj:w
17611762
}
17621763

17631764
// The input proofs above were made originally using the fake commit tx
@@ -2240,34 +2241,87 @@ func (a *AuxSweeper) registerAndBroadcastSweep(req *sweep.BumpRequest,
22402241
return nil
22412242
}
22422243

2243-
ourSweepOutput, err := req.ExtraTxOut.UnwrapOrErr(
2244-
fmt.Errorf("extra tx out not populated"),
2244+
// If this is a transaction that's only sweeping HTLC outputs via a
2245+
// pre-signed transaction, then we won't actually have an extra sweep
2246+
// output.
2247+
err = lfn.MapOptionZ(
2248+
req.ExtraTxOut,
2249+
func(extraTxOut sweep.SweepOutput) error {
2250+
ourSweepOutput, err := req.ExtraTxOut.UnwrapOrErr(
2251+
fmt.Errorf("extra tx out not populated"),
2252+
)
2253+
if err != nil {
2254+
return err
2255+
}
2256+
iKey, err := ourSweepOutput.InternalKey.UnwrapOrErr(
2257+
fmt.Errorf("internal key not populated"),
2258+
)
2259+
if err != nil {
2260+
return err
2261+
}
2262+
2263+
// We'll also use the passed in context to set the
2264+
// anchor key again for all the vOuts, but only for
2265+
// first level vPkts, as second level packets already
2266+
// commit to the internal key of the vOut.
2267+
vPkts := vPkts.directSpendPkts()
2268+
for idx := range vPkts {
2269+
for _, vOut := range vPkts[idx].Outputs {
2270+
vOut.SetAnchorInternalKey(
2271+
iKey,
2272+
a.cfg.ChainParams.HDCoinType,
2273+
)
2274+
}
2275+
}
2276+
2277+
return nil
2278+
},
22452279
)
22462280
if err != nil {
22472281
return err
22482282
}
2249-
internalKey, err := ourSweepOutput.InternalKey.UnwrapOrErr(
2250-
fmt.Errorf("internal key not populated"),
2251-
)
2252-
if err != nil {
2253-
return err
2283+
2284+
// For any second level outputs we're sweeping, we'll need to sign for
2285+
// it, as now we know the txid of the sweeping transaction.
2286+
for _, sweepSet := range vPkts.secondLevel {
2287+
for _, vPkt := range sweepSet.vPkts {
2288+
prevOut := sweepSet.btcInput.OutPoint()
2289+
for _, vIn := range vPkt.Inputs {
2290+
vIn.PrevID.OutPoint = prevOut
2291+
}
2292+
2293+
for _, vOut := range vPkt.Outputs {
2294+
vOut.Asset.PrevWitnesses[0].PrevID.OutPoint = prevOut //nolint:lll
2295+
}
2296+
}
22542297
}
22552298

2256-
log.Infof("Using %x for internal key: ",
2257-
internalKey.PubKey.SerializeCompressed())
2299+
// If we have second level vPkts, then we'll need to sign them here, as
2300+
// now we know the input we're spending which was set above.
2301+
for _, sweepSet := range vPkts.secondLevel {
2302+
tapSigDesc, err := sweepSet.tapSigDesc.UnwrapOrErr(
2303+
fmt.Errorf("tap sig desc not populated"),
2304+
)
2305+
if err != nil {
2306+
return err
2307+
}
22582308

2259-
// We'll also use the passed in context to set the anchor key again for
2260-
// all the vOuts.
2261-
for idx := range vPkts.firstLevelPkts() {
2262-
for _, vOut := range vPkts.firstLevelPkts()[idx].Outputs {
2263-
vOut.SetAnchorInternalKey(
2264-
internalKey, a.cfg.ChainParams.HDCoinType,
2265-
)
2309+
err = a.signSweepVpackets(
2310+
sweepSet.vPkts, *sweepSet.btcInput.SignDesc(),
2311+
tapSigDesc.TapTweak.Val, tapSigDesc.CtrlBlock.Val,
2312+
lfn.None[lnwallet.AuxSigDesc](),
2313+
lfn.None[uint32](),
2314+
)
2315+
if err != nil {
2316+
return fmt.Errorf("unable to sign second level "+
2317+
"vPkts: %w", err)
22662318
}
22672319
}
22682320

22692321
// Now that we have our vPkts, we'll re-create the output commitments.
2270-
outCommitments, err := tapsend.CreateOutputCommitments(vPkts.allPkts())
2322+
outCommitments, err := tapsend.CreateOutputCommitments(
2323+
vPkts.allPkts(),
2324+
)
22712325
if err != nil {
22722326
return fmt.Errorf("unable to create output "+
22732327
"commitments: %w", err)

0 commit comments

Comments
 (0)