Adapt intro node forward checks test for non-intro nodes
authorValentine Wallace <vwallace@protonmail.com>
Wed, 1 Nov 2023 18:55:38 +0000 (14:55 -0400)
committerValentine Wallace <vwallace@protonmail.com>
Sun, 25 Feb 2024 22:08:45 +0000 (19:08 -0300)
lightning/src/ln/blinded_payment_tests.rs

index 2f2854a64cb4c92f708d886eb12220ec4e4418e8..75d59d0ff7f66a06813a4d63c2ebe41b3bcf261d 100644 (file)
@@ -245,28 +245,32 @@ enum ForwardCheckFail {
 
 #[test]
 fn forward_checks_failure() {
-       do_forward_checks_failure(ForwardCheckFail::InboundOnionCheck);
-       do_forward_checks_failure(ForwardCheckFail::ForwardPayloadEncodedAsReceive);
-       do_forward_checks_failure(ForwardCheckFail::OutboundChannelCheck);
+       do_forward_checks_failure(ForwardCheckFail::InboundOnionCheck, true);
+       do_forward_checks_failure(ForwardCheckFail::InboundOnionCheck, false);
+       do_forward_checks_failure(ForwardCheckFail::ForwardPayloadEncodedAsReceive, true);
+       do_forward_checks_failure(ForwardCheckFail::ForwardPayloadEncodedAsReceive, false);
+       do_forward_checks_failure(ForwardCheckFail::OutboundChannelCheck, true);
+       do_forward_checks_failure(ForwardCheckFail::OutboundChannelCheck, false);
 }
 
-fn do_forward_checks_failure(check: ForwardCheckFail) {
+fn do_forward_checks_failure(check: ForwardCheckFail, intro_fails: bool) {
        // Ensure we'll fail backwards properly if a forwarding check fails on initial update_add
        // receipt.
-       let chanmon_cfgs = create_chanmon_cfgs(3);
-       let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
-       let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
-       let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
+       let chanmon_cfgs = create_chanmon_cfgs(4);
+       let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
+       let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
+       let mut nodes = create_network(4, &node_cfgs, &node_chanmgrs);
        // We need the session priv to construct a bogus onion packet later.
        *nodes[0].keys_manager.override_random_bytes.lock().unwrap() = Some([3; 32]);
        create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0);
        let chan_upd_1_2 = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 1_000_000, 0).0.contents;
+       let chan_upd_2_3 = create_announced_chan_between_nodes_with_value(&nodes, 2, 3, 1_000_000, 0).0.contents;
 
        let amt_msat = 5000;
-       let (_, payment_hash, payment_secret) = get_payment_preimage_hash(&nodes[2], Some(amt_msat), None);
+       let (_, payment_hash, payment_secret) = get_payment_preimage_hash(&nodes[3], Some(amt_msat), None);
        let route_params = get_blinded_route_parameters(amt_msat, payment_secret,
-               nodes.iter().skip(1).map(|n| n.node.get_our_node_id()).collect(), &[&chan_upd_1_2],
-               &chanmon_cfgs[2].keys_manager);
+               nodes.iter().skip(1).map(|n| n.node.get_our_node_id()).collect(),
+               &[&chan_upd_1_2, &chan_upd_2_3], &chanmon_cfgs[3].keys_manager);
 
        let route = get_route(&nodes[0], &route_params).unwrap();
        node_cfgs[0].router.expect_find_route(route_params.clone(), Ok(route.clone()));
@@ -304,12 +308,46 @@ fn do_forward_checks_failure(check: ForwardCheckFail) {
        let mut updates_0_1 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
        let update_add = &mut updates_0_1.update_add_htlcs[0];
 
-       cause_error!(1, 2, update_add);
+       if intro_fails {
+               cause_error!(1, 2, update_add);
+       }
 
        nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &update_add);
        check_added_monitors!(nodes[1], 0);
        do_commitment_signed_dance(&nodes[1], &nodes[0], &updates_0_1.commitment_signed, true, true);
 
+       if intro_fails {
+               let mut updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
+               nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &updates.update_fail_htlcs[0]);
+               do_commitment_signed_dance(&nodes[0], &nodes[1], &updates.commitment_signed, false, false);
+               expect_payment_failed_conditions(&nodes[0], payment_hash, false,
+                       PaymentFailedConditions::new().expected_htlc_error_data(INVALID_ONION_BLINDING, &[0; 32]));
+               return
+       }
+
+       expect_pending_htlcs_forwardable!(nodes[1]);
+       check_added_monitors!(nodes[1], 1);
+
+       let mut updates_1_2 = get_htlc_update_msgs!(nodes[1], nodes[2].node.get_our_node_id());
+       let mut update_add = &mut updates_1_2.update_add_htlcs[0];
+
+       cause_error!(2, 3, update_add);
+
+       nodes[2].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &update_add);
+       check_added_monitors!(nodes[2], 0);
+       do_commitment_signed_dance(&nodes[2], &nodes[1], &updates_1_2.commitment_signed, true, true);
+
+       let mut updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
+       let update_malformed = &mut updates.update_fail_malformed_htlcs[0];
+       assert_eq!(update_malformed.failure_code, INVALID_ONION_BLINDING);
+       assert_eq!(update_malformed.sha256_of_onion, [0; 32]);
+
+       // Ensure the intro node will properly blind the error if its downstream node failed to do so.
+       update_malformed.sha256_of_onion = [1; 32];
+       update_malformed.failure_code = INVALID_ONION_BLINDING ^ 1;
+       nodes[1].node.handle_update_fail_malformed_htlc(&nodes[2].node.get_our_node_id(), update_malformed);
+       do_commitment_signed_dance(&nodes[1], &nodes[2], &updates.commitment_signed, true, false);
+
        let mut updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
        nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &updates.update_fail_htlcs[0]);
        do_commitment_signed_dance(&nodes[0], &nodes[1], &updates.commitment_signed, false, false);