Skip to content

Commit 991d9b0

Browse files
jkczyzclaude
andcommitted
f - Consolidate paired writes to payment stores
Every on-chain payment update had to write both stores, and keeping them consistent relied on each call site doing the right thing. Nothing structural prevented a site from forgetting one of the writes or updating them inconsistently. No behavior change. Generated with assistance from Claude Code. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 441630c commit 991d9b0

1 file changed

Lines changed: 27 additions & 48 deletions

File tree

src/wallet/mod.rs

Lines changed: 27 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,8 @@ use persist::KVStoreWalletPersister;
5757
use crate::config::Config;
5858
use crate::fee_estimator::{ConfirmationTarget, FeeEstimator, OnchainFeeEstimator};
5959
use crate::logger::{log_debug, log_error, log_info, log_trace, LdkLogger, Logger};
60-
use crate::payment::pending_payment_store::{
61-
FundingCandidate, FundingDetails, FundingPurpose, PendingPaymentDetailsUpdate,
62-
};
63-
use crate::payment::store::{ConfirmationStatus, PaymentDetailsUpdate};
60+
use crate::payment::pending_payment_store::{FundingCandidate, FundingDetails, FundingPurpose};
61+
use crate::payment::store::ConfirmationStatus;
6462
use crate::payment::{
6563
PaymentDetails, PaymentDirection, PaymentKind, PaymentStatus, PendingPaymentDetails,
6664
};
@@ -291,13 +289,12 @@ impl Wallet {
291289
confirmation_status,
292290
);
293291

