Merge pull request #1852 from TheBlueMatt/2022-11-accept-bad-but-better-fee-updates
[rust-lightning] / lightning-invoice / src / utils.rs
index 1ef7cdee0d46e8ad3e7dcf6d1fcdf70d8fd4ecc8..b6442934da78898d56594a2f90951f47c9d35b50 100644 (file)
@@ -1,14 +1,14 @@
 //! Convenient utilities to create an invoice.
 
 use crate::{CreationError, Currency, Invoice, InvoiceBuilder, SignOrCreationError};
-use crate::payment::{InFlightHtlcs, Payer, Router};
+use crate::payment::{Payer, ScoringRouter};
 
 use crate::{prelude::*, Description, InvoiceDescription, Sha256};
 use bech32::ToBase32;
 use bitcoin_hashes::{Hash, sha256};
 use lightning::chain;
 use lightning::chain::chaininterface::{BroadcasterInterface, FeeEstimator};
-use lightning::chain::keysinterface::{Recipient, KeysInterface, Sign};
+use lightning::chain::keysinterface::{Recipient, KeysInterface};
 use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
 use lightning::ln::channelmanager::{ChannelDetails, ChannelManager, PaymentId, PaymentSendFailure, MIN_FINAL_CLTV_EXPIRY};
 #[cfg(feature = "std")]
@@ -16,7 +16,7 @@ use lightning::ln::channelmanager::{PhantomRouteHints, MIN_CLTV_EXPIRY_DELTA};
 use lightning::ln::inbound_payment::{create, create_from_hash, ExpandedKey};
 use lightning::ln::msgs::LightningError;
 use lightning::routing::gossip::{NetworkGraph, NodeId, RoutingFees};
-use lightning::routing::router::{Route, RouteHint, RouteHintHop, RouteParameters, find_route, RouteHop};
+use lightning::routing::router::{InFlightHtlcs, Route, RouteHint, RouteHintHop, RouteParameters, find_route, RouteHop, Router};
 use lightning::routing::scoring::{ChannelUsage, LockableScore, Score};
 use lightning::util::logger::Logger;
 use secp256k1::PublicKey;
@@ -54,7 +54,7 @@ use crate::sync::Mutex;
 /// [`ChannelManager::create_inbound_payment`]: lightning::ln::channelmanager::ChannelManager::create_inbound_payment
 /// [`ChannelManager::create_inbound_payment_for_hash`]: lightning::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash
 /// [`PhantomRouteHints::channels`]: lightning::ln::channelmanager::PhantomRouteHints::channels
