Skip to content

Commit dbc8edd

Browse files
committed
Introduce PaymentKind to payment store, track by PaymentId
1 parent d6e310c commit dbc8edd

File tree

10 files changed

+404
-197
lines changed

10 files changed

+404
-197
lines changed

bindings/ldk_node.udl

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ interface Node {
6868
void update_channel_config([ByRef]UserChannelId user_channel_id, PublicKey counterparty_node_id, ChannelConfig channel_config);
6969
[Throws=NodeError]
7070
void sync_wallets();
71-
PaymentDetails? payment([ByRef]PaymentHash payment_hash);
71+
PaymentDetails? payment([ByRef]PaymentId payment_id);
7272
[Throws=NodeError]
73-
void remove_payment([ByRef]PaymentHash payment_hash);
73+
void remove_payment([ByRef]PaymentId payment_id);
7474
BalanceDetails list_balances();
7575
sequence<PaymentDetails> list_payments();
7676
sequence<PeerDetails> list_peers();
@@ -82,9 +82,9 @@ interface Node {
8282

8383
interface Bolt11Payment {
8484
[Throws=NodeError]
85-
PaymentHash send([ByRef]Bolt11Invoice invoice);
85+
PaymentId send([ByRef]Bolt11Invoice invoice);
8686
[Throws=NodeError]
87-
PaymentHash send_using_amount([ByRef]Bolt11Invoice invoice, u64 amount_msat);
87+
PaymentId send_using_amount([ByRef]Bolt11Invoice invoice, u64 amount_msat);
8888
[Throws=NodeError]
8989
void send_probes([ByRef]Bolt11Invoice invoice);
9090
[Throws=NodeError]
@@ -101,7 +101,7 @@ interface Bolt11Payment {
101101

102102
interface SpontaneousPayment {
103103
[Throws=NodeError]
104-
PaymentHash send(u64 amount_msat, PublicKey node_id);
104+
PaymentId send(u64 amount_msat, PublicKey node_id);
105105
[Throws=NodeError]
106106
void send_probes(u64 amount_msat, PublicKey node_id);
107107
};
@@ -139,6 +139,7 @@ enum NodeError {
139139
"InvalidSocketAddress",
140140
"InvalidPublicKey",
141141
"InvalidSecretKey",
142+
"InvalidPaymentId",
142143
"InvalidPaymentHash",
143144
"InvalidPaymentPreimage",
144145
"InvalidPaymentSecret",
@@ -219,6 +220,14 @@ interface ClosureReason {
219220
HTLCsTimedOut();
220221
};
221222

223+
[Enum]
224+
interface PaymentKind {
225+
Onchain();
226+
Bolt11(PaymentHash hash, PaymentPreimage? preimage, PaymentSecret? secret);
227+
Bolt11Jit(PaymentHash hash, PaymentPreimage? preimage, PaymentSecret? secret, LSPFeeLimits lsp_fee_limits);
228+
Spontaneous(PaymentHash hash, PaymentPreimage? preimage);
229+
};
230+
222231
enum PaymentDirection {
223232
"Inbound",
224233
"Outbound",
@@ -236,13 +245,11 @@ dictionary LSPFeeLimits {
236245
};
237246

238247
dictionary PaymentDetails {
239-
PaymentHash hash;
240-
PaymentPreimage? preimage;
241-
PaymentSecret? secret;
248+
PaymentId id;
249+
PaymentKind kind;
242250
u64? amount_msat;
243251
PaymentDirection direction;
244252
PaymentStatus status;
245-
LSPFeeLimits? lsp_fee_limits;
246253
};
247254

248255
[NonExhaustive]
@@ -364,6 +371,9 @@ typedef string Address;
364371
[Custom]
365372
typedef string Bolt11Invoice;
366373

374+
[Custom]
375+
typedef string PaymentId;
376+
367377
[Custom]
368378
typedef string PaymentHash;
369379

src/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ pub enum Error {
4747
InvalidPublicKey,
4848
/// The given secret key is invalid.
4949
InvalidSecretKey,
50+
/// The given payment id is invalid.
51+
InvalidPaymentId,
5052
/// The given payment hash is invalid.
5153
InvalidPaymentHash,
5254
/// The given payment pre-image is invalid.
@@ -100,6 +102,7 @@ impl fmt::Display for Error {
100102
Self::InvalidSocketAddress => write!(f, "The given network address is invalid."),
101103
Self::InvalidPublicKey => write!(f, "The given public key is invalid."),
102104
Self::InvalidSecretKey => write!(f, "The given secret key is invalid."),
105+
Self::InvalidPaymentId => write!(f, "The given payment id is invalid."),
103106
Self::InvalidPaymentHash => write!(f, "The given payment hash is invalid."),
104107
Self::InvalidPaymentPreimage => write!(f, "The given payment preimage is invalid."),
105108
Self::InvalidPaymentSecret => write!(f, "The given payment secret is invalid."),

src/event.rs

Lines changed: 61 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ use crate::{
44
};
55

66
use crate::payment::payment_store::{
7-
PaymentDetails, PaymentDetailsUpdate, PaymentDirection, PaymentStatus, PaymentStore,
7+
PaymentDetails, PaymentDetailsUpdate, PaymentDirection, PaymentKind, PaymentStatus,
8+
PaymentStore,
89
};
910

1011
use crate::io::{
@@ -17,6 +18,7 @@ use lightning::chain::chaininterface::ConfirmationTarget;
1718
use lightning::events::{ClosureReason, PaymentPurpose};
1819
use lightning::events::{Event as LdkEvent, PaymentFailureReason};
1920
use lightning::impl_writeable_tlv_based_enum;
21+
use lightning::ln::channelmanager::PaymentId;
2022
use lightning::ln::{ChannelId, PaymentHash};
2123
use lightning::routing::gossip::NodeId;
2224
use lightning::util::errors::APIError;
@@ -410,7 +412,8 @@ where
410412
onion_fields: _,
411413
counterparty_skimmed_fee_msat,
412414
} => {
413-
if let Some(info) = self.payment_store.get(&payment_hash) {
415+
let payment_id = PaymentId(payment_hash.0);
416+
if let Some(info) = self.payment_store.get(&payment_id) {
414417
if info.status == PaymentStatus::Succeeded {
415418
log_info!(
416419
self.logger,
@@ -422,7 +425,7 @@ where
422425

423426
let update = PaymentDetailsUpdate {
424427
status: Some(PaymentStatus::Failed),
425-
..PaymentDetailsUpdate::new(payment_hash)
428+
..PaymentDetailsUpdate::new(payment_id)
426429
};
427430
self.payment_store.update(&update).unwrap_or_else(|e| {
428431
log_error!(self.logger, "Failed to access payment store: {}", e);
@@ -431,17 +434,22 @@ where
431434
return;
432435
}
433436

434-
let max_total_opening_fee_msat = info
435-
.lsp_fee_limits
436-
.and_then(|l| {
437-
l.max_total_opening_fee_msat.or_else(|| {
438-
l.max_proportional_opening_fee_ppm_msat.and_then(|max_prop_fee| {
439-
// If it's a variable amount payment, compute the actual fee.
440-
compute_opening_fee(amount_msat, 0, max_prop_fee)
437+
let max_total_opening_fee_msat = match info.kind {
438+
PaymentKind::Bolt11Jit { lsp_fee_limits, .. } => {
439+
lsp_fee_limits
440+
.max_total_opening_fee_msat
441+
.or_else(|| {
442+
lsp_fee_limits.max_proportional_opening_fee_ppm_msat.and_then(
443+
|max_prop_fee| {
444+
// If it's a variable amount payment, compute the actual fee.
445+
compute_opening_fee(amount_msat, 0, max_prop_fee)
446+
},
447+
)
441448
})
442-
})
443-
})
444-
.unwrap_or(0);
449+
.unwrap_or(0)
450+
},
451+
_ => 0,
452+
};
445453

446454
if counterparty_skimmed_fee_msat > max_total_opening_fee_msat {
447455
log_info!(
@@ -455,7 +463,7 @@ where
455463

456464
let update = PaymentDetailsUpdate {
457465
status: Some(PaymentStatus::Failed),
458-
..PaymentDetailsUpdate::new(payment_hash)
466+
..PaymentDetailsUpdate::new(payment_id)
459467
};
460468
self.payment_store.update(&update).unwrap_or_else(|e| {
461469
log_error!(self.logger, "Failed to access payment store: {}", e);
@@ -516,7 +524,7 @@ where
516524

517525
let update = PaymentDetailsUpdate {
518526
status: Some(PaymentStatus::Failed),
519-
..PaymentDetailsUpdate::new(payment_hash)
527+
..PaymentDetailsUpdate::new(payment_id)
520528
};
521529
self.payment_store.update(&update).unwrap_or_else(|e| {
522530
log_error!(self.logger, "Failed to access payment store: {}", e);
@@ -538,6 +546,7 @@ where
538546
hex_utils::to_string(&payment_hash.0),
539547
amount_msat,
540548
);
549+
let payment_id = PaymentId(payment_hash.0);
541550
match purpose {
542551
PaymentPurpose::Bolt11InvoicePayment {
543552
payment_preimage,
@@ -549,7 +558,7 @@ where
549558
secret: Some(Some(payment_secret)),
550559
amount_msat: Some(Some(amount_msat)),
551560
status: Some(PaymentStatus::Succeeded),
552-
..PaymentDetailsUpdate::new(payment_hash)
561+
..PaymentDetailsUpdate::new(payment_id)
553562
};
554563
match self.payment_store.update(&update) {
555564
Ok(true) => (),
@@ -591,14 +600,16 @@ where
591600
return;
592601
},
593602
PaymentPurpose::SpontaneousPayment(preimage) => {
594-
let payment = PaymentDetails {
595-
preimage: Some(preimage),
603+
let kind = PaymentKind::Spontaneous {
596604
hash: payment_hash,
597-
secret: None,
605+
preimage: Some(preimage),
606+
};
607+
let payment = PaymentDetails {
608+
id: payment_id,
609+
kind,
598610
amount_msat: Some(amount_msat),
599611
direction: PaymentDirection::Inbound,
600612
status: PaymentStatus::Succeeded,
601-
lsp_fee_limits: None,
602613
};
603614

604615
match self.payment_store.insert(payment) {
@@ -631,14 +642,32 @@ where
631642
panic!("Failed to push to event queue");
632643
});
633644
},
634-
LdkEvent::PaymentSent { payment_preimage, payment_hash, fee_paid_msat, .. } => {
635-
if let Some(mut payment) = self.payment_store.get(&payment_hash) {
636-
payment.preimage = Some(payment_preimage);
637-
payment.status = PaymentStatus::Succeeded;
638-
self.payment_store.insert(payment.clone()).unwrap_or_else(|e| {
639-
log_error!(self.logger, "Failed to access payment store: {}", e);
640-
panic!("Failed to access payment store");
641-
});
645+
LdkEvent::PaymentSent {
646+
payment_id,
647+
payment_preimage,
648+
payment_hash,
649+
fee_paid_msat,
650+
..
651+
} => {
652+
let payment_id = if let Some(id) = payment_id {
653+
id
654+
} else {
655+
debug_assert!(false, "payment_id should always be set.");
656+
return;
657+
};
658+
659+
let update = PaymentDetailsUpdate {
660+
preimage: Some(Some(payment_preimage)),
661+
status: Some(PaymentStatus::Succeeded),
662+
..PaymentDetailsUpdate::new(payment_id)
663+
};
664+
665+
self.payment_store.update(&update).unwrap_or_else(|e| {
666+
log_error!(self.logger, "Failed to access payment store: {}", e);
667+
panic!("Failed to access payment store");
668+
});
669+
670+
self.payment_store.get(&payment_id).map(|payment| {
642671
log_info!(
643672
self.logger,
644673
"Successfully sent payment of {}msat{} from \
@@ -652,15 +681,16 @@ where
652681
hex_utils::to_string(&payment_hash.0),
653682
hex_utils::to_string(&payment_preimage.0)
654683
);
655-
}
684+
});
685+
656686
self.event_queue
657687
.add_event(Event::PaymentSuccessful { payment_hash, fee_paid_msat })
658688
.unwrap_or_else(|e| {
659689
log_error!(self.logger, "Failed to push to event queue: {}", e);
660690
panic!("Failed to push to event queue");
661691
});
662692
},
663-
LdkEvent::PaymentFailed { payment_hash, reason, .. } => {
693+
LdkEvent::PaymentFailed { payment_id, payment_hash, reason, .. } => {
664694
log_info!(
665695
self.logger,
666696
"Failed to send payment to payment hash {:?} due to {:?}.",
@@ -670,7 +700,7 @@ where
670700

671701
let update = PaymentDetailsUpdate {
672702
status: Some(PaymentStatus::Failed),
673-
..PaymentDetailsUpdate::new(payment_hash)
703+
..PaymentDetailsUpdate::new(payment_id)
674704
};
675705
self.payment_store.update(&update).unwrap_or_else(|e| {
676706
log_error!(self.logger, "Failed to access payment store: {}", e);

src/lib.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ pub use types::{ChannelDetails, PeerDetails, UserChannelId};
141141
use logger::{log_error, log_info, log_trace, FilesystemLogger, Logger};
142142

143143
use lightning::chain::{BestBlock, Confirm};
144+
use lightning::ln::channelmanager::PaymentId;
144145
use lightning::ln::msgs::SocketAddress;
145-
use lightning::ln::PaymentHash;
146146

147147
use lightning::util::config::{ChannelHandshakeConfig, UserConfig};
148148
pub use lightning::util::logger::Level as LogLevel;
@@ -1143,16 +1143,16 @@ impl Node {
11431143
}
11441144
}
11451145

1146-
/// Retrieve the details of a specific payment with the given hash.
1146+
/// Retrieve the details of a specific payment with the given id.
11471147
///
11481148
/// Returns `Some` if the payment was known and `None` otherwise.
1149-
pub fn payment(&self, payment_hash: &PaymentHash) -> Option<PaymentDetails> {
1150-
self.payment_store.get(payment_hash)
1149+
pub fn payment(&self, payment_id: &PaymentId) -> Option<PaymentDetails> {
1150+
self.payment_store.get(payment_id)
11511151
}
11521152

1153-
/// Remove the payment with the given hash from the store.
1154-
pub fn remove_payment(&self, payment_hash: &PaymentHash) -> Result<(), Error> {
1155-
self.payment_store.remove(&payment_hash)
1153+
/// Remove the payment with the given id from the store.
1154+
pub fn remove_payment(&self, payment_id: &PaymentId) -> Result<(), Error> {
1155+
self.payment_store.remove(&payment_id)
11561156
}
11571157

11581158
/// Retrieves an overview of all known balances.

0 commit comments

Comments
 (0)