Use `crate::prelude::*` rather than specific imports
[rust-lightning] / lightning-invoice / src / utils.rs
index 744c2654cd84705965999d09f602e4c17f2de3dd..1d6b9210afd967f58c79e7453f53a3eda856a9ee 100644 (file)
@@ -4,7 +4,7 @@ use crate::{Bolt11Invoice, CreationError, Currency, InvoiceBuilder, SignOrCreati
 
 use crate::{prelude::*, Description, Bolt11InvoiceDescription, Sha256};
 use bech32::ToBase32;
-use bitcoin_hashes::Hash;
+use bitcoin::hashes::Hash;
 use lightning::chain;
 use lightning::chain::chaininterface::{BroadcasterInterface, FeeEstimator};
 use lightning::sign::{Recipient, NodeSigner, SignerProvider, EntropySource};
@@ -14,10 +14,12 @@ use lightning::ln::channelmanager::{PhantomRouteHints, MIN_CLTV_EXPIRY_DELTA};
 use lightning::ln::inbound_payment::{create, create_from_hash, ExpandedKey};
 use lightning::routing::gossip::RoutingFees;
 use lightning::routing::router::{RouteHint, RouteHintHop, Router};
-use lightning::util::logger::Logger;
+use lightning::util::logger::{Logger, Record};
 use secp256k1::PublicKey;
+use alloc::collections::{btree_map, BTreeMap};
 use core::ops::Deref;
 use core::time::Duration;
+#[cfg(not(feature = "std"))]
 use core::iter::Iterator;
 
 /// Utility to create an invoice that can be paid to one of multiple nodes, or a "phantom invoice."
@@ -158,7 +160,7 @@ where
 
        let invoice = match description {
                Bolt11InvoiceDescription::Direct(description) => {
-                       InvoiceBuilder::new(network).description(description.0.clone())
+                       InvoiceBuilder::new(network).description(description.0.0.clone())
                }
                Bolt11InvoiceDescription::Hash(hash) => InvoiceBuilder::new(network).description_hash(hash.0),
        };
@@ -335,7 +337,7 @@ pub fn create_invoice_from_channelmanager<M: Deref, T: Deref, ES: Deref, NS: Der
        min_final_cltv_expiry_delta: Option<u16>,
 ) -> Result<Bolt11Invoice, SignOrCreationError<()>>
 where
-       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
        T::Target: BroadcasterInterface,
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
@@ -376,7 +378,7 @@ pub fn create_invoice_from_channelmanager_with_description_hash<M: Deref, T: Der
        invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option<u16>,
 ) -> Result<Bolt11Invoice, SignOrCreationError<()>>
 where
-       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+       M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
        T::Target: BroadcasterInterface,
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
@@ -406,7 +408,7 @@ pub fn create_invoice_from_channelmanager_with_description_hash_and_duration_sin
        duration_since_epoch: Duration, invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option<u16>,
 ) -> Result<Bolt11Invoice, SignOrCreationError<()>>
                where
-                       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+                       M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
                        T::Target: BroadcasterInterface,
                        ES::Target: EntropySource,
                        NS::Target: NodeSigner,
@@ -431,7 +433,7 @@ pub fn create_invoice_from_channelmanager_and_duration_since_epoch<M: Deref, T:
        invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option<u16>,
 ) -> Result<Bolt11Invoice, SignOrCreationError<()>>
                where
-                       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+                       M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
                        T::Target: BroadcasterInterface,
                        ES::Target: EntropySource,
                        NS::Target: NodeSigner,
@@ -455,7 +457,7 @@ fn _create_invoice_from_channelmanager_and_duration_since_epoch<M: Deref, T: Der
        duration_since_epoch: Duration, invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option<u16>,
 ) -> Result<Bolt11Invoice, SignOrCreationError<()>>
                where
-                       M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+                       M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
                        T::Target: BroadcasterInterface,
                        ES::Target: EntropySource,
                        NS::Target: NodeSigner,
@@ -488,7 +490,7 @@ pub fn create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_
        invoice_expiry_delta_secs: u32, payment_hash: PaymentHash, min_final_cltv_expiry_delta: Option<u16>,
 ) -> Result<Bolt11Invoice, SignOrCreationError<()>>
        where
-               M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+               M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
                T::Target: BroadcasterInterface,
                ES::Target: EntropySource,
                NS::Target: NodeSigner,
@@ -518,7 +520,7 @@ fn _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_has
        payment_secret: PaymentSecret, min_final_cltv_expiry_delta: Option<u16>,
 ) -> Result<Bolt11Invoice, SignOrCreationError<()>>
        where
