diff --git a/Cargo.toml b/Cargo.toml index f22092cb5..61d2685ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,37 +28,42 @@ panic = 'abort' # Abort on panic default = [] [dependencies] -lightning = { version = "0.0.125", features = ["std"] } -lightning-invoice = { version = "0.32.0" } -lightning-net-tokio = { version = "0.0.125" } -lightning-persister = { version = "0.0.125" } -lightning-background-processor = { version = "0.0.125", features = ["futures"] } -lightning-rapid-gossip-sync = { version = "0.0.125" } -lightning-block-sync = { version = "0.0.125", features = ["rpc-client", "tokio"] } -lightning-transaction-sync = { version = "0.0.125", features = ["esplora-async-https", "time"] } -lightning-liquidity = { version = "0.1.0-alpha.6", features = ["std"] } - -#lightning = { git = "https://github.com/lightningdevkit/rust-lightning", branch="main", features = ["std"] } -#lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", branch="main" } -#lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning", branch="main" } -#lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", branch="main" } -#lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", branch="main", features = ["futures"] } -#lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", branch="main" } -#lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", branch="main", features = ["esplora-async"] } -#lightning-liquidity = { git = "https://github.com/lightningdevkit/lightning-liquidity", branch="main", features = ["std"] } +lightning = { version = "0.1.0", features = ["std"] } +lightning-types = { version = "0.2.0" } +lightning-invoice = { version = "0.33.0", features = ["std"] } +lightning-net-tokio = { version = "0.1.0" } +lightning-persister = { version = "0.1.0" } +lightning-background-processor = { version = "0.1.0", features = ["futures"] } +lightning-rapid-gossip-sync = { version = "0.1.0" } +lightning-block-sync = { version = "0.1.0", features = ["rpc-client", "tokio"] } +lightning-transaction-sync = { version = "0.1.0", features = ["esplora-async-https", "time"] } +lightning-liquidity = { version = "0.1.0", features = ["std"] } + +#lightning = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main", features = ["std"] } +#lightning-types = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main" } +#lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main", features = ["std"] } +#lightning-net-tokio = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main" } +#lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main" } +#lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main", features = ["futures"] } +#lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main" } +#lightning-block-sync = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main", features = ["rpc-client", "tokio"] } +#lightning-transaction-sync = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main", features = ["esplora-async-https", "time"] } +#lightning-liquidity = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main" } #lightning = { path = "../rust-lightning/lightning", features = ["std"] } -#lightning-invoice = { path = "../rust-lightning/lightning-invoice" } +#lightning-types = { path = "../rust-lightning/lightning-types" } +#lightning-invoice = { path = "../rust-lightning/lightning-invoice", features = ["std"] } #lightning-net-tokio = { path = "../rust-lightning/lightning-net-tokio" } #lightning-persister = { path = "../rust-lightning/lightning-persister" } #lightning-background-processor = { path = "../rust-lightning/lightning-background-processor", features = ["futures"] } #lightning-rapid-gossip-sync = { path = "../rust-lightning/lightning-rapid-gossip-sync" } -#lightning-transaction-sync = { path = "../rust-lightning/lightning-transaction-sync", features = ["esplora-async"] } -#lightning-liquidity = { path = "../lightning-liquidity", features = ["std"] } +#lightning-block-sync = { path = "../rust-lightning/lightning-block-sync", features = ["rpc-client", "tokio"] } +#lightning-transaction-sync = { path = "../rust-lightning/lightning-transaction-sync", features = ["esplora-async-https", "time"] } +#lightning-liquidity = { path = "../rust-lightning/lightning-liquidity", features = ["std"] } -bdk_chain = { version = "=0.19.0", default-features = false, features = ["std"] } -bdk_esplora = { version = "=0.18.0", default-features = false, features = ["async-https-rustls"]} -bdk_wallet = { version = "=1.0.0-beta.4", default-features = false, features = ["std", "keys-bip39"]} +bdk_chain = { version = "0.21.1", default-features = false, features = ["std"] } +bdk_esplora = { version = "0.20.1", default-features = false, features = ["async-https-rustls", "tokio"]} +bdk_wallet = { version = "1.0.0", default-features = false, features = ["std", "keys-bip39"]} reqwest = { version = "0.11", default-features = false, features = ["json", "rustls-tls"] } rusqlite = { version = "0.31.0", features = ["bundled"] } @@ -70,7 +75,7 @@ base64 = { version = "0.22.1", default-features = false, features = ["std"] } rand = "0.8.5" chrono = { version = "0.4", default-features = false, features = ["clock"] } tokio = { version = "1.37", default-features = false, features = [ "rt-multi-thread", "time", "sync", "macros" ] } -esplora-client = { version = "0.9", default-features = false } +esplora-client = { version = "0.11", default-features = false, features = ["tokio", "async-https-rustls"] } libc = "0.2" uniffi = { version = "0.27.3", features = ["build"], optional = true } serde = { version = "1.0.210", default-features = false, features = ["std", "derive"] } @@ -83,8 +88,9 @@ prost = { version = "0.11.6", default-features = false} winapi = { version = "0.3", features = ["winbase"] } [dev-dependencies] -lightning = { version = "0.0.125", features = ["std", "_test_utils"] } +lightning = { version = "0.1.0", features = ["std", "_test_utils"] } #lightning = { git = "https://github.com/lightningdevkit/rust-lightning", branch="main", features = ["std", "_test_utils"] } +#lightning = { path = "../rust-lightning/lightning", features = ["std", "_test_utils"] } electrum-client = { version = "0.21.0", default-features = true } bitcoincore-rpc = { version = "0.19.0", default-features = false } proptest = "1.0.0" diff --git a/bindings/ldk_node.udl b/bindings/ldk_node.udl index bc99c1783..5ea0e4173 100644 --- a/bindings/ldk_node.udl +++ b/bindings/ldk_node.udl @@ -280,7 +280,8 @@ interface Event { PaymentFailed(PaymentId? payment_id, PaymentHash? payment_hash, PaymentFailureReason? reason); PaymentReceived(PaymentId? payment_id, PaymentHash payment_hash, u64 amount_msat, sequence custom_records); PaymentClaimable(PaymentId payment_id, PaymentHash payment_hash, u64 claimable_amount_msat, u32? claim_deadline, sequence custom_records); - PaymentForwarded(ChannelId prev_channel_id, ChannelId next_channel_id, UserChannelId? prev_user_channel_id, UserChannelId? next_user_channel_id, u64? total_fee_earned_msat, u64? skimmed_fee_msat, boolean claim_from_onchain_tx, u64? outbound_amount_forwarded_msat); + PaymentForwarded(ChannelId prev_channel_id, ChannelId next_channel_id, UserChannelId? + prev_user_channel_id, UserChannelId? next_user_channel_id, PublicKey? prev_node_id, PublicKey? next_node_id, u64? total_fee_earned_msat, u64? skimmed_fee_msat, boolean claim_from_onchain_tx, u64? outbound_amount_forwarded_msat); ChannelPending(ChannelId channel_id, UserChannelId user_channel_id, ChannelId former_temporary_channel_id, PublicKey counterparty_node_id, OutPoint funding_txo); ChannelReady(ChannelId channel_id, UserChannelId user_channel_id, PublicKey? counterparty_node_id); ChannelClosed(ChannelId channel_id, UserChannelId user_channel_id, PublicKey? counterparty_node_id, ClosureReason? reason); @@ -296,6 +297,7 @@ enum PaymentFailureReason { "UnknownRequiredFeatures", "InvoiceRequestExpired", "InvoiceRequestRejected", + "BlindedPathCreationFailed", }; [Enum] diff --git a/src/balance.rs b/src/balance.rs index c43386d80..4d75c6c8e 100644 --- a/src/balance.rs +++ b/src/balance.rs @@ -10,9 +10,10 @@ use crate::sweep::value_from_descriptor; use lightning::chain::channelmonitor::Balance as LdkBalance; use lightning::chain::channelmonitor::BalanceSource; use lightning::ln::types::ChannelId; -use lightning::ln::{PaymentHash, PaymentPreimage}; use lightning::util::sweep::{OutputSpendStatus, TrackedSpendableOutput}; +use lightning_types::payment::{PaymentHash, PaymentPreimage}; + use bitcoin::secp256k1::PublicKey; use bitcoin::{BlockHash, Txid}; diff --git a/src/builder.rs b/src/builder.rs index fac2ae0c5..d4987d805 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -907,7 +907,7 @@ fn build_with_store_internal( )); // Read ChannelMonitor state from store - let mut channel_monitors = match read_channel_monitors( + let channel_monitors = match read_channel_monitors( Arc::clone(&kv_store), Arc::clone(&keys_manager), Arc::clone(&keys_manager), @@ -936,6 +936,9 @@ fn build_with_store_internal( 100; } + let message_router = + Arc::new(MessageRouter::new(Arc::clone(&network_graph), Arc::clone(&keys_manager))); + // Initialize the ChannelManager let channel_manager = { if let Ok(res) = kv_store.read( @@ -945,7 +948,7 @@ fn build_with_store_internal( ) { let mut reader = Cursor::new(res); let channel_monitor_references = - channel_monitors.iter_mut().map(|(_, chanmon)| chanmon).collect(); + channel_monitors.iter().map(|(_, chanmon)| chanmon).collect(); let read_args = ChannelManagerReadArgs::new( Arc::clone(&keys_manager), Arc::clone(&keys_manager), @@ -954,6 +957,7 @@ fn build_with_store_internal( Arc::clone(&chain_monitor), Arc::clone(&tx_broadcaster), Arc::clone(&router), + Arc::clone(&message_router), Arc::clone(&logger), user_config, channel_monitor_references, @@ -978,6 +982,7 @@ fn build_with_store_internal( Arc::clone(&chain_monitor), Arc::clone(&tx_broadcaster), Arc::clone(&router), + Arc::clone(&message_router), Arc::clone(&logger), Arc::clone(&keys_manager), Arc::clone(&keys_manager), @@ -1000,18 +1005,17 @@ fn build_with_store_internal( })?; } - let message_router = MessageRouter::new(Arc::clone(&network_graph), Arc::clone(&keys_manager)); - // Initialize the PeerManager let onion_messenger: Arc = Arc::new(OnionMessenger::new( Arc::clone(&keys_manager), Arc::clone(&keys_manager), Arc::clone(&logger), Arc::clone(&channel_manager), - Arc::new(message_router), + message_router, Arc::clone(&channel_manager), IgnoringMessageHandler {}, IgnoringMessageHandler {}, + IgnoringMessageHandler {}, )); let ephemeral_bytes: [u8; 32] = keys_manager.get_secure_random_bytes(); @@ -1055,7 +1059,8 @@ fn build_with_store_internal( let liquidity_source = liquidity_source_config.as_ref().and_then(|lsc| { lsc.lsps2_service.as_ref().map(|(address, node_id, token)| { let lsps2_client_config = Some(LSPS2ClientConfig {}); - let liquidity_client_config = Some(LiquidityClientConfig { lsps2_client_config }); + let liquidity_client_config = + Some(LiquidityClientConfig { lsps1_client_config: None, lsps2_client_config }); let liquidity_manager = Arc::new(LiquidityManager::new( Arc::clone(&keys_manager), Arc::clone(&channel_manager), diff --git a/src/chain/bitcoind_rpc.rs b/src/chain/bitcoind_rpc.rs index 38bc4f2ee..3a3073378 100644 --- a/src/chain/bitcoind_rpc.rs +++ b/src/chain/bitcoind_rpc.rs @@ -38,10 +38,7 @@ impl BitcoindRpcClient { let rpc_credentials = BASE64_STANDARD.encode(format!("{}:{}", rpc_user.clone(), rpc_password.clone())); - let rpc_client = Arc::new( - RpcClient::new(&rpc_credentials, http_endpoint) - .expect("RpcClient::new is actually infallible"), - ); + let rpc_client = Arc::new(RpcClient::new(&rpc_credentials, http_endpoint)); let latest_mempool_timestamp = AtomicU64::new(0); diff --git a/src/chain/mod.rs b/src/chain/mod.rs index 6c89476d2..58d8a6417 100644 --- a/src/chain/mod.rs +++ b/src/chain/mod.rs @@ -787,18 +787,12 @@ impl ChainSource { for target in confirmation_targets { let num_blocks = get_num_block_defaults_for_target(target); + // Convert the retrieved fee rate and fall back to 1 sat/vb if we fail or it + // yields less than that. This is mostly necessary to continue on + // `signet`/`regtest` where we might not get estimates (or bogus values). let converted_estimate_sat_vb = - esplora_client::convert_fee_rate(num_blocks, estimates.clone()).map_err( - |e| { - log_error!( - logger, - "Failed to convert fee rate estimates for {:?}: {}", - target, - e - ); - Error::FeerateEstimationUpdateFailed - }, - )?; + esplora_client::convert_fee_rate(num_blocks, estimates.clone()) + .map_or(1.0, |converted| converted.max(1.0)); let fee_rate = FeeRate::from_sat_per_kwu((converted_estimate_sat_vb * 250.0) as u64); diff --git a/src/event.rs b/src/event.rs index 5f5812cdb..1de77e937 100644 --- a/src/event.rs +++ b/src/event.rs @@ -32,11 +32,12 @@ use lightning::events::{Event as LdkEvent, PaymentFailureReason}; use lightning::impl_writeable_tlv_based_enum; use lightning::ln::channelmanager::PaymentId; use lightning::ln::types::ChannelId; -use lightning::ln::{PaymentHash, PaymentPreimage}; use lightning::routing::gossip::NodeId; use lightning::util::errors::APIError; use lightning::util::ser::{Readable, ReadableArgs, Writeable, Writer}; +use lightning_types::payment::{PaymentHash, PaymentPreimage}; + use lightning_liquidity::lsps2::utils::compute_opening_fee; use bitcoin::blockdata::locktime::absolute::LockTime; @@ -120,6 +121,16 @@ pub enum Event { /// This will be `None` if the payment was settled via an on-chain transaction. See the /// caveat described for the `total_fee_earned_msat` field. next_user_channel_id: Option, + /// The node id of the previous node. + /// + /// This is only `None` for HTLCs received prior to LDK Node v0.5 or for events serialized by + /// versions prior to v0.5. + prev_node_id: Option, + /// The node id of the next node. + /// + /// This is only `None` for HTLCs received prior to LDK Node v0.5 or for events serialized by + /// versions prior to v0.5. + next_node_id: Option, /// The total fee, in milli-satoshis, which was earned as a result of the payment. /// /// Note that if we force-closed the channel over which we forwarded an HTLC while the HTLC @@ -257,7 +268,9 @@ impl_writeable_tlv_based_enum!(Event, }, (7, PaymentForwarded) => { (0, prev_channel_id, required), + (1, prev_node_id, option), (2, next_channel_id, required), + (3, next_node_id, option), (4, prev_user_channel_id, option), (6, next_user_channel_id, option), (8, total_fee_earned_msat, option), @@ -550,6 +563,7 @@ where claim_deadline, onion_fields, counterparty_skimmed_fee_msat, + payment_id: _, } => { let payment_id = PaymentId(payment_hash.0); if let Some(info) = self.payment_store.get(&payment_id) { @@ -812,6 +826,7 @@ where htlcs: _, sender_intended_total_msat: _, onion_fields, + payment_id: _, } => { let payment_id = PaymentId(payment_hash.0); log_info!( @@ -1025,7 +1040,7 @@ where counterparty_node_id, funding_satoshis, channel_type, - push_msat: _, + channel_negotiation_type: _, is_announced: _, params: _, } => { @@ -1139,6 +1154,8 @@ where next_channel_id, prev_user_channel_id, next_user_channel_id, + prev_node_id, + next_node_id, total_fee_earned_msat, skimmed_fee_msat, claim_from_onchain_tx, @@ -1149,6 +1166,8 @@ where next_channel_id: next_channel_id.expect("next_channel_id expected for events generated by LDK versions greater than 0.0.107."), prev_user_channel_id: prev_user_channel_id.map(UserChannelId), next_user_channel_id: next_user_channel_id.map(UserChannelId), + prev_node_id, + next_node_id, total_fee_earned_msat, skimmed_fee_msat, claim_from_onchain_tx, diff --git a/src/io/test_utils.rs b/src/io/test_utils.rs index 98b33fa5f..aed03b6fc 100644 --- a/src/io/test_utils.rs +++ b/src/io/test_utils.rs @@ -11,7 +11,6 @@ use lightning::ln::functional_test_utils::{ }; use lightning::util::persist::{read_channel_monitors, KVStore, KVSTORE_NAMESPACE_KEY_MAX_LEN}; -use lightning::chain::channelmonitor::CLOSED_CHANNEL_UPDATE_ID; use lightning::events::ClosureReason; use lightning::util::test_utils; use lightning::{check_added_monitors, check_closed_broadcast, check_closed_event}; @@ -186,5 +185,5 @@ pub(crate) fn do_test_store(store_0: &K, store_1: &K) { check_added_monitors!(nodes[1], 1); // Make sure everything is persisted as expected after close. - check_persisted_data!(CLOSED_CHANNEL_UPDATE_ID); + check_persisted_data!(11); } diff --git a/src/lib.rs b/src/lib.rs index 363812292..140c6bb41 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -100,6 +100,7 @@ pub use bip39; pub use bitcoin; pub use lightning; pub use lightning_invoice; +pub use lightning_types; pub use vss_client; pub use balance::{BalanceDetails, LightningBalance, PendingSweepBalance}; @@ -823,7 +824,6 @@ impl Node { Arc::clone(&self.runtime), Arc::clone(&self.channel_manager), Arc::clone(&self.connection_manager), - Arc::clone(&self.keys_manager), self.liquidity_source.clone(), Arc::clone(&self.payment_store), Arc::clone(&self.peer_store), @@ -841,7 +841,6 @@ impl Node { Arc::clone(&self.runtime), Arc::clone(&self.channel_manager), Arc::clone(&self.connection_manager), - Arc::clone(&self.keys_manager), self.liquidity_source.clone(), Arc::clone(&self.payment_store), Arc::clone(&self.peer_store), diff --git a/src/message_handler.rs b/src/message_handler.rs index 38999512e..cebd1ea07 100644 --- a/src/message_handler.rs +++ b/src/message_handler.rs @@ -7,11 +7,12 @@ use crate::liquidity::LiquiditySource; -use lightning::ln::features::{InitFeatures, NodeFeatures}; use lightning::ln::peer_handler::CustomMessageHandler; use lightning::ln::wire::CustomMessageReader; use lightning::util::logger::Logger; +use lightning_types::features::{InitFeatures, NodeFeatures}; + use lightning_liquidity::lsps0::ser::RawLSPSMessage; use bitcoin::secp256k1::PublicKey; @@ -63,7 +64,7 @@ where L::Target: Logger, { fn handle_custom_message( - &self, msg: Self::CustomMessage, sender_node_id: &PublicKey, + &self, msg: Self::CustomMessage, sender_node_id: PublicKey, ) -> Result<(), lightning::ln::msgs::LightningError> { match self { Self::Ignoring => Ok(()), // Should be unreachable!() as the reader will return `None` @@ -91,7 +92,7 @@ where } } - fn provided_init_features(&self, their_node_id: &PublicKey) -> InitFeatures { + fn provided_init_features(&self, their_node_id: PublicKey) -> InitFeatures { match self { Self::Ignoring => InitFeatures::empty(), Self::Liquidity { liquidity_source, .. } => { @@ -101,7 +102,7 @@ where } fn peer_connected( - &self, their_node_id: &PublicKey, msg: &lightning::ln::msgs::Init, inbound: bool, + &self, their_node_id: PublicKey, msg: &lightning::ln::msgs::Init, inbound: bool, ) -> Result<(), ()> { match self { Self::Ignoring => Ok(()), @@ -111,7 +112,7 @@ where } } - fn peer_disconnected(&self, their_node_id: &PublicKey) { + fn peer_disconnected(&self, their_node_id: PublicKey) { match self { Self::Ignoring => {}, Self::Liquidity { liquidity_source, .. } => { diff --git a/src/payment/bolt11.rs b/src/payment/bolt11.rs index 708c127bd..d2a5840c0 100644 --- a/src/payment/bolt11.rs +++ b/src/payment/bolt11.rs @@ -20,24 +20,22 @@ use crate::payment::store::{ }; use crate::payment::SendingParameters; use crate::peer_store::{PeerInfo, PeerStore}; -use crate::types::{ChannelManager, KeysManager}; +use crate::types::ChannelManager; -use lightning::ln::channelmanager::{PaymentId, RecipientOnionFields, Retry, RetryableSendFailure}; -use lightning::ln::invoice_utils::{ - create_invoice_from_channelmanager_and_duration_since_epoch, - create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_hash, +use lightning::ln::bolt11_payment; +use lightning::ln::channelmanager::{ + Bolt11InvoiceParameters, PaymentId, RecipientOnionFields, Retry, RetryableSendFailure, }; -use lightning::ln::{PaymentHash, PaymentPreimage}; use lightning::routing::router::{PaymentParameters, RouteParameters}; -use lightning::ln::bolt11_payment; -use lightning_invoice::{Bolt11Invoice, Currency}; +use lightning_types::payment::{PaymentHash, PaymentPreimage}; + +use lightning_invoice::{Bolt11Invoice, Bolt11InvoiceDescription, Description}; use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::hashes::Hash; use std::sync::{Arc, RwLock}; -use std::time::SystemTime; /// A payment handler allowing to create and pay [BOLT 11] invoices. /// @@ -49,7 +47,6 @@ pub struct Bolt11Payment { runtime: Arc>>>, channel_manager: Arc, connection_manager: Arc>>, - keys_manager: Arc, liquidity_source: Option>>>, payment_store: Arc>>, peer_store: Arc>>, @@ -62,7 +59,6 @@ impl Bolt11Payment { runtime: Arc>>>, channel_manager: Arc, connection_manager: Arc>>, - keys_manager: Arc, liquidity_source: Option>>>, payment_store: Arc>>, peer_store: Arc>>, config: Arc, @@ -72,7 +68,6 @@ impl Bolt11Payment { runtime, channel_manager, connection_manager, - keys_manager, liquidity_source, payment_store, peer_store, @@ -468,41 +463,20 @@ impl Bolt11Payment { &self, amount_msat: Option, description: &str, expiry_secs: u32, manual_claim_payment_hash: Option, ) -> Result { - let currency = Currency::from(self.config.network); - let keys_manager = Arc::clone(&self.keys_manager); - let duration = SystemTime::now() - .duration_since(SystemTime::UNIX_EPOCH) - .expect("for the foreseeable future this shouldn't happen"); + let invoice_description = Bolt11InvoiceDescription::Direct( + Description::new(description.to_string()).map_err(|_| Error::InvoiceCreationFailed)?, + ); let invoice = { - let invoice_res = if let Some(payment_hash) = manual_claim_payment_hash { - create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_hash( - &self.channel_manager, - keys_manager, - Arc::clone(&self.logger), - currency, - amount_msat, - description.to_string(), - duration, - expiry_secs, - payment_hash, - None, - ) - } else { - create_invoice_from_channelmanager_and_duration_since_epoch( - &self.channel_manager, - keys_manager, - Arc::clone(&self.logger), - currency, - amount_msat, - description.to_string(), - duration, - expiry_secs, - None, - ) + let invoice_params = Bolt11InvoiceParameters { + amount_msats: amount_msat, + description: invoice_description, + invoice_expiry_delta_secs: Some(expiry_secs), + payment_hash: manual_claim_payment_hash, + ..Default::default() }; - match invoice_res { + match self.channel_manager.create_bolt11_invoice(invoice_params) { Ok(inv) => { log_info!(self.logger, "Invoice created: {}", inv); inv @@ -748,7 +722,7 @@ impl Bolt11Payment { Error::InvalidInvoice })? } else { - bolt11_payment::payment_parameters_from_zero_amount_invoice(&invoice, amount_msat).map_err(|_| { + bolt11_payment::payment_parameters_from_variable_amount_invoice(&invoice, amount_msat).map_err(|_| { log_error!(self.logger, "Failed to send probes due to the given invoice unexpectedly being not \"zero-amount\"."); Error::InvalidInvoice })? diff --git a/src/payment/bolt12.rs b/src/payment/bolt12.rs index 90024b7d3..c32b1a1a8 100644 --- a/src/payment/bolt12.rs +++ b/src/payment/bolt12.rs @@ -93,7 +93,7 @@ impl Bolt12Payment { max_total_routing_fee_msat, ) { Ok(()) => { - let payee_pubkey = offer.signing_pubkey(); + let payee_pubkey = offer.issuer_signing_pubkey(); log_info!( self.logger, "Initiated sending {}msat to {:?}", @@ -197,7 +197,7 @@ impl Bolt12Payment { max_total_routing_fee_msat, ) { Ok(()) => { - let payee_pubkey = offer.signing_pubkey(); + let payee_pubkey = offer.issuer_signing_pubkey(); log_info!( self.logger, "Initiated sending {}msat to {:?}", diff --git a/src/payment/spontaneous.rs b/src/payment/spontaneous.rs index a0f91134c..cff630781 100644 --- a/src/payment/spontaneous.rs +++ b/src/payment/spontaneous.rs @@ -17,10 +17,11 @@ use crate::payment::SendingParameters; use crate::types::{ChannelManager, CustomTlvRecord, KeysManager}; use lightning::ln::channelmanager::{PaymentId, RecipientOnionFields, Retry, RetryableSendFailure}; -use lightning::ln::{PaymentHash, PaymentPreimage}; use lightning::routing::router::{PaymentParameters, RouteParameters}; use lightning::sign::EntropySource; +use lightning_types::payment::{PaymentHash, PaymentPreimage}; + use bitcoin::secp256k1::PublicKey; use std::sync::{Arc, RwLock}; @@ -122,7 +123,7 @@ impl SpontaneousPayment { None => RecipientOnionFields::spontaneous_empty(), }; - match self.channel_manager.send_spontaneous_payment_with_retry( + match self.channel_manager.send_spontaneous_payment( Some(payment_preimage), recipient_fields, PaymentId(payment_hash.0), diff --git a/src/payment/store.rs b/src/payment/store.rs index ee82544dc..fbeba669b 100644 --- a/src/payment/store.rs +++ b/src/payment/store.rs @@ -15,7 +15,6 @@ use crate::Error; use lightning::ln::channelmanager::PaymentId; use lightning::ln::msgs::DecodeError; -use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret}; use lightning::offers::offer::OfferId; use lightning::util::ser::{Readable, Writeable}; use lightning::util::string::UntrustedString; @@ -24,6 +23,8 @@ use lightning::{ impl_writeable_tlv_based_enum, write_tlv_fields, }; +use lightning_types::payment::{PaymentHash, PaymentPreimage, PaymentSecret}; + use std::collections::HashMap; use std::iter::FromIterator; use std::ops::Deref; diff --git a/src/payment/unified_qr.rs b/src/payment/unified_qr.rs index 88d372456..029416b84 100644 --- a/src/payment/unified_qr.rs +++ b/src/payment/unified_qr.rs @@ -256,22 +256,19 @@ impl<'a> bip21::de::DeserializationState<'a> for DeserializationState { "lightning" => { let bolt11_value = String::try_from(value).map_err(|_| Error::UriParameterParsingFailed)?; - if let Ok(invoice) = bolt11_value.parse::() { - self.bolt11_invoice = Some(invoice); - Ok(bip21::de::ParamKind::Known) - } else { - Ok(bip21::de::ParamKind::Unknown) - } + let invoice = bolt11_value + .parse::() + .map_err(|_| Error::UriParameterParsingFailed)?; + self.bolt11_invoice = Some(invoice); + Ok(bip21::de::ParamKind::Known) }, "lno" => { let bolt12_value = String::try_from(value).map_err(|_| Error::UriParameterParsingFailed)?; - if let Ok(offer) = bolt12_value.parse::() { - self.bolt12_offer = Some(offer); - Ok(bip21::de::ParamKind::Known) - } else { - Ok(bip21::de::ParamKind::Unknown) - } + let offer = + bolt12_value.parse::().map_err(|_| Error::UriParameterParsingFailed)?; + self.bolt12_offer = Some(offer); + Ok(bip21::de::ParamKind::Known) }, _ => Ok(bip21::de::ParamKind::Unknown), } diff --git a/src/types.rs b/src/types.rs index 4ec8e9fe8..fc1ea8d31 100644 --- a/src/types.rs +++ b/src/types.rs @@ -64,6 +64,7 @@ pub(crate) type ChannelManager = lightning::ln::channelmanager::ChannelManager< Arc, Arc, Arc, + Arc, Arc, >; @@ -114,6 +115,7 @@ pub(crate) type OnionMessenger = lightning::onion_message::messenger::OnionMesse Arc, IgnoringMessageHandler, IgnoringMessageHandler, + IgnoringMessageHandler, >; pub(crate) type MessageRouter = lightning::onion_message::messenger::DefaultMessageRouter< diff --git a/src/uniffi_types.rs b/src/uniffi_types.rs index 9cb88597d..89e11efc5 100644 --- a/src/uniffi_types.rs +++ b/src/uniffi_types.rs @@ -16,17 +16,18 @@ pub use crate::config::{ pub use crate::graph::{ChannelInfo, ChannelUpdateInfo, NodeAnnouncementInfo, NodeInfo}; pub use crate::payment::store::{LSPFeeLimits, PaymentDirection, PaymentKind, PaymentStatus}; pub use crate::payment::{MaxTotalRoutingFeeLimit, QrPaymentResult, SendingParameters}; -pub use crate::types::CustomTlvRecord; pub use lightning::chain::channelmonitor::BalanceSource; pub use lightning::events::{ClosureReason, PaymentFailureReason}; -pub use lightning::ln::types::{ChannelId, PaymentHash, PaymentPreimage, PaymentSecret}; +pub use lightning::ln::types::ChannelId; pub use lightning::offers::invoice::Bolt12Invoice; pub use lightning::offers::offer::{Offer, OfferId}; pub use lightning::offers::refund::Refund; pub use lightning::routing::gossip::{NodeAlias, NodeId, RoutingFees}; pub use lightning::util::string::UntrustedString; +pub use lightning_types::payment::{PaymentHash, PaymentPreimage, PaymentSecret}; + pub use lightning_invoice::Bolt11Invoice; pub use bitcoin::{Address, BlockHash, Network, OutPoint, Txid}; diff --git a/src/wallet/mod.rs b/src/wallet/mod.rs index a4d4b066e..3533e6fef 100644 --- a/src/wallet/mod.rs +++ b/src/wallet/mod.rs @@ -16,18 +16,18 @@ use lightning::chain::chaininterface::BroadcasterInterface; use lightning::chain::{BestBlock, Listen}; use lightning::events::bump_transaction::{Utxo, WalletSource}; +use lightning::ln::inbound_payment::ExpandedKey; use lightning::ln::msgs::{DecodeError, UnsignedGossipMessage}; use lightning::ln::script::ShutdownScript; use lightning::sign::{ - ChangeDestinationSource, EntropySource, InMemorySigner, KeyMaterial, KeysManager, NodeSigner, - OutputSpender, Recipient, SignerProvider, SpendableOutputDescriptor, + ChangeDestinationSource, EntropySource, InMemorySigner, KeysManager, NodeSigner, OutputSpender, + Recipient, SignerProvider, SpendableOutputDescriptor, }; use lightning::util::message_signing; use lightning_invoice::RawBolt11Invoice; use bdk_chain::spk_client::{FullScanRequest, SyncRequest}; -use bdk_chain::ChainPosition; use bdk_wallet::{Balance, KeychainKind, PersistedWallet, SignOptions, Update}; use bitcoin::blockdata::constants::WITNESS_SCALE_FACTOR; @@ -139,11 +139,7 @@ where let mut locked_wallet = self.inner.lock().unwrap(); let mut tx_builder = locked_wallet.build_tx(); - tx_builder - .add_recipient(output_script, amount) - .fee_rate(fee_rate) - .nlocktime(locktime) - .enable_rbf(); + tx_builder.add_recipient(output_script, amount).fee_rate(fee_rate).nlocktime(locktime); let mut psbt = match tx_builder.finish() { Ok(psbt) => { @@ -255,10 +251,7 @@ where OnchainSendAmount::ExactRetainingReserve { amount_sats, .. } => { let mut tx_builder = locked_wallet.build_tx(); let amount = Amount::from_sat(amount_sats); - tx_builder - .add_recipient(address.script_pubkey(), amount) - .fee_rate(fee_rate) - .enable_rbf(); + tx_builder.add_recipient(address.script_pubkey(), amount).fee_rate(fee_rate); tx_builder }, OnchainSendAmount::AllRetainingReserve { cur_anchor_reserve_sats } => { @@ -277,8 +270,7 @@ where change_address_info.address.script_pubkey(), Amount::from_sat(cur_anchor_reserve_sats), ) - .fee_rate(fee_rate) - .enable_rbf(); + .fee_rate(fee_rate); match tmp_tx_builder.finish() { Ok(psbt) => psbt.unsigned_tx, Err(err) => { @@ -316,17 +308,12 @@ where let mut tx_builder = locked_wallet.build_tx(); tx_builder .add_recipient(address.script_pubkey(), estimated_spendable_amount) - .fee_absolute(estimated_tx_fee) - .enable_rbf(); + .fee_absolute(estimated_tx_fee); tx_builder }, OnchainSendAmount::AllDrainingReserve => { let mut tx_builder = locked_wallet.build_tx(); - tx_builder - .drain_wallet() - .drain_to(address.script_pubkey()) - .fee_rate(fee_rate) - .enable_rbf(); + tx_builder.drain_wallet().drain_to(address.script_pubkey()).fee_rate(fee_rate); tx_builder }, }; @@ -526,7 +513,7 @@ where let mut utxos = Vec::new(); let confirmed_txs: Vec = locked_wallet .transactions() - .filter(|t| matches!(t.chain_position, ChainPosition::Confirmed(_))) + .filter(|t| t.chain_position.is_confirmed()) .map(|t| t.tx_node.txid) .collect(); let unspent_confirmed_utxos = @@ -715,8 +702,8 @@ where self.inner.ecdh(recipient, other_key, tweak) } - fn get_inbound_payment_key_material(&self) -> KeyMaterial { - self.inner.get_inbound_payment_key_material() + fn get_inbound_payment_key(&self) -> ExpandedKey { + self.inner.get_inbound_payment_key() } fn sign_invoice( @@ -734,12 +721,6 @@ where ) -> Result { self.inner.sign_bolt12_invoice(invoice) } - - fn sign_bolt12_invoice_request( - &self, invoice_request: &lightning::offers::invoice_request::UnsignedInvoiceRequest, - ) -> Result { - self.inner.sign_bolt12_invoice_request(invoice_request) - } } impl OutputSpender for WalletKeysManager diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 65567cb64..f3cff00dc 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -17,10 +17,12 @@ use ldk_node::{ }; use lightning::ln::msgs::SocketAddress; -use lightning::ln::{PaymentHash, PaymentPreimage}; use lightning::routing::gossip::NodeAlias; use lightning::util::persist::KVStore; use lightning::util::test_utils::TestStore; + +use lightning_types::payment::{PaymentHash, PaymentPreimage}; + use lightning_persister::fs_store::FilesystemStore; use bitcoin::hashes::sha256::Hash as Sha256; diff --git a/tests/integration_tests_rust.rs b/tests/integration_tests_rust.rs index 937af241b..2737a3d18 100644 --- a/tests/integration_tests_rust.rs +++ b/tests/integration_tests_rust.rs @@ -868,11 +868,10 @@ fn unified_qr_send_receive() { expect_payment_successful_event!(node_a, Some(offer_payment_id), None); - // Removed one character from the offer to fall back on to invoice. - // Still needs work - let uri_str_with_invalid_offer = &uri_str[..uri_str.len() - 1]; + // Cut off the BOLT12 part to fallback to BOLT11. + let uri_str_without_offer = uri_str.split("&lno=").next().unwrap(); let invoice_payment_id: PaymentId = - match node_a.unified_qr_payment().send(uri_str_with_invalid_offer) { + match node_a.unified_qr_payment().send(uri_str_without_offer) { Ok(QrPaymentResult::Bolt12 { payment_id: _ }) => { panic!("Expected Bolt11 payment but got Bolt12"); }, @@ -893,11 +892,9 @@ fn unified_qr_send_receive() { let onchain_uqr_payment = node_b.unified_qr_payment().receive(expect_onchain_amount_sats, "asdf", 4_000).unwrap(); - // Removed a character from the offer, so it would move on to the other parameters. - let txid = match node_a - .unified_qr_payment() - .send(&onchain_uqr_payment.as_str()[..onchain_uqr_payment.len() - 1]) - { + // Cut off any lightning part to fallback to on-chain only. + let uri_str_without_lightning = onchain_uqr_payment.split("&lightning=").next().unwrap(); + let txid = match node_a.unified_qr_payment().send(&uri_str_without_lightning) { Ok(QrPaymentResult::Bolt12 { payment_id: _ }) => { panic!("Expected on-chain payment but got Bolt12") },