Merge pull request #1656 from ViktorTigerstrom/2022-08-forward-htlcs-as-standalone...
[rust-lightning] / lightning-invoice / src / payment.rs
index 0d99041ad9e854207dc802f8a96b187d8ac3995f..3b4fe7092bc38272882a14f71cf7741dd0cdc7ea 100644 (file)
 //! #         first_hops: Option<&[&ChannelDetails]>, _inflight_htlcs: InFlightHtlcs
 //! #     ) -> Result<Route, LightningError> { unimplemented!() }
 //! #
-//! #     fn notify_payment_path_failed(&self, path: Vec<&RouteHop>, short_channel_id: u64) {  unimplemented!() }
-//! #     fn notify_payment_path_successful(&self, path: Vec<&RouteHop>) {  unimplemented!() }
-//! #     fn notify_payment_probe_successful(&self, path: Vec<&RouteHop>) {  unimplemented!() }
-//! #     fn notify_payment_probe_failed(&self, path: Vec<&RouteHop>, short_channel_id: u64) { unimplemented!() }
+//! #     fn notify_payment_path_failed(&self, path: &[&RouteHop], short_channel_id: u64) {  unimplemented!() }
+//! #     fn notify_payment_path_successful(&self, path: &[&RouteHop]) {  unimplemented!() }
+//! #     fn notify_payment_probe_successful(&self, path: &[&RouteHop]) {  unimplemented!() }
+//! #     fn notify_payment_probe_failed(&self, path: &[&RouteHop], short_channel_id: u64) { unimplemented!() }
 //! # }
 //! #
 //! # struct FakeScorer {}
@@ -273,13 +273,13 @@ pub trait Router {
                first_hops: Option<&[&ChannelDetails]>, inflight_htlcs: InFlightHtlcs
        ) -> Result<Route, LightningError>;
        /// Lets the router know that payment through a specific path has failed.
-       fn notify_payment_path_failed(&self, path: Vec<&RouteHop>, short_channel_id: u64);
+       fn notify_payment_path_failed(&self, path: &[&RouteHop], short_channel_id: u64);
        /// Lets the router know that payment through a specific path was successful.
-       fn notify_payment_path_successful(&self, path: Vec<&RouteHop>);
+       fn notify_payment_path_successful(&self, path: &[&RouteHop]);
        /// Lets the router know that a payment probe was successful.
-       fn notify_payment_probe_successful(&self, path: Vec<&RouteHop>);
+       fn notify_payment_probe_successful(&self, path: &[&RouteHop]);
        /// Lets the router know that a payment probe failed.
-       fn notify_payment_probe_failed(&self, path: Vec<&RouteHop>, short_channel_id: u64);
+       fn notify_payment_probe_failed(&self, path: &[&RouteHop], short_channel_id: u64);
 }
 
 /// Strategies available to retry payment path failures for an [`Invoice`].
