Skip to content

Commit 072ca8b

Browse files
committed
Minor adjustment to fee rate handling in RBF fee bumping
Use user-provided fee rate for bumping transaction and return an error if it is too low, otherwise use system estimated fee rate and retry mechanism. Also switches the RBF test to use `random_chain_source`, and removes unnecessary sleep-based waits.
1 parent 2f5a966 commit 072ca8b

File tree

2 files changed

+28
-12
lines changed

2 files changed

+28
-12
lines changed

src/wallet/mod.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ impl Wallet {
338338
WalletEvent::TxUnconfirmed { txid, tx, old_block_time: None } => {
339339
let payment_id = self
340340
.find_payment_by_txid(txid)
341+
.or_else(|| self.find_payment_by_tx_conflicts(locked_wallet, &tx))
341342
.unwrap_or_else(|| PaymentId(txid.to_byte_array()));
342343

343344
let payment = self.create_payment_from_tx(
@@ -378,14 +379,15 @@ impl Wallet {
378379
);
379380
let payment =
380381
self.payment_store.get(&payment_id).ok_or(Error::InvalidPaymentId)?;
381-
let pending_payment_details = self
382-
.create_pending_payment_from_tx(payment.clone(), conflict_txids.clone());
382+
let pending_payment_details =
383+
self.create_pending_payment_from_tx(payment, conflict_txids.clone());
383384

384385
self.pending_payment_store.insert_or_update(pending_payment_details)?;
385386
},
386387
WalletEvent::TxDropped { txid, tx } => {
387388
let payment_id = self
388389
.find_payment_by_txid(txid)
390+
.or_else(|| self.find_payment_by_tx_conflicts(locked_wallet, &tx))
389391
.unwrap_or_else(|| PaymentId(txid.to_byte_array()));
390392
let payment = self.create_payment_from_tx(
391393
locked_wallet,
@@ -1053,6 +1055,15 @@ impl Wallet {
10531055
None
10541056
}
10551057

1058+
fn find_payment_by_tx_conflicts(
1059+
&self, locked_wallet: &PersistedWallet<KVStoreWalletPersister>, tx: &Transaction,
1060+
) -> Option<PaymentId> {
1061+
locked_wallet
1062+
.tx_graph()
1063+
.direct_conflicts(tx)
1064+
.find_map(|(_, conflict_txid)| self.find_payment_by_txid(conflict_txid))
1065+
}
1066+
10561067
#[allow(deprecated)]
10571068
pub(crate) fn bump_fee_rbf(
10581069
&self, payment_id: PaymentId, fee_rate: Option<FeeRate>,
@@ -1125,13 +1136,13 @@ impl Wallet {
11251136
old_fee_rate.to_sat_per_kwu() + INCREMENTAL_RELAY_FEE_SAT_PER_1000_WEIGHT as u64;
11261137

11271138
let confirmation_target = ConfirmationTarget::OnchainPayment;
1128-
let estimated_fee_rate =
1129-
fee_rate.unwrap_or_else(|| self.fee_estimator.estimate_fee_rate(confirmation_target));
1139+
let estimated_fee_rate = self.fee_estimator.estimate_fee_rate(confirmation_target);
11301140

11311141
// Use the higher of minimum RBF requirement or current network estimate
11321142
let final_fee_rate_sat_per_kwu =
11331143
min_required_fee_rate_sat_per_kwu.max(estimated_fee_rate.to_sat_per_kwu());
1134-
let final_fee_rate = FeeRate::from_sat_per_kwu(final_fee_rate_sat_per_kwu);
1144+
let final_fee_rate =
1145+
fee_rate.unwrap_or_else(|| FeeRate::from_sat_per_kwu(final_fee_rate_sat_per_kwu));
11351146

11361147
let mut psbt = {
11371148
let mut builder = locked_wallet.build_fee_bump(txid).map_err(|e| {
@@ -1156,6 +1167,17 @@ impl Wallet {
11561167
match builder.finish() {
11571168
Ok(psbt) => Ok(psbt),
11581169
Err(CreateTxError::FeeRateTooLow { required: required_fee_rate }) => {
1170+
if fee_rate.is_some() {
1171+
log_error!(
1172+
self.logger,
1173+
"Provided fee rate {} is too low for RBF fee bump of txid {}, required minimum fee rate: {}",
1174+
fee_rate.unwrap(),
1175+
txid,
1176+
required_fee_rate
1177+
);
1178+
return Err(Error::InvalidFeeRate);
1179+
}
1180+
11591181
log_info!(self.logger, "BDK requires higher fee rate: {}", required_fee_rate);
11601182

11611183
// BDK may require a higher fee rate than our estimate due to

tests/integration_tests_rust.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2466,7 +2466,7 @@ async fn persistence_backwards_compatibility() {
24662466
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
24672467
async fn onchain_fee_bump_rbf() {
24682468
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();
2469-
let chain_source = TestChainSource::Esplora(&electrsd);
2469+
let chain_source = random_chain_source(&bitcoind, &electrsd);
24702470
let (node_a, node_b) = setup_two_nodes(&chain_source, false, true, false);
24712471

24722472
// Fund both nodes
@@ -2516,9 +2516,6 @@ async fn onchain_fee_bump_rbf() {
25162516
let new_txid = node_b.onchain_payment().bump_fee_rbf(payment_id, None).unwrap();
25172517
wait_for_tx(&electrsd.client, new_txid).await;
25182518

2519-
// Sleep to allow for transaction propagation
2520-
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
2521-
25222519
node_a.sync_wallets().unwrap();
25232520
node_b.sync_wallets().unwrap();
25242521

@@ -2557,9 +2554,6 @@ async fn onchain_fee_bump_rbf() {
25572554
let second_bump_txid = node_b.onchain_payment().bump_fee_rbf(payment_id, None).unwrap();
25582555
wait_for_tx(&electrsd.client, second_bump_txid).await;
25592556

2560-
// Sleep to allow for transaction propagation
2561-
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
2562-
25632557
node_a.sync_wallets().unwrap();
25642558
node_b.sync_wallets().unwrap();
25652559

0 commit comments

Comments
 (0)