From e7d370b56a88bdcb39916fb6724505437e86c10c Mon Sep 17 00:00:00 2001 From: shaavan Date: Thu, 18 Jul 2024 19:38:31 +0530 Subject: [PATCH] Introduce test for padding 1. Add test to verify blinded message and payment path padding. --- lightning/src/blinded_path/utils.rs | 10 ++++- lightning/src/ln/blinded_payment_tests.rs | 37 +++++++++++++++++++ .../src/onion_message/functional_tests.rs | 24 ++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/lightning/src/blinded_path/utils.rs b/lightning/src/blinded_path/utils.rs index 2c12619f686..ede220d3ae8 100644 --- a/lightning/src/blinded_path/utils.rs +++ b/lightning/src/blinded_path/utils.rs @@ -199,4 +199,12 @@ impl Writeable for WithPadding { self.tlvs.write(writer) } -} \ No newline at end of file +} + +#[cfg(test)] +/// Checks if all the packets in the blinded path are properly padded, ensuring they are of equal size. +pub fn is_properly_padded(path: &BlindedPath) -> bool { + let first_hop = path.blinded_hops.first().expect("BlindedPath must have at least one hop"); + let first_payload_size = first_hop.encrypted_payload.len(); + path.blinded_hops.iter().all(|hop| hop.encrypted_payload.len() == first_payload_size) +} diff --git a/lightning/src/ln/blinded_payment_tests.rs b/lightning/src/ln/blinded_payment_tests.rs index e15204e1766..66ab0da6ad1 100644 --- a/lightning/src/ln/blinded_payment_tests.rs +++ b/lightning/src/ln/blinded_payment_tests.rs @@ -8,6 +8,7 @@ // licenses. use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey}; +use crate::blinded_path::utils::is_properly_padded; use crate::blinded_path::BlindedPath; use crate::blinded_path::payment::{ForwardNode, ForwardTlvs, PaymentConstraints, PaymentContext, PaymentRelay, ReceiveTlvs}; use crate::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PaymentFailureReason}; @@ -1332,3 +1333,39 @@ fn custom_tlvs_to_blinded_path() { .with_custom_tlvs(recipient_onion_fields.custom_tlvs.clone()) ); } + +#[test] +fn blinded_payment_path_padding() { + // Make sure that for a blinded payment path, all encrypted payloads are padded to equal lengths. + let chanmon_cfgs = create_chanmon_cfgs(5); + let node_cfgs = create_node_cfgs(5, &chanmon_cfgs); + let node_chanmgrs = create_node_chanmgrs(5, &node_cfgs, &[None, None, None, None, None]); + let mut nodes = create_network(5, &node_cfgs, &node_chanmgrs); + create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0); + create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 1_000_000, 0); + let chan_upd_2_3 = create_announced_chan_between_nodes_with_value(&nodes, 2, 3, 1_000_000, 0).0.contents; + let chan_upd_3_4 = create_announced_chan_between_nodes_with_value(&nodes, 3, 4, 1_000_000, 0).0.contents; + + // Get all our nodes onto the same height so payments don't fail for CLTV violations. + connect_blocks(&nodes[0], nodes[4].best_block_info().1 - nodes[0].best_block_info().1); + connect_blocks(&nodes[1], nodes[4].best_block_info().1 - nodes[1].best_block_info().1); + connect_blocks(&nodes[2], nodes[4].best_block_info().1 - nodes[2].best_block_info().1); + assert_eq!(nodes[4].best_block_info().1, nodes[3].best_block_info().1); + + let amt_msat = 5000; + let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash(&nodes[4], Some(amt_msat), None); + + let blinded_path = blinded_payment_path(payment_secret, 1, 1_0000_0000, + nodes.iter().skip(2).map(|n| n.node.get_our_node_id()).collect(), &[&chan_upd_2_3, &chan_upd_3_4], + &chanmon_cfgs[4].keys_manager + ); + + is_properly_padded(&blinded_path.1); + + let route_params = RouteParameters::from_payment_params_and_value(PaymentParameters::blinded(vec![blinded_path]), amt_msat); + + nodes[0].node.send_payment(payment_hash, RecipientOnionFields::spontaneous_empty(), PaymentId(payment_hash.0), route_params, Retry::Attempts(0)).unwrap(); + check_added_monitors(&nodes[0], 1); + pass_along_route(&nodes[0], &[&[&nodes[1], &nodes[2], &nodes[3], &nodes[4]]], amt_msat, payment_hash, payment_secret); + claim_payment(&nodes[0], &[&nodes[1], &nodes[2], &nodes[3], &nodes[4]], payment_preimage); +} diff --git a/lightning/src/onion_message/functional_tests.rs b/lightning/src/onion_message/functional_tests.rs index 16e62bf33f4..523fbf53847 100644 --- a/lightning/src/onion_message/functional_tests.rs +++ b/lightning/src/onion_message/functional_tests.rs @@ -9,6 +9,7 @@ //! Onion message testing and test utilities live here. +use crate::blinded_path::utils::is_properly_padded; use crate::blinded_path::{BlindedPath, EmptyNodeIdLookUp}; use crate::blinded_path::message::{ForwardNode, MessageContext, OffersContext}; use crate::events::{Event, EventsProvider}; @@ -539,6 +540,29 @@ fn too_big_packet_error() { assert_eq!(err, SendError::TooBigPacket); } +#[test] +fn blinded_path_padding() { + // Make sure that for a blinded path, all encrypted payloads are padded to equal lengths. + let nodes = create_nodes(4); + let test_msg = TestCustomMessage::Pong; + + let secp_ctx = Secp256k1::new(); + let intermediate_nodes = [ + ForwardNode { node_id: nodes[1].node_id, short_channel_id: None }, + ForwardNode { node_id: nodes[2].node_id, short_channel_id: None }, + ]; + let context = MessageContext::Custom(Vec::new()); + let blinded_path = BlindedPath::new_for_message(&intermediate_nodes, nodes[3].node_id, context, &*nodes[3].entropy_source, &secp_ctx).unwrap(); + + assert!(is_properly_padded(&blinded_path)); + + let destination = Destination::BlindedPath(blinded_path); + + nodes[0].messenger.send_onion_message(test_msg, destination, None).unwrap(); + nodes[3].custom_message_handler.expect_message(TestCustomMessage::Pong); + pass_along_path(&nodes); +} + #[test] fn we_are_intro_node() { // If we are sending straight to a blinded path and we are the introduction node, we need to