Skip to content

Commit fdae635

Browse files
committed
Fix inbound on-chain payment txid not updating after RBF replacement
1 parent b0e159a commit fdae635

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

src/wallet/mod.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ impl Wallet {
260260

261261
let payment_id = self
262262
.find_payment_by_txid(txid)
263+
.or_else(|| self.find_payment_by_conflicting_tx(locked_wallet, &tx))
263264
.unwrap_or_else(|| PaymentId(txid.to_byte_array()));
264265

265266
let payment = self.create_payment_from_tx(
@@ -348,6 +349,7 @@ impl Wallet {
348349
WalletEvent::TxUnconfirmed { txid, tx, old_block_time: None } => {
349350
let payment_id = self
350351
.find_payment_by_txid(txid)
352+
.or_else(|| self.find_payment_by_conflicting_tx(locked_wallet, &tx))
351353
.unwrap_or_else(|| PaymentId(txid.to_byte_array()));
352354

353355
let payment = self.create_payment_from_tx(
@@ -396,6 +398,7 @@ impl Wallet {
396398
WalletEvent::TxDropped { txid, tx } => {
397399
let payment_id = self
398400
.find_payment_by_txid(txid)
401+
.or_else(|| self.find_payment_by_conflicting_tx(locked_wallet, &tx))
399402
.unwrap_or_else(|| PaymentId(txid.to_byte_array()));
400403
let payment = self.create_payment_from_tx(
401404
locked_wallet,
@@ -1209,6 +1212,48 @@ impl Wallet {
12091212
return Some(replaced_details.details.id);
12101213
}
12111214

1215+
// Also check the payment store for onchain payments with this txid.
1216+
if let Some(payment) = self
1217+
.payment_store
1218+
.list_filter(
1219+
|p| matches!(&p.kind, PaymentKind::Onchain { txid, .. } if *txid == target_txid),
1220+
)
1221+
.first()
1222+
{
1223+
return Some(payment.id);
1224+
}
1225+
1226+
None
1227+
}
1228+
1229+
fn find_payment_by_conflicting_tx(
1230+
&self, locked_wallet: &PersistedWallet<KVStoreWalletPersister>, tx: &Transaction,
1231+
) -> Option<PaymentId> {
1232+
let target_txid = tx.compute_txid();
1233+
let spent_outpoints: std::collections::HashSet<OutPoint> =
1234+
tx.input.iter().map(|input| input.previous_output).collect();
1235+
1236+
let onchain_payments = self.payment_store.list_filter(|p| {
1237+
matches!(p.kind, PaymentKind::Onchain { .. }) && p.status != PaymentStatus::Failed
1238+
});
1239+
1240+
for payment in onchain_payments {
1241+
if let PaymentKind::Onchain { txid: existing_txid, .. } = &payment.kind {
1242+
if *existing_txid == target_txid {
1243+
continue;
1244+
}
1245+
if let Some(existing_tx_details) = locked_wallet.tx_details(*existing_txid) {
1246+
let shares_inputs = existing_tx_details
1247+
.tx
1248+
.input
1249+
.iter()
1250+
.any(|input| spent_outpoints.contains(&input.previous_output));
1251+
if shares_inputs {
1252+
return Some(payment.id);
1253+
}
1254+
}
1255+
}
1256+
}
12121257
None
12131258
}
12141259

0 commit comments

Comments
 (0)