Skip to content

Commit 876fafe

Browse files
committed
Update static invoice store for invoice requests
With the merge of lightningdevkit/rust-lightning#4049, it is now possible for a static invoice server to forward the invoice request to the recipient if they are online.
1 parent 7729e0c commit 876fafe

File tree

3 files changed

+70
-30
lines changed

3 files changed

+70
-30
lines changed

Cargo.toml

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,17 @@ default = []
5252
#lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main" }
5353
#lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main" }
5454

55-
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0", features = ["std"] }
56-
lightning-types = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0" }
57-
lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0", features = ["std"] }
58-
lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0" }
59-
lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0" }
60-
lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0" }
61-
lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0" }
62-
lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0", features = ["rest-client", "rpc-client", "tokio"] }
63-
lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0", features = ["esplora-async-https", "electrum-rustls-ring", "time"] }
64-
lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0" }
65-
lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0" }
55+
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5ae19b4fde9ff952e0ac1106990099a821372095", features = ["std"] }
56+
lightning-types = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5ae19b4fde9ff952e0ac1106990099a821372095" }
57+
lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5ae19b4fde9ff952e0ac1106990099a821372095", features = ["std"] }
58+
lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5ae19b4fde9ff952e0ac1106990099a821372095" }
59+
lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5ae19b4fde9ff952e0ac1106990099a821372095" }
60+
lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5ae19b4fde9ff952e0ac1106990099a821372095" }
61+
lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5ae19b4fde9ff952e0ac1106990099a821372095" }
62+
lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5ae19b4fde9ff952e0ac1106990099a821372095", features = ["rest-client", "rpc-client", "tokio"] }
63+
lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5ae19b4fde9ff952e0ac1106990099a821372095", features = ["esplora-async-https", "electrum-rustls-ring", "time"] }
64+
lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5ae19b4fde9ff952e0ac1106990099a821372095" }
65+
lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5ae19b4fde9ff952e0ac1106990099a821372095" }
6666

6767
#lightning = { path = "../rust-lightning/lightning", features = ["std"] }
6868
#lightning-types = { path = "../rust-lightning/lightning-types" }
@@ -109,7 +109,7 @@ winapi = { version = "0.3", features = ["winbase"] }
109109
[dev-dependencies]
110110
#lightning = { version = "0.1.0", features = ["std", "_test_utils"] }
111111
#lightning = { git = "https://github.com/lightningdevkit/rust-lightning", branch="main", features = ["std", "_test_utils"] }
112-
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0", features = ["std", "_test_utils"] }
112+
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "5ae19b4fde9ff952e0ac1106990099a821372095", features = ["std", "_test_utils"] }
113113
#lightning = { path = "../rust-lightning/lightning", features = ["std", "_test_utils"] }
114114
proptest = "1.0.0"
115115
regex = "1.5.6"

src/event.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1500,13 +1500,19 @@ where
15001500

