Expand test to cover Bolt11 custom TLVs
What changed, and why it matters
This commit only expands an existing automated test. It renames a test function, adds assertions, and uses new test helpers to verify that custom extra data fields (called 'custom TLVs') are preserved when paying a BOLT11 invoice. There is no change to production code, no bug fix, and no security-related behavior change.
No action required. This is a test-only change and does not affect runtime security.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff in lightning/src/ln/invoice_utils.rs modifies a single unit test. It renames create_and_pay_for_bolt11_invoice to create_and_pay_for_bolt11_invoice_with_custom_tlvs, introduces a RecipientCustomTlvs value, builds OptionalBolt11PaymentParams with it, and replaces direct message handling with PassAlongPathArgs/claim_payment_along_route helpers that carry the custom TLVs through the simulated payment flow. No library code is altered.
Changed components
lightning/src/ln/invoice_utils.rs (test module only)Inspect captured patch +32 / −18
diff --git a/lightning/src/ln/invoice_utils.rs b/lightning/src/ln/invoice_utils.rs
index 96a62a9..90b3b5c 100644
--- a/lightning/src/ln/invoice_utils.rs
+++ b/lightning/src/ln/invoice_utils.rs
@@ -620,7 +620,8 @@ mod test {
};
use crate::ln::functional_test_utils::*;
use crate::ln::msgs::{BaseMessageHandler, ChannelMessageHandler, MessageSendEvent};
- use crate::routing::router::{PaymentParameters, RouteParameters};
+ use crate::ln::outbound_payment::RecipientCustomTlvs;
+ use crate::routing::router::{PaymentParameters, RouteParameters, RouteParametersConfig};
use crate::sign::PhantomKeysManager;
use crate::types::payment::{PaymentHash, PaymentPreimage};
use crate::util::config::UserConfig;
@@ -663,26 +664,26 @@ mod test {
}
#[test]
- fn create_and_pay_for_bolt11_invoice() {
+ fn create_and_pay_for_bolt11_invoice_with_custom_tlvs() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
create_unannounced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001);
- let node_a_id = nodes[0].node.get_our_node_id();
-
+ let amt_msat = 10_000;
let description =
Bolt11InvoiceDescription::Direct(Description::new("test".to_string()).unwrap());
let non_default_invoice_expiry_secs = 4200;
+
let invoice_params = Bolt11InvoiceParameters {
- amount_msats: Some(10_000),
+ amount_msats: Some(amt_msat),
description,
invoice_expiry_delta_secs: Some(non_default_invoice_expiry_secs),
..Default::default()
};
let invoice = nodes[1].node.create_bolt11_invoice(invoice_params).unwrap();
- assert_eq!(invoice.amount_milli_satoshis(), Some(10_000));
+ assert_eq!(invoice.amount_milli_satoshis(), Some(amt_msat));
// If no `min_final_cltv_expiry_delta` is specified, then it should be `MIN_FINAL_CLTV_EXPIRY_DELTA`.
assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
assert_eq!(
@@ -694,6 +695,10 @@ mod test {
Duration::from_secs(non_default_invoice_expiry_secs.into())
);
+ let (payment_hash, payment_secret) = (invoice.payment_hash(), *invoice.payment_secret());
+
+ let preimage = nodes[1].node.get_payment_preimage(payment_hash, payment_secret).unwrap();
+
// Invoice SCIDs should always use inbound SCID aliases over the real channel ID, if one is
// available.
let chan = &nodes[1].node.list_usable_channels()[0];
@@ -707,25 +712,34 @@ mod test {
assert_eq!(invoice.route_hints()[0].0[0].htlc_minimum_msat, chan.inbound_htlc_minimum_msat);
assert_eq!(invoice.route_hints()[0].0[0].htlc_maximum_msat, chan.inbound_htlc_maximum_msat);
+ let custom_tlvs = RecipientCustomTlvs::new(vec![(65537, vec![42; 42])]).unwrap();
+ let optional_params = OptionalBolt11PaymentParams {
+ custom_tlvs: custom_tlvs.clone(),
+ route_params_config: RouteParametersConfig::default(),
+ retry_strategy: Retry::Attempts(0),
+ };
+
nodes[0]
.node
- .pay_for_bolt11_invoice(
- &invoice,
- PaymentId([42; 32]),
- None,
- OptionalBolt11PaymentParams::default(),
- )
+ .pay_for_bolt11_invoice(&invoice, PaymentId([42; 32]), None, optional_params)
.unwrap();
check_added_monitors(&nodes[0], 1);
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
assert_eq!(events.len(), 1);
- let payment_event = SendEvent::from_event(events.remove(0));
- nodes[1].node.handle_update_add_htlc(node_a_id, &payment_event.msgs[0]);
- nodes[1].node.handle_commitment_signed_batch_test(node_a_id, &payment_event.commitment_msg);
- check_added_monitors(&nodes[1], 1);
- let events = nodes[1].node.get_and_clear_pending_msg_events();
- assert_eq!(events.len(), 2);
+ let ev = remove_first_msg_event_to_node(&nodes[1].node.get_our_node_id(), &mut events);
+
+ let path = &[&nodes[1]];
+ let args = PassAlongPathArgs::new(&nodes[0], path, amt_msat, payment_hash, ev)
+ .with_payment_preimage(preimage)
+ .with_payment_secret(payment_secret)
+ .with_custom_tlvs(custom_tlvs.clone().into_inner());
+
+ do_pass_along_path(args);
+ claim_payment_along_route(
+ ClaimAlongRouteArgs::new(&nodes[0], &[&[&nodes[1]]], preimage)
+ .with_custom_tlvs(custom_tlvs.into_inner()),
+ );
}
fn do_create_invoice_min_final_cltv_delta(with_custom_delta: bool) {
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.