Skip to content

Commit 6a594f9

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 94bdfa5 commit 6a594f9

File tree

1 file changed

+72
-17
lines changed

1 file changed

+72
-17
lines changed

tapchannel/aux_sweeper.go

Lines changed: 72 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1754,6 +1754,7 @@ func (a *AuxSweeper) resolveContract(
17541754
default:
17551755
return lfn.Errf[returnType]("unknown resolution type: %v",
17561756
req.Type)
1757+
// TODO(roasbeef): need to do HTLC revocation casesj:w
17571758
}
17581759

17591760
// The input proofs above were made originally using the fake commit tx
@@ -2222,34 +2223,88 @@ func (a *AuxSweeper) registerAndBroadcastSweep(req *sweep.BumpRequest,
22222223
return nil
22232224
}
22242225

2225-
ourSweepOutput, err := req.ExtraTxOut.UnwrapOrErr(
2226-
fmt.Errorf("extra tx out not populated"),
2226+
// If this is a transaction that's only sweeping HTLC outputs via a
2227+
// pre-signed transaction, then we won't actually have an extra sweep
2228+
// output.
2229+
err = lfn.MapOptionZ(
2230+
req.ExtraTxOut,
2231+
func(extraTxOut sweep.SweepOutput) error {
2232+
ourSweepOutput, err := req.ExtraTxOut.UnwrapOrErr(
2233+
fmt.Errorf("extra tx out not populated"),
2234+
)
2235+
if err != nil {
2236+
return err
2237+
}
2238+
iKey, err := ourSweepOutput.InternalKey.UnwrapOrErr(
2239+
fmt.Errorf("internal key not populated"),
2240+
)
2241+
if err != nil {
2242+
return err
2243+
}
2244+
2245+
// We'll also use the passed in context to set the
2246+
// anchor key again for all the vOuts, but only for
2247+
// first level vPkts, as second level packets already
2248+
// commit to the internal key of the vOut.
2249+
vPkts := vPkts.directSpendPkts()
2250+
for idx := range vPkts {
2251+
for _, vOut := range vPkts[idx].Outputs {
2252+
vOut.SetAnchorInternalKey(
2253+
iKey,
2254+
a.cfg.ChainParams.HDCoinType,
2255+
)
2256+
}
2257+
}
2258+
2259+
return nil
2260+
},
22272261
)
22282262
if err != nil {
22292263
return err
22302264
}
2231-
internalKey, err := ourSweepOutput.InternalKey.UnwrapOrErr(
2232-
fmt.Errorf("internal key not populated"),
2233-
)
2234-
if err != nil {
2235-
return err
2265+
2266+
// For any second level outputs we're sweeping, we'll need to sign for
2267+
// it, as now we know the txid of the sweeping transaction.
2268+
for _, sweepSet := range vPkts.secondLevel {
2269+
for _, vPkt := range sweepSet.vPkts {
2270+
prevOut := sweepSet.btcInput.OutPoint()
2271+
for _, vIn := range vPkt.Inputs {
2272+
vIn.PrevID.OutPoint = prevOut
2273+
}
2274+
2275+
for _, vOut := range vPkt.Outputs {
2276+
//nolint:lll
2277+
vOut.Asset.PrevWitnesses[0].PrevID.OutPoint = prevOut
2278+
}
2279+
}
22362280
}
22372281

2238-
log.Infof("Using %x for internal key: ",
2239-
internalKey.PubKey.SerializeCompressed())
2282+
// If we have second level vPkts, then we'll need to sign them here, as
2283+
// now we know the input we're spending which was set above.
2284+
for _, sweepSet := range vPkts.secondLevel {
2285+
tapSigDesc, err := sweepSet.tapSigDesc.UnwrapOrErr(
2286+
fmt.Errorf("tap sig desc not populated"),
2287+
)
2288+
if err != nil {
2289+
return err
2290+
}
22402291

2241-
// We'll also use the passed in context to set the anchor key again for
2242-
// all the vOuts.
2243-
for idx := range vPkts.firstLevelPkts() {
2244-
for _, vOut := range vPkts.firstLevelPkts()[idx].Outputs {
2245-
vOut.SetAnchorInternalKey(
2246-
internalKey, a.cfg.ChainParams.HDCoinType,
2247-
)
2292+
err = a.signSweepVpackets(
2293+
sweepSet.vPkts, *sweepSet.btcInput.SignDesc(),
2294+
tapSigDesc.TapTweak.Val, tapSigDesc.CtrlBlock.Val,
2295+
lfn.None[lnwallet.AuxSigDesc](),
2296+
lfn.None[uint32](),
2297+
)
2298+
if err != nil {
2299+
return fmt.Errorf("unable to sign second level "+
2300+
"vPkts: %w", err)
22482301
}
22492302
}
22502303

22512304
// Now that we have our vPkts, we'll re-create the output commitments.
2252-
outCommitments, err := tapsend.CreateOutputCommitments(vPkts.allPkts())
2305+
outCommitments, err := tapsend.CreateOutputCommitments(
2306+
vPkts.allPkts(),
2307+
)
22532308
if err != nil {
22542309
return fmt.Errorf("unable to create output "+
22552310
"commitments: %w", err)

0 commit comments

Comments
 (0)