15011501
LdkEvent::PersistStaticInvoice {
15021502
invoice,
1503+
invoice_request_path,
15031504
invoice_slot,
15041505
recipient_id,
15051506
invoice_persisted_path,
15061507
} => {
15071508
if let Some(store) = self.static_invoice_store.as_ref() {
15081509
match store
1509-
.handle_persist_static_invoice(invoice, invoice_slot, recipient_id)
1510+
.handle_persist_static_invoice(
1511+
invoice,
1512+
invoice_request_path,
1513+
invoice_slot,
1514+
recipient_id,
1515+
)
15101516
.await
15111517
{
15121518
Ok(_) => {
@@ -1519,16 +1525,24 @@ where
15191525
};
15201526
}
15211527
},
1522-
LdkEvent::StaticInvoiceRequested { recipient_id, invoice_slot, reply_path } => {
1528+
LdkEvent::StaticInvoiceRequested {
1529+
recipient_id,
1530+
invoice_slot,
1531+
reply_path,
1532+
invoice_request,
1533+
} => {
15231534
if let Some(store) = self.static_invoice_store.as_ref() {
15241535
let invoice =
15251536
store.handle_static_invoice_requested(&recipient_id, invoice_slot).await;
15261537

15271538
match invoice {
1528-
Ok(Some(invoice)) => {
1529-
if let Err(e) =
1530-
self.channel_manager.send_static_invoice(invoice, reply_path)
1531-
{
1539+
Ok(Some((invoice, invoice_request_path))) => {
1540+
if let Err(e) = self.channel_manager.respond_to_static_invoice_request(
1541+
invoice,
1542+
reply_path,
1543+
invoice_request,
1544+
invoice_request_path,
1545+
) {
15321546
log_error!(self.logger, "Failed to send static invoice: {:?}", e);
15331547
}
15341548
},

src/payment/asynchronous/static_invoice_store.rs

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,23 @@ use crate::types::DynStore;
1515
use bitcoin::hashes::sha256::Hash as Sha256;
1616
use bitcoin::hashes::Hash;
1717

18-
use lightning::{offers::static_invoice::StaticInvoice, util::ser::Writeable};
18+
use lightning::blinded_path::message::BlindedMessagePath;
19+
use lightning::impl_writeable_tlv_based;
20+
use lightning::{offers::static_invoice::StaticInvoice, util::ser::Readable, util::ser::Writeable};
1921

2022
use std::sync::{Arc, Mutex};
2123
use std::time::Duration;
2224

25+
struct PersistedStaticInvoice {
26+
invoice: StaticInvoice,
27+
request_path: BlindedMessagePath,
28+
}
29+
30+
impl_writeable_tlv_based!(PersistedStaticInvoice, {
31+
(0, invoice, required),
32+
(2, request_path, required)
33+
});
34+
2335
pub(crate) struct StaticInvoiceStore {
2436
kv_store: Arc<DynStore>,
2537
request_rate_limiter: Mutex<RateLimiter>,
@@ -60,20 +72,24 @@ impl StaticInvoiceStore {
6072

6173
pub(crate) async fn handle_static_invoice_requested(
6274
&self, recipient_id: &[u8], invoice_slot: u16,
63-
) -> Result<Option<StaticInvoice>, lightning::io::Error> {
75+
) -> Result<Option<(StaticInvoice, BlindedMessagePath)>, lightning::io::Error> {
6476
Self::check_rate_limit(&self.request_rate_limiter, &recipient_id)?;
6577

6678
let (secondary_namespace, key) = Self::get_storage_location(invoice_slot, recipient_id);
6779

6880
self.kv_store
6981
.read(STATIC_INVOICE_STORE_PRIMARY_NAMESPACE, &secondary_namespace, &key)
7082
.and_then(|data| {
71-
data.try_into().map(Some).map_err(|e| {
72-
lightning::io::Error::new(
73-
lightning::io::ErrorKind::InvalidData,
74-
format!("Failed to parse static invoice: {:?}", e),
75-
)
76-
})
83+
PersistedStaticInvoice::read(&mut &*data)
84+
.map(|persisted_invoice| {
85+
Some((persisted_invoice.invoice, persisted_invoice.request_path))
86+
})
87+
.map_err(|e| {
88+
lightning::io::Error::new(
89+
lightning::io::ErrorKind::InvalidData,
90+
format!("Failed to parse static invoice: {:?}", e),
91+
)
92+
})
7793
})
7894
.or_else(
7995
|e| {
@@ -87,14 +103,18 @@ impl StaticInvoiceStore {
87103
}
88104

89105
pub(crate) async fn handle_persist_static_invoice(
90-
&self, invoice: StaticInvoice, invoice_slot: u16, recipient_id: Vec<u8>,
106+
&self, invoice: StaticInvoice, invoice_request_path: BlindedMessagePath, invoice_slot: u16,
107+
recipient_id: Vec<u8>,
91108
) -> Result<(), lightning::io::Error> {
92109
Self::check_rate_limit(&self.persist_rate_limiter, &recipient_id)?;
93110

94111
let (secondary_namespace, key) = Self::get_storage_location(invoice_slot, &recipient_id);
95112

113+
let persisted_invoice =
114+
PersistedStaticInvoice { invoice, request_path: invoice_request_path };
115+
96116
let mut buf = Vec::new();
97-
invoice.write(&mut buf)?;
117+
persisted_invoice.write(&mut buf)?;
98118

99119
// Static invoices will be persisted at "static_invoices/<sha256(recipient_id)>/<invoice_slot>".
100120
//
@@ -144,15 +164,21 @@ mod tests {
144164

145165
let static_invoice = invoice();
146166
let recipient_id = vec![1, 1, 1];
167+
let invoice_request_path = blinded_path();
147168
assert!(static_invoice_store
148-
.handle_persist_static_invoice(static_invoice.clone(), 0, recipient_id.clone())
169+
.handle_persist_static_invoice(
170+
static_invoice.clone(),
171+
invoice_request_path.clone(),
172+
0,
173+
recipient_id.clone()
174+
)
149175
.await
150176
.is_ok());
151177

152178
let requested_invoice =
153179
static_invoice_store.handle_static_invoice_requested(&recipient_id, 0).await.unwrap();
154180

155-
assert_eq!(requested_invoice.unwrap(), static_invoice);
181+
assert_eq!(requested_invoice.unwrap(), (static_invoice, invoice_request_path));
156182

157183
assert!(static_invoice_store
158184
.handle_static_invoice_requested(&recipient_id, 1)

0 commit comments

Comments
 (0)