Skip to content

Commit 7d4b84e

Browse files
committed
f Restore BOLT11 duplicate payments
Keep outbound BOLT11 payments keyed by payment hash so repeated attempts to pay the same invoice can still return DuplicatePayment. Co-Authored-By: HAL 9000
1 parent a9d3dcf commit 7d4b84e

3 files changed

Lines changed: 12 additions & 8 deletions

File tree

src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,7 +1016,6 @@ impl Node {
10161016
Bolt11Payment::new(
10171017
Arc::clone(&self.runtime),
10181018
Arc::clone(&self.channel_manager),
1019-
Arc::clone(&self.keys_manager),
10201019
Arc::clone(&self.connection_manager),
10211020
Arc::clone(&self.liquidity_source),
10221021
Arc::clone(&self.payment_store),
@@ -1035,7 +1034,6 @@ impl Node {
10351034
Arc::new(Bolt11Payment::new(
10361035
Arc::clone(&self.runtime),
10371036
Arc::clone(&self.channel_manager),
1038-
Arc::clone(&self.keys_manager),
10391037
Arc::clone(&self.connection_manager),
10401038
Arc::clone(&self.liquidity_source),
10411039
Arc::clone(&self.payment_store),

src/payment/bolt11.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ use lightning::ln::channelmanager::{
1919
};
2020
use lightning::ln::outbound_payment::{Bolt11PaymentError, Retry, RetryableSendFailure};
2121
use lightning::routing::router::{PaymentParameters, RouteParameters, RouteParametersConfig};
22-
use lightning::sign::EntropySource;
2322
use lightning_invoice::{
2423
Bolt11Invoice as LdkBolt11Invoice, Bolt11InvoiceDescription as LdkBolt11InvoiceDescription,
2524
};
@@ -38,7 +37,7 @@ use crate::payment::store::{
3837
};
3938
use crate::peer_store::{PeerInfo, PeerStore};
4039
use crate::runtime::Runtime;
41-
use crate::types::{ChannelManager, KeysManager, PaymentStore};
40+
use crate::types::{ChannelManager, PaymentStore};
4241

4342
#[cfg(not(feature = "uniffi"))]
4443
type Bolt11Invoice = LdkBolt11Invoice;
@@ -70,7 +69,6 @@ impl_writeable_tlv_based!(PaymentMetadata, {
7069
pub struct Bolt11Payment {
7170
runtime: Arc<Runtime>,
7271
channel_manager: Arc<ChannelManager>,
73-
keys_manager: Arc<KeysManager>,
7472
connection_manager: Arc<ConnectionManager<Arc<Logger>>>,
7573
liquidity_source: Arc<LiquiditySource<Arc<Logger>>>,
7674
payment_store: Arc<PaymentStore>,
@@ -83,15 +81,14 @@ pub struct Bolt11Payment {
8381
impl Bolt11Payment {
8482
pub(crate) fn new(
8583
runtime: Arc<Runtime>, channel_manager: Arc<ChannelManager>,
86-
keys_manager: Arc<KeysManager>, connection_manager: Arc<ConnectionManager<Arc<Logger>>>,
84+
connection_manager: Arc<ConnectionManager<Arc<Logger>>>,
8785
liquidity_source: Arc<LiquiditySource<Arc<Logger>>>, payment_store: Arc<PaymentStore>,
8886
peer_store: Arc<PeerStore<Arc<Logger>>>, config: Arc<Config>,
8987
is_running: Arc<RwLock<bool>>, logger: Arc<Logger>,
9088
) -> Self {
9189
Self {
9290
runtime,
9391
channel_manager,
94-
keys_manager,
9592
connection_manager,
9693
liquidity_source,
9794
payment_store,
@@ -210,7 +207,15 @@ impl Bolt11Payment {
210207
}
211208

212209
let payment_hash = invoice.payment_hash();
213-
let payment_id = PaymentId(self.keys_manager.get_secure_random_bytes());
210+
let payment_id = PaymentId(invoice.payment_hash().0);
211+
if let Some(payment) = self.payment_store.get(&payment_id) {
212+
if payment.status == PaymentStatus::Pending
213+
|| payment.status == PaymentStatus::Succeeded
214+
{
215+
log_error!(self.logger, "Payment error: an invoice must not be paid twice.");
216+
return Err(Error::DuplicatePayment);
217+
}
218+
}
214219

215220
let route_params_config =
216221
route_parameters.or(self.config.route_parameters).unwrap_or_default();

tests/common/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,6 +1272,7 @@ pub(crate) async fn do_channel_full_cycle<E: ElectrumApi>(
12721272

12731273
println!("\nA send");
12741274
let outbound_payment_id = node_a.bolt11_payment().send(&invoice, None).unwrap();
1275+
assert_eq!(Err(NodeError::DuplicatePayment), node_a.bolt11_payment().send(&invoice, None));
12751276

12761277
assert!(!node_a.list_payments_with_filter(|p| p.id == outbound_payment_id).is_empty());
12771278

0 commit comments

Comments
 (0)