294-
self.payment_store.insert_or_update(payment.clone())?;
295-
296292
if payment_status == PaymentStatus::Pending {
297293
let pending_payment =
298294
self.create_pending_payment_from_tx(payment, Vec::new());
299-
300-
self.pending_payment_store.insert_or_update(pending_payment)?;
295+
self.persist_pending(pending_payment)?;
296+
} else {
297+
self.payment_store.insert_or_update(payment)?;
301298
}
302299
},
303300
WalletEvent::ChainTipChanged { new_tip, .. } => {
@@ -389,10 +386,8 @@ impl Wallet {
389386
PaymentStatus::Pending,
390387
ConfirmationStatus::Unconfirmed,
391388
);
392-
let pending_payment =
393-
self.create_pending_payment_from_tx(payment.clone(), Vec::new());
394-
self.payment_store.insert_or_update(payment)?;
395-
self.pending_payment_store.insert_or_update(pending_payment)?;
389+
let pending_payment = self.create_pending_payment_from_tx(payment, Vec::new());
390+
self.persist_pending(pending_payment)?;
396391
},
397392
WalletEvent::TxReplaced { txid, conflicts, .. } => {
398393
let Some(payment_id) = self.find_payment_by_txid(txid) else {
@@ -445,10 +440,8 @@ impl Wallet {
445440
PaymentStatus::Pending,
446441
ConfirmationStatus::Unconfirmed,
447442
);
448-
let pending_payment =
449-
self.create_pending_payment_from_tx(payment.clone(), Vec::new());
450-
self.payment_store.insert_or_update(payment)?;
451-
self.pending_payment_store.insert_or_update(pending_payment)?;
443+
let pending_payment = self.create_pending_payment_from_tx(payment, Vec::new());
444+
self.persist_pending(pending_payment)?;
452445
},
453446
_ => {
454447
continue;
@@ -1270,6 +1263,15 @@ impl Wallet {
12701263
PendingPaymentDetails::new(payment, conflicting_txids)
12711264
}
12721265

1266+
/// Writes a [`PendingPaymentDetails`] and its inner [`PaymentDetails`] to their
1267+
/// respective stores in a fixed order. Callers that need to keep the two stores in
1268+
/// sync should always go through this.
1269+
fn persist_pending(&self, pending: PendingPaymentDetails) -> Result<(), Error> {
1270+
self.payment_store.insert_or_update(pending.details.clone())?;
1271+
self.pending_payment_store.insert_or_update(pending)?;
1272+
Ok(())
1273+
}
1274+
12731275
/// Called on `ChannelReady` to mark a funding payment (channel open or splice) as
12741276
/// succeeded.
12751277
///
@@ -1469,14 +1471,7 @@ impl Wallet {
14691471
pending.details.kind =
14701472
PaymentKind::Onchain { txid: event_txid, status: confirmation_status };
14711473

1472-
let update = PendingPaymentDetailsUpdate {
1473-
id: payment_id,
1474-
payment_update: Some(PaymentDetailsUpdate::from(&pending.details)),
1475-
conflicting_txids: Some(pending.conflicting_txids.clone()),
1476-
funding_details: Some(pending.funding_details.clone()),
1477-
};
1478-
self.payment_store.insert_or_update(pending.details.clone())?;
1479-
self.pending_payment_store.update(update)?;
1474+
self.persist_pending(pending)?;
14801475

14811476
Ok(true)
14821477
}
@@ -1712,11 +1707,8 @@ impl Wallet {
17121707
ConfirmationStatus::Unconfirmed,
17131708
);
17141709

1715-
let pending_payment_store =
1716-
self.create_pending_payment_from_tx(new_payment.clone(), Vec::new());
1717-
1718-
self.pending_payment_store.insert_or_update(pending_payment_store)?;
1719-
self.payment_store.insert_or_update(new_payment)?;
1710+
let pending_payment = self.create_pending_payment_from_tx(new_payment, Vec::new());
1711+
self.persist_pending(pending_payment)?;
17201712

17211713
log_info!(self.logger, "RBF successful: replaced {} with {}", txid, new_txid);
17221714

@@ -1783,14 +1775,10 @@ impl Wallet {
17831775
candidates: vec![candidate],
17841776
};
17851777

1786-
let pending = PendingPaymentDetails::with_funding_details(
1787-
details.clone(),
1788-
Vec::new(),
1789-
funding_details,
1790-
);
1778+
let pending =
1779+
PendingPaymentDetails::with_funding_details(details, Vec::new(), funding_details);
17911780

1792-
self.payment_store.insert_or_update(details)?;
1793-
self.pending_payment_store.insert_or_update(pending)?;
1781+
self.persist_pending(pending)?;
17941782
log_debug!(
17951783
self.logger,
17961784
"Recorded channel-funding broadcast {} for channel {}",
@@ -1871,13 +1859,12 @@ impl Wallet {
18711859

18721860
let conflicting_txids = replaced_txid.into_iter().collect();
18731861
let pending = PendingPaymentDetails::with_funding_details(
1874-
details.clone(),
1862+
details,
18751863
conflicting_txids,
18761864
funding_details,
18771865
);
18781866

1879-
self.payment_store.insert_or_update(details)?;
1880-
self.pending_payment_store.insert_or_update(pending)?;
1867+
self.persist_pending(pending)?;
18811868
log_debug!(
18821869
self.logger,
18831870
"Recorded splice broadcast {} for channel {}",
@@ -1913,15 +1900,7 @@ impl Wallet {
19131900
pending.details.fee_paid_msat = Some(fee_paid_msat);
19141901
pending.funding_details = Some(funding_details);
19151902

1916-
let update = PendingPaymentDetailsUpdate {
1917-
id: pending.details.id,
1918-
payment_update: Some(PaymentDetailsUpdate::from(&pending.details)),
1919-
conflicting_txids: Some(pending.conflicting_txids.clone()),
1920-
funding_details: Some(pending.funding_details.clone()),
1921-
};
1922-
1923-
self.payment_store.insert_or_update(pending.details.clone())?;
1924-
self.pending_payment_store.update(update)?;
1903+
self.persist_pending(pending)?;
19251904
log_debug!(
19261905
self.logger,
19271906
"Recorded splice RBF broadcast {} for channel {} (replaces {})",

0 commit comments

Comments
 (0)