From: Valentine Wallace Date: Sat, 29 Apr 2023 18:47:59 +0000 (-0400) Subject: Error if clear hints are provided for blinded PaymentParams X-Git-Tag: v0.0.116-alpha1~47^2~5 X-Git-Url: http://git.bitcoin.ninja/?a=commitdiff_plain;h=cea78f585ab710e6494111420660ef11c2ea7db5;p=rust-lightning Error if clear hints are provided for blinded PaymentParams --- diff --git a/fuzz/src/router.rs b/fuzz/src/router.rs index fe6f1647f..7c09c8600 100644 --- a/fuzz/src/router.rs +++ b/fuzz/src/router.rs @@ -300,7 +300,7 @@ pub fn do_test(data: &[u8], out: Out) { let final_cltv_expiry_delta = slice_to_be32(get_slice!(4)); let route_params = RouteParameters { payment_params: PaymentParameters::from_node_id(*target, final_cltv_expiry_delta) - .with_route_hints(last_hops.clone()), + .with_route_hints(last_hops.clone()).unwrap(), final_value_msat, }; let _ = find_route(&our_pubkey, &route_params, &net_graph, diff --git a/lightning-invoice/src/payment.rs b/lightning-invoice/src/payment.rs index 11757be2e..2fc895aae 100644 --- a/lightning-invoice/src/payment.rs +++ b/lightning-invoice/src/payment.rs @@ -152,7 +152,7 @@ fn pay_invoice_using_amount( let mut payment_params = PaymentParameters::from_node_id(invoice.recover_payee_pub_key(), invoice.min_final_cltv_expiry_delta() as u32) .with_expiry_time(expiry_time_from_unix_epoch(invoice).as_secs()) - .with_route_hints(invoice.route_hints()); + .with_route_hints(invoice.route_hints()).unwrap(); if let Some(features) = invoice.features() { payment_params = payment_params.with_features(features.clone()); } diff --git a/lightning-invoice/src/utils.rs b/lightning-invoice/src/utils.rs index 4f421b9ec..109e03d0f 100644 --- a/lightning-invoice/src/utils.rs +++ b/lightning-invoice/src/utils.rs @@ -839,7 +839,7 @@ mod test { let payment_params = PaymentParameters::from_node_id(invoice.recover_payee_pub_key(), invoice.min_final_cltv_expiry_delta() as u32) .with_features(invoice.features().unwrap().clone()) - .with_route_hints(invoice.route_hints()); + .with_route_hints(invoice.route_hints()).unwrap(); let route_params = RouteParameters { payment_params, final_value_msat: invoice.amount_milli_satoshis().unwrap(), @@ -1295,7 +1295,7 @@ mod test { let payment_params = PaymentParameters::from_node_id(invoice.recover_payee_pub_key(), invoice.min_final_cltv_expiry_delta() as u32) .with_features(invoice.features().unwrap().clone()) - .with_route_hints(invoice.route_hints()); + .with_route_hints(invoice.route_hints()).unwrap(); let params = RouteParameters { payment_params, final_value_msat: invoice.amount_milli_satoshis().unwrap(), diff --git a/lightning/src/ln/onion_route_tests.rs b/lightning/src/ln/onion_route_tests.rs index 96977e690..209d05461 100644 --- a/lightning/src/ln/onion_route_tests.rs +++ b/lightning/src/ln/onion_route_tests.rs @@ -715,7 +715,7 @@ fn do_test_onion_failure_stale_channel_update(announced_channel: bool) { }])]; let payment_params = PaymentParameters::from_node_id(*channel_to_update_counterparty, TEST_FINAL_CLTV) .with_features(nodes[2].node.invoice_features()) - .with_route_hints(hop_hints); + .with_route_hints(hop_hints).unwrap(); get_route_and_payment_hash!(nodes[0], nodes[2], payment_params, PAYMENT_AMT) }; send_along_route_with_secret(&nodes[0], route.clone(), &[&[&nodes[1], &nodes[2]]], PAYMENT_AMT, @@ -987,7 +987,7 @@ macro_rules! get_phantom_route { htlc_minimum_msat: None, htlc_maximum_msat: None, } - ])]); + ])]).unwrap(); let scorer = test_utils::TestScorer::new(); let network_graph = $nodes[0].network_graph.read_only(); (get_route( diff --git a/lightning/src/ln/payment_tests.rs b/lightning/src/ln/payment_tests.rs index f7404a7b7..ecbc75b16 100644 --- a/lightning/src/ln/payment_tests.rs +++ b/lightning/src/ln/payment_tests.rs @@ -1409,7 +1409,7 @@ fn do_test_intercepted_payment(test: InterceptTest) { htlc_minimum_msat: None, htlc_maximum_msat: None, }]) - ]) + ]).unwrap() .with_features(nodes[2].node.invoice_features()); let route_params = RouteParameters { payment_params, diff --git a/lightning/src/ln/priv_short_conf_tests.rs b/lightning/src/ln/priv_short_conf_tests.rs index 3b56bb10a..280d967bb 100644 --- a/lightning/src/ln/priv_short_conf_tests.rs +++ b/lightning/src/ln/priv_short_conf_tests.rs @@ -68,7 +68,7 @@ fn test_priv_forwarding_rejection() { let last_hops = vec![route_hint]; let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV) .with_features(nodes[2].node.invoice_features()) - .with_route_hints(last_hops); + .with_route_hints(last_hops).unwrap(); let (route, our_payment_hash, our_payment_preimage, our_payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], payment_params, 10_000); nodes[0].node.send_payment_with_route(&route, our_payment_hash, @@ -237,7 +237,7 @@ fn test_routed_scid_alias() { }])]; let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), 42) .with_features(nodes[2].node.invoice_features()) - .with_route_hints(hop_hints); + .with_route_hints(hop_hints).unwrap(); let (route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], payment_params, 100_000); assert_eq!(route.paths[0].hops[1].short_channel_id, last_hop[0].inbound_scid_alias.unwrap()); nodes[0].node.send_payment_with_route(&route, payment_hash, @@ -403,7 +403,7 @@ fn test_inbound_scid_privacy() { }])]; let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), 42) .with_features(nodes[2].node.invoice_features()) - .with_route_hints(hop_hints.clone()); + .with_route_hints(hop_hints.clone()).unwrap(); let (route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], payment_params, 100_000); assert_eq!(route.paths[0].hops[1].short_channel_id, last_hop[0].inbound_scid_alias.unwrap()); nodes[0].node.send_payment_with_route(&route, payment_hash, @@ -419,7 +419,7 @@ fn test_inbound_scid_privacy() { let payment_params_2 = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), 42) .with_features(nodes[2].node.invoice_features()) - .with_route_hints(hop_hints); + .with_route_hints(hop_hints).unwrap(); let (route_2, payment_hash_2, _, payment_secret_2) = get_route_and_payment_hash!(nodes[0], nodes[2], payment_params_2, 100_000); assert_eq!(route_2.paths[0].hops[1].short_channel_id, last_hop[0].short_channel_id.unwrap()); nodes[0].node.send_payment_with_route(&route_2, payment_hash_2, @@ -471,7 +471,7 @@ fn test_scid_alias_returned() { }])]; let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), 42) .with_features(nodes[2].node.invoice_features()) - .with_route_hints(hop_hints); + .with_route_hints(hop_hints).unwrap(); let (mut route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], payment_params, 10_000); assert_eq!(route.paths[0].hops[1].short_channel_id, nodes[2].node.list_usable_channels()[0].inbound_scid_alias.unwrap()); diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index 06a36a03a..17641c3da 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -637,11 +637,16 @@ impl PaymentParameters { Self { features: Some(features), ..self } } - /// Includes hints for routing to the payee. + /// Includes hints for routing to the payee. Errors if the parameters were initialized with + /// blinded payment paths. /// /// This is not exported to bindings users since bindings don't support move semantics - pub fn with_route_hints(self, route_hints: Vec) -> Self { - Self { payee: Payee::Clear { route_hints }, ..self } + pub fn with_route_hints(self, route_hints: Vec) -> Result { + match self.payee { + Payee::Blinded { .. } => Err(()), + Payee::Clear { .. } => + Ok(Self { payee: Payee::Clear { route_hints }, ..self }) + } } /// Includes a payment expiration in seconds relative to the UNIX epoch. @@ -2934,13 +2939,13 @@ 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); + 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."); } else { panic!(); } } - let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops_multi_private_channels(&nodes)); + 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(); assert_eq!(route.paths[0].hops.len(), 5); @@ -3010,7 +3015,7 @@ mod tests { fn ignores_empty_last_hops_test() { let (secp_ctx, network_graph, _, _, logger) = build_graph(); let (_, our_id, _, nodes) = get_nodes(&secp_ctx); - let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(empty_last_hop(&nodes)); + let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(empty_last_hop(&nodes)).unwrap(); 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(); @@ -3090,7 +3095,7 @@ mod tests { let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph(); let (_, our_id, privkeys, nodes) = get_nodes(&secp_ctx); let last_hops = multi_hop_last_hops_hint([nodes[2], nodes[3]]); - let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops.clone()); + let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops.clone()).unwrap(); 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(); @@ -3164,7 +3169,7 @@ mod tests { let non_announced_pubkey = PublicKey::from_secret_key(&secp_ctx, &non_announced_privkey); let last_hops = multi_hop_last_hops_hint([nodes[2], non_announced_pubkey]); - let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops.clone()); + let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops.clone()).unwrap(); let scorer = ln_test_utils::TestScorer::new(); // Test through channels 2, 3, 0xff00, 0xff01. // Test shows that multiple hop hints are considered. @@ -3270,7 +3275,7 @@ mod tests { fn last_hops_with_public_channel_test() { let (secp_ctx, network_graph, _, _, logger) = build_graph(); let (_, our_id, _, nodes) = get_nodes(&secp_ctx); - let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops_with_public_channel(&nodes)); + let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops_with_public_channel(&nodes)).unwrap(); 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(); @@ -3329,7 +3334,7 @@ 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()); + 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(); assert_eq!(route.paths[0].hops.len(), 2); @@ -3350,7 +3355,7 @@ 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); + 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(); assert_eq!(route.paths[0].hops.len(), 4); @@ -3443,7 +3448,7 @@ mod tests { htlc_minimum_msat: None, htlc_maximum_msat: last_hop_htlc_max, }]); - let payment_params = PaymentParameters::from_node_id(target_node_id, 42).with_route_hints(vec![last_hops]); + let payment_params = PaymentParameters::from_node_id(target_node_id, 42).with_route_hints(vec![last_hops]).unwrap(); let our_chans = vec![get_channel_details(Some(42), middle_node_id, InitFeatures::from_le_bytes(vec![0b11]), outbound_capacity_msat)]; let scorer = ln_test_utils::TestScorer::new(); let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet); @@ -4644,7 +4649,7 @@ mod tests { cltv_expiry_delta: 42, htlc_minimum_msat: None, htlc_maximum_msat: None, - }])]).with_max_channel_saturation_power_of_half(0); + }])]).unwrap().with_max_channel_saturation_power_of_half(0); // Keep only two paths from us to nodes[2], both with a 99sat HTLC maximum, with one with // no fee and one with a 1msat fee. Previously, trying to route 100 sats to nodes[2] here @@ -5218,7 +5223,7 @@ mod tests { fn prefers_shorter_route_with_higher_fees() { let (secp_ctx, network_graph, _, _, logger) = build_graph(); let (_, our_id, _, nodes) = get_nodes(&secp_ctx); - let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops(&nodes)); + let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops(&nodes)).unwrap(); // Without penalizing each hop 100 msats, a longer path with lower fees is chosen. let scorer = ln_test_utils::TestScorer::new(); @@ -5291,7 +5296,7 @@ mod tests { fn avoids_routing_through_bad_channels_and_nodes() { let (secp_ctx, network, _, _, logger) = build_graph(); let (_, our_id, _, nodes) = get_nodes(&secp_ctx); - let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops(&nodes)); + let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops(&nodes)).unwrap(); let network_graph = network.read_only(); // A path to nodes[6] exists when no penalties are applied to any channel. @@ -5414,7 +5419,7 @@ mod tests { // Make sure that generally there is at least one route available let feasible_max_total_cltv_delta = 1008; - let feasible_payment_params = PaymentParameters::from_node_id(nodes[6], 0).with_route_hints(last_hops(&nodes)) + let feasible_payment_params = PaymentParameters::from_node_id(nodes[6], 0).with_route_hints(last_hops(&nodes)).unwrap() .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(); @@ -5424,7 +5429,7 @@ mod tests { // But not if we exclude all paths on the basis of their accumulated CLTV delta let fail_max_total_cltv_delta = 23; - let fail_payment_params = PaymentParameters::from_node_id(nodes[6], 0).with_route_hints(last_hops(&nodes)) + 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) { @@ -5444,7 +5449,7 @@ mod tests { let network_graph = network.read_only(); let scorer = ln_test_utils::TestScorer::new(); - let mut payment_params = PaymentParameters::from_node_id(nodes[6], 0).with_route_hints(last_hops(&nodes)) + let mut payment_params = PaymentParameters::from_node_id(nodes[6], 0).with_route_hints(last_hops(&nodes)).unwrap() .with_max_path_count(1); let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet); let random_seed_bytes = keys_manager.get_secure_random_bytes(); @@ -5500,7 +5505,7 @@ mod tests { let scorer = ln_test_utils::TestScorer::new(); - let payment_params = PaymentParameters::from_node_id(nodes[6], 42).with_route_hints(last_hops(&nodes)); + 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();