From: Jeffrey Czyz Date: Mon, 28 Oct 2024 22:28:10 +0000 (-0500) Subject: Add a BOLT11 invoice utility to ChannelManager X-Git-Url: http://git.bitcoin.ninja/?a=commitdiff_plain;h=3c6896c9fa9538dfccce3fd3b72257fa29dd960c;p=rust-lightning Add a BOLT11 invoice utility to ChannelManager Now that the lightning crate depends on the lightning_invoice crate, the utility functions previously living in the latter can be implemented on ChannelManager. Additionally, the parameters are now moved to a struct in order to remove the increasingly combinatorial blow-up of methods. The new Bolt11InvoiceParameters is used to determine what values to set in the invoice. Using None for any given parameter results in a reasonable the default or a behavior determined by the ChannelManager as detailed in the documentation. --- diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 5c39e9017..9631851eb 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -102,6 +102,8 @@ use { crate::offers::refund::RefundMaybeWithDerivedMetadataBuilder, }; +use lightning_invoice::{Bolt11Invoice, Bolt11InvoiceDescription, CreationError, Currency, Description, InvoiceBuilder as Bolt11InvoiceBuilder, SignOrCreationError, DEFAULT_EXPIRY_TIME}; + use alloc::collections::{btree_map, BTreeMap}; use crate::io; @@ -2199,7 +2201,7 @@ where L::Target: Logger, { default_configuration: UserConfig, - pub(super) chain_hash: ChainHash, + chain_hash: ChainHash, fee_estimator: LowerBoundedFeeEstimator, chain_monitor: M, tx_broadcaster: T, @@ -9093,6 +9095,145 @@ where self.finish_close_channel(failure); } } + + /// Utility for creating a BOLT11 invoice that can be verified by [`ChannelManager`] without + /// storing any additional state. It achieves this by including a [`PaymentSecret`] in the + /// invoice which it uses to verify that the invoice has not expired and the payment amount is + /// sufficient, reproducing the [`PaymentPreimage`] if applicable. + pub fn create_bolt11_invoice( + &self, params: Bolt11InvoiceParameters, + ) -> Result> { + let Bolt11InvoiceParameters { + amount_msats, description, invoice_expiry_delta_secs, min_final_cltv_expiry_delta, + payment_hash, + } = params; + + let currency = + Network::from_chain_hash(self.chain_hash).map(Into::into).unwrap_or(Currency::Bitcoin); + + #[cfg(feature = "std")] + let duration_since_epoch = { + use std::time::SystemTime; + SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) + .expect("for the foreseeable future this shouldn't happen") + }; + #[cfg(not(feature = "std"))] + let duration_since_epoch = + Duration::from_secs(self.highest_seen_timestamp.load(Ordering::Acquire) as u64); + + if let Some(min_final_cltv_expiry_delta) = min_final_cltv_expiry_delta { + if min_final_cltv_expiry_delta.saturating_add(3) < MIN_FINAL_CLTV_EXPIRY_DELTA { + return Err(SignOrCreationError::CreationError(CreationError::MinFinalCltvExpiryDeltaTooShort)); + } + } + + let (payment_hash, payment_secret) = match payment_hash { + Some(payment_hash) => { + let payment_secret = self + .create_inbound_payment_for_hash( + payment_hash, amount_msats, + invoice_expiry_delta_secs.unwrap_or(DEFAULT_EXPIRY_TIME as u32), + min_final_cltv_expiry_delta, + ) + .map_err(|()| SignOrCreationError::CreationError(CreationError::InvalidAmount))?; + (payment_hash, payment_secret) + }, + None => { + self + .create_inbound_payment( + amount_msats, invoice_expiry_delta_secs.unwrap_or(DEFAULT_EXPIRY_TIME as u32), + min_final_cltv_expiry_delta, + ) + .map_err(|()| SignOrCreationError::CreationError(CreationError::InvalidAmount))? + }, + }; + + log_trace!(self.logger, "Creating invoice with payment hash {}", &payment_hash); + + let invoice = Bolt11InvoiceBuilder::new(currency); + let invoice = match description { + Bolt11InvoiceDescription::Direct(description) => invoice.description(description.into_inner().0), + Bolt11InvoiceDescription::Hash(hash) => invoice.description_hash(hash.0), + }; + + let mut invoice = invoice + .duration_since_epoch(duration_since_epoch) + .payee_pub_key(self.get_our_node_id()) + .payment_hash(Hash::from_slice(&payment_hash.0).unwrap()) + .payment_secret(payment_secret) + .basic_mpp() + .min_final_cltv_expiry_delta( + // Add a buffer of 3 to the delta if present, otherwise use LDK's minimum. + min_final_cltv_expiry_delta.map(|x| x.saturating_add(3)).unwrap_or(MIN_FINAL_CLTV_EXPIRY_DELTA).into() + ); + + if let Some(invoice_expiry_delta_secs) = invoice_expiry_delta_secs{ + invoice = invoice.expiry_time(Duration::from_secs(invoice_expiry_delta_secs.into())); + } + + if let Some(amount_msats) = amount_msats { + invoice = invoice.amount_milli_satoshis(amount_msats); + } + + let channels = self.list_channels(); + let route_hints = super::invoice_utils::sort_and_filter_channels(channels, amount_msats, &self.logger); + for hint in route_hints { + invoice = invoice.private_route(hint); + } + + let raw_invoice = invoice.build_raw().map_err(|e| SignOrCreationError::CreationError(e))?; + let signature = self.node_signer.sign_invoice(&raw_invoice, Recipient::Node); + + raw_invoice + .sign(|_| signature) + .map(|invoice| Bolt11Invoice::from_signed(invoice).unwrap()) + .map_err(|e| SignOrCreationError::SignError(e)) + } +} + +/// Parameters used with [`create_bolt11_invoice`]. +/// +/// [`create_bolt11_invoice`]: ChannelManager::create_bolt11_invoice +pub struct Bolt11InvoiceParameters { + /// The amount for the invoice, if any. + pub amount_msats: Option, + + /// The description for what the invoice is for, or hash of such description. + pub description: Bolt11InvoiceDescription, + + /// The invoice expiration relative to its creation time. If not set, the invoice will expire in + /// [`DEFAULT_EXPIRY_TIME`] by default. + /// + /// The creation time used is the duration since the Unix epoch for `std` builds. For non-`std` + /// builds, the highest block timestamp seen is used instead. + pub invoice_expiry_delta_secs: Option, + + /// The minimum `cltv_expiry` for the last HTLC in the route. If not set, will use + /// [`MIN_FINAL_CLTV_EXPIRY_DELTA`]. + /// + /// If set, must be at least [`MIN_FINAL_CLTV_EXPIRY_DELTA`], and a three-block buffer will be + /// added as well to allow for up to a few new block confirmations during routing. + pub min_final_cltv_expiry_delta: Option, + + /// The payment hash used in the invoice. If not set, a payment hash will be generated using a + /// preimage that can be reproduced by [`ChannelManager`] without storing any state. + /// + /// Uses the payment hash if set. This may be useful if you're building an on-chain swap or + /// involving another protocol where the payment hash is also involved outside the scope of + /// lightning. + pub payment_hash: Option, +} + +impl Default for Bolt11InvoiceParameters { + fn default() -> Self { + Self { + amount_msats: None, + description: Bolt11InvoiceDescription::Direct(Description::empty()), + invoice_expiry_delta_secs: None, + min_final_cltv_expiry_delta: None, + payment_hash: None, + } + } } macro_rules! create_offer_builder { ($self: ident, $builder: ty) => { diff --git a/lightning/src/ln/invoice_utils.rs b/lightning/src/ln/invoice_utils.rs index 1df7bfa08..01767ab05 100644 --- a/lightning/src/ln/invoice_utils.rs +++ b/lightning/src/ln/invoice_utils.rs @@ -6,13 +6,12 @@ use lightning_invoice::{Description, Bolt11InvoiceDescription, Sha256}; use crate::prelude::*; use bitcoin::hashes::Hash; -use bitcoin::network::Network; use crate::chain; use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator}; use crate::sign::{Recipient, NodeSigner, SignerProvider, EntropySource}; -use crate::types::payment::{PaymentHash, PaymentSecret}; +use crate::types::payment::PaymentHash; use crate::ln::channel_state::ChannelDetails; -use crate::ln::channelmanager::{ChannelManager, PhantomRouteHints, MIN_CLTV_EXPIRY_DELTA, MIN_FINAL_CLTV_EXPIRY_DELTA}; +use crate::ln::channelmanager::{Bolt11InvoiceParameters, ChannelManager, PhantomRouteHints, MIN_CLTV_EXPIRY_DELTA, MIN_FINAL_CLTV_EXPIRY_DELTA}; use crate::ln::inbound_payment::{create, create_from_hash, ExpandedKey}; use crate::routing::gossip::RoutingFees; use crate::routing::router::{RouteHint, RouteHintHop, Router}; @@ -314,7 +313,6 @@ fn rotate_through_iterators>(mut vecs: Vec) -> impl }) } -#[cfg(feature = "std")] /// Utility to construct an invoice. Generally, unless you want to do something like a custom /// cltv_expiry, this is what you should be using to create an invoice. The reason being, this /// method stores the invoice's payment secret and preimage in `ChannelManager`, so (a) the user @@ -331,9 +329,8 @@ fn rotate_through_iterators>(mut vecs: Vec) -> impl /// /// [`MIN_FINAL_CLTV_EXPIRY_DETLA`]: crate::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY_DELTA pub fn create_invoice_from_channelmanager( - channelmanager: &ChannelManager, node_signer: NS, logger: L, - amt_msat: Option, description: String, invoice_expiry_delta_secs: u32, - min_final_cltv_expiry_delta: Option, + channelmanager: &ChannelManager, amt_msat: Option, + description: String, invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option, ) -> Result> where M::Target: chain::Watch<::EcdsaSigner>, @@ -346,21 +343,17 @@ where MR::Target: MessageRouter, L::Target: Logger, { - use std::time::SystemTime; - let duration_since_epoch = SystemTime::now() - .duration_since(SystemTime::UNIX_EPOCH) - .expect("for the foreseeable future this shouldn't happen"); - - _create_invoice_from_channelmanager_and_duration_since_epoch( - channelmanager, node_signer, logger, amt_msat, - Bolt11InvoiceDescription::Direct( - Description::new(description).map_err(SignOrCreationError::CreationError)?, - ), - duration_since_epoch, invoice_expiry_delta_secs, min_final_cltv_expiry_delta, - ) + let description = Description::new(description).map_err(SignOrCreationError::CreationError)?; + let params = Bolt11InvoiceParameters { + amount_msats: amt_msat, + description: Bolt11InvoiceDescription::Direct(description), + invoice_expiry_delta_secs: Some(invoice_expiry_delta_secs), + min_final_cltv_expiry_delta, + payment_hash: None, + }; + channelmanager.create_bolt11_invoice(params) } -#[cfg(feature = "std")] /// Utility to construct an invoice. Generally, unless you want to do something like a custom /// cltv_expiry, this is what you should be using to create an invoice. The reason being, this /// method stores the invoice's payment secret and preimage in `ChannelManager`, so (a) the user @@ -378,37 +371,9 @@ where /// /// [`MIN_FINAL_CLTV_EXPIRY_DETLA`]: crate::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY_DELTA pub fn create_invoice_from_channelmanager_with_description_hash( - channelmanager: &ChannelManager, node_signer: NS, logger: L, - amt_msat: Option, description_hash: Sha256, - invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option, -) -> Result> -where - M::Target: chain::Watch<::EcdsaSigner>, - T::Target: BroadcasterInterface, - ES::Target: EntropySource, - NS::Target: NodeSigner, - SP::Target: SignerProvider, - F::Target: FeeEstimator, - R::Target: Router, - MR::Target: MessageRouter, - L::Target: Logger, -{ - use std::time::SystemTime; - let duration_since_epoch = SystemTime::now() - .duration_since(SystemTime::UNIX_EPOCH) - .expect("for the foreseeable future this shouldn't happen"); - - _create_invoice_from_channelmanager_and_duration_since_epoch( - channelmanager, node_signer, logger, amt_msat, - Bolt11InvoiceDescription::Hash(description_hash), - duration_since_epoch, invoice_expiry_delta_secs, min_final_cltv_expiry_delta, - ) -} - -fn _create_invoice_from_channelmanager_and_duration_since_epoch( - channelmanager: &ChannelManager, node_signer: NS, logger: L, - amt_msat: Option, description: Bolt11InvoiceDescription, - duration_since_epoch: Duration, invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option, + channelmanager: &ChannelManager, amt_msat: Option, + description_hash: Sha256, invoice_expiry_delta_secs: u32, + min_final_cltv_expiry_delta: Option, ) -> Result> where M::Target: chain::Watch<::EcdsaSigner>, @@ -421,21 +386,16 @@ where MR::Target: MessageRouter, L::Target: Logger, { - if min_final_cltv_expiry_delta.is_some() && min_final_cltv_expiry_delta.unwrap().saturating_add(3) < MIN_FINAL_CLTV_EXPIRY_DELTA { - return Err(SignOrCreationError::CreationError(CreationError::MinFinalCltvExpiryDeltaTooShort)); - } - - // `create_inbound_payment` only returns an error if the amount is greater than the total bitcoin - // supply. - let (payment_hash, payment_secret) = channelmanager - .create_inbound_payment(amt_msat, invoice_expiry_delta_secs, min_final_cltv_expiry_delta) - .map_err(|()| SignOrCreationError::CreationError(CreationError::InvalidAmount))?; - _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_hash( - channelmanager, node_signer, logger, amt_msat, description, duration_since_epoch, - invoice_expiry_delta_secs, payment_hash, payment_secret, min_final_cltv_expiry_delta) + let params = Bolt11InvoiceParameters { + amount_msats: amt_msat, + description: Bolt11InvoiceDescription::Hash(description_hash), + invoice_expiry_delta_secs: Some(invoice_expiry_delta_secs), + min_final_cltv_expiry_delta, + payment_hash: None, + }; + channelmanager.create_bolt11_invoice(params) } -#[cfg(feature = "std")] /// See [`create_invoice_from_channelmanager`]. /// /// This version allows for providing custom [`PaymentHash`] and description hash for the invoice. @@ -444,9 +404,9 @@ where /// the payment hash is also involved outside the scope of lightning and want to set the /// description hash. pub fn create_invoice_from_channelmanager_with_description_hash_and_payment_hash( - channelmanager: &ChannelManager, node_signer: NS, logger: L, - amt_msat: Option, description_hash: Sha256, - invoice_expiry_delta_secs: u32, payment_hash: PaymentHash, min_final_cltv_expiry_delta: Option, + channelmanager: &ChannelManager, amt_msat: Option, + description_hash: Sha256, invoice_expiry_delta_secs: u32, payment_hash: PaymentHash, + min_final_cltv_expiry_delta: Option, ) -> Result> where M::Target: chain::Watch<::EcdsaSigner>, @@ -459,33 +419,25 @@ where MR::Target: MessageRouter, L::Target: Logger, { - use std::time::SystemTime; - let duration_since_epoch = SystemTime::now() - .duration_since(SystemTime::UNIX_EPOCH) - .expect("for the foreseeable future this shouldn't happen"); - - let payment_secret = channelmanager - .create_inbound_payment_for_hash(payment_hash, amt_msat, invoice_expiry_delta_secs, - min_final_cltv_expiry_delta) - .map_err(|()| SignOrCreationError::CreationError(CreationError::InvalidAmount))?; - _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_hash( - channelmanager, node_signer, logger, amt_msat, - Bolt11InvoiceDescription::Hash(description_hash), - duration_since_epoch, invoice_expiry_delta_secs, payment_hash, payment_secret, + let params = Bolt11InvoiceParameters { + amount_msats: amt_msat, + description: Bolt11InvoiceDescription::Hash(description_hash), + invoice_expiry_delta_secs: Some(invoice_expiry_delta_secs), min_final_cltv_expiry_delta, - ) + payment_hash: Some(payment_hash), + }; + channelmanager.create_bolt11_invoice(params) } -#[cfg(feature = "std")] /// See [`create_invoice_from_channelmanager`]. /// /// This version allows for providing a custom [`PaymentHash`] for the invoice. /// This may be useful if you're building an on-chain swap or involving another protocol where /// the payment hash is also involved outside the scope of lightning. pub fn create_invoice_from_channelmanager_with_payment_hash( - channelmanager: &ChannelManager, node_signer: NS, logger: L, - amt_msat: Option, description: String, invoice_expiry_delta_secs: u32, - payment_hash: PaymentHash, min_final_cltv_expiry_delta: Option, + channelmanager: &ChannelManager, amt_msat: Option, + description: String, invoice_expiry_delta_secs: u32, payment_hash: PaymentHash, + min_final_cltv_expiry_delta: Option, ) -> Result> where M::Target: chain::Watch<::EcdsaSigner>, @@ -498,91 +450,15 @@ where MR::Target: MessageRouter, L::Target: Logger, { - use std::time::SystemTime; - let duration_since_epoch = SystemTime::now() - .duration_since(SystemTime::UNIX_EPOCH) - .expect("for the foreseeable future this shouldn't happen"); - - let payment_secret = channelmanager - .create_inbound_payment_for_hash(payment_hash, amt_msat, invoice_expiry_delta_secs, - min_final_cltv_expiry_delta) - .map_err(|()| SignOrCreationError::CreationError(CreationError::InvalidAmount))?; - _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_hash( - channelmanager, node_signer, logger, amt_msat, - Bolt11InvoiceDescription::Direct( - Description::new(description).map_err(SignOrCreationError::CreationError)?, - ), - duration_since_epoch, invoice_expiry_delta_secs, payment_hash, payment_secret, + let description = Description::new(description).map_err(SignOrCreationError::CreationError)?; + let params = Bolt11InvoiceParameters { + amount_msats: amt_msat, + description: Bolt11InvoiceDescription::Direct(description), + invoice_expiry_delta_secs: Some(invoice_expiry_delta_secs), min_final_cltv_expiry_delta, - ) -} - -fn _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_hash( - channelmanager: &ChannelManager, node_signer: NS, logger: L, - amt_msat: Option, description: Bolt11InvoiceDescription, - duration_since_epoch: Duration, invoice_expiry_delta_secs: u32, payment_hash: PaymentHash, - payment_secret: PaymentSecret, min_final_cltv_expiry_delta: Option, -) -> Result> -where - M::Target: chain::Watch<::EcdsaSigner>, - T::Target: BroadcasterInterface, - ES::Target: EntropySource, - NS::Target: NodeSigner, - SP::Target: SignerProvider, - F::Target: FeeEstimator, - R::Target: Router, - MR::Target: MessageRouter, - L::Target: Logger, -{ - let our_node_pubkey = channelmanager.get_our_node_id(); - let channels = channelmanager.list_channels(); - - let network = Network::from_chain_hash(channelmanager.chain_hash) - .map(Into::into) - .unwrap_or(Currency::Bitcoin); - - if min_final_cltv_expiry_delta.is_some() && min_final_cltv_expiry_delta.unwrap().saturating_add(3) < MIN_FINAL_CLTV_EXPIRY_DELTA { - return Err(SignOrCreationError::CreationError(CreationError::MinFinalCltvExpiryDeltaTooShort)); - } - - log_trace!(logger, "Creating invoice with payment hash {}", &payment_hash); - - let invoice = match description { - Bolt11InvoiceDescription::Direct(description) => { - InvoiceBuilder::new(network).description(description.into_inner().0) - } - Bolt11InvoiceDescription::Hash(hash) => InvoiceBuilder::new(network).description_hash(hash.0), + payment_hash: Some(payment_hash), }; - - let mut invoice = invoice - .duration_since_epoch(duration_since_epoch) - .payee_pub_key(our_node_pubkey) - .payment_hash(Hash::from_slice(&payment_hash.0).unwrap()) - .payment_secret(payment_secret) - .basic_mpp() - .min_final_cltv_expiry_delta( - // Add a buffer of 3 to the delta if present, otherwise use LDK's minimum. - min_final_cltv_expiry_delta.map(|x| x.saturating_add(3)).unwrap_or(MIN_FINAL_CLTV_EXPIRY_DELTA).into()) - .expiry_time(Duration::from_secs(invoice_expiry_delta_secs.into())); - if let Some(amt) = amt_msat { - invoice = invoice.amount_milli_satoshis(amt); - } - - let route_hints = sort_and_filter_channels(channels, amt_msat, &logger); - for hint in route_hints { - invoice = invoice.private_route(hint); - } - - let raw_invoice = match invoice.build_raw() { - Ok(inv) => inv, - Err(e) => return Err(SignOrCreationError::CreationError(e)) - }; - let signature = node_signer.sign_invoice(&raw_invoice, Recipient::Node); - let signed_raw_invoice = raw_invoice.sign(|_| signature); - match signed_raw_invoice { - Ok(inv) => Ok(Bolt11Invoice::from_signed(inv).unwrap()), - Err(e) => Err(SignOrCreationError::SignError(e)) - } + channelmanager.create_bolt11_invoice(params) } /// Sorts and filters the `channels` for an invoice, and returns the corresponding `RouteHint`s to include @@ -604,7 +480,7 @@ where /// * Limited to a total of 3 channels. /// * Sorted by lowest inbound capacity if an online channel with the minimum amount requested exists, /// otherwise sort by highest inbound capacity to give the payment the best chance of succeeding. -fn sort_and_filter_channels( +pub(super) fn sort_and_filter_channels( channels: Vec, min_inbound_capacity_msat: Option, logger: &L, @@ -878,8 +754,7 @@ mod test { create_unannounced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001); let non_default_invoice_expiry_secs = 4200; let invoice = create_invoice_from_channelmanager( - nodes[1].node, nodes[1].keys_manager, nodes[1].logger, - Some(10_000), "test".to_string(), non_default_invoice_expiry_secs, None, + nodes[1].node, Some(10_000), "test".to_string(), non_default_invoice_expiry_secs, None, ).unwrap(); assert_eq!(invoice.amount_milli_satoshis(), Some(10_000)); // If no `min_final_cltv_expiry_delta` is specified, then it should be `MIN_FINAL_CLTV_EXPIRY_DELTA`. @@ -929,8 +804,7 @@ mod test { let custom_min_final_cltv_expiry_delta = Some(50); let invoice = create_invoice_from_channelmanager( - nodes[1].node, nodes[1].keys_manager, nodes[1].logger, - Some(10_000), "".into(), 3600, + nodes[1].node, Some(10_000), "".into(), 3600, if with_custom_delta { custom_min_final_cltv_expiry_delta } else { None }, ).unwrap(); assert_eq!(invoice.min_final_cltv_expiry_delta(), if with_custom_delta { @@ -952,8 +826,7 @@ mod test { let custom_min_final_cltv_expiry_delta = Some(21); let invoice = create_invoice_from_channelmanager( - nodes[1].node, nodes[1].keys_manager, nodes[1].logger, - Some(10_000), "".into(), 3600, custom_min_final_cltv_expiry_delta, + nodes[1].node, Some(10_000), "".into(), 3600, custom_min_final_cltv_expiry_delta, ).unwrap(); assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64); } @@ -966,8 +839,7 @@ mod test { let nodes = create_network(2, &node_cfgs, &node_chanmgrs); let description_hash = Sha256(Hash::hash("Testing description_hash".as_bytes())); let invoice = create_invoice_from_channelmanager_with_description_hash( - nodes[1].node, nodes[1].keys_manager, nodes[1].logger, - Some(10_000), description_hash, 3600, None, + nodes[1].node, Some(10_000), description_hash, 3600, None, ).unwrap(); assert_eq!(invoice.amount_milli_satoshis(), Some(10_000)); assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64); @@ -982,8 +854,7 @@ mod test { let nodes = create_network(2, &node_cfgs, &node_chanmgrs); let payment_hash = PaymentHash([0; 32]); let invoice = create_invoice_from_channelmanager_with_payment_hash( - nodes[1].node, nodes[1].keys_manager, nodes[1].logger, - Some(10_000), "test".to_string(), 3600, payment_hash, None, + nodes[1].node, Some(10_000), "test".to_string(), 3600, payment_hash, None, ).unwrap(); assert_eq!(invoice.amount_milli_satoshis(), Some(10_000)); assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64); @@ -1273,8 +1144,7 @@ mod test { mut chan_ids_to_match: HashSet ) { let invoice = create_invoice_from_channelmanager( - invoice_node.node, invoice_node.keys_manager, invoice_node.logger, - invoice_amt, "test".to_string(), 3600, None, + invoice_node.node, invoice_amt, "test".to_string(), 3600, None, ).unwrap(); let hints = invoice.private_routes(); @@ -1911,8 +1781,8 @@ mod test { let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]); let nodes = create_network(2, &node_cfgs, &node_chanmgrs); let result = create_invoice_from_channelmanager( - nodes[1].node, nodes[1].keys_manager, nodes[1].logger, - Some(10_000), "Some description".into(), 3600, Some(MIN_FINAL_CLTV_EXPIRY_DELTA - 4), + nodes[1].node, Some(10_000), "Some description".into(), 3600, + Some(MIN_FINAL_CLTV_EXPIRY_DELTA - 4), ); match result { Err(SignOrCreationError::CreationError(CreationError::MinFinalCltvExpiryDeltaTooShort)) => {},