Refer to payment info as `info` in `inbound_payment` not `metadata`
What changed, and why it matters
This commit is a simple renaming of internal variables, constants, and comments from 'metadata' to 'info' in one file. It does not change any program logic, cryptography, or behavior. The change was made to avoid confusion with a separate Lightning concept also called 'payment metadata'. There is no security issue here.
No security action needed. Treat as a normal code-cleanup/refactoring commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch in lightning/src/ln/inbound_payment.rs renames identifiers (METADATA_LEN, METADATA_KEY_LEN, metadata_key, metadata_bytes, decrypt_metadata, etc.) to INFO_ / info_ equivalents and updates associated doc comments. The diff shows no algorithmic, cryptographic, or control-flow changes. Constant values, key derivation, HMAC inputs, ChaCha20 operations, and verification logic remain identical.
Changed components
lightning/src/ln/inbound_payment.rsInspect captured patch +62 / −65
diff --git a/lightning/src/ln/inbound_payment.rs b/lightning/src/ln/inbound_payment.rs
index a759770..b525185 100644
--- a/lightning/src/ln/inbound_payment.rs
+++ b/lightning/src/ln/inbound_payment.rs
@@ -28,10 +28,10 @@ use crate::util::logger::Logger;
use crate::prelude::*;
pub(crate) const IV_LEN: usize = 16;
-const METADATA_LEN: usize = 16;
-const METADATA_KEY_LEN: usize = 32;
+const INFO_LEN: usize = 16;
+const INFO_KEY_LEN: usize = 32;
const AMT_MSAT_LEN: usize = 8;
-// Used to shift the payment type bits to take up the top 3 bits of the metadata bytes, or to
+// Used to shift the payment type bits to take up the top 3 bits of the info bytes, or to
// retrieve said payment type bits.
const METHOD_TYPE_OFFSET: usize = 5;
@@ -40,20 +40,20 @@ const METHOD_TYPE_OFFSET: usize = 5;
/// [`NodeSigner::get_expanded_key`]: crate::sign::NodeSigner::get_expanded_key
#[derive(Hash, Copy, Clone, PartialEq, Eq, Debug)]
pub struct ExpandedKey {
- /// The key used to encrypt the bytes containing the payment metadata (i.e. the amount and
+ /// The key used to encrypt the bytes containing the payment info (i.e. the amount and
/// expiry, included for payment verification on decryption).
- metadata_key: [u8; 32],
- /// The key used to authenticate an LDK-provided payment hash and metadata as previously
+ info_key: [u8; 32],
+ /// The key used to authenticate an LDK-provided payment hash and info as previously
/// registered with LDK.
ldk_pmt_hash_key: [u8; 32],
- /// The key used to authenticate a user-provided payment hash and metadata as previously
+ /// The key used to authenticate a user-provided payment hash and info as previously
/// registered with LDK.
user_pmt_hash_key: [u8; 32],
/// The base key used to derive signing keys and authenticate messages for BOLT 12 Offers.
offers_base_key: [u8; 32],
/// The key used to encrypt message metadata for BOLT 12 Offers.
offers_encryption_key: [u8; 32],
- /// The key used to authenticate spontaneous payments' metadata as previously registered with LDK
+ /// The key used to authenticate spontaneous payments' info as previously registered with LDK
/// for inclusion in a blinded path.
spontaneous_pmt_key: [u8; 32],
/// The key used to authenticate phantom-node-shared blinded paths as generated by us. Note
@@ -68,7 +68,7 @@ impl ExpandedKey {
/// It is recommended to cache this value and not regenerate it for each new inbound payment.
pub fn new(key_material: [u8; 32]) -> ExpandedKey {
let (
- metadata_key,
+ info_key,
ldk_pmt_hash_key,
user_pmt_hash_key,
offers_base_key,
@@ -77,7 +77,7 @@ impl ExpandedKey {
phantom_node_blinded_path_key,
) = hkdf_extract_expand_7x(b"LDK Inbound Payment Key Expansion", &key_material);
Self {
- metadata_key,
+ info_key,
ldk_pmt_hash_key,
user_pmt_hash_key,
offers_base_key,
@@ -133,7 +133,7 @@ impl Method {
}
}
-fn min_final_cltv_expiry_delta_from_metadata(bytes: [u8; METADATA_LEN]) -> u16 {
+fn min_final_cltv_expiry_delta_from_info(bytes: [u8; INFO_LEN]) -> u16 {
let expiry_bytes = &bytes[AMT_MSAT_LEN..];
u16::from_be_bytes([expiry_bytes[0], expiry_bytes[1]])
}
@@ -156,7 +156,7 @@ pub fn create<ES: EntropySource>(
keys: &ExpandedKey, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32,
entropy_source: &ES, current_time: u64, min_final_cltv_expiry_delta: Option<u16>,
) -> Result<(PaymentHash, PaymentSecret), ()> {
- let metadata_bytes = construct_metadata_bytes(
+ let info_bytes = construct_info_bytes(
min_value_msat,
if min_final_cltv_expiry_delta.is_some() {
Method::LdkPaymentHashCustomFinalCltv
@@ -174,11 +174,11 @@ pub fn create<ES: EntropySource>(
let mut hmac = HmacEngine::<Sha256>::new(&keys.ldk_pmt_hash_key);
hmac.input(&iv_bytes);
- hmac.input(&metadata_bytes);
+ hmac.input(&info_bytes);
let payment_preimage_bytes = Hmac::from_engine(hmac).to_byte_array();
let ldk_pmt_hash = PaymentHash(Sha256::hash(&payment_preimage_bytes).to_byte_array());
- let payment_secret = construct_payment_secret(&iv_bytes, &metadata_bytes, &keys.metadata_key);
+ let payment_secret = construct_payment_secret(&iv_bytes, &info_bytes, &keys.info_key);
Ok((ldk_pmt_hash, payment_secret))
}
@@ -196,7 +196,7 @@ pub fn create_from_hash(
keys: &ExpandedKey, min_value_msat: Option<u64>, payment_hash: PaymentHash,
invoice_expiry_delta_secs: u32, current_time: u64, min_final_cltv_expiry_delta: Option<u16>,
) -> Result<PaymentSecret, ()> {
- let metadata_bytes = construct_metadata_bytes(
+ let info_bytes = construct_info_bytes(
min_value_msat,
if min_final_cltv_expiry_delta.is_some() {
Method::UserPaymentHashCustomFinalCltv
@@ -209,21 +209,21 @@ pub fn create_from_hash(
)?;
let mut hmac = HmacEngine::<Sha256>::new(&keys.user_pmt_hash_key);
- hmac.input(&metadata_bytes);
+ hmac.input(&info_bytes);
hmac.input(&payment_hash.0);
let hmac_bytes = Hmac::from_engine(hmac).to_byte_array();
let mut iv_bytes = [0 as u8; IV_LEN];
iv_bytes.copy_from_slice(&hmac_bytes[..IV_LEN]);
- Ok(construct_payment_secret(&iv_bytes, &metadata_bytes, &keys.metadata_key))
+ Ok(construct_payment_secret(&iv_bytes, &info_bytes, &keys.info_key))
}
pub(crate) fn create_for_spontaneous_payment(
keys: &ExpandedKey, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32,
current_time: u64, min_final_cltv_expiry_delta: Option<u16>,
) -> Result<PaymentSecret, ()> {
- let metadata_bytes = construct_metadata_bytes(
+ let info_bytes = construct_info_bytes(
min_value_msat,
Method::SpontaneousPayment,
invoice_expiry_delta_secs,
@@ -232,13 +232,13 @@ pub(crate) fn create_for_spontaneous_payment(
)?;
let mut hmac = HmacEngine::<Sha256>::new(&keys.spontaneous_pmt_key);
- hmac.input(&metadata_bytes);
+ hmac.input(&info_bytes);
let hmac_bytes = Hmac::from_engine(hmac).to_byte_array();
let mut iv_bytes = [0 as u8; IV_LEN];
iv_bytes.copy_from_slice(&hmac_bytes[..IV_LEN]);
- Ok(construct_payment_secret(&iv_bytes, &metadata_bytes, &keys.metadata_key))
+ Ok(construct_payment_secret(&iv_bytes, &info_bytes, &keys.info_key))
}
pub(crate) fn calculate_absolute_expiry(
@@ -252,10 +252,10 @@ pub(crate) fn calculate_absolute_expiry(
highest_seen_timestamp + invoice_expiry_delta_secs as u64 + 7200
}
-fn construct_metadata_bytes(
+fn construct_info_bytes(
min_value_msat: Option<u64>, payment_type: Method, invoice_expiry_delta_secs: u32,
highest_seen_timestamp: u64, min_final_cltv_expiry_delta: Option<u16>,
-) -> Result<[u8; METADATA_LEN], ()> {
+) -> Result<[u8; INFO_LEN], ()> {
if min_value_msat.is_some() && min_value_msat.unwrap() > MAX_VALUE_MSAT {
return Err(());
}
@@ -290,29 +290,28 @@ fn construct_metadata_bytes(
expiry_bytes[1] |= bytes[1];
}
- let mut metadata_bytes: [u8; METADATA_LEN] = [0; METADATA_LEN];
+ let mut info_bytes: [u8; INFO_LEN] = [0; INFO_LEN];
- metadata_bytes[..AMT_MSAT_LEN].copy_from_slice(&min_amt_msat_bytes);
- metadata_bytes[AMT_MSAT_LEN..].copy_from_slice(&expiry_bytes);
+ info_bytes[..AMT_MSAT_LEN].copy_from_slice(&min_amt_msat_bytes);
+ info_bytes[AMT_MSAT_LEN..].copy_from_slice(&expiry_bytes);
- Ok(metadata_bytes)
+ Ok(info_bytes)
}
fn construct_payment_secret(
- iv_bytes: &[u8; IV_LEN], metadata_bytes: &[u8; METADATA_LEN],
- metadata_key: &[u8; METADATA_KEY_LEN],
+ iv_bytes: &[u8; IV_LEN], info_bytes: &[u8; INFO_LEN], info_key: &[u8; INFO_KEY_LEN],
) -> PaymentSecret {
let mut payment_secret_bytes: [u8; 32] = [0; 32];
- let (iv_slice, encrypted_metadata_slice) = payment_secret_bytes.split_at_mut(IV_LEN);
+ let (iv_slice, encrypted_info_slice) = payment_secret_bytes.split_at_mut(IV_LEN);
iv_slice.copy_from_slice(iv_bytes);
- encrypted_metadata_slice.copy_from_slice(metadata_bytes);
+ encrypted_info_slice.copy_from_slice(info_bytes);
ChaCha20::new_from_block(
- Key::new(*metadata_key),
+ Key::new(*info_key),
Nonce::new(iv_bytes[4..].try_into().unwrap()),
u32::from_le_bytes(iv_bytes[..4].try_into().unwrap()),
)
- .apply_keystream(encrypted_metadata_slice);
+ .apply_keystream(encrypted_info_slice);
PaymentSecret(payment_secret_bytes)
}
@@ -320,13 +319,13 @@ fn construct_payment_secret(
/// Check that an inbound payment's `payment_data` field is sane.
///
/// LDK does not store any data for pending inbound payments. Instead, we construct our payment
-/// secret (and, if supplied by LDK, our payment preimage) to include encrypted metadata about the
-/// payment.
+/// secret (and, if supplied by LDK, our payment preimage) to include encrypted information about
+/// the payment.
///
-/// For payments without a custom `min_final_cltv_expiry_delta`, the metadata is constructed as:
+/// For payments without a custom `min_final_cltv_expiry_delta`, the payment info is:
/// payment method (3 bits) || payment amount (8 bytes - 3 bits) || expiry (8 bytes)
///
-/// For payments including a custom `min_final_cltv_expiry_delta`, the metadata is constructed as:
+/// For payments including a custom `min_final_cltv_expiry_delta`, the payment info is:
/// payment method (3 bits) || payment amount (8 bytes - 3 bits) || min_final_cltv_expiry_delta (2 bytes) || expiry (6 bytes)
///
/// In both cases the result is then encrypted using a key derived from [`NodeSigner::get_expanded_key`].
@@ -339,14 +338,14 @@ fn construct_payment_secret(
/// method is called, then the payment method bits mentioned above are represented internally as
/// [`Method::LdkPaymentHash`]. If the latter, [`Method::UserPaymentHash`].
///
-/// For the former method, the payment preimage is constructed as an HMAC of payment metadata and
-/// random bytes. Because the payment secret is also encoded with these random bytes and metadata
-/// (with the metadata encrypted with a block cipher), we're able to authenticate the preimage on
+/// For the former method, the payment preimage is constructed as an HMAC of payment info and
+/// random bytes. Because the payment secret is also encoded with these random bytes and info
+/// (with the info encrypted with a block cipher), we're able to authenticate the preimage on
/// payment receipt.
///
/// For the latter, the payment secret instead contains an HMAC of the user-provided payment hash
-/// and payment metadata (encrypted with a block cipher), allowing us to authenticate the payment
-/// hash and metadata on payment receipt.
+/// and payment info (encrypted with a block cipher), allowing us to authenticate the payment
+/// hash and info on payment receipt.
///
/// See [`ExpandedKey`] docs for more info on the individual keys used.
///
@@ -357,14 +356,13 @@ pub(super) fn verify<L: Logger>(
payment_hash: PaymentHash, payment_data: &msgs::FinalOnionHopData, highest_seen_timestamp: u64,
keys: &ExpandedKey, logger: &L,
) -> Result<(Option<PaymentPreimage>, Option<u16>), ()> {
- let (iv_bytes, metadata_bytes) = decrypt_metadata(payment_data.payment_secret, keys);
+ let (iv_bytes, info_bytes) = decrypt_info(payment_data.payment_secret, keys);
- let payment_type_res =
- Method::from_bits((metadata_bytes[0] & 0b1110_0000) >> METHOD_TYPE_OFFSET);
+ let payment_type_res = Method::from_bits((info_bytes[0] & 0b1110_0000) >> METHOD_TYPE_OFFSET);
let mut amt_msat_bytes = [0; AMT_MSAT_LEN];
- let mut expiry_bytes = [0; METADATA_LEN - AMT_MSAT_LEN];
- amt_msat_bytes.copy_from_slice(&metadata_bytes[..AMT_MSAT_LEN]);
- expiry_bytes.copy_from_slice(&metadata_bytes[AMT_MSAT_LEN..]);
+ let mut expiry_bytes = [0; INFO_LEN - AMT_MSAT_LEN];
+ amt_msat_bytes.copy_from_slice(&info_bytes[..AMT_MSAT_LEN]);
+ expiry_bytes.copy_from_slice(&info_bytes[AMT_MSAT_LEN..]);
// Zero out the bits reserved to indicate the payment type.
amt_msat_bytes[0] &= 0b00011111;
let mut min_final_cltv_expiry_delta = None;
@@ -375,7 +373,7 @@ pub(super) fn verify<L: Logger>(
match payment_type_res {
Ok(Method::UserPaymentHash) | Ok(Method::UserPaymentHashCustomFinalCltv) => {
let mut hmac = HmacEngine::<Sha256>::new(&keys.user_pmt_hash_key);
- hmac.input(&metadata_bytes[..]);
+ hmac.input(&info_bytes[..]);
hmac.input(&payment_hash.0);
if !fixed_time_eq(
&iv_bytes,
@@ -390,7 +388,7 @@ pub(super) fn verify<L: Logger>(
}
},
Ok(Method::LdkPaymentHash) | Ok(Method::LdkPaymentHashCustomFinalCltv) => {
- match derive_ldk_payment_preimage(payment_hash, &iv_bytes, &metadata_bytes, keys) {
+ match derive_ldk_payment_preimage(payment_hash, &iv_bytes, &info_bytes, keys) {
Ok(preimage) => payment_preimage = Some(preimage),
Err(bad_preimage_bytes) => {
log_trace!(
@@ -405,7 +403,7 @@ pub(super) fn verify<L: Logger>(
},
Ok(Method::SpontaneousPayment) => {
let mut hmac = HmacEngine::<Sha256>::new(&keys.spontaneous_pmt_key);
- hmac.input(&metadata_bytes[..]);
+ hmac.input(&info_bytes[..]);
if !fixed_time_eq(
&iv_bytes,
&Hmac::from_engine(hmac).to_byte_array().split_at_mut(IV_LEN).0,
@@ -427,8 +425,7 @@ pub(super) fn verify<L: Logger>(
match payment_type_res {
Ok(Method::UserPaymentHashCustomFinalCltv) | Ok(Method::LdkPaymentHashCustomFinalCltv) => {
- min_final_cltv_expiry_delta =
- Some(min_final_cltv_expiry_delta_from_metadata(metadata_bytes));
+ min_final_cltv_expiry_delta = Some(min_final_cltv_expiry_delta_from_info(info_bytes));
// Zero out first two bytes of expiry reserved for `min_final_cltv_expiry_delta`.
expiry_bytes[0] &= 0;
expiry_bytes[1] &= 0;
@@ -455,11 +452,11 @@ pub(super) fn verify<L: Logger>(
pub(super) fn get_payment_preimage(
payment_hash: PaymentHash, payment_secret: PaymentSecret, keys: &ExpandedKey,
) -> Result<PaymentPreimage, APIError> {
- let (iv_bytes, metadata_bytes) = decrypt_metadata(payment_secret, keys);
+ let (iv_bytes, info_bytes) = decrypt_info(payment_secret, keys);
- match Method::from_bits((metadata_bytes[0] & 0b1110_0000) >> METHOD_TYPE_OFFSET) {
+ match Method::from_bits((info_bytes[0] & 0b1110_0000) >> METHOD_TYPE_OFFSET) {
Ok(Method::LdkPaymentHash) | Ok(Method::LdkPaymentHashCustomFinalCltv) => {
- derive_ldk_payment_preimage(payment_hash, &iv_bytes, &metadata_bytes, keys).map_err(
+ derive_ldk_payment_preimage(payment_hash, &iv_bytes, &info_bytes, keys).map_err(
|bad_preimage_bytes| APIError::APIMisuseError {
err: format!(
"Payment hash {} did not match decoded preimage {}",
@@ -484,34 +481,34 @@ pub(super) fn get_payment_preimage(
}
}
-fn decrypt_metadata(
+fn decrypt_info(
payment_secret: PaymentSecret, keys: &ExpandedKey,
-) -> ([u8; IV_LEN], [u8; METADATA_LEN]) {
+) -> ([u8; IV_LEN], [u8; INFO_LEN]) {
let mut iv_bytes = [0; IV_LEN];
- let (iv_slice, encrypted_metadata_bytes) = payment_secret.0.split_at(IV_LEN);
+ let (iv_slice, encrypted_info_bytes) = payment_secret.0.split_at(IV_LEN);
iv_bytes.copy_from_slice(iv_slice);
- let mut metadata_bytes: [u8; METADATA_LEN] = [0; METADATA_LEN];
- metadata_bytes.copy_from_slice(encrypted_metadata_bytes);
+ let mut info_bytes: [u8; INFO_LEN] = [0; INFO_LEN];
+ info_bytes.copy_from_slice(encrypted_info_bytes);
ChaCha20::new_from_block(
- Key::new(keys.metadata_key),
+ Key::new(keys.info_key),
Nonce::new(iv_bytes[4..].try_into().unwrap()),
u32::from_le_bytes(iv_bytes[..4].try_into().unwrap()),
)
- .apply_keystream(&mut metadata_bytes);
+ .apply_keystream(&mut info_bytes);
- (iv_bytes, metadata_bytes)
+ (iv_bytes, info_bytes)
}
// Errors if the payment preimage doesn't match `payment_hash`. Returns the bad preimage bytes in
// this case.
fn derive_ldk_payment_preimage(
- payment_hash: PaymentHash, iv_bytes: &[u8; IV_LEN], metadata_bytes: &[u8; METADATA_LEN],
+ payment_hash: PaymentHash, iv_bytes: &[u8; IV_LEN], info_bytes: &[u8; INFO_LEN],
keys: &ExpandedKey,
) -> Result<PaymentPreimage, [u8; 32]> {
let mut hmac = HmacEngine::<Sha256>::new(&keys.ldk_pmt_hash_key);
hmac.input(iv_bytes);
- hmac.input(metadata_bytes);
+ hmac.input(info_bytes);
let decoded_payment_preimage = Hmac::from_engine(hmac).to_byte_array();
if !fixed_time_eq(&payment_hash.0, &Sha256::hash(&decoded_payment_preimage).to_byte_array()) {
return Err(decoded_payment_preimage);
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.