-
Notifications
You must be signed in to change notification settings - Fork 411
Add onion message blinded control tlv payload padding #1771
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,9 +13,11 @@ use bitcoin::secp256k1::{self, PublicKey, Secp256k1, SecretKey}; | |
|
||
use chain::keysinterface::KeysInterface; | ||
use super::utils; | ||
use ::get_control_tlv_length; | ||
use ln::msgs::DecodeError; | ||
use util::chacha20poly1305rfc::ChaChaPolyWriteAdapter; | ||
use util::ser::{Readable, VecWriter, Writeable, Writer}; | ||
use super::packet::{ControlTlvs, Padding}; | ||
|
||
use io; | ||
use prelude::*; | ||
|
@@ -54,10 +56,11 @@ impl BlindedRoute { | |
/// will be the destination node. | ||
/// | ||
/// Errors if less than two hops are provided or if `node_pk`(s) are invalid. | ||
// TODO: make all payloads the same size with padding + add dummy hops | ||
pub fn new<K: KeysInterface, T: secp256k1::Signing + secp256k1::Verification> | ||
(node_pks: &[PublicKey], keys_manager: &K, secp_ctx: &Secp256k1<T>) -> Result<Self, ()> | ||
{ | ||
// TODO: Add dummy hops | ||
pub fn new<K: KeysInterface, T: secp256k1::Signing + secp256k1::Verification> ( | ||
node_pks: &[PublicKey], keys_manager: &K, secp_ctx: &Secp256k1<T>, | ||
include_next_blinding_override_padding: bool | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Think we can get rid of this parameter, we should only need to make the blinded hops equal length for the sake of the sender not being able to tell which hop is the last But based on the spec test vectors I can see why you added this. Asked Rusty to clarify: https://github.com/lightning/bolts/pull/759/files#r997283120 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice, thanks for asking :)! IIUC another case where we also need to support padding for next blinding override in blinded There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I've always disagreed with that spec wording, bc that just means sending from a list of unblinded hops to a blinded route (i.e. |
||
) -> Result<Self, ()> { | ||
if node_pks.len() < 2 { return Err(()) } | ||
let blinding_secret_bytes = keys_manager.get_secure_random_bytes(); | ||
let blinding_secret = SecretKey::from_slice(&blinding_secret_bytes[..]).expect("RNG is busted"); | ||
|
@@ -66,16 +69,18 @@ impl BlindedRoute { | |
Ok(BlindedRoute { | ||
introduction_node_id, | ||
blinding_point: PublicKey::from_secret_key(secp_ctx, &blinding_secret), | ||
blinded_hops: blinded_hops(secp_ctx, node_pks, &blinding_secret).map_err(|_| ())?, | ||
blinded_hops: blinded_hops(secp_ctx, node_pks, &blinding_secret, include_next_blinding_override_padding).map_err(|_| ())?, | ||
}) | ||
} | ||
} | ||
|
||
/// Construct blinded hops for the given `unblinded_path`. | ||
fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>( | ||
secp_ctx: &Secp256k1<T>, unblinded_path: &[PublicKey], session_priv: &SecretKey | ||
secp_ctx: &Secp256k1<T>, unblinded_path: &[PublicKey], session_priv: &SecretKey, | ||
include_next_blinding_override_padding: bool | ||
) -> Result<Vec<BlindedHop>, secp256k1::Error> { | ||
let mut blinded_hops = Vec::with_capacity(unblinded_path.len()); | ||
let max_length = get_control_tlv_length!(true, include_next_blinding_override_padding); | ||
|
||
let mut prev_ss_and_blinded_node_id = None; | ||
utils::construct_keys_callback(secp_ctx, unblinded_path, None, session_priv, |blinded_node_id, _, _, encrypted_payload_ss, unblinded_pk, _| { | ||
|
@@ -84,6 +89,7 @@ fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>( | |
let payload = ForwardTlvs { | ||
next_node_id: pk, | ||
next_blinding_override: None, | ||
total_length: max_length, | ||
}; | ||
blinded_hops.push(BlindedHop { | ||
blinded_node_id: prev_blinded_node_id, | ||
|
@@ -95,7 +101,7 @@ fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>( | |
})?; | ||
|
||
if let Some((final_ss, final_blinded_node_id)) = prev_ss_and_blinded_node_id { | ||
let final_payload = ReceiveTlvs { path_id: None }; | ||
let final_payload = ReceiveTlvs { path_id: None, total_length: max_length, }; | ||
blinded_hops.push(BlindedHop { | ||
blinded_node_id: final_blinded_node_id, | ||
encrypted_payload: encrypt_payload(final_payload, final_ss), | ||
|
@@ -150,39 +156,171 @@ impl_writeable!(BlindedHop, { | |
|
||
/// TLVs to encode in an intermediate onion message packet's hop data. When provided in a blinded | ||
/// route, they are encoded into [`BlindedHop::encrypted_payload`]. | ||
#[derive(Clone, Copy)] | ||
pub(crate) struct ForwardTlvs { | ||
/// The node id of the next hop in the onion message's path. | ||
pub(super) next_node_id: PublicKey, | ||
/// Senders to a blinded route use this value to concatenate the route they find to the | ||
/// introduction node with the blinded route. | ||
pub(super) next_blinding_override: Option<PublicKey>, | ||
/// The length the tlv should have when it's serialized, with padding included if needed. | ||
/// Used to ensure that all control tlvs in a blinded route have the same length. | ||
pub(super) total_length: u16, | ||
} | ||
|
||
/// Similar to [`ForwardTlvs`], but these TLVs are for the final node. | ||
#[derive(Clone, Copy)] | ||
pub(crate) struct ReceiveTlvs { | ||
/// If `path_id` is `Some`, it is used to identify the blinded route that this onion message is | ||
/// sending to. This is useful for receivers to check that said blinded route is being used in | ||
/// the right context. | ||
pub(super) path_id: Option<[u8; 32]>, | ||
/// The length the tlv should have when it's serialized, with padding included if needed. | ||
/// Used to ensure that all control tlvs in a blinded route have the same length. | ||
pub(super) total_length: u16, | ||
} | ||
|
||
impl Writeable for ForwardTlvs { | ||
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> { | ||
// TODO: write padding | ||
encode_tlv_stream!(writer, { | ||
(1, Padding::new_from_tlv(ControlTlvs::Forward(*self)), option), | ||
(4, self.next_node_id, required), | ||
(8, self.next_blinding_override, option) | ||
(8, self.next_blinding_override, option), | ||
}); | ||
Ok(()) | ||
} | ||
} | ||
|
||
impl Writeable for ReceiveTlvs { | ||
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> { | ||
// TODO: write padding | ||
encode_tlv_stream!(writer, { | ||
(1, Padding::new_from_tlv(ControlTlvs::Receive(*self)), option), | ||
(6, self.path_id, option), | ||
}); | ||
Ok(()) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod test { | ||
use bitcoin::secp256k1::{PublicKey, SecretKey, Secp256k1}; | ||
use ::get_control_tlv_length; | ||
use super::{ForwardTlvs, ReceiveTlvs, blinded_hops}; | ||
use util::ser::{VecWriter, Writeable}; | ||
|
||
#[test] | ||
fn padding_is_correctly_serialized() { | ||
let max_length = get_control_tlv_length!(true, true); | ||
|
||
let dummy_next_node_id = PublicKey::from_slice(&hex::decode("030101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap(); | ||
let dummy_blinding_override = PublicKey::from_slice(&hex::decode("030202020202020202020202020202020202020202020202020202020202020202").unwrap()[..]).unwrap(); | ||
let dummy_path_id = [1; 32]; | ||
|
||
let no_padding_tlv = ForwardTlvs { | ||
next_node_id: dummy_next_node_id, | ||
next_blinding_override: Some(dummy_blinding_override), | ||
total_length: max_length, | ||
}; | ||
|
||
let blinding_override_padding_tlv = ForwardTlvs { | ||
next_node_id: dummy_next_node_id, | ||
next_blinding_override: None, | ||
total_length: max_length, | ||
}; | ||
|
||
let recieve_tlv_padding_tlv = ReceiveTlvs { | ||
path_id: Some(dummy_path_id), | ||
total_length: max_length, | ||
}; | ||
|
||
let full_padding_tlv = ReceiveTlvs { | ||
path_id: None, | ||
total_length: max_length, | ||
}; | ||
|
||
let mut w = VecWriter(Vec::new()); | ||
no_padding_tlv.write(&mut w).unwrap(); | ||
let serialized_no_padding_tlv = w.0; | ||
// As `serialized_no_padding_tlv` is the longest tlv, no padding is expected. | ||
// Expected data tlv is: | ||
// 1. 4 (type) for `next_node_id` | ||
// 2. 33 (length) for the length of a point/public key | ||
// 3. 33 bytes of the `dummy_next_node_id` | ||
// 4. 8 (type) for `next_blinding_override` | ||
// 5. 33 (length) for the length of a point/public key | ||
// 6. 33 bytes of the `dummy_blinding_override` | ||
let expected_serialized_no_padding_tlv_payload = &hex::decode("04210301010101010101010101010101010101010101010101010101010101010101010821030202020202020202020202020202020202020202020202020202020202020202").unwrap()[..]; | ||
assert_eq!(serialized_no_padding_tlv, expected_serialized_no_padding_tlv_payload); | ||
assert_eq!(serialized_no_padding_tlv.len(), max_length as usize); | ||
|
||
w = VecWriter(Vec::new()); | ||
blinding_override_padding_tlv.write(&mut w).unwrap(); | ||
let serialized_blinding_override_padding_tlv = w.0; | ||
// As `serialized_blinding_override_padding_tlv` has no `next_blinding_override`, 35 bytes | ||
// of padding is expected (the serialized length of `next_blinding_override`). | ||
// Expected data tlv is: | ||
// 1. 1 (type) for padding | ||
// 2. 33 (length) given the length of a the missing `next_blinding_override` | ||
// 3. 33 0 bytes of padding | ||
// 4. 4 (type) for `next_node_id` | ||
// 5. 33 (length) for the length of a point/public key | ||
// 6. 33 bytes of the `dummy_next_node_id` | ||
let expected_serialized_blinding_override_padding_tlv = &hex::decode("01210000000000000000000000000000000000000000000000000000000000000000000421030101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]; | ||
assert_eq!(serialized_blinding_override_padding_tlv, expected_serialized_blinding_override_padding_tlv); | ||
assert_eq!(serialized_blinding_override_padding_tlv.len(), max_length as usize); | ||
|
||
w = VecWriter(Vec::new()); | ||
recieve_tlv_padding_tlv.write(&mut w).unwrap(); | ||
let serialized_recieve_tlv_padding_tlv = w.0; | ||
// As `recieve_tlv_padding_tlv` is a `ReceiveTlv` and has a `path_id`, 36 bytes of padding | ||
// is expected, ie. 70 (value of `max_length`) - 34 (the serialized length of `path_id`). | ||
// Expected data tlv is: | ||
// 1. 1 (type) for padding | ||
// 2. 34 (length) given 70 - 34 | ||
// 3. 34 0 bytes of padding | ||
// 4. 6 (type) for `path_id` | ||
// 5. 32 (length) for the length of a `path_id` | ||
// 6. 32 bytes of the `path_id` | ||
let expected_serialized_recieve_tlv_padding_tlv_payload = &hex::decode("01220000000000000000000000000000000000000000000000000000000000000000000006200101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]; | ||
assert_eq!(serialized_recieve_tlv_padding_tlv, expected_serialized_recieve_tlv_padding_tlv_payload); | ||
assert_eq!(serialized_recieve_tlv_padding_tlv.len(), max_length as usize); | ||
|
||
w = VecWriter(Vec::new()); | ||
full_padding_tlv.write(&mut w).unwrap(); | ||
let serialized_full_padding_tlv = w.0; | ||
// As `serialized_full_padding_tlv` is a `ReceiveTlv` with no data at alll, 70 bytes of | ||
// padding is expected (value of `max_length`). | ||
// Expected data tlv is: | ||
// 1. 1 (type) for padding | ||
// 2. 68 (length) the length of the padding minus the prefix | ||
// 3. 68 0 bytes of padding | ||
let expected_serialized_full_padding_tlv_payload = &hex::decode("01440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap()[..]; | ||
assert_eq!(serialized_full_padding_tlv, expected_serialized_full_padding_tlv_payload); | ||
assert_eq!(serialized_full_padding_tlv.len(), max_length as usize); | ||
} | ||
|
||
#[test] | ||
fn blinded_hops_are_same_length() { | ||
let secp_ctx = Secp256k1::new(); | ||
let first_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&hex::decode(format!("{:02}", 41).repeat(32)).unwrap()[..]).unwrap()); | ||
let middle_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&hex::decode(format!("{:02}", 42).repeat(32)).unwrap()[..]).unwrap()); | ||
let recieve_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&hex::decode(format!("{:02}", 43).repeat(32)).unwrap()[..]).unwrap()); | ||
let session_priv = SecretKey::from_slice(&hex::decode(format!("{:02}", 3).repeat(32)).unwrap()[..]).unwrap(); | ||
|
||
let blinded_hops = blinded_hops(&secp_ctx, &[first_node_id, middle_node_id, recieve_node_id], &session_priv, false).unwrap(); | ||
|
||
// Verify that the blinded hops returned from `blinded_hops` have the same | ||
// `encrypted_payload` length, regardless of which type of payload it is. | ||
let mut expected_encrypted_payload_len = None; | ||
for blinded_hop in blinded_hops { | ||
match expected_encrypted_payload_len { | ||
None => { | ||
expected_encrypted_payload_len = Some(blinded_hop.encrypted_payload.len()); | ||
}, | ||
Some(expected_len) => { | ||
assert_eq!(blinded_hop.encrypted_payload.len(), expected_len) | ||
} | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,11 +13,13 @@ use chain::keysinterface::{KeysInterface, Recipient}; | |
use ln::features::InitFeatures; | ||
use ln::msgs::{self, OnionMessageHandler}; | ||
use super::{BlindedRoute, Destination, OnionMessenger, SendError}; | ||
use super::messenger::packet_payloads_and_keys; | ||
use super::packet::{Payload, ForwardControlTlvs, ReceiveControlTlvs}; | ||
use util::enforcing_trait_impls::EnforcingSigner; | ||
use util::test_utils; | ||
|
||
use bitcoin::network::constants::Network; | ||
use bitcoin::secp256k1::{PublicKey, Secp256k1}; | ||
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey}; | ||
|
||
use sync::Arc; | ||
|
||
|
@@ -98,7 +100,7 @@ fn two_unblinded_two_blinded() { | |
let nodes = create_nodes(5); | ||
|
||
let secp_ctx = Secp256k1::new(); | ||
let blinded_route = BlindedRoute::new(&[nodes[3].get_node_pk(), nodes[4].get_node_pk()], &*nodes[4].keys_manager, &secp_ctx).unwrap(); | ||
let blinded_route = BlindedRoute::new(&[nodes[3].get_node_pk(), nodes[4].get_node_pk()], &*nodes[4].keys_manager, &secp_ctx, true).unwrap(); | ||
|
||
nodes[0].messenger.send_onion_message(&[nodes[1].get_node_pk(), nodes[2].get_node_pk()], Destination::BlindedRoute(blinded_route), None).unwrap(); | ||
pass_along_path(&nodes, None); | ||
|
@@ -109,7 +111,7 @@ fn three_blinded_hops() { | |
let nodes = create_nodes(4); | ||
|
||
let secp_ctx = Secp256k1::new(); | ||
let blinded_route = BlindedRoute::new(&[nodes[1].get_node_pk(), nodes[2].get_node_pk(), nodes[3].get_node_pk()], &*nodes[3].keys_manager, &secp_ctx).unwrap(); | ||
let blinded_route = BlindedRoute::new(&[nodes[1].get_node_pk(), nodes[2].get_node_pk(), nodes[3].get_node_pk()], &*nodes[3].keys_manager, &secp_ctx, true).unwrap(); | ||
|
||
nodes[0].messenger.send_onion_message(&[], Destination::BlindedRoute(blinded_route), None).unwrap(); | ||
pass_along_path(&nodes, None); | ||
|
@@ -133,13 +135,13 @@ fn invalid_blinded_route_error() { | |
|
||
// 0 hops | ||
let secp_ctx = Secp256k1::new(); | ||
let mut blinded_route = BlindedRoute::new(&[nodes[1].get_node_pk(), nodes[2].get_node_pk()], &*nodes[2].keys_manager, &secp_ctx).unwrap(); | ||
let mut blinded_route = BlindedRoute::new(&[nodes[1].get_node_pk(), nodes[2].get_node_pk()], &*nodes[2].keys_manager, &secp_ctx, true).unwrap(); | ||
blinded_route.blinded_hops.clear(); | ||
let err = nodes[0].messenger.send_onion_message(&[], Destination::BlindedRoute(blinded_route), None).unwrap_err(); | ||
assert_eq!(err, SendError::TooFewBlindedHops); | ||
|
||
// 1 hop | ||
let mut blinded_route = BlindedRoute::new(&[nodes[1].get_node_pk(), nodes[2].get_node_pk()], &*nodes[2].keys_manager, &secp_ctx).unwrap(); | ||
let mut blinded_route = BlindedRoute::new(&[nodes[1].get_node_pk(), nodes[2].get_node_pk()], &*nodes[2].keys_manager, &secp_ctx, true).unwrap(); | ||
blinded_route.blinded_hops.remove(0); | ||
assert_eq!(blinded_route.blinded_hops.len(), 1); | ||
let err = nodes[0].messenger.send_onion_message(&[], Destination::BlindedRoute(blinded_route), None).unwrap_err(); | ||
|
@@ -152,7 +154,7 @@ fn reply_path() { | |
let secp_ctx = Secp256k1::new(); | ||
|
||
// Destination::Node | ||
let reply_path = BlindedRoute::new(&[nodes[2].get_node_pk(), nodes[1].get_node_pk(), nodes[0].get_node_pk()], &*nodes[0].keys_manager, &secp_ctx).unwrap(); | ||
let reply_path = BlindedRoute::new(&[nodes[2].get_node_pk(), nodes[1].get_node_pk(), nodes[0].get_node_pk()], &*nodes[0].keys_manager, &secp_ctx, false).unwrap(); | ||
nodes[0].messenger.send_onion_message(&[nodes[1].get_node_pk(), nodes[2].get_node_pk()], Destination::Node(nodes[3].get_node_pk()), Some(reply_path)).unwrap(); | ||
pass_along_path(&nodes, None); | ||
// Make sure the last node successfully decoded the reply path. | ||
|
@@ -161,8 +163,8 @@ fn reply_path() { | |
format!("Received an onion message with path_id: None and reply_path").to_string(), 1); | ||
|
||
// Destination::BlindedRoute | ||
let blinded_route = BlindedRoute::new(&[nodes[1].get_node_pk(), nodes[2].get_node_pk(), nodes[3].get_node_pk()], &*nodes[3].keys_manager, &secp_ctx).unwrap(); | ||
let reply_path = BlindedRoute::new(&[nodes[2].get_node_pk(), nodes[1].get_node_pk(), nodes[0].get_node_pk()], &*nodes[0].keys_manager, &secp_ctx).unwrap(); | ||
let blinded_route = BlindedRoute::new(&[nodes[1].get_node_pk(), nodes[2].get_node_pk(), nodes[3].get_node_pk()], &*nodes[3].keys_manager, &secp_ctx, true).unwrap(); | ||
let reply_path = BlindedRoute::new(&[nodes[2].get_node_pk(), nodes[1].get_node_pk(), nodes[0].get_node_pk()], &*nodes[0].keys_manager, &secp_ctx, false).unwrap(); | ||
|
||
nodes[0].messenger.send_onion_message(&[], Destination::BlindedRoute(blinded_route), Some(reply_path)).unwrap(); | ||
pass_along_path(&nodes, None); | ||
|
@@ -180,3 +182,75 @@ fn peer_buffer_full() { | |
let err = nodes[0].messenger.send_onion_message(&[], Destination::Node(nodes[1].get_node_pk()), None).unwrap_err(); | ||
assert_eq!(err, SendError::BufferFull); | ||
} | ||
|
||
#[test] | ||
fn onion_message_blinded_control_tlv_payloads_are_same_length() { | ||
let nodes = create_nodes(4); | ||
let secp_ctx = Secp256k1::new(); | ||
let two_blinded_hops = BlindedRoute::new(&[nodes[2].get_node_pk(), nodes[3].get_node_pk()], &*nodes[3].keys_manager, &secp_ctx, true).unwrap(); | ||
let three_blinded_hops = BlindedRoute::new(&[nodes[1].get_node_pk(), nodes[2].get_node_pk(), nodes[3].get_node_pk()], &*nodes[3].keys_manager, &secp_ctx, true).unwrap(); | ||
let session_priv = SecretKey::from_slice(&hex::decode(format!("{:02}", 3).repeat(32)).unwrap()[..]).unwrap(); | ||
|
||
let only_unblinded_payloads = packet_payloads_and_keys(&secp_ctx, &[nodes[0].get_node_pk(), nodes[1].get_node_pk()], Destination::Node(nodes[2].get_node_pk()), None, &session_priv).unwrap().0; | ||
let one_unblinded_and_three_blinded_payloads = packet_payloads_and_keys(&secp_ctx, &[nodes[1].get_node_pk()], Destination::BlindedRoute(three_blinded_hops), None, &session_priv).unwrap().0; | ||
// When more that one unblinded payload exists, the blinded payloads should be the same length | ||
// as the largest unblinded payload. | ||
let multiple_unblinded_and_blinded_payloads = packet_payloads_and_keys(&secp_ctx, &[nodes[0].get_node_pk(), nodes[1].get_node_pk()], Destination::BlindedRoute(two_blinded_hops), None, &session_priv).unwrap().0; | ||
|
||
// Verify that the blinded contol tlv payloads returned from `packet_payloads_and_keys` have | ||
// the same length, and that the payload for every blinded payload matches the length of the | ||
// largest unblinded payload length. | ||
Comment on lines
+201
to
+202
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The spec is a little unclear in regarding this, but the test vectors seems to indicate that this should be the case. |
||
for payloads in [only_unblinded_payloads, one_unblinded_and_three_blinded_payloads, multiple_unblinded_and_blinded_payloads].iter() { | ||
let mut longest_tlv_length = None; | ||
|
||
macro_rules! assign_longest_tlv_length { | ||
($unblinded_tlv_length: expr) => { | ||
if longest_tlv_length.map(|current_len| $unblinded_tlv_length > current_len).unwrap_or(true) { | ||
longest_tlv_length = Some($unblinded_tlv_length); | ||
} | ||
}; | ||
} | ||
|
||
macro_rules! assert_correct_tlv_length { | ||
($tlv_length: expr) => { | ||
match longest_tlv_length { | ||
None => { | ||
longest_tlv_length = Some($tlv_length); | ||
}, | ||
Some(expected_len) => { | ||
assert_eq!($tlv_length, expected_len); | ||
} | ||
} | ||
}; | ||
} | ||
|
||
for payload in payloads { | ||
match &payload.0 { | ||
Payload::Forward(control_tlvs) => { | ||
match control_tlvs { | ||
ForwardControlTlvs::Blinded(bytes) => { | ||
// 16 deducted to account for the 16 byte tag of the ChaCha encryption | ||
// in Blinded ControlTLVs | ||
assert_correct_tlv_length!(bytes.len() as u16 - 16); | ||
}, | ||
ForwardControlTlvs::Unblinded(tlv) => { | ||
assign_longest_tlv_length!(tlv.total_length); | ||
}, | ||
} | ||
}, | ||
Payload::Receive { control_tlvs, .. } => { | ||
match control_tlvs { | ||
ReceiveControlTlvs::Blinded(bytes) => { | ||
// 16 deducted to account for the 16 byte tag of the ChaCha encryption | ||
// in Blinded ControlTLVs | ||
assert_correct_tlv_length!(bytes.len() as u16 - 16); | ||
}, | ||
ReceiveControlTlvs::Unblinded(tlv) => { | ||
assign_longest_tlv_length!(tlv.total_length); | ||
}, | ||
} | ||
}, | ||
}; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems bad. Will check why
#[macro_export]
places theget_control_tlv_length
in the root of the lightning crate foronion_message::utils
, but not for inln::functional_test_utils
and similar.