Skip to content

Commit 447cba5

Browse files
committed
tapchannel: fix change output index calculation
This fixes a bug where we previously assumed there would only ever be one asset input in a sweep. But when we sweep multiple HTLCs at the same time, the change output index isn't static and needs to be calculated based on the asset commitment output indexes.
1 parent b35e6e0 commit 447cba5

File tree

1 file changed

+19
-13
lines changed

1 file changed

+19
-13
lines changed

tapchannel/aux_sweeper.go

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2256,26 +2256,20 @@ func (a *AuxSweeper) sweepContracts(inputs []input.Input,
22562256
// sweepExclusionProofGen is a helper function that generates an exclusion
22572257
// proof for the internal key of the change output.
22582258
func sweepExclusionProofGen(sweepInternalKey keychain.KeyDescriptor,
2259-
) tapsend.ExclusionProofGenerator {
2259+
changeOutputIndex uint32) tapsend.ExclusionProofGenerator {
22602260

22612261
return func(target *proof.BaseProofParams,
22622262
isAnchor tapsend.IsAnchor) error {
22632263

2264-
tsProof, err := proof.CreateTapscriptProof(nil)
2265-
if err != nil {
2266-
return fmt.Errorf("error creating tapscript proof: %w",
2267-
err)
2268-
}
2269-
22702264
// We only need to generate an exclusion proof for the second
22712265
// output in the commitment transaction.
2272-
//
2273-
// TODO(roasbeef): case of no change?
22742266
target.ExclusionProofs = append(
22752267
target.ExclusionProofs, proof.TaprootProof{
2276-
OutputIndex: 1,
2277-
InternalKey: sweepInternalKey.PubKey,
2278-
TapscriptProof: tsProof,
2268+
OutputIndex: changeOutputIndex,
2269+
InternalKey: sweepInternalKey.PubKey,
2270+
TapscriptProof: &proof.TapscriptProof{
2271+
Bip86: true,
2272+
},
22792273
},
22802274
)
22812275

@@ -2415,6 +2409,15 @@ func (a *AuxSweeper) registerAndBroadcastSweep(req *sweep.BumpRequest,
24152409
"commitments: %w", err)
24162410
}
24172411

2412+
// We need to find out what the highest output index of any asset output
2413+
// commitments is, so we know the change output will be one higher.
2414+
highestOutputIndex := uint32(0)
2415+
for outIdx := range outCommitments {
2416+
if outIdx > highestOutputIndex {
2417+
highestOutputIndex = outIdx
2418+
}
2419+
}
2420+
24182421
changeInternalKey, err := req.DeliveryAddress.InternalKey.UnwrapOrErr(
24192422
fmt.Errorf("change internal key not populated"),
24202423
)
@@ -2435,8 +2438,11 @@ func (a *AuxSweeper) registerAndBroadcastSweep(req *sweep.BumpRequest,
24352438
for idx := range allVpkts {
24362439
vPkt := allVpkts[idx]
24372440
for outIdx := range vPkt.Outputs {
2441+
// The change output is always the last output in the
2442+
// commitment transaction, one index higher than the
2443+
// highest asset commitment output index.
24382444
exclusionCreator := sweepExclusionProofGen(
2439-
changeInternalKey,
2445+
changeInternalKey, highestOutputIndex+1,
24402446
)
24412447

24422448
proofSuffix, err := tapsend.CreateProofSuffixCustom(

0 commit comments

Comments
 (0)