X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning-invoice%2Fsrc%2Fpayment.rs;h=ee85fab0b5dbe8081d3b21e367c36125c28ecf92;hb=7bc52aa62cb3c32f51b242ad3fa0ae16aee80cec;hp=0d99041ad9e854207dc802f8a96b187d8ac3995f;hpb=c353c3ed7c40e689a3b9fb6730c6dabbd3c92cc5;p=rust-lightning diff --git a/lightning-invoice/src/payment.rs b/lightning-invoice/src/payment.rs index 0d99041a..ee85fab0 100644 --- a/lightning-invoice/src/payment.rs +++ b/lightning-invoice/src/payment.rs @@ -77,10 +77,10 @@ //! # first_hops: Option<&[&ChannelDetails]>, _inflight_htlcs: InFlightHtlcs //! # ) -> Result { 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 {} @@ -149,6 +149,7 @@ use lightning::routing::router::{PaymentParameters, Route, RouteHop, RouteParame use lightning::util::errors::APIError; use lightning::util::events::{Event, EventHandler}; use lightning::util::logger::Logger; +use lightning::util::ser::Writeable; use time_utils::Time; use crate::sync::Mutex; @@ -273,13 +274,13 @@ pub trait Router { first_hops: Option<&[&ChannelDetails]>, inflight_htlcs: InFlightHtlcs ) -> Result; /// 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 +677,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::>(); - 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 +704,7 @@ where }, Event::PaymentPathSuccessful { path, .. } => { let path = path.iter().collect::>(); - 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 +716,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::>(); - 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::>(); - self.router.notify_payment_probe_failed(path, *short_channel_id); + self.router.notify_payment_probe_failed(&path, *short_channel_id); } }, _ => {}, @@ -741,12 +742,12 @@ 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 { + self.0.get(&(channel_scid, source < target)).map(|v| *v) } } -impl lightning::util::ser::Writeable for InFlightHtlcs { +impl Writeable for InFlightHtlcs { fn write(&self, writer: &mut W) -> Result<(), io::Error> { self.0.write(writer) } } @@ -764,7 +765,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 +901,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 +964,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 +1010,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 +1024,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 +1069,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 +1108,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 +1167,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 +1203,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 +1236,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 +1284,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 +1414,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 +1460,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 +1646,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 +1658,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 +1845,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 +1872,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 { @@ -1911,7 +1913,7 @@ mod tests { #[cfg(c_bindings)] impl lightning::util::ser::Writeable for TestScorer { - fn write(&self, _: &mut W) -> Result<(), std::io::Error> { unreachable!(); } + fn write(&self, _: &mut W) -> Result<(), lightning::io::Error> { unreachable!(); } } impl Score for TestScorer { @@ -2132,13 +2134,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) { @@ -2162,24 +2164,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 +2215,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 +2273,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 +2394,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 +2412,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"); } });