From: Elias Rohrer Date: Thu, 31 Aug 2023 10:25:38 +0000 (+0200) Subject: Have `get_route` take `RouteParameters` X-Git-Tag: v0.0.117-alpha1~27^2~3 X-Git-Url: http://git.bitcoin.ninja/?a=commitdiff_plain;h=266a3aa9152e9d50570ae41b3be1548a715d0754;p=rust-lightning Have `get_route` take `RouteParameters` --- diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index a11e5c813..d7167146c 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -527,10 +527,8 @@ pub fn do_test(data: &[u8], logger: &Arc) { 4 => { let final_value_msat = slice_to_be24(get_slice!(3)) as u64; let payment_params = PaymentParameters::from_node_id(get_pubkey!(), 42); - let params = RouteParameters { - payment_params, - final_value_msat, - }; + let params = RouteParameters::from_payment_params_and_value( + payment_params, final_value_msat); let mut payment_hash = PaymentHash([0; 32]); payment_hash.0[0..8].copy_from_slice(&be64_to_array(payments_sent)); let mut sha = Sha256::engine(); @@ -548,10 +546,8 @@ pub fn do_test(data: &[u8], logger: &Arc) { 15 => { let final_value_msat = slice_to_be24(get_slice!(3)) as u64; let payment_params = PaymentParameters::from_node_id(get_pubkey!(), 42); - let params = RouteParameters { - payment_params, - final_value_msat, - }; + let params = RouteParameters::from_payment_params_and_value( + payment_params, final_value_msat); let mut payment_hash = PaymentHash([0; 32]); payment_hash.0[0..8].copy_from_slice(&be64_to_array(payments_sent)); let mut sha = Sha256::engine(); diff --git a/fuzz/src/router.rs b/fuzz/src/router.rs index 830f6f4e2..b7d45bf72 100644 --- a/fuzz/src/router.rs +++ b/fuzz/src/router.rs @@ -326,11 +326,10 @@ pub fn do_test(data: &[u8], out: Out) { let mut last_hops = Vec::new(); last_hops!(last_hops); find_routes!(first_hops, node_pks.iter(), |final_amt, final_delta, target: &PublicKey| { - RouteParameters { - payment_params: PaymentParameters::from_node_id(*target, final_delta) + RouteParameters::from_payment_params_and_value( + PaymentParameters::from_node_id(*target, final_delta) .with_route_hints(last_hops.clone()).unwrap(), - final_value_msat: final_amt, - } + final_amt) }); }, x => { @@ -366,11 +365,9 @@ pub fn do_test(data: &[u8], out: Out) { let mut features = Bolt12InvoiceFeatures::empty(); features.set_basic_mpp_optional(); find_routes!(first_hops, vec![dummy_pk].iter(), |final_amt, _, _| { - RouteParameters { - payment_params: PaymentParameters::blinded(last_hops.clone()) - .with_bolt12_features(features.clone()).unwrap(), - final_value_msat: final_amt, - } + RouteParameters::from_payment_params_and_value(PaymentParameters::blinded(last_hops.clone()) + .with_bolt12_features(features.clone()).unwrap(), + final_amt) }); } } diff --git a/lightning-invoice/src/utils.rs b/lightning-invoice/src/utils.rs index 744c2654c..a512b2de0 100644 --- a/lightning-invoice/src/utils.rs +++ b/lightning-invoice/src/utils.rs @@ -869,10 +869,8 @@ 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]); @@ -1326,10 +1324,8 @@ 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]); diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 213a2882f..5624204a5 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -9653,10 +9653,9 @@ mod tests { let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &expected_route, 100_000); // Next, attempt a keysend payment and make sure it fails. - let route_params = RouteParameters { - payment_params: PaymentParameters::for_keysend(expected_route.last().unwrap().node.get_our_node_id(), TEST_FINAL_CLTV, false), - final_value_msat: 100_000, - }; + let route_params = RouteParameters::from_payment_params_and_value( + PaymentParameters::for_keysend(expected_route.last().unwrap().node.get_our_node_id(), + TEST_FINAL_CLTV, false), 100_000); let route = find_route( &nodes[0].node.get_our_node_id(), &route_params, &nodes[0].network_graph, None, nodes[0].logger, &scorer, &(), &random_seed_bytes @@ -9744,10 +9743,10 @@ mod tests { pass_along_path(&nodes[0], &path, 100_000, payment_hash, None, event, true, Some(payment_preimage)); // Next, attempt a keysend payment and make sure it fails. - let route_params = RouteParameters { - payment_params: PaymentParameters::for_keysend(expected_route.last().unwrap().node.get_our_node_id(), TEST_FINAL_CLTV, false), - final_value_msat: 100_000, - }; + let route_params = RouteParameters::from_payment_params_and_value( + PaymentParameters::for_keysend(expected_route.last().unwrap().node.get_our_node_id(), TEST_FINAL_CLTV, false), + 100_000 + ); let route = find_route( &nodes[0].node.get_our_node_id(), &route_params, &nodes[0].network_graph, None, nodes[0].logger, &scorer, &(), &random_seed_bytes @@ -9793,10 +9792,8 @@ mod tests { let payee_pubkey = nodes[1].node.get_our_node_id(); let _chan = create_chan_between_nodes(&nodes[0], &nodes[1]); - let route_params = RouteParameters { - payment_params: PaymentParameters::for_keysend(payee_pubkey, 40, false), - final_value_msat: 10_000, - }; + let route_params = RouteParameters::from_payment_params_and_value( + PaymentParameters::for_keysend(payee_pubkey, 40, false), 10_000); let network_graph = nodes[0].network_graph.clone(); let first_hops = nodes[0].node.list_usable_channels(); let scorer = test_utils::TestScorer::new(); @@ -9840,10 +9837,8 @@ mod tests { let payee_pubkey = nodes[1].node.get_our_node_id(); let _chan = create_chan_between_nodes(&nodes[0], &nodes[1]); - let route_params = RouteParameters { - payment_params: PaymentParameters::for_keysend(payee_pubkey, 40, false), - final_value_msat: 10_000, - }; + let route_params = RouteParameters::from_payment_params_and_value( + PaymentParameters::for_keysend(payee_pubkey, 40, false), 10_000); let network_graph = nodes[0].network_graph.clone(); let first_hops = nodes[0].node.list_usable_channels(); let scorer = test_utils::TestScorer::new(); @@ -10740,9 +10735,9 @@ pub mod bench { let payment_secret = $node_b.create_inbound_payment_for_hash(payment_hash, None, 7200, None).unwrap(); $node_a.send_payment(payment_hash, RecipientOnionFields::secret_only(payment_secret), - PaymentId(payment_hash.0), RouteParameters { - payment_params, final_value_msat: 10_000, - }, Retry::Attempts(0)).unwrap(); + PaymentId(payment_hash.0), + RouteParameters::from_payment_params_and_value(payment_params, 10_000), + Retry::Attempts(0)).unwrap(); let payment_event = SendEvent::from_event($node_a.get_and_clear_pending_msg_events().pop().unwrap()); $node_b.handle_update_add_htlc(&$node_a.get_our_node_id(), &payment_event.msgs[0]); $node_b.handle_commitment_signed(&$node_a.get_our_node_id(), &payment_event.commitment_msg); diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index b8c2e0859..a43cfae9e 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -19,7 +19,7 @@ use crate::events::bump_transaction::{BumpTransactionEventHandler, Wallet, Walle use crate::ln::{ChannelId, PaymentPreimage, PaymentHash, PaymentSecret}; use crate::ln::channelmanager::{self, AChannelManager, ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, RecipientOnionFields, PaymentId, MIN_CLTV_EXPIRY_DELTA}; use crate::routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate}; -use crate::routing::router::{self, PaymentParameters, Route}; +use crate::routing::router::{self, PaymentParameters, Route, RouteParameters}; use crate::ln::features::InitFeatures; use crate::ln::msgs; use crate::ln::msgs::{ChannelMessageHandler,RoutingMessageHandler}; @@ -1838,14 +1838,14 @@ macro_rules! get_payment_preimage_hash { } /// Gets a route from the given sender to the node described in `payment_params`. -pub fn get_route(send_node: &Node, payment_params: &PaymentParameters, recv_value: u64) -> Result { +pub fn get_route(send_node: &Node, route_params: &RouteParameters) -> Result { let scorer = TestScorer::new(); let keys_manager = TestKeysInterface::new(&[0u8; 32], bitcoin::network::constants::Network::Testnet); let random_seed_bytes = keys_manager.get_secure_random_bytes(); router::get_route( - &send_node.node.get_our_node_id(), payment_params, &send_node.network_graph.read_only(), + &send_node.node.get_our_node_id(), route_params, &send_node.network_graph.read_only(), Some(&send_node.node.list_usable_channels().iter().collect::>()), - recv_value, send_node.logger, &scorer, &(), &random_seed_bytes + send_node.logger, &scorer, &(), &random_seed_bytes ) } @@ -1854,9 +1854,10 @@ pub fn get_route(send_node: &Node, payment_params: &PaymentParameters, recv_valu /// Don't use this, use the identically-named function instead. #[macro_export] macro_rules! get_route { - ($send_node: expr, $payment_params: expr, $recv_value: expr) => { - $crate::ln::functional_test_utils::get_route(&$send_node, &$payment_params, $recv_value) - } + ($send_node: expr, $payment_params: expr, $recv_value: expr) => {{ + let route_params = $crate::routing::router::RouteParameters::from_payment_params_and_value($payment_params, $recv_value); + $crate::ln::functional_test_utils::get_route(&$send_node, &route_params) + }} } #[cfg(test)] @@ -1868,9 +1869,10 @@ macro_rules! get_route_and_payment_hash { $crate::get_route_and_payment_hash!($send_node, $recv_node, payment_params, $recv_value) }}; ($send_node: expr, $recv_node: expr, $payment_params: expr, $recv_value: expr) => {{ + let route_params = $crate::routing::router::RouteParameters::from_payment_params_and_value($payment_params, $recv_value); let (payment_preimage, payment_hash, payment_secret) = $crate::ln::functional_test_utils::get_payment_preimage_hash(&$recv_node, Some($recv_value), None); - let route = $crate::ln::functional_test_utils::get_route(&$send_node, &$payment_params, $recv_value); + let route = $crate::ln::functional_test_utils::get_route(&$send_node, &route_params); (route.unwrap(), payment_hash, payment_preimage, payment_secret) }} } @@ -2464,7 +2466,8 @@ pub const TEST_FINAL_CLTV: u32 = 70; pub fn route_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash, PaymentSecret) { let payment_params = PaymentParameters::from_node_id(expected_route.last().unwrap().node.get_our_node_id(), TEST_FINAL_CLTV) .with_bolt11_features(expected_route.last().unwrap().node.invoice_features()).unwrap(); - let route = get_route(origin_node, &payment_params, recv_value).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, recv_value); + let route = get_route(origin_node, &route_params).unwrap(); assert_eq!(route.paths.len(), 1); assert_eq!(route.paths[0].hops.len(), expected_route.len()); for (node, hop) in expected_route.iter().zip(route.paths[0].hops.iter()) { @@ -2478,14 +2481,14 @@ pub fn route_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: pub fn route_over_limit<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) { let payment_params = PaymentParameters::from_node_id(expected_route.last().unwrap().node.get_our_node_id(), TEST_FINAL_CLTV) .with_bolt11_features(expected_route.last().unwrap().node.invoice_features()).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, recv_value); let network_graph = origin_node.network_graph.read_only(); let scorer = test_utils::TestScorer::new(); let seed = [0u8; 32]; let keys_manager = test_utils::TestKeysInterface::new(&seed, Network::Testnet); let random_seed_bytes = keys_manager.get_secure_random_bytes(); - let route = router::get_route( - &origin_node.node.get_our_node_id(), &payment_params, &network_graph, - None, recv_value, origin_node.logger, &scorer, &(), &random_seed_bytes).unwrap(); + let route = router::get_route(&origin_node.node.get_our_node_id(), &route_params, &network_graph, + None, origin_node.logger, &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 1); assert_eq!(route.paths[0].hops.len(), expected_route.len()); for (node, hop) in expected_route.iter().zip(route.paths[0].hops.iter()) { diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index d3401e5f0..8c71e5bd9 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -26,7 +26,7 @@ use crate::ln::channel::{DISCONNECT_PEER_AWAITING_RESPONSE_TICKS, ChannelError}; use crate::ln::{chan_utils, onion_utils}; use crate::ln::chan_utils::{OFFERED_HTLC_SCRIPT_WEIGHT, htlc_success_tx_weight, htlc_timeout_tx_weight, HTLCOutputInCommitment}; use crate::routing::gossip::{NetworkGraph, NetworkUpdate}; -use crate::routing::router::{Path, PaymentParameters, Route, RouteHop, get_route}; +use crate::routing::router::{Path, PaymentParameters, Route, RouteHop, get_route, RouteParameters}; use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, NodeFeatures}; use crate::ln::msgs; use crate::ln::msgs::{ChannelMessageHandler, RoutingMessageHandler, ErrorAction}; @@ -7137,8 +7137,11 @@ fn test_check_htlc_underpaying() { let scorer = test_utils::TestScorer::new(); let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes(); - let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV).with_bolt11_features(nodes[1].node.invoice_features()).unwrap(); - let route = get_route(&nodes[0].node.get_our_node_id(), &payment_params, &nodes[0].network_graph.read_only(), None, 10_000, nodes[0].logger, &scorer, &(), &random_seed_bytes).unwrap(); + let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), + TEST_FINAL_CLTV).with_bolt11_features(nodes[1].node.invoice_features()).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 10_000); + let route = get_route(&nodes[0].node.get_our_node_id(), &route_params, &nodes[0].network_graph.read_only(), + None, nodes[0].logger, &scorer, &(), &random_seed_bytes).unwrap(); let (_, our_payment_hash, _) = get_payment_preimage_hash!(nodes[0]); let our_payment_secret = nodes[1].node.create_inbound_payment_for_hash(our_payment_hash, Some(100_000), 7200, None).unwrap(); nodes[0].node.send_payment_with_route(&route, our_payment_hash, @@ -7394,12 +7397,14 @@ fn test_bump_penalty_txn_on_revoked_htlcs() { let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), 50).with_bolt11_features(nodes[1].node.invoice_features()).unwrap(); let scorer = test_utils::TestScorer::new(); let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes(); - let route = get_route(&nodes[0].node.get_our_node_id(), &payment_params, &nodes[0].network_graph.read_only(), None, - 3_000_000, nodes[0].logger, &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 3_000_000); + let route = get_route(&nodes[0].node.get_our_node_id(), &route_params, &nodes[0].network_graph.read_only(), None, + nodes[0].logger, &scorer, &(), &random_seed_bytes).unwrap(); let payment_preimage = send_along_route(&nodes[0], route, &[&nodes[1]], 3_000_000).0; let payment_params = PaymentParameters::from_node_id(nodes[0].node.get_our_node_id(), 50).with_bolt11_features(nodes[0].node.invoice_features()).unwrap(); - let route = get_route(&nodes[1].node.get_our_node_id(), &payment_params, &nodes[1].network_graph.read_only(), None, - 3_000_000, nodes[0].logger, &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 3_000_000); + let route = get_route(&nodes[1].node.get_our_node_id(), &route_params, &nodes[1].network_graph.read_only(), None, + nodes[0].logger, &scorer, &(), &random_seed_bytes).unwrap(); send_along_route(&nodes[1], route, &[&nodes[0]], 3_000_000); let revoked_local_txn = get_local_commitment_txn!(nodes[1], chan.2); diff --git a/lightning/src/ln/onion_route_tests.rs b/lightning/src/ln/onion_route_tests.rs index d326c1aab..469517b02 100644 --- a/lightning/src/ln/onion_route_tests.rs +++ b/lightning/src/ln/onion_route_tests.rs @@ -19,7 +19,7 @@ use crate::ln::channel::EXPIRE_PREV_CONFIG_TICKS; use crate::ln::channelmanager::{HTLCForwardInfo, FailureCode, CLTV_FAR_FAR_AWAY, DISABLE_GOSSIP_TICKS, MIN_CLTV_EXPIRY_DELTA, PendingAddHTLCInfo, PendingHTLCInfo, PendingHTLCRouting, PaymentId, RecipientOnionFields}; use crate::ln::onion_utils; use crate::routing::gossip::{NetworkUpdate, RoutingFees}; -use crate::routing::router::{get_route, PaymentParameters, Route, RouteHint, RouteHintHop}; +use crate::routing::router::{get_route, PaymentParameters, Route, RouteParameters, RouteHint, RouteHintHop}; use crate::ln::features::{InitFeatures, Bolt11InvoiceFeatures}; use crate::ln::msgs; use crate::ln::msgs::{ChannelMessageHandler, ChannelUpdate}; @@ -1048,10 +1048,11 @@ macro_rules! get_phantom_route { ])]).unwrap(); let scorer = test_utils::TestScorer::new(); let network_graph = $nodes[0].network_graph.read_only(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, $amt); (get_route( - &$nodes[0].node.get_our_node_id(), &payment_params, &network_graph, + &$nodes[0].node.get_our_node_id(), &route_params, &network_graph, Some(&$nodes[0].node.list_usable_channels().iter().collect::>()), - $amt, $nodes[0].logger, &scorer, &(), &[0u8; 32] + $nodes[0].logger, &scorer, &(), &[0u8; 32] ).unwrap(), phantom_route_hint.phantom_scid) } }} diff --git a/lightning/src/ln/outbound_payment.rs b/lightning/src/ln/outbound_payment.rs index f60bf565e..38ae89aec 100644 --- a/lightning/src/ln/outbound_payment.rs +++ b/lightning/src/ln/outbound_payment.rs @@ -1565,10 +1565,7 @@ mod tests { PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()), 0 ).with_expiry_time(past_expiry_time); - let expired_route_params = RouteParameters { - payment_params, - final_value_msat: 0, - }; + let expired_route_params = RouteParameters::from_payment_params_and_value(payment_params, 0); let pending_events = Mutex::new(VecDeque::new()); if on_retry { outbound_payments.add_new_pending_payment(PaymentHash([0; 32]), RecipientOnionFields::spontaneous_empty(), @@ -1609,10 +1606,7 @@ mod tests { let payment_params = PaymentParameters::from_node_id( PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()), 0); - let route_params = RouteParameters { - payment_params, - final_value_msat: 0, - }; + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 0); router.expect_find_route(route_params.clone(), Err(LightningError { err: String::new(), action: ErrorAction::IgnoreError })); @@ -1652,10 +1646,7 @@ mod tests { let sender_pk = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); let receiver_pk = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[43; 32]).unwrap()); let payment_params = PaymentParameters::from_node_id(sender_pk, 0); - let route_params = RouteParameters { - payment_params: payment_params.clone(), - final_value_msat: 0, - }; + let route_params = RouteParameters::from_payment_params_and_value(payment_params.clone(), 0); let failed_scid = 42; let route = Route { paths: vec![Path { hops: vec![RouteHop { diff --git a/lightning/src/ln/payment_tests.rs b/lightning/src/ln/payment_tests.rs index f0c3fa92d..f8000423b 100644 --- a/lightning/src/ln/payment_tests.rs +++ b/lightning/src/ln/payment_tests.rs @@ -94,10 +94,7 @@ fn mpp_retry() { // Initiate the MPP payment. let payment_id = PaymentId(payment_hash.0); - let mut route_params = RouteParameters { - payment_params: route.payment_params.clone().unwrap(), - final_value_msat: amt_msat, - }; + let mut route_params = RouteParameters::from_payment_params_and_value(route.payment_params.clone().unwrap(), amt_msat); nodes[0].router.expect_find_route(route_params.clone(), Ok(route.clone())); nodes[0].node.send_payment(payment_hash, RecipientOnionFields::secret_only(payment_secret), @@ -257,10 +254,8 @@ fn do_test_keysend_payments(public_node: bool, with_retry: bool) { } let payer_pubkey = nodes[0].node.get_our_node_id(); let payee_pubkey = nodes[1].node.get_our_node_id(); - let route_params = RouteParameters { - payment_params: PaymentParameters::for_keysend(payee_pubkey, 40, false), - final_value_msat: 10000, - }; + let route_params = RouteParameters::from_payment_params_and_value( + PaymentParameters::for_keysend(payee_pubkey, 40, false), 10000); let network_graph = nodes[0].network_graph.clone(); let channels = nodes[0].node.list_usable_channels(); @@ -319,10 +314,8 @@ fn test_mpp_keysend() { let payer_pubkey = nodes[0].node.get_our_node_id(); let payee_pubkey = nodes[3].node.get_our_node_id(); let recv_value = 15_000_000; - let route_params = RouteParameters { - payment_params: PaymentParameters::for_keysend(payee_pubkey, 40, true), - final_value_msat: recv_value, - }; + let route_params = RouteParameters::from_payment_params_and_value( + PaymentParameters::for_keysend(payee_pubkey, 40, true), recv_value); let scorer = test_utils::TestScorer::new(); let random_seed_bytes = chanmon_cfgs[0].keys_manager.get_secure_random_bytes(); let route = find_route(&payer_pubkey, &route_params, &network_graph, None, nodes[0].logger, @@ -531,10 +524,7 @@ fn do_retry_with_no_persist(confirm_before_reload: bool) { let amt_msat = 1_000_000; let (route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], amt_msat); let (payment_preimage_1, payment_hash_1, _, payment_id_1) = send_along_route(&nodes[0], route.clone(), &[&nodes[1], &nodes[2]], 1_000_000); - let route_params = RouteParameters { - payment_params: route.payment_params.clone().unwrap(), - final_value_msat: amt_msat, - }; + let route_params = RouteParameters::from_payment_params_and_value(route.payment_params.clone().unwrap(), amt_msat); nodes[0].node.send_payment(payment_hash, RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap(); check_added_monitors!(nodes[0], 1); @@ -1111,10 +1101,11 @@ fn get_ldk_payment_preimage() { let scorer = test_utils::TestScorer::new(); let keys_manager = test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet); let random_seed_bytes = keys_manager.get_secure_random_bytes(); - let route = get_route( - &nodes[0].node.get_our_node_id(), &payment_params, &nodes[0].network_graph.read_only(), - Some(&nodes[0].node.list_usable_channels().iter().collect::>()), - amt_msat, nodes[0].logger, &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, amt_msat); + let route = get_route( &nodes[0].node.get_our_node_id(), &route_params, + &nodes[0].network_graph.read_only(), + Some(&nodes[0].node.list_usable_channels().iter().collect::>()), nodes[0].logger, + &scorer, &(), &random_seed_bytes).unwrap(); nodes[0].node.send_payment_with_route(&route, payment_hash, RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0)).unwrap(); check_added_monitors!(nodes[0], 1); @@ -1224,7 +1215,7 @@ fn failed_probe_yields_event() { let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), 42); - let (route, _, _, _) = get_route_and_payment_hash!(&nodes[0], nodes[2], &payment_params, 9_998_000); + let (route, _, _, _) = get_route_and_payment_hash!(&nodes[0], nodes[2], payment_params, 9_998_000); let (payment_hash, payment_id) = nodes[0].node.send_probe(route.paths[0].clone()).unwrap(); @@ -1273,7 +1264,7 @@ fn onchain_failed_probe_yields_event() { let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), 42); // Send a dust HTLC, which will be treated as if it timed out once the channel hits the chain. - let (route, _, _, _) = get_route_and_payment_hash!(&nodes[0], nodes[2], &payment_params, 1_000); + let (route, _, _, _) = get_route_and_payment_hash!(&nodes[0], nodes[2], payment_params, 1_000); let (payment_hash, payment_id) = nodes[0].node.send_probe(route.paths[0].clone()).unwrap(); // node[0] -- update_add_htlcs -> node[1] @@ -1661,15 +1652,10 @@ fn do_test_intercepted_payment(test: InterceptTest) { }]) ]).unwrap() .with_bolt11_features(nodes[2].node.invoice_features()).unwrap(); - let route_params = RouteParameters { - payment_params, - final_value_msat: amt_msat, - }; - let route = get_route( - &nodes[0].node.get_our_node_id(), &route_params.payment_params, - &nodes[0].network_graph.read_only(), None, route_params.final_value_msat, - nodes[0].logger, &scorer, &(), &random_seed_bytes, - ).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, amt_msat,); + let route = get_route( &nodes[0].node.get_our_node_id(), &route_params, + &nodes[0].network_graph.read_only(), None, nodes[0].logger, &scorer, &(), + &random_seed_bytes,).unwrap(); let (payment_hash, payment_secret) = nodes[2].node.create_inbound_payment(Some(amt_msat), 60 * 60, None).unwrap(); nodes[0].node.send_payment_with_route(&route, payment_hash, @@ -1850,10 +1836,7 @@ fn do_accept_underpaying_htlcs_config(num_mpp_parts: usize) { let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV) .with_route_hints(route_hints).unwrap() .with_bolt11_features(nodes[2].node.invoice_features()).unwrap(); - let route_params = RouteParameters { - payment_params, - final_value_msat: amt_msat, - }; + let route_params = RouteParameters::from_payment_params_and_value(payment_params, amt_msat); let (payment_hash, payment_secret) = nodes[2].node.create_inbound_payment(Some(amt_msat), 60 * 60, None).unwrap(); nodes[0].node.send_payment(payment_hash, RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(0)).unwrap(); @@ -1980,10 +1963,7 @@ fn do_automatic_retries(test: AutoRetry) { let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV) .with_expiry_time(payment_expiry_secs as u64) .with_bolt11_features(invoice_features).unwrap(); - let route_params = RouteParameters { - payment_params, - final_value_msat: amt_msat, - }; + let route_params = RouteParameters::from_payment_params_and_value(payment_params, amt_msat); let (_, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], amt_msat); macro_rules! pass_failed_attempt_with_retry_along_path { @@ -2199,10 +2179,7 @@ fn auto_retry_partial_failure() { let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV) .with_expiry_time(payment_expiry_secs as u64) .with_bolt11_features(invoice_features).unwrap(); - let route_params = RouteParameters { - payment_params, - final_value_msat: amt_msat, - }; + let route_params = RouteParameters::from_payment_params_and_value(payment_params, amt_msat); // Ensure the first monitor update (for the initial send path1 over chan_1) succeeds, but the // second (for the initial send path2 over chan_2) fails. @@ -2273,14 +2250,14 @@ fn auto_retry_partial_failure() { nodes[0].router.expect_find_route(route_params.clone(), Ok(send_route)); let mut payment_params = route_params.payment_params.clone(); payment_params.previously_failed_channels.push(chan_2_id); - nodes[0].router.expect_find_route(RouteParameters { - payment_params, final_value_msat: amt_msat / 2, - }, Ok(retry_1_route)); + nodes[0].router.expect_find_route( + RouteParameters::from_payment_params_and_value(payment_params, amt_msat / 2), + Ok(retry_1_route)); let mut payment_params = route_params.payment_params.clone(); payment_params.previously_failed_channels.push(chan_3_id); - nodes[0].router.expect_find_route(RouteParameters { - payment_params, final_value_msat: amt_msat / 4, - }, Ok(retry_2_route)); + nodes[0].router.expect_find_route( + RouteParameters::from_payment_params_and_value(payment_params, amt_msat / 4), + Ok(retry_2_route)); // Send a payment that will partially fail on send, then partially fail on retry, then succeed. nodes[0].node.send_payment(payment_hash, RecipientOnionFields::secret_only(payment_secret), @@ -2416,10 +2393,7 @@ fn auto_retry_zero_attempts_send_error() { let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV) .with_expiry_time(payment_expiry_secs as u64) .with_bolt11_features(invoice_features).unwrap(); - let route_params = RouteParameters { - payment_params, - final_value_msat: amt_msat, - }; + let route_params = RouteParameters::from_payment_params_and_value(payment_params, amt_msat); chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::PermanentFailure); nodes[0].node.send_payment(payment_hash, RecipientOnionFields::secret_only(payment_secret), @@ -2456,10 +2430,7 @@ fn fails_paying_after_rejected_by_payee() { let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV) .with_expiry_time(payment_expiry_secs as u64) .with_bolt11_features(invoice_features).unwrap(); - let route_params = RouteParameters { - payment_params, - final_value_msat: amt_msat, - }; + let route_params = RouteParameters::from_payment_params_and_value(payment_params, amt_msat); nodes[0].node.send_payment(payment_hash, RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap(); @@ -2503,10 +2474,8 @@ fn retry_multi_path_single_failed_payment() { let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV) .with_expiry_time(payment_expiry_secs as u64) .with_bolt11_features(invoice_features).unwrap(); - let route_params = RouteParameters { - payment_params: payment_params.clone(), - final_value_msat: amt_msat, - }; + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), amt_msat); let chans = nodes[0].node.list_usable_channels(); let mut route = Route { @@ -2536,12 +2505,11 @@ fn retry_multi_path_single_failed_payment() { route.paths[1].hops[0].fee_msat = 50_000_000; let mut pay_params = route.payment_params.clone().unwrap(); pay_params.previously_failed_channels.push(chans[1].short_channel_id.unwrap()); - nodes[0].router.expect_find_route(RouteParameters { - payment_params: pay_params, - // Note that the second request here requests the amount we originally failed to send, - // not the amount remaining on the full payment, which should be changed. - final_value_msat: 100_000_001, - }, Ok(route.clone())); + nodes[0].router.expect_find_route( + // Note that the second request here requests the amount we originally failed to send, + // not the amount remaining on the full payment, which should be changed. + RouteParameters::from_payment_params_and_value(pay_params, 100_000_001), + Ok(route.clone())); { let scorer = chanmon_cfgs[0].scorer.read().unwrap(); @@ -2596,10 +2564,7 @@ fn immediate_retry_on_failure() { let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV) .with_expiry_time(payment_expiry_secs as u64) .with_bolt11_features(invoice_features).unwrap(); - let route_params = RouteParameters { - payment_params, - final_value_msat: amt_msat, - }; + let route_params = RouteParameters::from_payment_params_and_value(payment_params, amt_msat); let chans = nodes[0].node.list_usable_channels(); let mut route = Route { @@ -2623,9 +2588,9 @@ fn immediate_retry_on_failure() { route.paths[1].hops[0].fee_msat = 50_000_001; let mut pay_params = route_params.payment_params.clone(); pay_params.previously_failed_channels.push(chans[0].short_channel_id.unwrap()); - nodes[0].router.expect_find_route(RouteParameters { - payment_params: pay_params, final_value_msat: amt_msat, - }, Ok(route.clone())); + nodes[0].router.expect_find_route( + RouteParameters::from_payment_params_and_value(pay_params, amt_msat), + Ok(route.clone())); nodes[0].node.send_payment(payment_hash, RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap(); @@ -2684,10 +2649,7 @@ fn no_extra_retries_on_back_to_back_fail() { let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV) .with_expiry_time(payment_expiry_secs as u64) .with_bolt11_features(invoice_features).unwrap(); - let route_params = RouteParameters { - payment_params, - final_value_msat: amt_msat, - }; + let route_params = RouteParameters::from_payment_params_and_value(payment_params, amt_msat); let mut route = Route { paths: vec![ @@ -2730,10 +2692,9 @@ fn no_extra_retries_on_back_to_back_fail() { // On retry, we'll only return one path route.paths.remove(1); route.paths[0].hops[1].fee_msat = amt_msat; - nodes[0].router.expect_find_route(RouteParameters { - payment_params: second_payment_params, - final_value_msat: amt_msat, - }, Ok(route.clone())); + nodes[0].router.expect_find_route( + RouteParameters::from_payment_params_and_value(second_payment_params, amt_msat), + Ok(route.clone())); nodes[0].node.send_payment(payment_hash, RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap(); @@ -2886,10 +2847,7 @@ fn test_simple_partial_retry() { let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV) .with_expiry_time(payment_expiry_secs as u64) .with_bolt11_features(invoice_features).unwrap(); - let route_params = RouteParameters { - payment_params, - final_value_msat: amt_msat, - }; + let route_params = RouteParameters::from_payment_params_and_value(payment_params, amt_msat); let mut route = Route { paths: vec![ @@ -2931,10 +2889,9 @@ fn test_simple_partial_retry() { second_payment_params.previously_failed_channels = vec![chan_2_scid]; // On retry, we'll only be asked for one path (or 100k sats) route.paths.remove(0); - nodes[0].router.expect_find_route(RouteParameters { - payment_params: second_payment_params, - final_value_msat: amt_msat / 2, - }, Ok(route.clone())); + nodes[0].router.expect_find_route( + RouteParameters::from_payment_params_and_value(second_payment_params, amt_msat / 2), + Ok(route.clone())); nodes[0].node.send_payment(payment_hash, RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap(); @@ -3052,10 +3009,7 @@ fn test_threaded_payment_retries() { let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV) .with_expiry_time(payment_expiry_secs as u64) .with_bolt11_features(invoice_features).unwrap(); - let mut route_params = RouteParameters { - payment_params, - final_value_msat: amt_msat, - }; + let mut route_params = RouteParameters::from_payment_params_and_value(payment_params, amt_msat); let mut route = Route { paths: vec![ @@ -3303,11 +3257,10 @@ fn do_claim_from_closed_chan(fail_payment: bool) { create_announced_chan_between_nodes(&nodes, 2, 3); let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[3]); - let mut route_params = RouteParameters { - payment_params: PaymentParameters::from_node_id(nodes[3].node.get_our_node_id(), TEST_FINAL_CLTV) + let mut route_params = RouteParameters::from_payment_params_and_value( + PaymentParameters::from_node_id(nodes[3].node.get_our_node_id(), TEST_FINAL_CLTV) .with_bolt11_features(nodes[1].node.invoice_features()).unwrap(), - final_value_msat: 10_000_000, - }; + 10_000_000); let mut route = nodes[0].router.find_route(&nodes[0].node.get_our_node_id(), &route_params, None, nodes[0].node.compute_inflight_htlcs()).unwrap(); // Make sure the route is ordered as the B->D path before C->D @@ -3517,10 +3470,7 @@ fn test_retry_custom_tlvs() { // Initiate the payment let payment_id = PaymentId(payment_hash.0); - let mut route_params = RouteParameters { - payment_params: route.payment_params.clone().unwrap(), - final_value_msat: amt_msat, - }; + let mut route_params = RouteParameters::from_payment_params_and_value(route.payment_params.clone().unwrap(), amt_msat); let custom_tlvs = vec![((1 << 16) + 1, vec![0x42u8; 16])]; let onion_fields = RecipientOnionFields::secret_only(payment_secret); @@ -3772,10 +3722,7 @@ fn do_test_payment_metadata_consistency(do_reload: bool, do_modify: bool) { let payment_params = PaymentParameters::from_node_id(nodes[3].node.get_our_node_id(), TEST_FINAL_CLTV) .with_bolt11_features(nodes[1].node.invoice_features()).unwrap(); - let mut route_params = RouteParameters { - payment_params, - final_value_msat: amt_msat, - }; + let mut route_params = RouteParameters::from_payment_params_and_value(payment_params, amt_msat); // Send the MPP payment, delivering the updated commitment state to nodes[1]. nodes[0].node.send_payment(payment_hash, RecipientOnionFields { diff --git a/lightning/src/ln/shutdown_tests.rs b/lightning/src/ln/shutdown_tests.rs index f975e1841..38db58c55 100644 --- a/lightning/src/ln/shutdown_tests.rs +++ b/lightning/src/ln/shutdown_tests.rs @@ -13,7 +13,7 @@ use crate::sign::{EntropySource, SignerProvider}; use crate::chain::transaction::OutPoint; use crate::events::{Event, MessageSendEvent, MessageSendEventsProvider, ClosureReason}; use crate::ln::channelmanager::{self, PaymentSendFailure, PaymentId, RecipientOnionFields, ChannelShutdownState, ChannelDetails}; -use crate::routing::router::{PaymentParameters, get_route}; +use crate::routing::router::{PaymentParameters, get_route, RouteParameters}; use crate::ln::msgs; use crate::ln::msgs::{ChannelMessageHandler, ErrorAction}; use crate::ln::script::ShutdownScript; @@ -313,9 +313,14 @@ fn updates_shutdown_wait() { let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[0]); let payment_params_1 = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV).with_bolt11_features(nodes[1].node.invoice_features()).unwrap(); - let route_1 = get_route(&nodes[0].node.get_our_node_id(), &payment_params_1, &nodes[0].network_graph.read_only(), None, 100000, &logger, &scorer, &(), &random_seed_bytes).unwrap(); - let payment_params_2 = PaymentParameters::from_node_id(nodes[0].node.get_our_node_id(), TEST_FINAL_CLTV).with_bolt11_features(nodes[0].node.invoice_features()).unwrap(); - let route_2 = get_route(&nodes[1].node.get_our_node_id(), &payment_params_2, &nodes[1].network_graph.read_only(), None, 100000, &logger, &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params_1, 100_000); + let route_1 = get_route(&nodes[0].node.get_our_node_id(), &route_params, + &nodes[0].network_graph.read_only(), None, &logger, &scorer, &(), &random_seed_bytes).unwrap(); + let payment_params_2 = PaymentParameters::from_node_id(nodes[0].node.get_our_node_id(), + TEST_FINAL_CLTV).with_bolt11_features(nodes[0].node.invoice_features()).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params_2, 100_000); + let route_2 = get_route(&nodes[1].node.get_our_node_id(), &route_params, + &nodes[1].network_graph.read_only(), None, &logger, &scorer, &(), &random_seed_bytes).unwrap(); unwrap_send_err!(nodes[0].node.send_payment_with_route(&route_1, payment_hash, RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0) ), true, APIError::ChannelUnavailable {..}, {}); diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index a279568cd..799b64079 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -1407,19 +1407,21 @@ pub fn find_route( ) -> Result where L::Target: Logger, GL::Target: Logger { let graph_lock = network_graph.read_only(); - let mut route = get_route(our_node_pubkey, &route_params.payment_params, &graph_lock, first_hops, - route_params.final_value_msat, logger, scorer, score_params, - random_seed_bytes)?; + let mut route = get_route(our_node_pubkey, &route_params, &graph_lock, first_hops, logger, + scorer, score_params, random_seed_bytes)?; add_random_cltv_offset(&mut route, &route_params.payment_params, &graph_lock, random_seed_bytes); Ok(route) } pub(crate) fn get_route( - our_node_pubkey: &PublicKey, payment_params: &PaymentParameters, network_graph: &ReadOnlyNetworkGraph, - first_hops: Option<&[&ChannelDetails]>, final_value_msat: u64, logger: L, scorer: &S, score_params: &S::ScoreParams, + our_node_pubkey: &PublicKey, route_params: &RouteParameters, network_graph: &ReadOnlyNetworkGraph, + first_hops: Option<&[&ChannelDetails]>, logger: L, scorer: &S, score_params: &S::ScoreParams, _random_seed_bytes: &[u8; 32] ) -> Result where L::Target: Logger { + + let payment_params = &route_params.payment_params; + let final_value_msat = route_params.final_value_msat; // If we're routing to a blinded recipient, we won't have their node id. Therefore, keep the // unblinded payee id as an option. We also need a non-optional "payee id" for path construction, // so use a dummy id for this in the blinded case. @@ -2592,17 +2594,15 @@ pub fn build_route_from_hops( ) -> Result where L::Target: Logger, GL::Target: Logger { let graph_lock = network_graph.read_only(); - let mut route = build_route_from_hops_internal( - our_node_pubkey, hops, &route_params.payment_params, &graph_lock, - route_params.final_value_msat, logger, random_seed_bytes)?; + let mut route = build_route_from_hops_internal(our_node_pubkey, hops, &route_params, + &graph_lock, logger, random_seed_bytes)?; add_random_cltv_offset(&mut route, &route_params.payment_params, &graph_lock, random_seed_bytes); Ok(route) } fn build_route_from_hops_internal( - our_node_pubkey: &PublicKey, hops: &[PublicKey], payment_params: &PaymentParameters, - network_graph: &ReadOnlyNetworkGraph, final_value_msat: u64, logger: L, - random_seed_bytes: &[u8; 32] + our_node_pubkey: &PublicKey, hops: &[PublicKey], route_params: &RouteParameters, + network_graph: &ReadOnlyNetworkGraph, logger: L, random_seed_bytes: &[u8; 32], ) -> Result where L::Target: Logger { struct HopScorer { @@ -2649,8 +2649,7 @@ fn build_route_from_hops_internal( let scorer = HopScorer { our_node_id, hop_ids }; - get_route(our_node_pubkey, payment_params, network_graph, None, final_value_msat, - logger, &scorer, &(), random_seed_bytes) + get_route(our_node_pubkey, route_params, network_graph, None, logger, &scorer, &(), random_seed_bytes) } #[cfg(test)] @@ -2660,7 +2659,7 @@ mod tests { use crate::routing::utxo::UtxoResult; use crate::routing::router::{get_route, build_route_from_hops_internal, add_random_cltv_offset, default_node_features, BlindedTail, InFlightHtlcs, Path, PaymentParameters, Route, RouteHint, RouteHintHop, RouteHop, RoutingFees, - DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA, MAX_PATH_LENGTH_ESTIMATE}; + DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA, MAX_PATH_LENGTH_ESTIMATE, RouteParameters}; use crate::routing::scoring::{ChannelUsage, FixedPenaltyScorer, ScoreLookUp, ProbabilisticScorer, ProbabilisticScoringFeeParameters, ProbabilisticScoringDecayParameters}; use crate::routing::test_utils::{add_channel, add_or_update_node, build_graph, build_line_graph, id_to_feature_flags, get_nodes, update_channel}; use crate::chain::transaction::OutPoint; @@ -2743,11 +2742,17 @@ mod tests { // Simple route to 2 via 1 - if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 0, Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { - assert_eq!(err, "Cannot send a payment of 0 msat"); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 0); + if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, + &route_params, &network_graph.read_only(), None, Arc::clone(&logger), &scorer, &(), + &random_seed_bytes) { + assert_eq!(err, "Cannot send a payment of 0 msat"); } else { panic!(); } - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 100); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths[0].hops.len(), 2); assert_eq!(route.paths[0].hops[0].pubkey, nodes[1]); @@ -2778,12 +2783,15 @@ mod tests { let our_chans = vec![get_channel_details(Some(2), our_id, InitFeatures::from_le_bytes(vec![0b11]), 100000)]; - if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = - get_route(&our_id, &payment_params, &network_graph.read_only(), Some(&our_chans.iter().collect::>()), 100, Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { - assert_eq!(err, "First hop cannot have our_node_pubkey as a destination."); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 100); + if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, + &route_params, &network_graph.read_only(), Some(&our_chans.iter().collect::>()), + Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { + assert_eq!(err, "First hop cannot have our_node_pubkey as a destination."); } else { panic!(); } - - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths[0].hops.len(), 2); } @@ -2891,8 +2899,12 @@ mod tests { }); // Not possible to send 199_999_999, because the minimum on channel=2 is 200_000_000. - if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 199_999_999, Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { - assert_eq!(err, "Failed to find a path to the given destination"); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params, 199_999_999); + if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, + &route_params, &network_graph.read_only(), None, Arc::clone(&logger), &scorer, &(), + &random_seed_bytes) { + assert_eq!(err, "Failed to find a path to the given destination"); } else { panic!(); } // Lift the restriction on the first hop. @@ -2910,7 +2922,8 @@ mod tests { }); // A payment above the minimum should pass - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 199_999_999, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths[0].hops.len(), 2); } @@ -2992,7 +3005,10 @@ mod tests { excess_data: Vec::new() }); - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 60_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 60_000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); // Overpay fees to hit htlc_minimum_msat. let overpaid_fees = route.paths[0].hops[0].fee_msat + route.paths[1].hops[0].fee_msat; // TODO: this could be better balanced to overpay 10k and not 15k. @@ -3037,14 +3053,17 @@ mod tests { excess_data: Vec::new() }); - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 60_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); // Fine to overpay for htlc_minimum_msat if it allows us to save fee. assert_eq!(route.paths.len(), 1); assert_eq!(route.paths[0].hops[0].short_channel_id, 12); let fees = route.paths[0].hops[0].fee_msat; assert_eq!(fees, 5_000); - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 50_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 50_000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); // Not fine to overpay for htlc_minimum_msat if it requires paying more than fee on // the other channel. assert_eq!(route.paths.len(), 1); @@ -3089,13 +3108,19 @@ mod tests { }); // If all the channels require some features we don't understand, route should fail - if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { - assert_eq!(err, "Failed to find a path to the given destination"); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 100); + if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, + &route_params, &network_graph.read_only(), None, Arc::clone(&logger), &scorer, &(), + &random_seed_bytes) { + assert_eq!(err, "Failed to find a path to the given destination"); } else { panic!(); } // If we specify a channel to node7, that overrides our local channel view and that gets used - let our_chans = vec![get_channel_details(Some(42), nodes[7].clone(), InitFeatures::from_le_bytes(vec![0b11]), 250_000_000)]; - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), Some(&our_chans.iter().collect::>()), 100, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let our_chans = vec![get_channel_details(Some(42), nodes[7].clone(), + InitFeatures::from_le_bytes(vec![0b11]), 250_000_000)]; + let route = get_route(&our_id, &route_params, &network_graph.read_only(), + Some(&our_chans.iter().collect::>()), Arc::clone(&logger), &scorer, &(), + &random_seed_bytes).unwrap(); assert_eq!(route.paths[0].hops.len(), 2); assert_eq!(route.paths[0].hops[0].pubkey, nodes[7]); @@ -3130,13 +3155,19 @@ mod tests { add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[7], unknown_features.clone(), 1); // If all nodes require some features we don't understand, route should fail - if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { - assert_eq!(err, "Failed to find a path to the given destination"); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 100); + if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, + &route_params, &network_graph.read_only(), None, Arc::clone(&logger), &scorer, &(), + &random_seed_bytes) { + assert_eq!(err, "Failed to find a path to the given destination"); } else { panic!(); } // If we specify a channel to node7, that overrides our local channel view and that gets used - let our_chans = vec![get_channel_details(Some(42), nodes[7].clone(), InitFeatures::from_le_bytes(vec![0b11]), 250_000_000)]; - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), Some(&our_chans.iter().collect::>()), 100, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let our_chans = vec![get_channel_details(Some(42), nodes[7].clone(), + InitFeatures::from_le_bytes(vec![0b11]), 250_000_000)]; + let route = get_route(&our_id, &route_params, &network_graph.read_only(), + Some(&our_chans.iter().collect::>()), Arc::clone(&logger), &scorer, &(), + &random_seed_bytes).unwrap(); assert_eq!(route.paths[0].hops.len(), 2); assert_eq!(route.paths[0].hops[0].pubkey, nodes[7]); @@ -3168,7 +3199,9 @@ mod tests { // Route to 1 via 2 and 3 because our channel to 1 is disabled let payment_params = PaymentParameters::from_node_id(nodes[0], 42); - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 100); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths[0].hops.len(), 3); assert_eq!(route.paths[0].hops[0].pubkey, nodes[1]); @@ -3194,8 +3227,12 @@ mod tests { // If we specify a channel to node7, that overrides our local channel view and that gets used let payment_params = PaymentParameters::from_node_id(nodes[2], 42); - let our_chans = vec![get_channel_details(Some(42), nodes[7].clone(), InitFeatures::from_le_bytes(vec![0b11]), 250_000_000)]; - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), Some(&our_chans.iter().collect::>()), 100, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 100); + let our_chans = vec![get_channel_details(Some(42), nodes[7].clone(), + InitFeatures::from_le_bytes(vec![0b11]), 250_000_000)]; + let route = get_route(&our_id, &route_params, &network_graph.read_only(), + Some(&our_chans.iter().collect::>()), Arc::clone(&logger), &scorer, &(), + &random_seed_bytes).unwrap(); assert_eq!(route.paths[0].hops.len(), 2); assert_eq!(route.paths[0].hops[0].pubkey, nodes[7]); @@ -3317,14 +3354,21 @@ mod tests { let mut invalid_last_hops = last_hops_multi_private_channels(&nodes); invalid_last_hops.push(invalid_last_hop); { - let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(invalid_last_hops).unwrap(); - if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { - assert_eq!(err, "Route hint cannot have the payee as the source."); + let payment_params = PaymentParameters::from_node_id(nodes[6], 42) + .with_route_hints(invalid_last_hops).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 100); + if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, + &route_params, &network_graph.read_only(), None, Arc::clone(&logger), &scorer, &(), + &random_seed_bytes) { + assert_eq!(err, "Route hint cannot have the payee as the source."); } else { panic!(); } } - let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops_multi_private_channels(&nodes)).unwrap(); - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let payment_params = PaymentParameters::from_node_id(nodes[6], 42) + .with_route_hints(last_hops_multi_private_channels(&nodes)).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 100); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths[0].hops.len(), 5); assert_eq!(route.paths[0].hops[0].pubkey, nodes[1]); @@ -3399,8 +3443,9 @@ mod tests { let random_seed_bytes = keys_manager.get_secure_random_bytes(); // Test handling of an empty RouteHint passed in Invoice. - - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 100); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths[0].hops.len(), 5); assert_eq!(route.paths[0].hops[0].pubkey, nodes[1]); @@ -3506,7 +3551,9 @@ mod tests { excess_data: Vec::new() }); - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 100); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths[0].hops.len(), 4); assert_eq!(route.paths[0].hops[0].pubkey, nodes[1]); @@ -3578,7 +3625,9 @@ mod tests { excess_data: Vec::new() }); - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, Arc::clone(&logger), &scorer, &(), &[42u8; 32]).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 100); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &[42u8; 32]).unwrap(); assert_eq!(route.paths[0].hops.len(), 4); assert_eq!(route.paths[0].hops[0].pubkey, nodes[1]); @@ -3660,7 +3709,9 @@ mod tests { // This test shows that public routes can be present in the invoice // which would be handled in the same manner. - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 100); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths[0].hops.len(), 5); assert_eq!(route.paths[0].hops[0].pubkey, nodes[1]); @@ -3712,8 +3763,12 @@ mod tests { // Simple test with outbound channel to 4 to test that last_hops and first_hops connect let our_chans = vec![get_channel_details(Some(42), nodes[3].clone(), InitFeatures::from_le_bytes(vec![0b11]), 250_000_000)]; let mut last_hops = last_hops(&nodes); - let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops.clone()).unwrap(); - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), Some(&our_chans.iter().collect::>()), 100, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let payment_params = PaymentParameters::from_node_id(nodes[6], 42) + .with_route_hints(last_hops.clone()).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 100); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), + Some(&our_chans.iter().collect::>()), Arc::clone(&logger), &scorer, &(), + &random_seed_bytes).unwrap(); assert_eq!(route.paths[0].hops.len(), 2); assert_eq!(route.paths[0].hops[0].pubkey, nodes[3]); @@ -3733,8 +3788,12 @@ mod tests { last_hops[0].0[0].fees.base_msat = 1000; // Revert to via 6 as the fee on 8 goes up - let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops).unwrap(); - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let payment_params = PaymentParameters::from_node_id(nodes[6], 42) + .with_route_hints(last_hops).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 100); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths[0].hops.len(), 4); assert_eq!(route.paths[0].hops[0].pubkey, nodes[1]); @@ -3768,7 +3827,9 @@ mod tests { assert_eq!(route.paths[0].hops[3].channel_features.le_flags(), &Vec::::new()); // We can't learn any flags from invoices, sadly // ...but still use 8 for larger payments as 6 has a variable feerate - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 2000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 2000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths[0].hops.len(), 5); assert_eq!(route.paths[0].hops[0].pubkey, nodes[1]); @@ -3833,8 +3894,10 @@ mod tests { let random_seed_bytes = keys_manager.get_secure_random_bytes(); let logger = ln_test_utils::TestLogger::new(); let network_graph = NetworkGraph::new(Network::Testnet, &logger); - let route = get_route(&source_node_id, &payment_params, &network_graph.read_only(), - Some(&our_chans.iter().collect::>()), route_val, &logger, &scorer, &(), &random_seed_bytes); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, route_val); + let route = get_route(&source_node_id, &route_params, &network_graph.read_only(), + Some(&our_chans.iter().collect::>()), &logger, &scorer, &(), + &random_seed_bytes); route } @@ -3955,15 +4018,21 @@ mod tests { { // Attempt to route more than available results in a failure. + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 250_000_001); if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route( - &our_id, &payment_params, &network_graph.read_only(), None, 250_000_001, Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { - assert_eq!(err, "Failed to find a sufficient route to the given destination"); + &our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { + assert_eq!(err, "Failed to find a sufficient route to the given destination"); } else { panic!(); } } { // Now, attempt to route an exact amount we have should be fine. - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 250_000_000, Arc::clone(&logger), &scorer, &(),&random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 250_000_000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(),&random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 1); let path = route.paths.last().unwrap(); assert_eq!(path.hops.len(), 2); @@ -3991,15 +4060,23 @@ mod tests { { // Attempt to route more than available results in a failure. + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 200_000_001); if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route( - &our_id, &payment_params, &network_graph.read_only(), Some(&our_chans.iter().collect::>()), 200_000_001, Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { - assert_eq!(err, "Failed to find a sufficient route to the given destination"); + &our_id, &route_params, &network_graph.read_only(), + Some(&our_chans.iter().collect::>()), Arc::clone(&logger), &scorer, + &(), &random_seed_bytes) { + assert_eq!(err, "Failed to find a sufficient route to the given destination"); } else { panic!(); } } { // Now, attempt to route an exact amount we have should be fine. - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), Some(&our_chans.iter().collect::>()), 200_000_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 200_000_000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), + Some(&our_chans.iter().collect::>()), Arc::clone(&logger), &scorer, &(), + &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 1); let path = route.paths.last().unwrap(); assert_eq!(path.hops.len(), 2); @@ -4038,15 +4115,21 @@ mod tests { { // Attempt to route more than available results in a failure. + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 15_001); if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route( - &our_id, &payment_params, &network_graph.read_only(), None, 15_001, Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { - assert_eq!(err, "Failed to find a sufficient route to the given destination"); + &our_id, &route_params, &network_graph.read_only(), None, Arc::clone(&logger), + &scorer, &(), &random_seed_bytes) { + assert_eq!(err, "Failed to find a sufficient route to the given destination"); } else { panic!(); } } { // Now, attempt to route an exact amount we have should be fine. - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 15_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 15_000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 1); let path = route.paths.last().unwrap(); assert_eq!(path.hops.len(), 2); @@ -4109,15 +4192,21 @@ mod tests { { // Attempt to route more than available results in a failure. + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 15_001); if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route( - &our_id, &payment_params, &network_graph.read_only(), None, 15_001, Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { - assert_eq!(err, "Failed to find a sufficient route to the given destination"); + &our_id, &route_params, &network_graph.read_only(), None, Arc::clone(&logger), + &scorer, &(), &random_seed_bytes) { + assert_eq!(err, "Failed to find a sufficient route to the given destination"); } else { panic!(); } } { // Now, attempt to route an exact amount we have should be fine. - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 15_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 15_000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 1); let path = route.paths.last().unwrap(); assert_eq!(path.hops.len(), 2); @@ -4141,15 +4230,21 @@ mod tests { { // Attempt to route more than available results in a failure. + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 10_001); if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route( - &our_id, &payment_params, &network_graph.read_only(), None, 10_001, Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { - assert_eq!(err, "Failed to find a sufficient route to the given destination"); + &our_id, &route_params, &network_graph.read_only(), None, Arc::clone(&logger), + &scorer, &(), &random_seed_bytes) { + assert_eq!(err, "Failed to find a sufficient route to the given destination"); } else { panic!(); } } { // Now, attempt to route an exact amount we have should be fine. - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 10_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 10_000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 1); let path = route.paths.last().unwrap(); assert_eq!(path.hops.len(), 2); @@ -4253,15 +4348,21 @@ mod tests { }); { // Attempt to route more than available results in a failure. + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 60_000); if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route( - &our_id, &payment_params, &network_graph.read_only(), None, 60_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { - assert_eq!(err, "Failed to find a sufficient route to the given destination"); + &our_id, &route_params, &network_graph.read_only(), None, Arc::clone(&logger), + &scorer, &(), &random_seed_bytes) { + assert_eq!(err, "Failed to find a sufficient route to the given destination"); } else { panic!(); } } { // Now, attempt to route 49 sats (just a bit below the capacity). - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 49_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 49_000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 1); let mut total_amount_paid_msat = 0; for path in &route.paths { @@ -4274,7 +4375,10 @@ mod tests { { // Attempt to route an exact amount is also fine - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 50_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params, 50_000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 1); let mut total_amount_paid_msat = 0; for path in &route.paths { @@ -4322,7 +4426,10 @@ mod tests { }); { - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 50_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params, 50_000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 1); let mut total_amount_paid_msat = 0; for path in &route.paths { @@ -4487,8 +4594,10 @@ mod tests { { // Attempt to route more than available results in a failure. + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 300_000); if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route( - &our_id, &payment_params, &network_graph.read_only(), None, 300_000, + &our_id, &route_params, &network_graph.read_only(), None, Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { assert_eq!(err, "Failed to find a sufficient route to the given destination"); } else { panic!(); } @@ -4497,8 +4606,10 @@ mod tests { { // Attempt to route while setting max_path_count to 0 results in a failure. let zero_payment_params = payment_params.clone().with_max_path_count(0); + let route_params = RouteParameters::from_payment_params_and_value( + zero_payment_params, 100); if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route( - &our_id, &zero_payment_params, &network_graph.read_only(), None, 100, + &our_id, &route_params, &network_graph.read_only(), None, Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { assert_eq!(err, "Can't find a route with no paths allowed."); } else { panic!(); } @@ -4509,8 +4620,10 @@ mod tests { // This is the case because the minimal_value_contribution_msat would require each path // to account for 1/3 of the total value, which is violated by 2 out of 3 paths. let fail_payment_params = payment_params.clone().with_max_path_count(3); + let route_params = RouteParameters::from_payment_params_and_value( + fail_payment_params, 250_000); if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route( - &our_id, &fail_payment_params, &network_graph.read_only(), None, 250_000, + &our_id, &route_params, &network_graph.read_only(), None, Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { assert_eq!(err, "Failed to find a sufficient route to the given destination"); } else { panic!(); } @@ -4519,8 +4632,10 @@ mod tests { { // Now, attempt to route 250 sats (just a bit below the capacity). // Our algorithm should provide us with these 3 paths. - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, - 250_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 250_000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 3); let mut total_amount_paid_msat = 0; for path in &route.paths { @@ -4537,8 +4652,10 @@ mod tests { { // Attempt to route an exact amount is also fine - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, - 290_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 290_000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 3); let mut total_amount_paid_msat = 0; for path in &route.paths { @@ -4572,7 +4689,8 @@ mod tests { let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet); let random_seed_bytes = keys_manager.get_secure_random_bytes(); let config = UserConfig::default(); - let payment_params = PaymentParameters::from_node_id(nodes[3], 42).with_bolt11_features(channelmanager::provided_invoice_features(&config)).unwrap(); + let payment_params = PaymentParameters::from_node_id(nodes[3], 42) + .with_bolt11_features(channelmanager::provided_invoice_features(&config)).unwrap(); // We need a route consisting of 3 paths: // From our node to node3 via {node0, node2}, {node7, node2, node4} and {node7, node2}. @@ -4707,16 +4825,22 @@ mod tests { { // Attempt to route more than available results in a failure. + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 350_000); if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route( - &our_id, &payment_params, &network_graph.read_only(), None, 350_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { - assert_eq!(err, "Failed to find a sufficient route to the given destination"); + &our_id, &route_params, &network_graph.read_only(), None, Arc::clone(&logger), + &scorer, &(), &random_seed_bytes) { + assert_eq!(err, "Failed to find a sufficient route to the given destination"); } else { panic!(); } } { // Now, attempt to route 300 sats (exact amount we can route). // Our algorithm should provide us with these 3 paths, 100 sats each. - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 300_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params, 300_000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 3); let mut total_amount_paid_msat = 0; @@ -4877,7 +5001,10 @@ mod tests { { // Now, attempt to route 180 sats. // Our algorithm should provide us with these 2 paths. - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 180_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params, 180_000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 2); let mut total_value_transferred_msat = 0; @@ -5047,15 +5174,20 @@ mod tests { { // Attempt to route more than available results in a failure. + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 210_000); if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route( - &our_id, &payment_params, &network_graph.read_only(), None, 210_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { - assert_eq!(err, "Failed to find a sufficient route to the given destination"); + &our_id, &route_params, &network_graph.read_only(), None, Arc::clone(&logger), + &scorer, &(), &random_seed_bytes) { + assert_eq!(err, "Failed to find a sufficient route to the given destination"); } else { panic!(); } } { // Now, attempt to route 200 sats (exact amount we can route). - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 200_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 200_000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 2); let mut total_amount_paid_msat = 0; @@ -5155,7 +5287,10 @@ mod tests { // Get a route for 100 sats and check that we found the MPP route no problem and didn't // overpay at all. - let mut route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params, 100_000); + let mut route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 2); route.paths.sort_by_key(|path| path.hops[0].short_channel_id); // Paths are manually ordered ordered by SCID, so: @@ -5273,16 +5408,22 @@ mod tests { { // Attempt to route more than available results in a failure. + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 150_000); if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route( - &our_id, &payment_params, &network_graph.read_only(), None, 150_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { - assert_eq!(err, "Failed to find a sufficient route to the given destination"); + &our_id, &route_params, &network_graph.read_only(), None, Arc::clone(&logger), + &scorer, &(), &random_seed_bytes) { + assert_eq!(err, "Failed to find a sufficient route to the given destination"); } else { panic!(); } } { // Now, attempt to route 125 sats (just a bit below the capacity of 3 channels). // Our algorithm should provide us with these 3 paths. - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 125_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 125_000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 3); let mut total_amount_paid_msat = 0; for path in &route.paths { @@ -5295,7 +5436,10 @@ mod tests { { // Attempt to route without the last small cheap channel - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 90_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params, 90_000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 2); let mut total_amount_paid_msat = 0; for path in &route.paths { @@ -5434,7 +5578,10 @@ mod tests { { // Now ensure the route flows simply over nodes 1 and 4 to 6. - let route = get_route(&our_id, &payment_params, &network.read_only(), None, 10_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params, 10_000); + let route = get_route(&our_id, &route_params, &network.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 1); assert_eq!(route.paths[0].hops.len(), 3); @@ -5505,7 +5652,10 @@ mod tests { { // Now, attempt to route 90 sats, which is exactly 90 sats at the last hop, plus the // 200% fee charged channel 13 in the 1-to-2 direction. - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 90_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params, 90_000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 1); assert_eq!(route.paths[0].hops.len(), 2); @@ -5571,7 +5721,10 @@ mod tests { // Now, attempt to route 90 sats, hitting the htlc_minimum on channel 4, but // overshooting the htlc_maximum on channel 2. Thus, we should pick the (absurdly // expensive) channels 12-13 path. - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 90_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params, 90_000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 1); assert_eq!(route.paths[0].hops.len(), 2); @@ -5610,10 +5763,12 @@ mod tests { let random_seed_bytes = keys_manager.get_secure_random_bytes(); { - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), Some(&[ + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 100_000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), Some(&[ &get_channel_details(Some(3), nodes[0], channelmanager::provided_init_features(&config), 200_000), &get_channel_details(Some(2), nodes[0], channelmanager::provided_init_features(&config), 10_000), - ]), 100_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + ]), Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 1); assert_eq!(route.paths[0].hops.len(), 1); @@ -5622,10 +5777,12 @@ mod tests { assert_eq!(route.paths[0].hops[0].fee_msat, 100_000); } { - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), Some(&[ + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 100_000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), Some(&[ &get_channel_details(Some(3), nodes[0], channelmanager::provided_init_features(&config), 50_000), &get_channel_details(Some(2), nodes[0], channelmanager::provided_init_features(&config), 50_000), - ]), 100_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + ]), Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 2); assert_eq!(route.paths[0].hops.len(), 1); assert_eq!(route.paths[1].hops.len(), 1); @@ -5648,7 +5805,9 @@ mod tests { // If we have several options above the 3xpayment value threshold, we should pick the // smallest of them, avoiding further fragmenting our available outbound balance to // this node. - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), Some(&[ + let route_params = RouteParameters::from_payment_params_and_value( + payment_params, 100_000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), Some(&[ &get_channel_details(Some(2), nodes[0], channelmanager::provided_init_features(&config), 50_000), &get_channel_details(Some(3), nodes[0], channelmanager::provided_init_features(&config), 50_000), &get_channel_details(Some(5), nodes[0], channelmanager::provided_init_features(&config), 50_000), @@ -5657,7 +5816,7 @@ mod tests { &get_channel_details(Some(8), nodes[0], channelmanager::provided_init_features(&config), 50_000), &get_channel_details(Some(9), nodes[0], channelmanager::provided_init_features(&config), 50_000), &get_channel_details(Some(4), nodes[0], channelmanager::provided_init_features(&config), 1_000_000), - ]), 100_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + ]), Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 1); assert_eq!(route.paths[0].hops.len(), 1); @@ -5677,10 +5836,10 @@ mod tests { let scorer = ln_test_utils::TestScorer::new(); let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet); let random_seed_bytes = keys_manager.get_secure_random_bytes(); - let route = get_route( - &our_id, &payment_params, &network_graph.read_only(), None, 100, - Arc::clone(&logger), &scorer, &(), &random_seed_bytes - ).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 100); + let route = get_route( &our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); let path = route.paths[0].hops.iter().map(|hop| hop.short_channel_id).collect::>(); assert_eq!(route.get_total_fees(), 100); @@ -5690,10 +5849,10 @@ mod tests { // Applying a 100 msat penalty to each hop results in taking channels 7 and 10 to nodes[6] // from nodes[2] rather than channel 6, 11, and 8, even though the longer path is cheaper. let scorer = FixedPenaltyScorer::with_penalty(100); - let route = get_route( - &our_id, &payment_params, &network_graph.read_only(), None, 100, - Arc::clone(&logger), &scorer, &(), &random_seed_bytes - ).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params, 100); + let route = get_route( &our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); let path = route.paths[0].hops.iter().map(|hop| hop.short_channel_id).collect::>(); assert_eq!(route.get_total_fees(), 300); @@ -5743,10 +5902,10 @@ mod tests { let scorer = ln_test_utils::TestScorer::new(); let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet); let random_seed_bytes = keys_manager.get_secure_random_bytes(); - let route = get_route( - &our_id, &payment_params, &network_graph, None, 100, - Arc::clone(&logger), &scorer, &(), &random_seed_bytes - ).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params, 100); + let route = get_route( &our_id, &route_params, &network_graph, None, Arc::clone(&logger), + &scorer, &(), &random_seed_bytes).unwrap(); let path = route.paths[0].hops.iter().map(|hop| hop.short_channel_id).collect::>(); assert_eq!(route.get_total_fees(), 100); @@ -5755,10 +5914,8 @@ mod tests { // A different path to nodes[6] exists if channel 6 cannot be routed over. let scorer = BadChannelScorer { short_channel_id: 6 }; - let route = get_route( - &our_id, &payment_params, &network_graph, None, 100, - Arc::clone(&logger), &scorer, &(), &random_seed_bytes - ).unwrap(); + let route = get_route( &our_id, &route_params, &network_graph, None, Arc::clone(&logger), + &scorer, &(), &random_seed_bytes).unwrap(); let path = route.paths[0].hops.iter().map(|hop| hop.short_channel_id).collect::>(); assert_eq!(route.get_total_fees(), 300); @@ -5767,14 +5924,12 @@ mod tests { // A path to nodes[6] does not exist if nodes[2] cannot be routed through. let scorer = BadNodeScorer { node_id: NodeId::from_pubkey(&nodes[2]) }; - match get_route( - &our_id, &payment_params, &network_graph, None, 100, - Arc::clone(&logger), &scorer, &(), &random_seed_bytes - ) { - Err(LightningError { err, .. } ) => { - assert_eq!(err, "Failed to find a path to the given destination"); - }, - Ok(_) => panic!("Expected error"), + match get_route( &our_id, &route_params, &network_graph, None, Arc::clone(&logger), + &scorer, &(), &random_seed_bytes) { + Err(LightningError { err, .. } ) => { + assert_eq!(err, "Failed to find a path to the given destination"); + }, + Ok(_) => panic!("Expected error"), } } @@ -5863,7 +6018,10 @@ mod tests { .with_max_total_cltv_expiry_delta(feasible_max_total_cltv_delta); let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet); let random_seed_bytes = keys_manager.get_secure_random_bytes(); - let route = get_route(&our_id, &feasible_payment_params, &network_graph, None, 100, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + feasible_payment_params, 100); + let route = get_route(&our_id, &route_params, &network_graph, None, Arc::clone(&logger), + &scorer, &(), &random_seed_bytes).unwrap(); let path = route.paths[0].hops.iter().map(|hop| hop.short_channel_id).collect::>(); assert_ne!(path.len(), 0); @@ -5871,7 +6029,10 @@ mod tests { let fail_max_total_cltv_delta = 23; let fail_payment_params = PaymentParameters::from_node_id(nodes[6], 0).with_route_hints(last_hops(&nodes)).unwrap() .with_max_total_cltv_expiry_delta(fail_max_total_cltv_delta); - match get_route(&our_id, &fail_payment_params, &network_graph, None, 100, Arc::clone(&logger), &scorer, &(), &random_seed_bytes) + let route_params = RouteParameters::from_payment_params_and_value( + fail_payment_params, 100); + match get_route(&our_id, &route_params, &network_graph, None, Arc::clone(&logger), &scorer, + &(), &random_seed_bytes) { Err(LightningError { err, .. } ) => { assert_eq!(err, "Failed to find a path to the given destination"); @@ -5896,9 +6057,16 @@ mod tests { // We should be able to find a route initially, and then after we fail a few random // channels eventually we won't be able to any longer. - assert!(get_route(&our_id, &payment_params, &network_graph, None, 100, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).is_ok()); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 100); + assert!(get_route(&our_id, &route_params, &network_graph, None, Arc::clone(&logger), + &scorer, &(), &random_seed_bytes).is_ok()); loop { - if let Ok(route) = get_route(&our_id, &payment_params, &network_graph, None, 100, Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 100); + if let Ok(route) = get_route(&our_id, &route_params, &network_graph, None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes) + { for chan in route.paths[0].hops.iter() { assert!(!payment_params.previously_failed_channels.contains(&chan.short_channel_id)); } @@ -5921,15 +6089,19 @@ mod tests { // First check we can actually create a long route on this graph. let feasible_payment_params = PaymentParameters::from_node_id(nodes[18], 0); - let route = get_route(&our_id, &feasible_payment_params, &network_graph, None, 100, - Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + feasible_payment_params, 100); + let route = get_route(&our_id, &route_params, &network_graph, None, Arc::clone(&logger), + &scorer, &(), &random_seed_bytes).unwrap(); let path = route.paths[0].hops.iter().map(|hop| hop.short_channel_id).collect::>(); assert!(path.len() == MAX_PATH_LENGTH_ESTIMATE.into()); // But we can't create a path surpassing the MAX_PATH_LENGTH_ESTIMATE limit. let fail_payment_params = PaymentParameters::from_node_id(nodes[19], 0); - match get_route(&our_id, &fail_payment_params, &network_graph, None, 100, - Arc::clone(&logger), &scorer, &(), &random_seed_bytes) + let route_params = RouteParameters::from_payment_params_and_value( + fail_payment_params, 100); + match get_route(&our_id, &route_params, &network_graph, None, Arc::clone(&logger), &scorer, + &(), &random_seed_bytes) { Err(LightningError { err, .. } ) => { assert_eq!(err, "Failed to find a path to the given destination"); @@ -5948,7 +6120,10 @@ mod tests { let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops(&nodes)).unwrap(); let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet); let random_seed_bytes = keys_manager.get_secure_random_bytes(); - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 100); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 1); let cltv_expiry_deltas_before = route.paths[0].hops.iter().map(|h| h.cltv_expiry_delta).collect::>(); @@ -5982,8 +6157,10 @@ mod tests { let keys_manager = ln_test_utils::TestKeysInterface::new(&[4u8; 32], Network::Testnet); let random_seed_bytes = keys_manager.get_secure_random_bytes(); - let mut route = get_route(&our_id, &payment_params, &network_graph, None, 100, - Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 100); + let mut route = get_route(&our_id, &route_params, &network_graph, None, + Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); add_random_cltv_offset(&mut route, &payment_params, &network_graph, &random_seed_bytes); let mut path_plausibility = vec![]; @@ -6047,8 +6224,9 @@ mod tests { let payment_params = PaymentParameters::from_node_id(nodes[3], 0); let hops = [nodes[1], nodes[2], nodes[4], nodes[3]]; - let route = build_route_from_hops_internal(&our_id, &hops, &payment_params, - &network_graph, 100, Arc::clone(&logger), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 100); + let route = build_route_from_hops_internal(&our_id, &hops, &route_params, &network_graph, + Arc::clone(&logger), &random_seed_bytes).unwrap(); let route_hop_pubkeys = route.paths[0].hops.iter().map(|hop| hop.pubkey).collect::>(); assert_eq!(hops.len(), route.paths[0].hops.len()); for (idx, hop_pubkey) in hops.iter().enumerate() { @@ -6095,7 +6273,10 @@ mod tests { let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet); let random_seed_bytes = keys_manager.get_secure_random_bytes(); // 100,000 sats is less than the available liquidity on each channel, set above. - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100_000_000, Arc::clone(&logger), &scorer, &ProbabilisticScoringFeeParameters::default(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params, 100_000_000); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &ProbabilisticScoringFeeParameters::default(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 2); assert!((route.paths[0].hops[1].short_channel_id == 4 && route.paths[1].hops[1].short_channel_id == 13) || (route.paths[1].hops[1].short_channel_id == 4 && route.paths[0].hops[1].short_channel_id == 13)); @@ -6196,17 +6377,22 @@ mod tests { // Then check we can get a normal route let payment_params = PaymentParameters::from_node_id(nodes[10], 42); - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, Arc::clone(&logger), &scorer, &scorer_params,&random_seed_bytes); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params, 100); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &scorer_params, &random_seed_bytes); assert!(route.is_ok()); // Then check that we can't get a route if we ban an intermediate node. scorer_params.add_banned(&NodeId::from_pubkey(&nodes[3])); - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, Arc::clone(&logger), &scorer, &scorer_params,&random_seed_bytes); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &scorer_params, &random_seed_bytes); assert!(route.is_err()); // Finally make sure we can route again, when we remove the ban. scorer_params.remove_banned(&NodeId::from_pubkey(&nodes[3])); - let route = get_route(&our_id, &payment_params, &network_graph.read_only(), None, 100, Arc::clone(&logger), &scorer, &scorer_params,&random_seed_bytes); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &scorer_params, &random_seed_bytes); assert!(route.is_ok()); } @@ -6241,8 +6427,10 @@ mod tests { // Make sure we'll error if our route hints don't have enough liquidity according to their // htlc_maximum_msat. + let route_params = RouteParameters::from_payment_params_and_value( + payment_params, max_htlc_msat + 1); if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, - &payment_params, &netgraph, None, max_htlc_msat + 1, Arc::clone(&logger), &scorer, &(), + &route_params, &netgraph, None, Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { assert_eq!(err, "Failed to find a sufficient route to the given destination"); @@ -6254,8 +6442,10 @@ mod tests { let payment_params = PaymentParameters::from_node_id(dest_node_id, 42) .with_route_hints(vec![route_hint_1, route_hint_2]).unwrap() .with_bolt11_features(channelmanager::provided_invoice_features(&config)).unwrap(); - let route = get_route(&our_id, &payment_params, &netgraph, None, max_htlc_msat + 1, - Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params, max_htlc_msat + 1); + let route = get_route(&our_id, &route_params, &netgraph, None, Arc::clone(&logger), + &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 2); assert!(route.paths[0].hops.last().unwrap().fee_msat <= max_htlc_msat); assert!(route.paths[1].hops.last().unwrap().fee_msat <= max_htlc_msat); @@ -6308,8 +6498,10 @@ mod tests { .with_route_hints(vec![route_hint_1, route_hint_2]).unwrap() .with_bolt11_features(channelmanager::provided_invoice_features(&config)).unwrap(); - let route = get_route(&our_node_id, &payment_params, &network_graph.read_only(), - Some(&first_hop.iter().collect::>()), amt_msat, Arc::clone(&logger), &scorer, &(), + let route_params = RouteParameters::from_payment_params_and_value( + payment_params, amt_msat); + let route = get_route(&our_node_id, &route_params, &network_graph.read_only(), + Some(&first_hop.iter().collect::>()), Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 2); assert!(route.paths[0].hops.last().unwrap().fee_msat <= max_htlc_msat); @@ -6322,8 +6514,8 @@ mod tests { get_channel_details(Some(42), intermed_node_id, InitFeatures::from_le_bytes(vec![0b11]), amt_msat - 10), get_channel_details(Some(43), intermed_node_id, InitFeatures::from_le_bytes(vec![0b11]), amt_msat - 10), ]; - let route = get_route(&our_node_id, &payment_params, &network_graph.read_only(), - Some(&first_hops.iter().collect::>()), amt_msat, Arc::clone(&logger), &scorer, &(), + let route = get_route(&our_node_id, &route_params, &network_graph.read_only(), + Some(&first_hops.iter().collect::>()), Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 2); assert!(route.paths[0].hops.last().unwrap().fee_msat <= max_htlc_msat); @@ -6352,8 +6544,10 @@ mod tests { (blinded_payinfo.clone(), blinded_path.clone()), (blinded_payinfo.clone(), blinded_path.clone())]) .with_bolt12_features(bolt12_features).unwrap(); - let route = get_route(&our_node_id, &payment_params, &network_graph.read_only(), - Some(&first_hops.iter().collect::>()), amt_msat, Arc::clone(&logger), &scorer, &(), + let route_params = RouteParameters::from_payment_params_and_value( + payment_params, amt_msat); + let route = get_route(&our_node_id, &route_params, &network_graph.read_only(), + Some(&first_hops.iter().collect::>()), Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 2); assert!(route.paths[0].hops.last().unwrap().fee_msat <= max_htlc_msat); @@ -6542,9 +6736,10 @@ mod tests { features: BlindedHopFeatures::empty(), }; - let final_amt_msat = 1001; let payment_params = PaymentParameters::blinded(vec![(blinded_payinfo.clone(), blinded_path.clone())]); - let route = get_route(&our_id, &payment_params, &network_graph, None, final_amt_msat , Arc::clone(&logger), + let route_params = RouteParameters::from_payment_params_and_value( + payment_params, 1001); + let route = get_route(&our_id, &route_params, &network_graph, None, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 1); assert_eq!(route.paths[0].hops.len(), 2); @@ -6598,7 +6793,8 @@ mod tests { let payment_params = PaymentParameters::blinded(vec![ (blinded_payinfo.clone(), invalid_blinded_path.clone()), (blinded_payinfo.clone(), invalid_blinded_path_2)]); - match get_route(&our_id, &payment_params, &network_graph, None, 1001, Arc::clone(&logger), + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 1001); + match get_route(&our_id, &route_params, &network_graph, None, Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { Err(LightningError { err, .. }) => { @@ -6609,8 +6805,9 @@ mod tests { invalid_blinded_path.introduction_node_id = our_id; let payment_params = PaymentParameters::blinded(vec![(blinded_payinfo.clone(), invalid_blinded_path.clone())]); - match get_route(&our_id, &payment_params, &network_graph, None, 1001, Arc::clone(&logger), - &scorer, &(), &random_seed_bytes) + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 1001); + match get_route(&our_id, &route_params, &network_graph, None, Arc::clone(&logger), &scorer, + &(), &random_seed_bytes) { Err(LightningError { err, .. }) => { assert_eq!(err, "Cannot generate a route to blinded paths if we are the introduction node to all of them"); @@ -6621,8 +6818,9 @@ mod tests { invalid_blinded_path.introduction_node_id = ln_test_utils::pubkey(46); invalid_blinded_path.blinded_hops.clear(); let payment_params = PaymentParameters::blinded(vec![(blinded_payinfo, invalid_blinded_path)]); - match get_route(&our_id, &payment_params, &network_graph, None, 1001, Arc::clone(&logger), - &scorer, &(), &random_seed_bytes) + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 1001); + match get_route(&our_id, &route_params, &network_graph, None, Arc::clone(&logger), &scorer, + &(), &random_seed_bytes) { Err(LightningError { err, .. }) => { assert_eq!(err, "0-hop blinded path provided"); @@ -6674,8 +6872,9 @@ mod tests { let payment_params = PaymentParameters::blinded(blinded_hints.clone()) .with_bolt12_features(bolt12_features.clone()).unwrap(); - let route = get_route(&our_id, &payment_params, &network_graph, None, - 100_000, Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value(payment_params, 100_000); + let route = get_route(&our_id, &route_params, &network_graph, None, Arc::clone(&logger), + &scorer, &(), &random_seed_bytes).unwrap(); assert_eq!(route.paths.len(), 2); let mut total_amount_paid_msat = 0; for path in route.paths.into_iter() { @@ -6761,17 +6960,21 @@ mod tests { let payment_params = PaymentParameters::blinded(blinded_hints.clone()); let netgraph = network_graph.read_only(); - if let Err(LightningError { err, .. }) = get_route(&nodes[0], &payment_params, &netgraph, - Some(&first_hops.iter().collect::>()), amt_msat, Arc::clone(&logger), &scorer, &(), + let route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), amt_msat); + if let Err(LightningError { err, .. }) = get_route(&nodes[0], &route_params, &netgraph, + Some(&first_hops.iter().collect::>()), Arc::clone(&logger), &scorer, &(), &random_seed_bytes) { - assert_eq!(err, "Failed to find a path to the given destination"); + assert_eq!(err, "Failed to find a path to the given destination"); } else { panic!("Expected error") } // Sending an exact amount accounting for the blinded path fee works. let amt_minus_blinded_path_fee = amt_msat - blinded_payinfo.fee_base_msat as u64; - let route = get_route(&nodes[0], &payment_params, &netgraph, - Some(&first_hops.iter().collect::>()), amt_minus_blinded_path_fee, - Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params, amt_minus_blinded_path_fee); + let route = get_route(&nodes[0], &route_params, &netgraph, + Some(&first_hops.iter().collect::>()), Arc::clone(&logger), &scorer, &(), + &random_seed_bytes).unwrap(); assert_eq!(route.get_total_fees(), blinded_payinfo.fee_base_msat as u64); assert_eq!(route.get_total_amount(), amt_minus_blinded_path_fee); } @@ -6836,9 +7039,11 @@ mod tests { .with_bolt12_features(bolt12_features.clone()).unwrap(); let netgraph = network_graph.read_only(); - let route = get_route(&nodes[0], &payment_params, &netgraph, - Some(&first_hops.iter().collect::>()), amt_msat, - Arc::clone(&logger), &scorer, &(), &random_seed_bytes).unwrap(); + let route_params = RouteParameters::from_payment_params_and_value( + payment_params, amt_msat); + let route = get_route(&nodes[0], &route_params, &netgraph, + Some(&first_hops.iter().collect::>()), Arc::clone(&logger), &scorer, &(), + &random_seed_bytes).unwrap(); assert_eq!(route.get_total_fees(), blinded_payinfo.fee_base_msat as u64); assert_eq!(route.get_total_amount(), amt_msat); } @@ -6970,10 +7175,12 @@ pub(crate) mod bench_utils { let params = PaymentParameters::from_node_id(dst, 42) .with_bolt11_features(features.clone()).unwrap(); let first_hop = first_hop(src); - let amt = starting_amount + seed % 1_000_000; + let amt_msat = starting_amount + seed % 1_000_000; + let route_params = RouteParameters::from_payment_params_and_value( + params.clone(), amt_msat); let path_exists = - get_route(&payer, ¶ms, &graph.read_only(), Some(&[&first_hop]), - amt, &TestLogger::new(), scorer, score_params, &random_seed_bytes).is_ok(); + get_route(&payer, &route_params, &graph.read_only(), Some(&[&first_hop]), + &TestLogger::new(), scorer, score_params, &random_seed_bytes).is_ok(); if path_exists { // ...and seed the scorer with success and failure data... seed = seed.overflowing_mul(6364136223846793005).0.overflowing_add(1).0; @@ -6985,10 +7192,11 @@ pub(crate) mod bench_utils { let mpp_features = channelmanager::provided_invoice_features(&UserConfig::default()); let params = PaymentParameters::from_node_id(dst, 42) .with_bolt11_features(mpp_features).unwrap(); - - let route_res = get_route(&payer, ¶ms, &graph.read_only(), - Some(&[&first_hop]), score_amt, &TestLogger::new(), scorer, - score_params, &random_seed_bytes); + let route_params = RouteParameters::from_payment_params_and_value( + params.clone(), score_amt); + let route_res = get_route(&payer, &route_params, &graph.read_only(), + Some(&[&first_hop]), &TestLogger::new(), scorer, score_params, + &random_seed_bytes); if let Ok(route) = route_res { for path in route.paths { if seed & 0x80 == 0 { @@ -7005,7 +7213,7 @@ pub(crate) mod bench_utils { score_amt /= 100; } - route_endpoints.push((first_hop, params, amt)); + route_endpoints.push((first_hop, params, amt_msat)); break; } } @@ -7014,8 +7222,10 @@ pub(crate) mod bench_utils { // Because we've changed channel scores, it's possible we'll take different routes to the // selected destinations, possibly causing us to fail because, eg, the newly-selected path // requires a too-high CLTV delta. - route_endpoints.retain(|(first_hop, params, amt)| { - get_route(&payer, params, &graph.read_only(), Some(&[first_hop]), *amt, + route_endpoints.retain(|(first_hop, params, amt_msat)| { + let route_params = RouteParameters::from_payment_params_and_value( + params.clone(), *amt_msat); + get_route(&payer, &route_params, &graph.read_only(), Some(&[first_hop]), &TestLogger::new(), scorer, score_params, &random_seed_bytes).is_ok() }); route_endpoints.truncate(route_count); @@ -7106,7 +7316,8 @@ pub mod benches { let mut idx = 0; bench.bench_function(bench_name, |b| b.iter(|| { let (first_hop, params, amt) = &route_endpoints[idx % route_endpoints.len()]; - assert!(get_route(&payer, params, &graph.read_only(), Some(&[first_hop]), *amt, + let route_params = RouteParameters::from_payment_params_and_value(params.clone(), *amt); + assert!(get_route(&payer, &route_params, &graph.read_only(), Some(&[first_hop]), &DummyLogger{}, &scorer, score_params, &random_seed_bytes).is_ok()); idx += 1; }));