diff --git a/Cargo.toml b/Cargo.toml index c2b7775ac..f3038ee96 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,17 +52,17 @@ default = [] #lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main" } #lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main" } -lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0", features = ["std"] } -lightning-types = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0" } -lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0", features = ["std"] } -lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0" } -lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0" } -lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0" } -lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0" } -lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0", features = ["rest-client", "rpc-client", "tokio"] } -lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0", features = ["esplora-async-https", "electrum-rustls-ring", "time"] } -lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0" } -lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0" } +lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b002e43ec5f9c1cbdcd1ac8588402c5a65ecd2e4", features = ["std"] } +lightning-types = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b002e43ec5f9c1cbdcd1ac8588402c5a65ecd2e4" } +lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b002e43ec5f9c1cbdcd1ac8588402c5a65ecd2e4", features = ["std"] } +lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b002e43ec5f9c1cbdcd1ac8588402c5a65ecd2e4" } +lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b002e43ec5f9c1cbdcd1ac8588402c5a65ecd2e4" } +lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b002e43ec5f9c1cbdcd1ac8588402c5a65ecd2e4" } +lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b002e43ec5f9c1cbdcd1ac8588402c5a65ecd2e4" } +lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b002e43ec5f9c1cbdcd1ac8588402c5a65ecd2e4", features = ["rest-client", "rpc-client", "tokio"] } +lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b002e43ec5f9c1cbdcd1ac8588402c5a65ecd2e4", features = ["esplora-async-https", "electrum-rustls-ring", "time"] } +lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b002e43ec5f9c1cbdcd1ac8588402c5a65ecd2e4" } +lightning-macros = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b002e43ec5f9c1cbdcd1ac8588402c5a65ecd2e4" } #lightning = { path = "../rust-lightning/lightning", features = ["std"] } #lightning-types = { path = "../rust-lightning/lightning-types" } @@ -109,7 +109,7 @@ winapi = { version = "0.3", features = ["winbase"] } [dev-dependencies] #lightning = { version = "0.1.0", features = ["std", "_test_utils"] } #lightning = { git = "https://github.com/lightningdevkit/rust-lightning", branch="main", features = ["std", "_test_utils"] } -lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "84398d9e5b3dc61c0a5c71972aa944f19948aef0", features = ["std", "_test_utils"] } +lightning = { git = "https://github.com/lightningdevkit/rust-lightning", rev = "b002e43ec5f9c1cbdcd1ac8588402c5a65ecd2e4", features = ["std", "_test_utils"] } #lightning = { path = "../rust-lightning/lightning", features = ["std", "_test_utils"] } proptest = "1.0.0" regex = "1.5.6" diff --git a/src/builder.rs b/src/builder.rs index d330597ee..b99c44cec 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1378,6 +1378,10 @@ fn build_with_store_internal( 100; } + if config.async_payment_services_enabled { + user_config.accept_forwards_to_priv_channels = true; + } + let message_router = Arc::new(MessageRouter::new(Arc::clone(&network_graph), Arc::clone(&keys_manager))); diff --git a/src/event.rs b/src/event.rs index 7a6dc4832..cd9146379 100644 --- a/src/event.rs +++ b/src/event.rs @@ -1500,13 +1500,19 @@ where LdkEvent::PersistStaticInvoice { invoice, + invoice_request_path, invoice_slot, recipient_id, invoice_persisted_path, } => { if let Some(store) = self.static_invoice_store.as_ref() { match store - .handle_persist_static_invoice(invoice, invoice_slot, recipient_id) + .handle_persist_static_invoice( + invoice, + invoice_request_path, + invoice_slot, + recipient_id, + ) .await { Ok(_) => { @@ -1519,16 +1525,24 @@ where }; } }, - LdkEvent::StaticInvoiceRequested { recipient_id, invoice_slot, reply_path } => { + LdkEvent::StaticInvoiceRequested { + recipient_id, + invoice_slot, + reply_path, + invoice_request, + } => { if let Some(store) = self.static_invoice_store.as_ref() { let invoice = store.handle_static_invoice_requested(&recipient_id, invoice_slot).await; match invoice { - Ok(Some(invoice)) => { - if let Err(e) = - self.channel_manager.send_static_invoice(invoice, reply_path) - { + Ok(Some((invoice, invoice_request_path))) => { + if let Err(e) = self.channel_manager.respond_to_static_invoice_request( + invoice, + reply_path, + invoice_request, + invoice_request_path, + ) { log_error!(self.logger, "Failed to send static invoice: {:?}", e); } }, diff --git a/src/payment/asynchronous/static_invoice_store.rs b/src/payment/asynchronous/static_invoice_store.rs index eed6720e5..f1aa702a4 100644 --- a/src/payment/asynchronous/static_invoice_store.rs +++ b/src/payment/asynchronous/static_invoice_store.rs @@ -15,11 +15,23 @@ use crate::types::DynStore; use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::hashes::Hash; -use lightning::{offers::static_invoice::StaticInvoice, util::ser::Writeable}; +use lightning::blinded_path::message::BlindedMessagePath; +use lightning::impl_writeable_tlv_based; +use lightning::{offers::static_invoice::StaticInvoice, util::ser::Readable, util::ser::Writeable}; use std::sync::{Arc, Mutex}; use std::time::Duration; +struct PersistedStaticInvoice { + invoice: StaticInvoice, + request_path: BlindedMessagePath, +} + +impl_writeable_tlv_based!(PersistedStaticInvoice, { + (0, invoice, required), + (2, request_path, required) +}); + pub(crate) struct StaticInvoiceStore { kv_store: Arc, request_rate_limiter: Mutex, @@ -60,7 +72,7 @@ impl StaticInvoiceStore { pub(crate) async fn handle_static_invoice_requested( &self, recipient_id: &[u8], invoice_slot: u16, - ) -> Result, lightning::io::Error> { + ) -> Result, lightning::io::Error> { Self::check_rate_limit(&self.request_rate_limiter, &recipient_id)?; let (secondary_namespace, key) = Self::get_storage_location(invoice_slot, recipient_id); @@ -68,12 +80,16 @@ impl StaticInvoiceStore { self.kv_store .read(STATIC_INVOICE_STORE_PRIMARY_NAMESPACE, &secondary_namespace, &key) .and_then(|data| { - data.try_into().map(Some).map_err(|e| { - lightning::io::Error::new( - lightning::io::ErrorKind::InvalidData, - format!("Failed to parse static invoice: {:?}", e), - ) - }) + PersistedStaticInvoice::read(&mut &*data) + .map(|persisted_invoice| { + Some((persisted_invoice.invoice, persisted_invoice.request_path)) + }) + .map_err(|e| { + lightning::io::Error::new( + lightning::io::ErrorKind::InvalidData, + format!("Failed to parse static invoice: {:?}", e), + ) + }) }) .or_else( |e| { @@ -87,14 +103,18 @@ impl StaticInvoiceStore { } pub(crate) async fn handle_persist_static_invoice( - &self, invoice: StaticInvoice, invoice_slot: u16, recipient_id: Vec, + &self, invoice: StaticInvoice, invoice_request_path: BlindedMessagePath, invoice_slot: u16, + recipient_id: Vec, ) -> Result<(), lightning::io::Error> { Self::check_rate_limit(&self.persist_rate_limiter, &recipient_id)?; let (secondary_namespace, key) = Self::get_storage_location(invoice_slot, &recipient_id); + let persisted_invoice = + PersistedStaticInvoice { invoice, request_path: invoice_request_path }; + let mut buf = Vec::new(); - invoice.write(&mut buf)?; + persisted_invoice.write(&mut buf)?; // Static invoices will be persisted at "static_invoices//". // @@ -144,15 +164,21 @@ mod tests { let static_invoice = invoice(); let recipient_id = vec![1, 1, 1]; + let invoice_request_path = blinded_path(); assert!(static_invoice_store - .handle_persist_static_invoice(static_invoice.clone(), 0, recipient_id.clone()) + .handle_persist_static_invoice( + static_invoice.clone(), + invoice_request_path.clone(), + 0, + recipient_id.clone() + ) .await .is_ok()); let requested_invoice = static_invoice_store.handle_static_invoice_requested(&recipient_id, 0).await.unwrap(); - assert_eq!(requested_invoice.unwrap(), static_invoice); + assert_eq!(requested_invoice.unwrap(), (static_invoice, invoice_request_path)); assert!(static_invoice_store .handle_static_invoice_requested(&recipient_id, 1) diff --git a/tests/common/mod.rs b/tests/common/mod.rs index f5bfe76fc..70c9a43a8 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -589,6 +589,13 @@ pub(crate) fn bump_fee_and_broadcast( pub fn open_channel( node_a: &TestNode, node_b: &TestNode, funding_amount_sat: u64, should_announce: bool, electrsd: &ElectrsD, +) -> OutPoint { + open_channel_push_amt(node_a, node_b, funding_amount_sat, None, should_announce, electrsd) +} + +pub fn open_channel_push_amt( + node_a: &TestNode, node_b: &TestNode, funding_amount_sat: u64, push_amount_msat: Option, + should_announce: bool, electrsd: &ElectrsD, ) -> OutPoint { if should_announce { node_a @@ -596,7 +603,7 @@ pub fn open_channel( node_b.node_id(), node_b.listening_addresses().unwrap().first().unwrap().clone(), funding_amount_sat, - None, + push_amount_msat, None, ) .unwrap(); @@ -606,7 +613,7 @@ pub fn open_channel( node_b.node_id(), node_b.listening_addresses().unwrap().first().unwrap().clone(), funding_amount_sat, - None, + push_amount_msat, None, ) .unwrap(); diff --git a/tests/integration_tests_rust.rs b/tests/integration_tests_rust.rs index c9f2f95fc..f2e8407cd 100644 --- a/tests/integration_tests_rust.rs +++ b/tests/integration_tests_rust.rs @@ -14,9 +14,9 @@ use common::{ generate_blocks_and_wait, logging::MultiNodeLogger, logging::{init_log_logger, validate_log_entry, TestLogWriter}, - open_channel, premine_and_distribute_funds, premine_blocks, prepare_rbf, random_config, - random_listening_addresses, setup_bitcoind_and_electrsd, setup_builder, setup_node, - setup_two_nodes, wait_for_tx, TestChainSource, TestSyncStore, + open_channel, open_channel_push_amt, premine_and_distribute_funds, premine_blocks, prepare_rbf, + random_config, random_listening_addresses, setup_bitcoind_and_electrsd, setup_builder, + setup_node, setup_two_nodes, wait_for_tx, TestChainSource, TestSyncStore, }; use ldk_node::config::EsploraSyncConfig; @@ -1137,11 +1137,14 @@ fn static_invoice_server() { let chain_source = TestChainSource::Esplora(&electrsd); let mut config_sender = random_config(true); + config_sender.node_config.listening_addresses = None; + config_sender.node_config.node_alias = None; config_sender.log_writer = TestLogWriter::Custom(Arc::new(MultiNodeLogger::new("sender ".to_string()))); let node_sender = setup_node(&chain_source, config_sender, None); let mut config_sender_lsp = random_config(true); + config_sender_lsp.node_config.async_payment_services_enabled = true; config_sender_lsp.log_writer = TestLogWriter::Custom(Arc::new(MultiNodeLogger::new("sender_lsp ".to_string()))); let node_sender_lsp = setup_node(&chain_source, config_sender_lsp, None); @@ -1154,9 +1157,10 @@ fn static_invoice_server() { let node_receiver_lsp = setup_node(&chain_source, config_receiver_lsp, None); let mut config_receiver = random_config(true); + config_receiver.node_config.listening_addresses = None; + config_receiver.node_config.node_alias = None; config_receiver.log_writer = TestLogWriter::Custom(Arc::new(MultiNodeLogger::new("receiver ".to_string()))); - let node_receiver = setup_node(&chain_source, config_receiver, None); let address_sender = node_sender.onchain_payment().new_address().unwrap(); @@ -1176,9 +1180,16 @@ fn static_invoice_server() { node_receiver_lsp.sync_wallets().unwrap(); node_receiver.sync_wallets().unwrap(); - open_channel(&node_sender, &node_sender_lsp, 400_000, true, &electrsd); + open_channel(&node_sender, &node_sender_lsp, 400_000, false, &electrsd); open_channel(&node_sender_lsp, &node_receiver_lsp, 400_000, true, &electrsd); - open_channel(&node_receiver_lsp, &node_receiver, 400_000, true, &electrsd); + open_channel_push_amt( + &node_receiver, + &node_receiver_lsp, + 400_000, + Some(200_000_000), + false, + &electrsd, + ); generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6); @@ -1201,14 +1212,14 @@ fn static_invoice_server() { .filter(|n| { node.network_graph().node(n).map_or(false, |info| info.announcement_info.is_some()) }) - .count() >= 4 + .count() >= 2 }; // Wait for everyone to see all channels and node announcements. - while node_sender.network_graph().list_channels().len() < 3 - || node_sender_lsp.network_graph().list_channels().len() < 3 - || node_receiver_lsp.network_graph().list_channels().len() < 3 - || node_receiver.network_graph().list_channels().len() < 3 + while node_sender.network_graph().list_channels().len() < 1 + || node_sender_lsp.network_graph().list_channels().len() < 1 + || node_receiver_lsp.network_graph().list_channels().len() < 1 + || node_receiver.network_graph().list_channels().len() < 1 || !has_node_announcements(&node_sender) || !has_node_announcements(&node_sender_lsp) || !has_node_announcements(&node_receiver_lsp)