Skip to content

Commit 7eea7a7

Browse files
committed
sweep: add requestID to monitorRecord
This way we can greatly simplify the method signatures, also paving the upcoming changes where we wanna make it clear when updating the monitorRecord, we only touch a portion of it.
1 parent bde5124 commit 7eea7a7

File tree

2 files changed

+84
-63
lines changed

2 files changed

+84
-63
lines changed

sweep/fee_bumper.go

Lines changed: 55 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -410,34 +410,35 @@ func (t *TxPublisher) Broadcast(req *BumpRequest) <-chan *BumpResult {
410410
lnutils.SpewLogClosure(req))
411411

412412
// Store the request.
413-
requestID, record := t.storeInitialRecord(req)
413+
record := t.storeInitialRecord(req)
414414

415415
// Create a chan to send the result to the caller.
416416
subscriber := make(chan *BumpResult, 1)
417-
t.subscriberChans.Store(requestID, subscriber)
417+
t.subscriberChans.Store(record.requestID, subscriber)
418418

419419
// Publish the tx immediately if specified.
420420
if req.Immediate {
421-
t.handleInitialBroadcast(record, requestID)
421+
t.handleInitialBroadcast(record)
422422
}
423423

424424
return subscriber
425425
}
426426

427427
// storeInitialRecord initializes a monitor record and saves it in the map.
428-
func (t *TxPublisher) storeInitialRecord(req *BumpRequest) (
429-
uint64, *monitorRecord) {
430-
428+
func (t *TxPublisher) storeInitialRecord(req *BumpRequest) *monitorRecord {
431429
// Increase the request counter.
432430
//
433431
// NOTE: this is the only place where we increase the counter.
434432
requestID := t.requestCounter.Add(1)
435433

436434
// Register the record.
437-
record := &monitorRecord{req: req}
435+
record := &monitorRecord{
436+
requestID: requestID,
437+
req: req,
438+
}
438439
t.records.Store(requestID, record)
439440

440-
return requestID, record
441+
return record
441442
}
442443

443444
// storeRecord stores the given record in the records map.
@@ -446,6 +447,7 @@ func (t *TxPublisher) storeRecord(requestID uint64, sweepCtx *sweepTxCtx,
446447

447448
// Register the record.
448449
t.records.Store(requestID, &monitorRecord{
450+
requestID: requestID,
449451
tx: sweepCtx.tx,
450452
req: req,
451453
feeFunction: f,
@@ -461,16 +463,25 @@ func (t *TxPublisher) Name() string {
461463

462464
// initializeTx initializes a fee function and creates an RBF-compliant tx. If
463465
// succeeded, the initial tx is stored in the records map.
464-
func (t *TxPublisher) initializeTx(requestID uint64, req *BumpRequest) error {
466+
func (t *TxPublisher) initializeTx(r *monitorRecord) error {
465467
// Create a fee bumping algorithm to be used for future RBF.
466-
feeAlgo, err := t.initializeFeeFunction(req)
468+
feeAlgo, err := t.initializeFeeFunction(r.req)
467469
if err != nil {
468470
return fmt.Errorf("init fee function: %w", err)
469471
}
470472

473+
// Attach the newly created fee function.
474+
//
475+
// TODO(yy): current we'd initialize a monitorRecord before creating the
476+
// fee function, while we could instead create the fee function first
477+
// then save it to the record. To make this happen we need to change the
478+
// conf target calculation below since we would be initializing the fee
479+
// function one block before.
480+
r.feeFunction = feeAlgo
481+
471482
// Create the initial tx to be broadcasted. This tx is guaranteed to
472483
// comply with the RBF restrictions.
473-
err = t.createRBFCompliantTx(requestID, req, feeAlgo)
484+
err = t.createRBFCompliantTx(r)
474485
if err != nil {
475486
return fmt.Errorf("create RBF-compliant tx: %w", err)
476487
}
@@ -511,24 +522,24 @@ func (t *TxPublisher) initializeFeeFunction(
511522
// so by creating a tx, validate it using `TestMempoolAccept`, and bump its fee
512523
// and redo the process until the tx is valid, or return an error when non-RBF
513524
// related errors occur or the budget has been used up.
514-
func (t *TxPublisher) createRBFCompliantTx(requestID uint64, req *BumpRequest,
515-
f FeeFunction) error {
525+
func (t *TxPublisher) createRBFCompliantTx(r *monitorRecord) error {
526+
f := r.feeFunction
516527

517528
for {
518529
// Create a new tx with the given fee rate and check its
519530
// mempool acceptance.
520-
sweepCtx, err := t.createAndCheckTx(req, f)
531+
sweepCtx, err := t.createAndCheckTx(r.req, f)
521532

522533
switch {
523534
case err == nil:
524535
// The tx is valid, store it.
525-
t.storeRecord(requestID, sweepCtx, req, f)
536+
t.storeRecord(r.requestID, sweepCtx, r.req, f)
526537

527538
log.Infof("Created initial sweep tx=%v for %v inputs: "+
528539
"feerate=%v, fee=%v, inputs:\n%v",
529-
sweepCtx.tx.TxHash(), len(req.Inputs),
540+
sweepCtx.tx.TxHash(), len(r.req.Inputs),
530541
f.FeeRate(), sweepCtx.fee,
531-
inputTypeSummary(req.Inputs))
542+
inputTypeSummary(r.req.Inputs))
532543

533544
return nil
534545

@@ -773,6 +784,9 @@ func (t *TxPublisher) handleResult(result *BumpResult) {
773784
// monitorRecord is used to keep track of the tx being monitored by the
774785
// publisher internally.
775786
type monitorRecord struct {
787+
// requestID is the ID of the request that created this record.
788+
requestID uint64
789+
776790
// tx is the tx being monitored.
777791
tx *wire.MsgTx
778792

@@ -915,51 +929,51 @@ func (t *TxPublisher) processRecords() {
915929
t.records.ForEach(visitor)
916930

917931
// Handle the initial broadcast.
918-
for requestID, r := range initialRecords {
919-
t.handleInitialBroadcast(r, requestID)
932+
for _, r := range initialRecords {
933+
t.handleInitialBroadcast(r)
920934
}
921935

922936
// For records that are confirmed, we'll notify the caller about this
923937
// result.
924-
for requestID, r := range confirmedRecords {
938+
for _, r := range confirmedRecords {
925939
log.Debugf("Tx=%v is confirmed", r.tx.TxHash())
926940
t.wg.Add(1)
927-
go t.handleTxConfirmed(r, requestID)
941+
go t.handleTxConfirmed(r)
928942
}
929943

930944
// Get the current height to be used in the following goroutines.
931945
currentHeight := t.currentHeight.Load()
932946

933947
// For records that are not confirmed, we perform a fee bump if needed.
934-
for requestID, r := range feeBumpRecords {
948+
for _, r := range feeBumpRecords {
935949
log.Debugf("Attempting to fee bump Tx=%v", r.tx.TxHash())
936950
t.wg.Add(1)
937-
go t.handleFeeBumpTx(requestID, r, currentHeight)
951+
go t.handleFeeBumpTx(r, currentHeight)
938952
}
939953

940954
// For records that are failed, we'll notify the caller about this
941955
// result.
942-
for requestID, r := range failedRecords {
956+
for _, r := range failedRecords {
943957
log.Debugf("Tx=%v has inputs been spent by a third party, "+
944958
"failing it now", r.tx.TxHash())
945959
t.wg.Add(1)
946-
go t.handleThirdPartySpent(r, requestID)
960+
go t.handleThirdPartySpent(r)
947961
}
948962
}
949963

950964
// handleTxConfirmed is called when a monitored tx is confirmed. It will
951965
// notify the subscriber then remove the record from the maps .
952966
//
953967
// NOTE: Must be run as a goroutine to avoid blocking on sending the result.
954-
func (t *TxPublisher) handleTxConfirmed(r *monitorRecord, requestID uint64) {
968+
func (t *TxPublisher) handleTxConfirmed(r *monitorRecord) {
955969
defer t.wg.Done()
956970

957971
// Create a result that will be sent to the resultChan which is
958972
// listened by the caller.
959973
result := &BumpResult{
960974
Event: TxConfirmed,
961975
Tx: r.tx,
962-
requestID: requestID,
976+
requestID: r.requestID,
963977
Fee: r.fee,
964978
FeeRate: r.feeFunction.FeeRate(),
965979
}
@@ -1017,10 +1031,8 @@ func (t *TxPublisher) handleInitialTxError(requestID uint64, err error) {
10171031
// 1. init a fee function based on the given strategy.
10181032
// 2. create an RBF-compliant tx and monitor it for confirmation.
10191033
// 3. notify the initial broadcast result back to the caller.
1020-
func (t *TxPublisher) handleInitialBroadcast(r *monitorRecord,
1021-
requestID uint64) {
1022-
1023-
log.Debugf("Initial broadcast for requestID=%v", requestID)
1034+
func (t *TxPublisher) handleInitialBroadcast(r *monitorRecord) {
1035+
log.Debugf("Initial broadcast for requestID=%v", r.requestID)
10241036

10251037
var (
10261038
result *BumpResult
@@ -1031,18 +1043,18 @@ func (t *TxPublisher) handleInitialBroadcast(r *monitorRecord,
10311043
// RBF rules.
10321044
//
10331045
// Create the initial tx to be broadcasted.
1034-
err = t.initializeTx(requestID, r.req)
1046+
err = t.initializeTx(r)
10351047
if err != nil {
10361048
log.Errorf("Initial broadcast failed: %v", err)
10371049

10381050
// We now handle the initialization error and exit.
1039-
t.handleInitialTxError(requestID, err)
1051+
t.handleInitialTxError(r.requestID, err)
10401052

10411053
return
10421054
}
10431055

10441056
// Successfully created the first tx, now broadcast it.
1045-
result, err = t.broadcast(requestID)
1057+
result, err = t.broadcast(r.requestID)
10461058
if err != nil {
10471059
// The broadcast failed, which can only happen if the tx record
10481060
// cannot be found or the aux sweeper returns an error. In
@@ -1051,7 +1063,7 @@ func (t *TxPublisher) handleInitialBroadcast(r *monitorRecord,
10511063
result = &BumpResult{
10521064
Event: TxFailed,
10531065
Err: err,
1054-
requestID: requestID,
1066+
requestID: r.requestID,
10551067
}
10561068
}
10571069

@@ -1062,9 +1074,7 @@ func (t *TxPublisher) handleInitialBroadcast(r *monitorRecord,
10621074
// attempt to bump the fee of the tx.
10631075
//
10641076
// NOTE: Must be run as a goroutine to avoid blocking on sending the result.
1065-
func (t *TxPublisher) handleFeeBumpTx(requestID uint64, r *monitorRecord,
1066-
currentHeight int32) {
1067-
1077+
func (t *TxPublisher) handleFeeBumpTx(r *monitorRecord, currentHeight int32) {
10681078
defer t.wg.Done()
10691079

10701080
oldTxid := r.tx.TxHash()
@@ -1095,7 +1105,7 @@ func (t *TxPublisher) handleFeeBumpTx(requestID uint64, r *monitorRecord,
10951105

10961106
// The fee function now has a new fee rate, we will use it to bump the
10971107
// fee of the tx.
1098-
resultOpt := t.createAndPublishTx(requestID, r)
1108+
resultOpt := t.createAndPublishTx(r)
10991109

11001110
// If there's a result, we will notify the caller about the result.
11011111
resultOpt.WhenSome(func(result BumpResult) {
@@ -1109,9 +1119,7 @@ func (t *TxPublisher) handleFeeBumpTx(requestID uint64, r *monitorRecord,
11091119
// and send a TxFailed event to the subscriber.
11101120
//
11111121
// NOTE: Must be run as a goroutine to avoid blocking on sending the result.
1112-
func (t *TxPublisher) handleThirdPartySpent(r *monitorRecord,
1113-
requestID uint64) {
1114-
1122+
func (t *TxPublisher) handleThirdPartySpent(r *monitorRecord) {
11151123
defer t.wg.Done()
11161124

11171125
// Create a result that will be sent to the resultChan which is
@@ -1123,7 +1131,7 @@ func (t *TxPublisher) handleThirdPartySpent(r *monitorRecord,
11231131
result := &BumpResult{
11241132
Event: TxFailed,
11251133
Tx: r.tx,
1126-
requestID: requestID,
1134+
requestID: r.requestID,
11271135
Err: ErrThirdPartySpent,
11281136
}
11291137

@@ -1134,7 +1142,7 @@ func (t *TxPublisher) handleThirdPartySpent(r *monitorRecord,
11341142
// createAndPublishTx creates a new tx with a higher fee rate and publishes it
11351143
// to the network. It will update the record with the new tx and fee rate if
11361144
// successfully created, and return the result when published successfully.
1137-
func (t *TxPublisher) createAndPublishTx(requestID uint64,
1145+
func (t *TxPublisher) createAndPublishTx(
11381146
r *monitorRecord) fn.Option[BumpResult] {
11391147

11401148
// Fetch the old tx.
@@ -1185,16 +1193,16 @@ func (t *TxPublisher) createAndPublishTx(requestID uint64,
11851193
Event: TxFailed,
11861194
Tx: oldTx,
11871195
Err: err,
1188-
requestID: requestID,
1196+
requestID: r.requestID,
11891197
})
11901198
}
11911199

11921200
// The tx has been created without any errors, we now register a new
11931201
// record by overwriting the same requestID.
1194-
t.storeRecord(requestID, sweepCtx, r.req, r.feeFunction)
1202+
t.storeRecord(r.requestID, sweepCtx, r.req, r.feeFunction)
11951203

11961204
// Attempt to broadcast this new tx.
1197-
result, err := t.broadcast(requestID)
1205+
result, err := t.broadcast(r.requestID)
11981206
if err != nil {
11991207
log.Infof("Failed to broadcast replacement tx %v: %v",
12001208
sweepCtx.tx.TxHash(), err)

0 commit comments

Comments
 (0)