-               M::Target: chain::Watch<<SP::Target as SignerProvider>::Signer>,
+               M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
                T::Target: BroadcasterInterface,
                ES::Target: EntropySource,
                NS::Target: NodeSigner,
@@ -538,7 +540,7 @@ fn _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_has
 
        let invoice = match description {
                Bolt11InvoiceDescription::Direct(description) => {
-                       InvoiceBuilder::new(network).description(description.0.clone())
+                       InvoiceBuilder::new(network).description(description.0.0.clone())
                }
                Bolt11InvoiceDescription::Hash(hash) => InvoiceBuilder::new(network).description_hash(hash.0),
        };
@@ -603,7 +605,7 @@ fn sort_and_filter_channels<L: Deref>(
 where
        L::Target: Logger,
 {
-       let mut filtered_channels: HashMap<PublicKey, ChannelDetails> = HashMap::new();
+       let mut filtered_channels: BTreeMap<PublicKey, ChannelDetails> = BTreeMap::new();
        let min_inbound_capacity = min_inbound_capacity_msat.unwrap_or(0);
        let mut min_capacity_channel_exists = false;
        let mut online_channel_exists = false;
@@ -626,6 +628,7 @@ where
 
        log_trace!(logger, "Considering {} channels for invoice route hints", channels.len());
        for channel in channels.into_iter().filter(|chan| chan.is_channel_ready) {
+               let logger = WithChannelDetails::from(logger, &channel);
                if channel.get_inbound_payment_scid().is_none() || channel.counterparty.forwarding_info.is_none() {
                        log_trace!(logger, "Ignoring channel {} for invoice route hints", &channel.channel_id);
                        continue;
@@ -663,7 +666,7 @@ where
                }
 
                match filtered_channels.entry(channel.counterparty.node_id) {
-                       hash_map::Entry::Occupied(mut entry) => {
+                       btree_map::Entry::Occupied(mut entry) => {
                                let current_max_capacity = entry.get().inbound_capacity_msat;
                                // If this channel is public and the previous channel is not, ensure we replace the
                                // previous channel to avoid announcing non-public channels.
@@ -696,7 +699,7 @@ where
                                                channel.inbound_capacity_msat);
                                }
                        }
-                       hash_map::Entry::Vacant(entry) => {
+                       btree_map::Entry::Vacant(entry) => {
                                entry.insert(channel);
                        }
                }
@@ -710,6 +713,7 @@ where
                .into_iter()
                .map(|(_, channel)| channel)
                .filter(|channel| {
+                       let logger = WithChannelDetails::from(logger, &channel);
                        let has_enough_capacity = channel.inbound_capacity_msat >= min_inbound_capacity;
                        let include_channel = if has_pub_unconf_chan {
                                // If we have a public channel, but it doesn't have enough confirmations to (yet)
@@ -790,16 +794,39 @@ fn prefer_current_channel(min_inbound_capacity_msat: Option<u64>, current_channe
        current_channel > candidate_channel
 }
 
+/// Adds relevant context to a [`Record`] before passing it to the wrapped [`Logger`].
+struct WithChannelDetails<'a, 'b, L: Deref> where L::Target: Logger {
+       /// The logger to delegate to after adding context to the record.
+       logger: &'a L,
+       /// The [`ChannelDetails`] for adding relevant context to the logged record.
+       details: &'b ChannelDetails
+}
+
+impl<'a, 'b, L: Deref> Logger for WithChannelDetails<'a, 'b, L> where L::Target: Logger {
+       fn log(&self, mut record: Record) {
+               record.peer_id = Some(self.details.counterparty.node_id);
+               record.channel_id = Some(self.details.channel_id);
+               self.logger.log(record)
+       }
+}
+
+impl<'a, 'b, L: Deref> WithChannelDetails<'a, 'b, L> where L::Target: Logger {
+       fn from(logger: &'a L, details: &'b ChannelDetails) -> Self {
+               Self { logger, details }
+       }
+}
+
 #[cfg(test)]
 mod test {
-       use core::cell::RefCell;
        use core::time::Duration;
        use crate::{Currency, Description, Bolt11InvoiceDescription, SignOrCreationError, CreationError};
-       use bitcoin_hashes::{Hash, sha256};
-       use bitcoin_hashes::sha256::Hash as Sha256;
+       use bitcoin::hashes::{Hash, sha256};
+       use bitcoin::hashes::sha256::Hash as Sha256;
        use lightning::sign::PhantomKeysManager;
-       use lightning::events::{MessageSendEvent, MessageSendEventsProvider, Event, EventsProvider};
-       use lightning::ln::{PaymentPreimage, PaymentHash};
+       use lightning::events::{MessageSendEvent, MessageSendEventsProvider};
+       use lightning::ln::PaymentHash;
+       #[cfg(feature = "std")]
+       use lightning::ln::PaymentPreimage;
        use lightning::ln::channelmanager::{PhantomRouteHints, MIN_FINAL_CLTV_EXPIRY_DELTA, PaymentId, RecipientOnionFields, Retry};
        use lightning::ln::functional_test_utils::*;
        use lightning::ln::msgs::ChannelMessageHandler;
@@ -808,6 +835,7 @@ mod test {
        use lightning::util::config::UserConfig;
        use crate::utils::{create_invoice_from_channelmanager_and_duration_since_epoch, rotate_through_iterators};
        use std::collections::HashSet;
+       use lightning::util::string::UntrustedString;
 
        #[test]
        fn test_prefer_current_channel() {
@@ -852,7 +880,7 @@ mod test {
                assert_eq!(invoice.amount_pico_btc(), Some(100_000));
                // If no `min_final_cltv_expiry_delta` is specified, then it should be `MIN_FINAL_CLTV_EXPIRY_DELTA`.
                assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
-               assert_eq!(invoice.description(), Bolt11InvoiceDescription::Direct(&Description("test".to_string())));
+               assert_eq!(invoice.description(), Bolt11InvoiceDescription::Direct(&Description(UntrustedString("test".to_string()))));
                assert_eq!(invoice.expiry_time(), Duration::from_secs(non_default_invoice_expiry_secs.into()));
 
                // Invoice SCIDs should always use inbound SCID aliases over the real channel ID, if one is
@@ -869,13 +897,10 @@ mod test {
                                invoice.min_final_cltv_expiry_delta() as u32)
                        .with_bolt11_features(invoice.features().unwrap().clone()).unwrap()
                        .with_route_hints(invoice.route_hints()).unwrap();
-               let route_params = RouteParameters {
-                       payment_params,
-                       final_value_msat: invoice.amount_milli_satoshis().unwrap(),
-               };
+               let route_params = RouteParameters::from_payment_params_and_value(
+                       payment_params, invoice.amount_milli_satoshis().unwrap());
                let payment_event = {
-                       let mut payment_hash = PaymentHash([0; 32]);
-                       payment_hash.0.copy_from_slice(&invoice.payment_hash().as_ref()[0..32]);
+                       let payment_hash = PaymentHash(invoice.payment_hash().to_byte_array());
                        nodes[0].node.send_payment(payment_hash,
                                RecipientOnionFields::secret_only(*invoice.payment_secret()),
                                PaymentId(payment_hash.0), route_params, Retry::Attempts(0)).unwrap();
@@ -965,7 +990,7 @@ mod test {
                ).unwrap();
                assert_eq!(invoice.amount_pico_btc(), Some(100_000));
                assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
-               assert_eq!(invoice.description(), Bolt11InvoiceDescription::Direct(&Description("test".to_string())));
+               assert_eq!(invoice.description(), Bolt11InvoiceDescription::Direct(&Description(UntrustedString("test".to_string()))));
                assert_eq!(invoice.payment_hash(), &sha256::Hash::from_slice(&payment_hash.0[..]).unwrap());
        }
 
@@ -1143,7 +1168,7 @@ mod test {
                // is never handled, the `channel.counterparty.forwarding_info` is never assigned.
                let mut private_chan_cfg = UserConfig::default();
                private_chan_cfg.channel_handshake_config.announced_channel = false;
-               let temporary_channel_id = nodes[2].node.create_channel(nodes[0].node.get_our_node_id(), 1_000_000, 500_000_000, 42, Some(private_chan_cfg)).unwrap();
+               let temporary_channel_id = nodes[2].node.create_channel(nodes[0].node.get_our_node_id(), 1_000_000, 500_000_000, 42, None, Some(private_chan_cfg)).unwrap();
                let open_channel = get_event_msg!(nodes[2], MessageSendEvent::SendOpenChannel, nodes[0].node.get_our_node_id());
                nodes[0].node.handle_open_channel(&nodes[2].node.get_our_node_id(), &open_channel);
                let accept_channel = get_event_msg!(nodes[0], MessageSendEvent::SendAcceptChannel, nodes[2].node.get_our_node_id());
@@ -1272,6 +1297,9 @@ mod test {
 
        #[cfg(feature = "std")]
        fn do_test_multi_node_receive(user_generated_pmt_hash: bool) {
+               use lightning::events::{Event, EventsProvider};
+               use core::cell::RefCell;
+
                let mut chanmon_cfgs = create_chanmon_cfgs(3);
                let seed_1 = [42u8; 32];
                let seed_2 = [43u8; 32];
@@ -1296,7 +1324,7 @@ mod test {
 
                let user_payment_preimage = PaymentPreimage([1; 32]);
                let payment_hash = if user_generated_pmt_hash {
-                       Some(PaymentHash(Sha256::hash(&user_payment_preimage.0[..]).into_inner()))
+                       Some(PaymentHash(Sha256::hash(&user_payment_preimage.0[..]).to_byte_array()))
                } else {
                        None
                };
@@ -1309,7 +1337,7 @@ mod test {
                                route_hints, nodes[1].keys_manager, nodes[1].keys_manager, nodes[1].logger,
                                Currency::BitcoinTestnet, None, Duration::from_secs(genesis_timestamp)
                        ).unwrap();
-               let (payment_hash, payment_secret) = (PaymentHash(invoice.payment_hash().into_inner()), *invoice.payment_secret());
+               let (payment_hash, payment_secret) = (PaymentHash(invoice.payment_hash().to_byte_array()), *invoice.payment_secret());
                let payment_preimage = if user_generated_pmt_hash {
                        user_payment_preimage
                } else {
@@ -1317,7 +1345,7 @@ mod test {
                };
 
                assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
-               assert_eq!(invoice.description(), Bolt11InvoiceDescription::Direct(&Description("test".to_string())));
+               assert_eq!(invoice.description(), Bolt11InvoiceDescription::Direct(&Description(UntrustedString("test".to_string()))));
                assert_eq!(invoice.route_hints().len(), 2);
                assert_eq!(invoice.expiry_time(), Duration::from_secs(non_default_invoice_expiry_secs.into()));
                assert!(!invoice.features().unwrap().supports_basic_mpp());
@@ -1326,13 +1354,10 @@ mod test {
                                invoice.min_final_cltv_expiry_delta() as u32)
                        .with_bolt11_features(invoice.features().unwrap().clone()).unwrap()
                        .with_route_hints(invoice.route_hints()).unwrap();
-               let params = RouteParameters {
-                       payment_params,
-                       final_value_msat: invoice.amount_milli_satoshis().unwrap(),
-               };
+               let params = RouteParameters::from_payment_params_and_value(
+                       payment_params, invoice.amount_milli_satoshis().unwrap());
                let (payment_event, fwd_idx) = {
-                       let mut payment_hash = PaymentHash([0; 32]);
-                       payment_hash.0.copy_from_slice(&invoice.payment_hash().as_ref()[0..32]);
+                       let payment_hash = PaymentHash(invoice.payment_hash().to_byte_array());
                        nodes[0].node.send_payment(payment_hash,
                                RecipientOnionFields::secret_only(*invoice.payment_secret()),
                                PaymentId(payment_hash.0), params, Retry::Attempts(0)).unwrap();
@@ -1457,7 +1482,7 @@ mod test {
                        nodes[2].node.get_phantom_route_hints(),
                ];
                let user_payment_preimage = PaymentPreimage([1; 32]);
-               let payment_hash = Some(PaymentHash(Sha256::hash(&user_payment_preimage.0[..]).into_inner()));
+               let payment_hash = Some(PaymentHash(Sha256::hash(&user_payment_preimage.0[..]).to_byte_array()));
                let non_default_invoice_expiry_secs = 4200;
                let min_final_cltv_expiry_delta = Some(100);
                let duration_since_epoch = Duration::from_secs(1234567);
@@ -1551,7 +1576,7 @@ mod test {
                // is never handled, the `channel.counterparty.forwarding_info` is never assigned.
                let mut private_chan_cfg = UserConfig::default();
                private_chan_cfg.channel_handshake_config.announced_channel = false;
-               let temporary_channel_id = nodes[1].node.create_channel(nodes[3].node.get_our_node_id(), 1_000_000, 500_000_000, 42, Some(private_chan_cfg)).unwrap();
+               let temporary_channel_id = nodes[1].node.create_channel(nodes[3].node.get_our_node_id(), 1_000_000, 500_000_000, 42, None, Some(private_chan_cfg)).unwrap();
                let open_channel = get_event_msg!(nodes[1], MessageSendEvent::SendOpenChannel, nodes[3].node.get_our_node_id());
                nodes[3].node.handle_open_channel(&nodes[1].node.get_our_node_id(), &open_channel);
                let accept_channel = get_event_msg!(nodes[3], MessageSendEvent::SendAcceptChannel, nodes[1].node.get_our_node_id());