]> git.bitcoin.ninja Git - rust-lightning/commitdiff
Error if clear hints are provided for blinded PaymentParams
authorValentine Wallace <vwallace@protonmail.com>
Sat, 29 Apr 2023 18:47:59 +0000 (14:47 -0400)
committerValentine Wallace <vwallace@protonmail.com>
Thu, 4 May 2023 14:50:53 +0000 (10:50 -0400)
fuzz/src/router.rs
lightning-invoice/src/payment.rs
lightning-invoice/src/utils.rs
lightning/src/ln/onion_route_tests.rs
lightning/src/ln/payment_tests.rs
lightning/src/ln/priv_short_conf_tests.rs
lightning/src/routing/router.rs

index fe6f1647f4d20c182558938b2ce475d6b7d1037b..7c09c860025f8ce084cafd854a05cf9569384335 100644 (file)
@@ -300,7 +300,7 @@ pub fn do_test<Out: test_logger::Output>(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,
index 11757be2e3a2f8399661da3b9b81d51f8457d6a6..2fc895aaed599e2070965679114313e2fbf3ab2b 100644 (file)
@@ -152,7 +152,7 @@ fn pay_invoice_using_amount<P: Deref>(
        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());
        }
index 4f421b9ecc0af095f8d45b95f9ac87c63ad7518c..109e03d0f8c94a56bb175009e47e4b2c23abfea4 100644 (file)
@@ -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(),
index 96977e690861ab5ee52f806e6659ebe52ba184c0..209d05461a839c0d296ffc8e9a414c3413b4532f 100644 (file)
@@ -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(
index f7404a7b716321c8df5598758babe1b36298794e..ecbc75b16e053adc577bc189b64d843738aa2d9b 100644 (file)
@@ -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,
index 3b56bb10af45a3ec8a8594a87a3a542a1c018771..280d967bbfa9bf0f83ecb58b6f4832d1f41e3936 100644 (file)
@@ -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());
 
index 06a36a03a73368347dd4ef8ddff6b3b6fca11fb8..17641c3da669ca159c39af0fdd57f77436cb639f 100644 (file)
@@ -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<RouteHint>) -> Self {
-               Self { payee: Payee::Clear { route_hints }, ..self }
+       pub fn with_route_hints(self, route_hints: Vec<RouteHint>) -> Result<Self, ()> {
+               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::<Vec<_>>()), 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();