You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix unified payment falling back to on-chain after PersistenceFailed
In UnifiedPayment::send, the BOLT11 leg's bolt11_invoice.send only
returns Err(PersistenceFailed) *after* pay_for_bolt11_invoice has
already succeeded and the Lightning payment is in-flight. The previous
match treated every remaining error as a fall-through to the next
payment method, so a persistence failure after initiation would
broadcast an on-chain transaction for the same URI — a duplicate
payment.
Err(Error::PersistenceFailed) on the BOLT11 leg is now terminal,
mirroring how DuplicatePayment is handled, and aborts the unified
payment instead of falling back to on-chain.
This is a regression hazard raised during review of the DuplicatePayment
fix (PR #1038). It is pre-existing and orthogonal to #1033; tracked
here as the unified variant of the broader post-commit persistence
hazard.
Per review discussion: rather than a dedicated node/channel fixture,
build unified_send_receive_bip21_uri's node_a on a PaymentFailingStore
(inert until armed) from the start, and add a PersistenceFailed
assertion at the end of that test using a fresh BOLT11-only URI. This
reuses the funding/channel/announcement setup and the successful-send
flow the test already has, rather than duplicating it.
Adds PaymentFailingStore (a KVStore wrapper that fails writes to the
payments namespace on demand) and setup_two_nodes_with_failing_store_a
(mirrors setup_two_nodes, but node_a is built on PaymentFailingStore).
Copy file name to clipboardExpand all lines: src/payment/unified.rs
+8Lines changed: 8 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -333,6 +333,14 @@ impl UnifiedPayment {
333
333
log_error!(self.logger,"Failed to send BOLT11 invoice: DuplicatePayment. This is part of a unified payment. Aborting to avoid duplicate payment.");
334
334
returnErr(Error::DuplicatePayment);
335
335
},
336
+
// A persistence failure may occur after the Lightning payment has
337
+
// already been initiated with the ChannelManager. Falling back to
338
+
// the on-chain method in that case would double-pay, so we abort
339
+
// instead of proceeding to the next payment method.
340
+
Err(Error::PersistenceFailed) => {
341
+
log_error!(self.logger,"Failed to send BOLT11 invoice: PersistenceFailed. This is part of a unified payment. Aborting to avoid a potential duplicate payment.");
342
+
returnErr(Error::PersistenceFailed);
343
+
},
336
344
Err(e) => {
337
345
log_error!(self.logger,"Failed to send BOLT11 invoice: {:?}. This is part of a unified payment. Falling back to the on-chain transaction.", e);
0 commit comments