-pub fn create_phantom_invoice<Signer: Sign, K: Deref, L: Deref>(
+pub fn create_phantom_invoice<K: Deref, L: Deref>(
        amt_msat: Option<u64>, payment_hash: Option<PaymentHash>, description: String,
        invoice_expiry_delta_secs: u32, phantom_route_hints: Vec<PhantomRouteHints>, keys_manager: K,
        logger: L, network: Currency,
@@ -65,7 +65,7 @@ where
 {
        let description = Description::new(description).map_err(SignOrCreationError::CreationError)?;
        let description = InvoiceDescription::Direct(&description,);
-       _create_phantom_invoice::<Signer, K, L>(
+       _create_phantom_invoice::<K, L>(
                amt_msat, payment_hash, description, invoice_expiry_delta_secs, phantom_route_hints,
                keys_manager, logger, network,
        )
@@ -103,7 +103,7 @@ where
 /// [`ChannelManager::create_inbound_payment`]: lightning::ln::channelmanager::ChannelManager::create_inbound_payment
 /// [`ChannelManager::create_inbound_payment_for_hash`]: lightning::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash
 /// [`PhantomRouteHints::channels`]: lightning::ln::channelmanager::PhantomRouteHints::channels
-pub fn create_phantom_invoice_with_description_hash<Signer: Sign, K: Deref, L: Deref>(
+pub fn create_phantom_invoice_with_description_hash<K: Deref, L: Deref>(
        amt_msat: Option<u64>, payment_hash: Option<PaymentHash>, invoice_expiry_delta_secs: u32,
        description_hash: Sha256, phantom_route_hints: Vec<PhantomRouteHints>, keys_manager: K,
        logger: L, network: Currency
@@ -112,14 +112,14 @@ where
        K::Target: KeysInterface,
        L::Target: Logger,
 {
-       _create_phantom_invoice::<Signer, K, L>(
+       _create_phantom_invoice::<K, L>(
                amt_msat, payment_hash, InvoiceDescription::Hash(&description_hash),
                invoice_expiry_delta_secs, phantom_route_hints, keys_manager, logger, network,
        )
 }
 
 #[cfg(feature = "std")]
-fn _create_phantom_invoice<Signer: Sign, K: Deref, L: Deref>(
+fn _create_phantom_invoice<K: Deref, L: Deref>(
        amt_msat: Option<u64>, payment_hash: Option<PaymentHash>, description: InvoiceDescription,
        invoice_expiry_delta_secs: u32, phantom_route_hints: Vec<PhantomRouteHints>, keys_manager: K,
        logger: L, network: Currency,
@@ -235,14 +235,14 @@ where
 ///
 /// `invoice_expiry_delta_secs` describes the number of seconds that the invoice is valid for
 /// in excess of the current time.
-pub fn create_invoice_from_channelmanager<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
-       channelmanager: &ChannelManager<Signer, M, T, K, F, L>, keys_manager: K, logger: L,
+pub fn create_invoice_from_channelmanager<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
+       channelmanager: &ChannelManager<M, T, K, F, L>, keys_manager: K, logger: L,
        network: Currency, amt_msat: Option<u64>, description: String, invoice_expiry_delta_secs: u32
 ) -> Result<Invoice, SignOrCreationError<()>>
 where
-       M::Target: chain::Watch<Signer>,
+       M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
        T::Target: BroadcasterInterface,
-       K::Target: KeysInterface<Signer = Signer>,
+       K::Target: KeysInterface,
        F::Target: FeeEstimator,
        L::Target: Logger,
 {
@@ -265,15 +265,15 @@ where
 ///
 /// `invoice_expiry_delta_secs` describes the number of seconds that the invoice is valid for
 /// in excess of the current time.
-pub fn create_invoice_from_channelmanager_with_description_hash<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
-       channelmanager: &ChannelManager<Signer, M, T, K, F, L>, keys_manager: K, logger: L,
+pub fn create_invoice_from_channelmanager_with_description_hash<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
+       channelmanager: &ChannelManager<M, T, K, F, L>, keys_manager: K, logger: L,
        network: Currency, amt_msat: Option<u64>, description_hash: Sha256,
        invoice_expiry_delta_secs: u32
 ) -> Result<Invoice, SignOrCreationError<()>>
 where
-       M::Target: chain::Watch<Signer>,
+       M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
        T::Target: BroadcasterInterface,
-       K::Target: KeysInterface<Signer = Signer>,
+       K::Target: KeysInterface,
        F::Target: FeeEstimator,
        L::Target: Logger,
 {
@@ -292,15 +292,15 @@ where
 /// See [`create_invoice_from_channelmanager_with_description_hash`]
 /// This version can be used in a `no_std` environment, where [`std::time::SystemTime`] is not
 /// available and the current time is supplied by the caller.
-pub fn create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
-       channelmanager: &ChannelManager<Signer, M, T, K, F, L>, keys_manager: K, logger: L,
+pub fn create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
+       channelmanager: &ChannelManager<M, T, K, F, L>, keys_manager: K, logger: L,
        network: Currency, amt_msat: Option<u64>, description_hash: Sha256,
        duration_since_epoch: Duration, invoice_expiry_delta_secs: u32
 ) -> Result<Invoice, SignOrCreationError<()>>
 where
-       M::Target: chain::Watch<Signer>,
+       M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
        T::Target: BroadcasterInterface,
-       K::Target: KeysInterface<Signer = Signer>,
+       K::Target: KeysInterface,
        F::Target: FeeEstimator,
        L::Target: Logger,
 {
@@ -314,15 +314,15 @@ where
 /// See [`create_invoice_from_channelmanager`]
 /// This version can be used in a `no_std` environment, where [`std::time::SystemTime`] is not
 /// available and the current time is supplied by the caller.
-pub fn create_invoice_from_channelmanager_and_duration_since_epoch<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
-       channelmanager: &ChannelManager<Signer, M, T, K, F, L>, keys_manager: K, logger: L,
+pub fn create_invoice_from_channelmanager_and_duration_since_epoch<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
+       channelmanager: &ChannelManager<M, T, K, F, L>, keys_manager: K, logger: L,
        network: Currency, amt_msat: Option<u64>, description: String, duration_since_epoch: Duration,
        invoice_expiry_delta_secs: u32
 ) -> Result<Invoice, SignOrCreationError<()>>
 where
-       M::Target: chain::Watch<Signer>,
+       M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
        T::Target: BroadcasterInterface,
-       K::Target: KeysInterface<Signer = Signer>,
+       K::Target: KeysInterface,
        F::Target: FeeEstimator,
        L::Target: Logger,
 {
@@ -335,15 +335,15 @@ where
        )
 }
 
-fn _create_invoice_from_channelmanager_and_duration_since_epoch<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
-       channelmanager: &ChannelManager<Signer, M, T, K, F, L>, keys_manager: K, logger: L,
+fn _create_invoice_from_channelmanager_and_duration_since_epoch<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>(
+       channelmanager: &ChannelManager<M, T, K, F, L>, keys_manager: K, logger: L,
        network: Currency, amt_msat: Option<u64>, description: InvoiceDescription,
        duration_since_epoch: Duration, invoice_expiry_delta_secs: u32
 ) -> Result<Invoice, SignOrCreationError<()>>
 where
-       M::Target: chain::Watch<Signer>,
+       M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
        T::Target: BroadcasterInterface,
-       K::Target: KeysInterface<Signer = Signer>,
+       K::Target: KeysInterface,
        F::Target: FeeEstimator,
        L::Target: Logger,
 {
@@ -552,8 +552,8 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, S: Deref> Router for DefaultR
        S::Target: for <'a> LockableScore<'a>,
 {
        fn find_route(
-               &self, payer: &PublicKey, params: &RouteParameters, _payment_hash: &PaymentHash,
-               first_hops: Option<&[&ChannelDetails]>, inflight_htlcs: InFlightHtlcs
+               &self, payer: &PublicKey, params: &RouteParameters, first_hops: Option<&[&ChannelDetails]>,
+               inflight_htlcs: InFlightHtlcs
        ) -> Result<Route, LightningError> {
                let random_seed_bytes = {
                        let mut locked_random_seed_bytes = self.random_seed_bytes.lock().unwrap();
@@ -567,7 +567,12 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, S: Deref> Router for DefaultR
                        &random_seed_bytes
                )
        }
+}
 
+impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, S: Deref> ScoringRouter for DefaultRouter<G, L, S> where
+       L::Target: Logger,
+       S::Target: for <'a> LockableScore<'a>,
+{
        fn notify_payment_path_failed(&self, path: &[&RouteHop], short_channel_id: u64) {
                self.scorer.lock().payment_path_failed(path, short_channel_id);
        }
@@ -585,11 +590,11 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, S: Deref> Router for DefaultR
        }
 }
 
-impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Payer for ChannelManager<Signer, M, T, K, F, L>
+impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Payer for ChannelManager<M, T, K, F, L>
 where
-       M::Target: chain::Watch<Signer>,
+       M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
        T::Target: BroadcasterInterface,
-       K::Target: KeysInterface<Signer = Signer>,
+       K::Target: KeysInterface,
        F::Target: FeeEstimator,
        L::Target: Logger,
 {
@@ -602,18 +607,16 @@ where
        }
 
        fn send_payment(
-               &self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option<PaymentSecret>
-       ) -> Result<PaymentId, PaymentSendFailure> {
-               let payment_id = PaymentId(payment_hash.0);
-               self.send_payment(route, payment_hash, payment_secret, payment_id).map(|()| payment_id)
+               &self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option<PaymentSecret>,
+               payment_id: PaymentId
+       ) -> Result<(), PaymentSendFailure> {
+               self.send_payment(route, payment_hash, payment_secret, payment_id)
        }
 
        fn send_spontaneous_payment(
-               &self, route: &Route, payment_preimage: PaymentPreimage,
-       ) -> Result<PaymentId, PaymentSendFailure> {
-               let payment_id = PaymentId(sha256::Hash::hash(&payment_preimage.0).into_inner());
-               self.send_spontaneous_payment(route, Some(payment_preimage), payment_id)
-                       .map(|_| payment_id)
+               &self, route: &Route, payment_preimage: PaymentPreimage, payment_id: PaymentId,
+       ) -> Result<(), PaymentSendFailure> {
+               self.send_spontaneous_payment(route, Some(payment_preimage), payment_id).map(|_| ())
        }
 
        fn retry_payment(
@@ -687,7 +690,6 @@ mod test {
        use lightning::ln::functional_test_utils::*;
        use lightning::ln::msgs::ChannelMessageHandler;
        use lightning::routing::router::{PaymentParameters, RouteParameters, find_route};
-       use lightning::util::enforcing_trait_impls::EnforcingSigner;
        use lightning::util::events::{MessageSendEvent, MessageSendEventsProvider, Event};
        use lightning::util::test_utils;
        use lightning::util::config::UserConfig;
@@ -871,6 +873,8 @@ mod test {
                get_event_msg!(nodes[2], MessageSendEvent::SendChannelUpdate, nodes[0].node.get_our_node_id());
                nodes[0].node.handle_channel_ready(&nodes[2].node.get_our_node_id(), &as_channel_ready);
                get_event_msg!(nodes[0], MessageSendEvent::SendChannelUpdate, nodes[2].node.get_our_node_id());
+               expect_channel_ready_event(&nodes[0], &nodes[2].node.get_our_node_id());
+               expect_channel_ready_event(&nodes[2], &nodes[0].node.get_our_node_id());
 
                // As `msgs::ChannelUpdate` was never handled for the participating node(s) of the second
                // channel, the channel will never be assigned any `counterparty.forwarding_info`.
@@ -1011,7 +1015,7 @@ mod test {
                let non_default_invoice_expiry_secs = 4200;
 
                let invoice =
-                       crate::utils::create_phantom_invoice::<EnforcingSigner, &test_utils::TestKeysInterface, &test_utils::TestLogger>(
+                       crate::utils::create_phantom_invoice::<&test_utils::TestKeysInterface, &test_utils::TestLogger>(
                                Some(payment_amt), payment_hash, "test".to_string(), non_default_invoice_expiry_secs,
                                route_hints, &nodes[1].keys_manager, &nodes[1].logger, Currency::BitcoinTestnet
                        ).unwrap();
@@ -1120,7 +1124,7 @@ mod test {
                        nodes[2].node.get_phantom_route_hints(),
                ];
 
-               let invoice = crate::utils::create_phantom_invoice::<EnforcingSigner, &test_utils::TestKeysInterface, &test_utils::TestLogger>(Some(payment_amt), Some(payment_hash), "test".to_string(), 3600, route_hints, &nodes[1].keys_manager, &nodes[1].logger, Currency::BitcoinTestnet).unwrap();
+               let invoice = crate::utils::create_phantom_invoice::<&test_utils::TestKeysInterface, &test_utils::TestLogger>(Some(payment_amt), Some(payment_hash), "test".to_string(), 3600, route_hints, &nodes[1].keys_manager, &nodes[1].logger, Currency::BitcoinTestnet).unwrap();
 
                let chan_0_1 = &nodes[1].node.list_usable_channels()[0];
                assert_eq!(invoice.route_hints()[0].0[0].htlc_minimum_msat, chan_0_1.inbound_htlc_minimum_msat);
@@ -1148,7 +1152,7 @@ mod test {
                let description_hash = crate::Sha256(Hash::hash("Description hash phantom invoice".as_bytes()));
                let non_default_invoice_expiry_secs = 4200;
                let invoice = crate::utils::create_phantom_invoice_with_description_hash::<
-                       EnforcingSigner, &test_utils::TestKeysInterface, &test_utils::TestLogger,
+                       &test_utils::TestKeysInterface, &test_utils::TestLogger,
                >(
                        Some(payment_amt), None, non_default_invoice_expiry_secs, description_hash,
                        route_hints, &nodes[1].keys_manager, &nodes[1].logger, Currency::BitcoinTestnet
@@ -1259,6 +1263,8 @@ mod test {
                get_event_msg!(nodes[1], MessageSendEvent::SendChannelUpdate, nodes[3].node.get_our_node_id());
                nodes[3].node.handle_channel_ready(&nodes[1].node.get_our_node_id(), &as_channel_ready);
                get_event_msg!(nodes[3], MessageSendEvent::SendChannelUpdate, nodes[1].node.get_our_node_id());
+               expect_channel_ready_event(&nodes[1], &nodes[3].node.get_our_node_id());
+               expect_channel_ready_event(&nodes[3], &nodes[1].node.get_our_node_id());
 
                // As `msgs::ChannelUpdate` was never handled for the participating node(s) of the third
                // channel, the channel will never be assigned any `counterparty.forwarding_info`.
@@ -1463,7 +1469,7 @@ mod test {
                        .map(|route_hint| route_hint.phantom_scid)
                        .collect::<HashSet<u64>>();
 
-               let invoice = crate::utils::create_phantom_invoice::<EnforcingSigner, &test_utils::TestKeysInterface, &test_utils::TestLogger>(invoice_amt, None, "test".to_string(), 3600, phantom_route_hints, &invoice_node.keys_manager, &invoice_node.logger, Currency::BitcoinTestnet).unwrap();
+               let invoice = crate::utils::create_phantom_invoice::<&test_utils::TestKeysInterface, &test_utils::TestLogger>(invoice_amt, None, "test".to_string(), 3600, phantom_route_hints, &invoice_node.keys_manager, &invoice_node.logger, Currency::BitcoinTestnet).unwrap();
 
                let invoice_hints = invoice.private_routes();