diff --git a/contractcourt/breach_arbitrator.go b/contractcourt/breach_arbitrator.go index 82b997746..a8154d0e6 100644 --- a/contractcourt/breach_arbitrator.go +++ b/contractcourt/breach_arbitrator.go @@ -752,7 +752,7 @@ justiceTxBroadcast: } return aux.NotifyBroadcast( - &bumpReq, finalTx.justiceTx, finalTx.fee, + &bumpReq, finalTx.justiceTx, finalTx.fee, nil, ) }) if err != nil { diff --git a/sweep/fee_bumper.go b/sweep/fee_bumper.go index fd3dfba9e..5ea4d8e4b 100644 --- a/sweep/fee_bumper.go +++ b/sweep/fee_bumper.go @@ -603,7 +603,9 @@ func (t *TxPublisher) broadcast(requestID uint64) (*BumpResult, error) { // Before we go to broadcast, we'll notify the aux sweeper, if it's // present of this new broadcast attempt. err := fn.MapOptionZ(t.cfg.AuxSweeper, func(aux AuxSweeper) error { - return aux.NotifyBroadcast(record.req, tx, record.fee) + return aux.NotifyBroadcast( + record.req, tx, record.fee, record.outpointToTxIndex, + ) }) if err != nil { return nil, fmt.Errorf("unable to notify aux sweeper: %w", err) @@ -725,6 +727,9 @@ type monitorRecord struct { // fee is the fee paid by the tx. fee btcutil.Amount + + // outpointToTxIndex is a map of outpoint to tx index. + outpointToTxIndex map[wire.OutPoint]int } // Start starts the publisher by subscribing to block epoch updates and kicking @@ -1042,10 +1047,11 @@ func (t *TxPublisher) createAndPublishTx(requestID uint64, // The tx has been created without any errors, we now register a new // record by overwriting the same requestID. t.records.Store(requestID, &monitorRecord{ - tx: sweepCtx.tx, - req: r.req, - feeFunction: r.feeFunction, - fee: sweepCtx.fee, + tx: sweepCtx.tx, + req: r.req, + feeFunction: r.feeFunction, + fee: sweepCtx.fee, + outpointToTxIndex: sweepCtx.outpointToTxIndex, }) // Attempt to broadcast this new tx. @@ -1199,6 +1205,10 @@ type sweepTxCtx struct { fee btcutil.Amount extraTxOut fn.Option[SweepOutput] + + // outpointToTxIndex maps the outpoint of the inputs to their index in + // the sweep transaction. + outpointToTxIndex map[wire.OutPoint]int } // createSweepTx creates a sweeping tx based on the given inputs, change @@ -1229,6 +1239,7 @@ func (t *TxPublisher) createSweepTx(inputs []input.Input, // We start by adding all inputs that commit to an output. We do this // since the input and output index must stay the same for the // signatures to be valid. + outpointToTxIndex := make(map[wire.OutPoint]int) for _, o := range inputs { if o.RequiredTxOut() == nil { continue @@ -1240,6 +1251,8 @@ func (t *TxPublisher) createSweepTx(inputs []input.Input, Sequence: o.BlocksToMaturity(), }) sweepTx.AddTxOut(o.RequiredTxOut()) + + outpointToTxIndex[o.OutPoint()] = len(sweepTx.TxOut) - 1 } // Sum up the value contained in the remaining inputs, and add them to @@ -1331,9 +1344,10 @@ func (t *TxPublisher) createSweepTx(inputs []input.Input, )(changeOutputsOpt) return &sweepTxCtx{ - tx: sweepTx, - fee: txFee, - extraTxOut: fn.FlattenOption(extraTxOut), + tx: sweepTx, + fee: txFee, + extraTxOut: fn.FlattenOption(extraTxOut), + outpointToTxIndex: outpointToTxIndex, }, nil } diff --git a/sweep/interface.go b/sweep/interface.go index acece3143..f2fff84b0 100644 --- a/sweep/interface.go +++ b/sweep/interface.go @@ -93,5 +93,6 @@ type AuxSweeper interface { // NotifyBroadcast is used to notify external callers of the broadcast // of a sweep transaction, generated by the passed BumpRequest. NotifyBroadcast(req *BumpRequest, tx *wire.MsgTx, - totalFees btcutil.Amount) error + totalFees btcutil.Amount, + outpointToTxIndex map[wire.OutPoint]int) error } diff --git a/sweep/mock_test.go b/sweep/mock_test.go index c623ca3c0..34202b145 100644 --- a/sweep/mock_test.go +++ b/sweep/mock_test.go @@ -352,7 +352,7 @@ func (m *MockAuxSweeper) ExtraBudgetForInputs( // NotifyBroadcast is used to notify external callers of the broadcast // of a sweep transaction, generated by the passed BumpRequest. func (*MockAuxSweeper) NotifyBroadcast(_ *BumpRequest, _ *wire.MsgTx, - _ btcutil.Amount) error { + _ btcutil.Amount, _ map[wire.OutPoint]int) error { return nil }