Skip to content

Commit

Permalink
Update Payment Tlvs to also contain the Option<Padding>
Browse files Browse the repository at this point in the history
Co-authored-by: Jeffrey Czyz <[email protected]>
  • Loading branch information
shaavan and jkczyz committed Aug 16, 2024
1 parent 039871c commit f511240
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 4 deletions.
48 changes: 46 additions & 2 deletions lightning/src/blinded_path/payment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
use bitcoin::secp256k1::{self, PublicKey, Secp256k1, SecretKey};

use crate::blinded_path::{BlindedHop, BlindedPath, IntroductionNode, NodeIdLookUp};
use crate::blinded_path::utils;
use crate::blinded_path::utils::{self, Padding};
use crate::crypto::streams::ChaChaPolyReadAdapter;
use crate::io;
use crate::io::Cursor;
Expand Down Expand Up @@ -50,6 +50,8 @@ pub struct ForwardNode {
/// Data to construct a [`BlindedHop`] for forwarding a payment.
#[derive(Clone, Debug)]
pub struct ForwardTlvs {
/// The padding data used to make all packets of a Blinded Path of same size
pub padding: Option<Padding>,
/// The short channel id this payment should be forwarded out over.
pub short_channel_id: u64,
/// Payment parameters for relaying over [`Self::short_channel_id`].
Expand All @@ -67,6 +69,8 @@ pub struct ForwardTlvs {
/// may not be valid if received by another lightning implementation.
#[derive(Clone, Debug)]
pub struct ReceiveTlvs {
/// The padding data used to make all packets of a Blinded Path of same size
pub padding: Option<Padding>,
/// Used to authenticate the sender of a payment to the receiver and tie MPP HTLCs together.
pub payment_secret: PaymentSecret,
/// Constraints for the receiver of this payment.
Expand All @@ -78,13 +82,29 @@ pub struct ReceiveTlvs {
/// Data to construct a [`BlindedHop`] for sending a payment over.
///
/// [`BlindedHop`]: crate::blinded_path::BlindedHop
#[derive(Clone)]
pub(crate) enum BlindedPaymentTlvs {
/// This blinded payment data is for a forwarding node.
Forward(ForwardTlvs),
/// This blinded payment data is for the receiving node.
Receive(ReceiveTlvs),
}

impl BlindedPaymentTlvs {
pub(crate) fn pad_to_length(mut self, length: usize) -> Self {
let pad_length = length.checked_sub(self.serialized_length());
debug_assert!(pad_length.is_some(), "Size of this packet should not be larger than the size of largest packet.");
let padding = Some(Padding::new(pad_length.unwrap()));

match &mut self {
BlindedPaymentTlvs::Forward(tlvs) => tlvs.padding = padding,
BlindedPaymentTlvs::Receive(tlvs) => tlvs.padding = padding,
}

self
}
}

/// Parameters for relaying over a given [`BlindedHop`].
///
/// [`BlindedHop`]: crate::blinded_path::BlindedHop
Expand Down Expand Up @@ -198,6 +218,7 @@ impl Writeable for ForwardTlvs {
if self.features == BlindedHopFeatures::empty() { None }
else { Some(&self.features) };
encode_tlv_stream!(w, {
(1, self.padding, option),
(2, self.short_channel_id, required),
(10, self.payment_relay, required),
(12, self.payment_constraints, required),
Expand All @@ -210,6 +231,7 @@ impl Writeable for ForwardTlvs {
impl Writeable for ReceiveTlvs {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
encode_tlv_stream!(w, {
(1, self.padding, option),
(12, self.payment_constraints, required),
(65536, self.payment_secret, required),
(65537, self.payment_context, required)
Expand Down Expand Up @@ -246,6 +268,7 @@ impl Readable for BlindedPaymentTlvs {
return Err(DecodeError::InvalidValue)
}
Ok(BlindedPaymentTlvs::Forward(ForwardTlvs {
padding: None,
short_channel_id,
payment_relay: payment_relay.ok_or(DecodeError::InvalidValue)?,
payment_constraints: payment_constraints.0.unwrap(),
Expand All @@ -254,6 +277,7 @@ impl Readable for BlindedPaymentTlvs {
} else {
if payment_relay.is_some() || features.is_some() { return Err(DecodeError::InvalidValue) }
Ok(BlindedPaymentTlvs::Receive(ReceiveTlvs {
padding: None,
payment_secret: payment_secret.ok_or(DecodeError::InvalidValue)?,
payment_constraints: payment_constraints.0.unwrap(),
payment_context: payment_context.0.unwrap(),
Expand All @@ -272,7 +296,14 @@ pub(super) fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>(
let tlvs = intermediate_nodes.iter().map(|node| BlindedPaymentTlvs::Forward(node.tlvs.clone()))
.chain(core::iter::once(BlindedPaymentTlvs::Receive(payee_tlvs)));

utils::construct_blinded_hops(secp_ctx, pks, tlvs, session_priv)
let max_length = tlvs.clone()
.map(|tlv| tlv.serialized_length())
.max()
.unwrap_or(0);

let length_tlvs = tlvs.map(|tlv| tlv.pad_to_length(max_length));

utils::construct_blinded_hops(secp_ctx, pks, length_tlvs, session_priv)
}

// Advance the blinded onion payment path by one hop, so make the second hop into the new
Expand Down Expand Up @@ -484,6 +515,7 @@ mod tests {
let intermediate_nodes = vec![ForwardNode {
node_id: dummy_pk,
tlvs: ForwardTlvs {
padding: None,
short_channel_id: 0,
payment_relay: PaymentRelay {
cltv_expiry_delta: 144,
Expand All @@ -500,6 +532,7 @@ mod tests {
}, ForwardNode {
node_id: dummy_pk,
tlvs: ForwardTlvs {
padding: None,
short_channel_id: 0,
payment_relay: PaymentRelay {
cltv_expiry_delta: 144,
Expand All @@ -515,6 +548,7 @@ mod tests {
htlc_maximum_msat: u64::max_value(),
}];
let recv_tlvs = ReceiveTlvs {
padding: None,
payment_secret: PaymentSecret([0; 32]),
payment_constraints: PaymentConstraints {
max_cltv_expiry: 0,
Expand All @@ -534,6 +568,7 @@ mod tests {
#[test]
fn compute_payinfo_1_hop() {
let recv_tlvs = ReceiveTlvs {
padding: None,
payment_secret: PaymentSecret([0; 32]),
payment_constraints: PaymentConstraints {
max_cltv_expiry: 0,
Expand All @@ -557,6 +592,7 @@ mod tests {
let intermediate_nodes = vec![ForwardNode {
node_id: dummy_pk,
tlvs: ForwardTlvs {
padding: None,
short_channel_id: 0,
payment_relay: PaymentRelay {
cltv_expiry_delta: 0,
Expand All @@ -573,6 +609,7 @@ mod tests {
}, ForwardNode {
node_id: dummy_pk,
tlvs: ForwardTlvs {
padding: None,
short_channel_id: 0,
payment_relay: PaymentRelay {
cltv_expiry_delta: 0,
Expand All @@ -588,6 +625,7 @@ mod tests {
htlc_maximum_msat: u64::max_value()
}];
let recv_tlvs = ReceiveTlvs {
padding: None,
payment_secret: PaymentSecret([0; 32]),
payment_constraints: PaymentConstraints {
max_cltv_expiry: 0,
Expand All @@ -608,6 +646,7 @@ mod tests {
let intermediate_nodes = vec![ForwardNode {
node_id: dummy_pk,
tlvs: ForwardTlvs {
padding: None,
short_channel_id: 0,
payment_relay: PaymentRelay {
cltv_expiry_delta: 0,
Expand All @@ -624,6 +663,7 @@ mod tests {
}, ForwardNode {
node_id: dummy_pk,
tlvs: ForwardTlvs {
padding: None,
short_channel_id: 0,
payment_relay: PaymentRelay {
cltv_expiry_delta: 0,
Expand All @@ -639,6 +679,7 @@ mod tests {
htlc_maximum_msat: u64::max_value()
}];
let recv_tlvs = ReceiveTlvs {
padding: None,
payment_secret: PaymentSecret([0; 32]),
payment_constraints: PaymentConstraints {
max_cltv_expiry: 0,
Expand All @@ -663,6 +704,7 @@ mod tests {
let intermediate_nodes = vec![ForwardNode {
node_id: dummy_pk,
tlvs: ForwardTlvs {
padding: None,
short_channel_id: 0,
payment_relay: PaymentRelay {
cltv_expiry_delta: 0,
Expand All @@ -679,6 +721,7 @@ mod tests {
}, ForwardNode {
node_id: dummy_pk,
tlvs: ForwardTlvs {
padding: None,
short_channel_id: 0,
payment_relay: PaymentRelay {
cltv_expiry_delta: 0,
Expand All @@ -694,6 +737,7 @@ mod tests {
htlc_maximum_msat: 10_000
}];
let recv_tlvs = ReceiveTlvs {
padding: None,
payment_secret: PaymentSecret([0; 32]),
payment_constraints: PaymentConstraints {
max_cltv_expiry: 0,
Expand Down
5 changes: 5 additions & 0 deletions lightning/src/ln/blinded_payment_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ fn blinded_payment_path(
intermediate_nodes.push(ForwardNode {
node_id: *node_id,
tlvs: ForwardTlvs {
padding: None,
short_channel_id: chan_upd.short_channel_id,
payment_relay: PaymentRelay {
cltv_expiry_delta: chan_upd.cltv_expiry_delta,
Expand All @@ -57,6 +58,7 @@ fn blinded_payment_path(
});
}
let payee_tlvs = ReceiveTlvs {
padding: None,
payment_secret,
payment_constraints: PaymentConstraints {
max_cltv_expiry: u32::max_value(),
Expand Down Expand Up @@ -104,6 +106,7 @@ fn do_one_hop_blinded_path(success: bool) {
let amt_msat = 5000;
let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash(&nodes[1], Some(amt_msat), None);
let payee_tlvs = ReceiveTlvs {
padding: None,
payment_secret,
payment_constraints: PaymentConstraints {
max_cltv_expiry: u32::max_value(),
Expand Down Expand Up @@ -148,6 +151,7 @@ fn mpp_to_one_hop_blinded_path() {
let amt_msat = 15_000_000;
let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash(&nodes[3], Some(amt_msat), None);
let payee_tlvs = ReceiveTlvs {
padding: None,
payment_secret,
payment_constraints: PaymentConstraints {
max_cltv_expiry: u32::max_value(),
Expand Down Expand Up @@ -1293,6 +1297,7 @@ fn custom_tlvs_to_blinded_path() {
let amt_msat = 5000;
let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash(&nodes[1], Some(amt_msat), None);
let payee_tlvs = ReceiveTlvs {
padding: None,
payment_secret,
payment_constraints: PaymentConstraints {
max_cltv_expiry: u32::max_value(),
Expand Down
1 change: 1 addition & 0 deletions lightning/src/ln/channelmanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9345,6 +9345,7 @@ where
let max_cltv_expiry = self.best_block.read().unwrap().height + CLTV_FAR_FAR_AWAY
+ LATENCY_GRACE_PERIOD_BLOCKS;
let payee_tlvs = ReceiveTlvs {
padding: None,
payment_secret,
payment_constraints: PaymentConstraints {
max_cltv_expiry,
Expand Down
1 change: 1 addition & 0 deletions lightning/src/ln/max_payment_path_len_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ fn one_hop_blinded_path_with_custom_tlv() {
let amt_msat = 100_000;
let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash(&nodes[2], Some(amt_msat), None);
let payee_tlvs = ReceiveTlvs {
padding: None,
payment_secret,
payment_constraints: PaymentConstraints {
max_cltv_expiry: u32::max_value(),
Expand Down
6 changes: 4 additions & 2 deletions lightning/src/ln/msgs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2758,7 +2758,8 @@ impl<NS: Deref> ReadableArgs<(Option<PublicKey>, &NS)> for InboundOnionPayload w
let mut reader = FixedLengthReader::new(&mut s, enc_tlvs.len() as u64);
match ChaChaPolyReadAdapter::read(&mut reader, rho)? {
ChaChaPolyReadAdapter { readable: BlindedPaymentTlvs::Forward(ForwardTlvs {
short_channel_id, payment_relay, payment_constraints, features
padding: _, short_channel_id, payment_relay,
payment_constraints, features
})} => {
if amt.is_some() || cltv_value.is_some() || total_msat.is_some() ||
keysend_preimage.is_some()
Expand All @@ -2774,7 +2775,8 @@ impl<NS: Deref> ReadableArgs<(Option<PublicKey>, &NS)> for InboundOnionPayload w
})
},
ChaChaPolyReadAdapter { readable: BlindedPaymentTlvs::Receive(ReceiveTlvs {
payment_secret, payment_constraints, payment_context
padding: _, payment_secret, payment_constraints,
payment_context
})} => {
if total_msat.unwrap_or(0) > MAX_VALUE_MSAT { return Err(DecodeError::InvalidValue) }
Ok(Self::BlindedReceive {
Expand Down
1 change: 1 addition & 0 deletions lightning/src/routing/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ impl<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, ES: Deref, S: Deref,
};
Some(payment::ForwardNode {
tlvs: ForwardTlvs {
padding: None,
short_channel_id,
payment_relay,
payment_constraints,
Expand Down

0 comments on commit f511240

Please sign in to comment.