@@ -676,16 +676,16 @@ where
 
                match event {
                        Event::PaymentPathFailed {
-                               payment_id, payment_hash, rejected_by_dest, path, short_channel_id, retry, ..
+                               payment_id, payment_hash, payment_failed_permanently, path, short_channel_id, retry, ..
                        } => {
                                if let Some(short_channel_id) = short_channel_id {
                                        let path = path.iter().collect::<Vec<_>>();
-                                       self.router.notify_payment_path_failed(path, *short_channel_id)
+                                       self.router.notify_payment_path_failed(&path, *short_channel_id)
                                }
 
                                if payment_id.is_none() {
                                        log_trace!(self.logger, "Payment {} has no id; not retrying", log_bytes!(payment_hash.0));
-                               } else if *rejected_by_dest {
+                               } else if *payment_failed_permanently {
                                        log_trace!(self.logger, "Payment {} rejected by destination; not retrying", log_bytes!(payment_hash.0));
                                        self.payer.abandon_payment(payment_id.unwrap());
                                } else if retry.is_none() {
@@ -703,7 +703,7 @@ where
                        },
                        Event::PaymentPathSuccessful { path, .. } => {
                                let path = path.iter().collect::<Vec<_>>();
-                               self.router.notify_payment_path_successful(path);
+                               self.router.notify_payment_path_successful(&path);
                        },
                        Event::PaymentSent { payment_hash, .. } => {
                                let mut payment_cache = self.payment_cache.lock().unwrap();
@@ -715,13 +715,13 @@ where
                        Event::ProbeSuccessful { payment_hash, path, .. } => {
                                log_trace!(self.logger, "Probe payment {} of {}msat was successful", log_bytes!(payment_hash.0), path.last().unwrap().fee_msat);
                                let path = path.iter().collect::<Vec<_>>();
-                               self.router.notify_payment_probe_successful(path);
+                               self.router.notify_payment_probe_successful(&path);
                        },
                        Event::ProbeFailed { payment_hash, path, short_channel_id, .. } => {
                                if let Some(short_channel_id) = short_channel_id {
                                        log_trace!(self.logger, "Probe payment {} of {}msat failed at channel {}", log_bytes!(payment_hash.0), path.last().unwrap().fee_msat, *short_channel_id);
                                        let path = path.iter().collect::<Vec<_>>();
-                                       self.router.notify_payment_probe_failed(path, *short_channel_id);
+                                       self.router.notify_payment_probe_failed(&path, *short_channel_id);
                                }
                        },
                        _ => {},
@@ -741,8 +741,8 @@ pub struct InFlightHtlcs(HashMap<(u64, bool), u64>);
 impl InFlightHtlcs {
        /// Returns liquidity in msat given the public key of the HTLC source, target, and short channel
        /// id.
-       pub fn used_liquidity_msat(&self, source: &NodeId, target: &NodeId, channel_scid: u64) -> Option<&u64> {
-               self.0.get(&(channel_scid, source < target))
+       pub fn used_liquidity_msat(&self, source: &NodeId, target: &NodeId, channel_scid: u64) -> Option<u64> {
+               self.0.get(&(channel_scid, source < target)).map(|v| *v)
        }
 }
 
@@ -764,7 +764,8 @@ mod tests {
        use utils::{ScorerAccountingForInFlightHtlcs, create_invoice_from_channelmanager_and_duration_since_epoch};
        use bitcoin_hashes::sha256::Hash as Sha256;
        use lightning::ln::PaymentPreimage;
-       use lightning::ln::features::{ChannelFeatures, NodeFeatures, InitFeatures};
+       use lightning::ln::channelmanager;
+       use lightning::ln::features::{ChannelFeatures, NodeFeatures};
        use lightning::ln::functional_test_utils::*;
        use lightning::ln::msgs::{ChannelMessageHandler, ErrorAction, LightningError};
        use lightning::routing::gossip::{EffectiveCapacity, NodeId};
@@ -899,7 +900,7 @@ mod tests {
                        payment_id,
                        payment_hash,
                        network_update: None,
-                       rejected_by_dest: false,
+                       payment_failed_permanently: false,
                        all_paths_failed: false,
                        path: TestRouter::path_for_value(final_value_msat),
                        short_channel_id: None,
@@ -962,7 +963,7 @@ mod tests {
                        payment_id,
                        payment_hash,
                        network_update: None,
-                       rejected_by_dest: false,
+                       payment_failed_permanently: false,
                        all_paths_failed: false,
                        path: TestRouter::path_for_value(final_value_msat),
                        short_channel_id: None,
@@ -1008,7 +1009,7 @@ mod tests {
                        payment_id,
                        payment_hash: PaymentHash(invoice.payment_hash().clone().into_inner()),
                        network_update: None,
-                       rejected_by_dest: false,
+                       payment_failed_permanently: false,
                        all_paths_failed: true,
                        path: TestRouter::path_for_value(final_value_msat),
                        short_channel_id: None,
@@ -1022,7 +1023,7 @@ mod tests {
                        payment_id,
                        payment_hash: PaymentHash(invoice.payment_hash().clone().into_inner()),
                        network_update: None,
-                       rejected_by_dest: false,
+                       payment_failed_permanently: false,
                        all_paths_failed: false,
                        path: TestRouter::path_for_value(final_value_msat / 2),
                        short_channel_id: None,
@@ -1067,7 +1068,7 @@ mod tests {
                        payment_id,
                        payment_hash: PaymentHash(invoice.payment_hash().clone().into_inner()),
                        network_update: None,
-                       rejected_by_dest: false,
+                       payment_failed_permanently: false,
                        all_paths_failed: true,
                        path: TestRouter::path_for_value(final_value_msat),
                        short_channel_id: None,
@@ -1106,7 +1107,7 @@ mod tests {
                        payment_id,
                        payment_hash: PaymentHash(invoice.payment_hash().clone().into_inner()),
                        network_update: None,
-                       rejected_by_dest: false,
+                       payment_failed_permanently: false,
                        all_paths_failed: false,
                        path: vec![],
                        short_channel_id: None,
@@ -1165,7 +1166,7 @@ mod tests {
                        payment_id,
                        payment_hash: PaymentHash(invoice.payment_hash().clone().into_inner()),
                        network_update: None,
-                       rejected_by_dest: false,
+                       payment_failed_permanently: false,
                        all_paths_failed: false,
                        path: vec![],
                        short_channel_id: None,
@@ -1201,7 +1202,7 @@ mod tests {
                        payment_id,
                        payment_hash: PaymentHash(invoice.payment_hash().clone().into_inner()),
                        network_update: None,
-                       rejected_by_dest: false,
+                       payment_failed_permanently: false,
                        all_paths_failed: false,
                        path: TestRouter::path_for_value(final_value_msat / 2),
                        short_channel_id: None,
@@ -1234,7 +1235,7 @@ mod tests {
                        payment_id,
                        payment_hash: PaymentHash(invoice.payment_hash().clone().into_inner()),
                        network_update: None,
-                       rejected_by_dest: true,
+                       payment_failed_permanently: true,
                        all_paths_failed: false,
                        path: vec![],
                        short_channel_id: None,
@@ -1282,7 +1283,7 @@ mod tests {
                        payment_id,
                        payment_hash,
                        network_update: None,
-                       rejected_by_dest: false,
+                       payment_failed_permanently: false,
                        all_paths_failed: false,
                        path: vec![],
                        short_channel_id: None,
@@ -1412,7 +1413,7 @@ mod tests {
                        payment_id,
                        payment_hash,
                        network_update: None,
-                       rejected_by_dest: false,
+                       payment_failed_permanently: false,
                        all_paths_failed: false,
                        path: vec![],
                        short_channel_id: None,
@@ -1458,7 +1459,7 @@ mod tests {
                        payment_id,
                        payment_hash,
                        network_update: None,
-                       rejected_by_dest: false,
+                       payment_failed_permanently: false,
                        all_paths_failed: false,
                        path,
                        short_channel_id,
@@ -1644,7 +1645,7 @@ mod tests {
                        payment_id,
                        payment_hash,
                        network_update: None,
-                       rejected_by_dest: false,
+                       payment_failed_permanently: false,
                        all_paths_failed: false,
                        path: TestRouter::path_for_value(final_value_msat),
                        short_channel_id: None,
@@ -1656,7 +1657,7 @@ mod tests {
                        payment_id,
                        payment_hash,
                        network_update: None,
-                       rejected_by_dest: false,
+                       payment_failed_permanently: false,
                        all_paths_failed: false,
                        path: TestRouter::path_for_value(final_value_msat / 2),
                        short_channel_id: None,
@@ -1843,20 +1844,20 @@ mod tests {
                        })
                }
 
-               fn notify_payment_path_failed(&self, path: Vec<&RouteHop>, short_channel_id: u64) {
-                       self.scorer.lock().payment_path_failed(&path, short_channel_id);
+               fn notify_payment_path_failed(&self, path: &[&RouteHop], short_channel_id: u64) {
+                       self.scorer.lock().payment_path_failed(path, short_channel_id);
                }
 
-               fn notify_payment_path_successful(&self, path: Vec<&RouteHop>) {
-                       self.scorer.lock().payment_path_successful(&path);
+               fn notify_payment_path_successful(&self, path: &[&RouteHop]) {
+                       self.scorer.lock().payment_path_successful(path);
                }
 
-               fn notify_payment_probe_successful(&self, path: Vec<&RouteHop>) {
-                       self.scorer.lock().probe_successful(&path);
+               fn notify_payment_probe_successful(&self, path: &[&RouteHop]) {
+                       self.scorer.lock().probe_successful(path);
                }
 
-               fn notify_payment_probe_failed(&self, path: Vec<&RouteHop>, short_channel_id: u64) {
-                       self.scorer.lock().probe_failed(&path, short_channel_id);
+               fn notify_payment_probe_failed(&self, path: &[&RouteHop], short_channel_id: u64) {
+                       self.scorer.lock().probe_failed(path, short_channel_id);
                }
        }
 
@@ -1870,13 +1871,13 @@ mod tests {
                        Err(LightningError { err: String::new(), action: ErrorAction::IgnoreError })
                }
 
-               fn notify_payment_path_failed(&self, _path: Vec<&RouteHop>, _short_channel_id: u64) {}
+               fn notify_payment_path_failed(&self, _path: &[&RouteHop], _short_channel_id: u64) {}
 
-               fn notify_payment_path_successful(&self, _path: Vec<&RouteHop>) {}
+               fn notify_payment_path_successful(&self, _path: &[&RouteHop]) {}
 
-               fn notify_payment_probe_successful(&self, _path: Vec<&RouteHop>) {}
+               fn notify_payment_probe_successful(&self, _path: &[&RouteHop]) {}
 
-               fn notify_payment_probe_failed(&self, _path: Vec<&RouteHop>, _short_channel_id: u64) {}
+               fn notify_payment_probe_failed(&self, _path: &[&RouteHop], _short_channel_id: u64) {}
        }
 
        struct TestScorer {
@@ -2132,13 +2133,13 @@ mod tests {
                        self.0.borrow_mut().pop_front().unwrap()
                }
 
-               fn notify_payment_path_failed(&self, _path: Vec<&RouteHop>, _short_channel_id: u64) {}
+               fn notify_payment_path_failed(&self, _path: &[&RouteHop], _short_channel_id: u64) {}
 
-               fn notify_payment_path_successful(&self, _path: Vec<&RouteHop>) {}
+               fn notify_payment_path_successful(&self, _path: &[&RouteHop]) {}
 
-               fn notify_payment_probe_successful(&self, _path: Vec<&RouteHop>) {}
+               fn notify_payment_probe_successful(&self, _path: &[&RouteHop]) {}
 
-               fn notify_payment_probe_failed(&self, _path: Vec<&RouteHop>, _short_channel_id: u64) {}
+               fn notify_payment_probe_failed(&self, _path: &[&RouteHop], _short_channel_id: u64) {}
        }
        impl ManualRouter {
                fn expect_find_route(&self, result: Result<Route, LightningError>) {
@@ -2162,24 +2163,24 @@ mod tests {
                let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None, None]);
                let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0, InitFeatures::known(), InitFeatures::known());
-               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0, InitFeatures::known(), InitFeatures::known());
+               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
                let chans = nodes[0].node.list_usable_channels();
                let mut route = Route {
                        paths: vec![
                                vec![RouteHop {
                                        pubkey: nodes[1].node.get_our_node_id(),
-                                       node_features: NodeFeatures::known(),
+                                       node_features: channelmanager::provided_node_features(),
                                        short_channel_id: chans[0].short_channel_id.unwrap(),
-                                       channel_features: ChannelFeatures::known(),
+                                       channel_features: channelmanager::provided_channel_features(),
                                        fee_msat: 10_000,
                                        cltv_expiry_delta: 100,
                                }],
                                vec![RouteHop {
                                        pubkey: nodes[1].node.get_our_node_id(),
-                                       node_features: NodeFeatures::known(),
+                                       node_features: channelmanager::provided_node_features(),
                                        short_channel_id: chans[1].short_channel_id.unwrap(),
-                                       channel_features: ChannelFeatures::known(),
+                                       channel_features: channelmanager::provided_channel_features(),
                                        fee_msat: 100_000_001, // Our default max-HTLC-value is 10% of the channel value, which this is one more than
                                        cltv_expiry_delta: 100,
                                }],
@@ -2213,16 +2214,16 @@ mod tests {
                let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None, None]);
                let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0, InitFeatures::known(), InitFeatures::known());
-               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0, InitFeatures::known(), InitFeatures::known());
+               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
+               create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features());
                let chans = nodes[0].node.list_usable_channels();
                let mut route = Route {
                        paths: vec![
                                vec![RouteHop {
                                        pubkey: nodes[1].node.get_our_node_id(),
-                                       node_features: NodeFeatures::known(),
+                                       node_features: channelmanager::provided_node_features(),
                                        short_channel_id: chans[0].short_channel_id.unwrap(),
-                                       channel_features: ChannelFeatures::known(),
+                                       channel_features: channelmanager::provided_channel_features(),
                                        fee_msat: 100_000_001, // Our default max-HTLC-value is 10% of the channel value, which this is one more than
                                        cltv_expiry_delta: 100,
                                }],
@@ -2271,38 +2272,38 @@ mod tests {
                let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
                let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
 
-               let chan_1_scid = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 0, InitFeatures::known(), InitFeatures::known()).0.contents.short_channel_id;
-               let chan_2_scid = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 10_000_000, 0, InitFeatures::known(), InitFeatures::known()).0.contents.short_channel_id;
+               let chan_1_scid = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 10_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
+               let chan_2_scid = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 10_000_000, 0, channelmanager::provided_init_features(), channelmanager::provided_init_features()).0.contents.short_channel_id;
 
                let mut route = Route {
                        paths: vec![
                                vec![RouteHop {
                                        pubkey: nodes[1].node.get_our_node_id(),
-                                       node_features: NodeFeatures::known(),
+                                       node_features: channelmanager::provided_node_features(),
                                        short_channel_id: chan_1_scid,
-                                       channel_features: ChannelFeatures::known(),
+                                       channel_features: channelmanager::provided_channel_features(),
                                        fee_msat: 0,
                                        cltv_expiry_delta: 100,
                                }, RouteHop {
                                        pubkey: nodes[2].node.get_our_node_id(),
-                                       node_features: NodeFeatures::known(),
+                                       node_features: channelmanager::provided_node_features(),
                                        short_channel_id: chan_2_scid,
-                                       channel_features: ChannelFeatures::known(),
+                                       channel_features: channelmanager::provided_channel_features(),
                                        fee_msat: 100_000_000,
                                        cltv_expiry_delta: 100,
                                }],
                                vec![RouteHop {
                                        pubkey: nodes[1].node.get_our_node_id(),
-                                       node_features: NodeFeatures::known(),
+                                       node_features: channelmanager::provided_node_features(),
                                        short_channel_id: chan_1_scid,
-                                       channel_features: ChannelFeatures::known(),
+                                       channel_features: channelmanager::provided_channel_features(),
                                        fee_msat: 0,
                                        cltv_expiry_delta: 100,
                                }, RouteHop {
                                        pubkey: nodes[2].node.get_our_node_id(),
-                                       node_features: NodeFeatures::known(),
+                                       node_features: channelmanager::provided_node_features(),
                                        short_channel_id: chan_2_scid,
-                                       channel_features: ChannelFeatures::known(),
+                                       channel_features: channelmanager::provided_channel_features(),
                                        fee_msat: 100_000_000,
                                        cltv_expiry_delta: 100,
                                }]
@@ -2392,8 +2393,8 @@ mod tests {
                // treated this as "HTLC complete" and dropped the retry counter, causing us to retry again
                // if the final HTLC failed.
                expected_events.borrow_mut().push_back(&|ev: &Event| {
-                       if let Event::PaymentPathFailed { rejected_by_dest, all_paths_failed, .. } = ev {
-                               assert!(!rejected_by_dest);
+                       if let Event::PaymentPathFailed { payment_failed_permanently, all_paths_failed, .. } = ev {
+                               assert!(!payment_failed_permanently);
                                assert!(all_paths_failed);
                        } else { panic!("Unexpected event"); }
                });
@@ -2410,8 +2411,8 @@ mod tests {
                commitment_signed_dance!(nodes[0], nodes[1], &bs_fail_update.commitment_signed, false, true);
 
                expected_events.borrow_mut().push_back(&|ev: &Event| {
-                       if let Event::PaymentPathFailed { rejected_by_dest, all_paths_failed, .. } = ev {
-                               assert!(!rejected_by_dest);
+                       if let Event::PaymentPathFailed { payment_failed_permanently, all_paths_failed, .. } = ev {
+                               assert!(!payment_failed_permanently);
                                assert!(all_paths_failed);
                        } else { panic!("Unexpected event"); }
                });