diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 5ad739906..4d92b2220 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -1066,16 +1066,24 @@ impl DaemonControl { must_select: !is_cancel, }) .collect(); - if !is_cancel { - candidate_coins.extend( - db_conn - .coins(&[CoinStatus::Confirmed], &[]) - .into_values() - .map(|c| CandidateCoin { + let confirmed_cands: Vec = db_conn + .coins(&[CoinStatus::Confirmed], &[]) + .into_values() + .filter_map(|c| { + // In case the user attempts RBF before the previous coins have been updated in the DB, + // they would be returned as confirmed and not spending. + if !prev_coins.contains_key(&c.outpoint) { + Some(CandidateCoin { coin: c, must_select: false, - }), - ); + }) + } else { + None + } + }) + .collect(); + if !is_cancel { + candidate_coins.extend(&confirmed_cands); } // Try with increasing feerate until fee paid by replacement transaction is high enough. // Replacement fee must be at least: @@ -1101,14 +1109,10 @@ impl DaemonControl { Err(CommandError::CoinSelectionError(_)) if is_cancel && candidate_coins.iter().all(|c| !c.must_select) => { - candidate_coins = prev_coins - .values() - .chain(db_conn.coins(&[CoinStatus::Confirmed], &[]).values()) - .map(|c| CandidateCoin { - coin: *c, - must_select: prev_coins.contains_key(&c.outpoint), - }) - .collect(); + for cand in candidate_coins.iter_mut() { + cand.must_select = true; + } + candidate_coins.extend(&confirmed_cands); continue; } Err(e) => {