Skip to content

Commit d7d9eb9

Browse files
committed
fix: BOLT12 arm of UnifiedPayment::send returns DuplicatePayment/PersistenceFailed errors
The BOLT12 arm used .map_err() + if let Ok, so DuplicatePayment and PersistenceFailed fell through to BOLT11/onchain — risking double payment. Now treats both as terminal, mirroring the BOLT11 fix in #1038. Fixes: #1060 AI-assisted: generated by Sera (Hermes Agent), verified manually. Signed-off-by: Bartok9 <259807879+Bartok9@users.noreply.github.com>
1 parent 685d038 commit d7d9eb9

1 file changed

Lines changed: 22 additions & 7 deletions

File tree

src/payment/unified.rs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -309,14 +309,29 @@ impl UnifiedPayment {
309309
)
310310
} else {
311311
self.bolt12_payment.send(&offer, None, None, route_parameters)
312-
}
313-
.map_err(|e| {
314-
log_error!(self.logger, "Failed to send BOLT12 offer: {:?}. This is part of a unified payment. Falling back to the BOLT11 invoice.", e);
315-
e
316-
});
312+
};
317313

318-
if let Ok(payment_id) = payment_result {
319-
return Ok(UnifiedPaymentResult::Bolt12 { payment_id });
314+
match payment_result {
315+
Ok(payment_id) => {
316+
return Ok(UnifiedPaymentResult::Bolt12 { payment_id });
317+
},
318+
// A duplicate payment already exists, so falling back to the
319+
// BOLT11 invoice would pay the same offer a second time.
320+
Err(Error::DuplicatePayment) => {
321+
log_error!(self.logger, "Failed to send BOLT12 offer: DuplicatePayment. This is part of a unified payment. Aborting to avoid duplicate payment.");
322+
return Err(Error::DuplicatePayment);
323+
},
324+
// A persistence failure may occur after the Lightning payment has
325+
// already been initiated with the ChannelManager. Falling back to
326+
// the BOLT11 invoice in that case would double-pay, so we abort
327+
// instead of proceeding to the next payment method.
328+
Err(Error::PersistenceFailed) => {
329+
log_error!(self.logger, "Failed to send BOLT12 offer: PersistenceFailed. This is part of a unified payment. Aborting to avoid a potential duplicate payment.");
330+
return Err(Error::PersistenceFailed);
331+
},
332+
Err(e) => {
333+
log_error!(self.logger, "Failed to send BOLT12 offer: {:?}. This is part of a unified payment. Falling back to the BOLT11 invoice.", e);
334+
},
320335
}
321336
},
322337
PaymentMethod::LightningBolt11(invoice) => {

0 commit comments

Comments
 (0)