Commit to payment_metadata in inbound payment HMAC#4528
Commit to payment_metadata in inbound payment HMAC#4528TheBlueMatt wants to merge 9 commits intolightningdevkit:mainfrom
Conversation
TheBlueMatt
commented
Mar 31, 2026
|
👋 Thanks for assigning @tnull as a reviewer! |
|
I've completed a thorough review of the entire PR diff. Let me verify my prior inline comment corrections. My prior review left the following comments:
No new issues found beyond what was already flagged. Here is my summary: Review SummaryNo new issues found. All prior comments have been reviewed for current applicability. Prior comments status:
Areas verified as correct:
Cross-cutting observations:
|
|
🔔 1st Reminder Hey @valentinewallace! This PR has been waiting for your review. |
valentinewallace
left a comment
There was a problem hiding this comment.
LGTM aside from CI and one or two of Claude's doc nits
| /// | ||
| /// Note that because it is exposed to the sender in the invoice you should consider encrypting | ||
| /// it. It is committed to, however, so cannot be modified by the sender. | ||
| pub payment_metadata: Option<Vec<u8>>, |
There was a problem hiding this comment.
nit: this could've been a separate commit
| let raw_invoice = if let Some(payment_metadata) = payment_metadata { | ||
| invoice.payment_metadata(payment_metadata).build_raw() |
There was a problem hiding this comment.
check length of payment_metadata and return error if greater than max allowed length of field in invoice?
There was a problem hiding this comment.
Hmm, lightning-invoice isn't aware of a limit - if there is one we should enforce it everywhere which seems like an orthogonal PR.
There was a problem hiding this comment.
shouldn't it be aware of the protocol limit here? https://github.com/TheBlueMatt/rust-lightning/blob/4bf195c5edae74699e9d7a9f598fa99a04679c29/lightning-invoice/src/ser.rs#L427
so passing metadata in the Bolt11InvoiceParameters above this would cause ldk to panic.
#[test]
fn test_create_invoice_payment_metadata_too_long() {
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);
let description = Bolt11InvoiceDescription::Direct(
Description::new("Some description".to_string()).unwrap(),
);
let invoice_params = Bolt11InvoiceParameters {
amount_msats: Some(10_000),
description,
payment_metadata: Some(vec![0; 640]),
..Default::default()
};
let _ = nodes[1].node.create_bolt11_invoice(invoice_params);
}
|
@TheBlueMatt any chance to get this into 0.3 still? We'd need it to make lightningdevkit/ldk-node#899 safe, which we want to do given we're now doing #4584 ^^ And, given this PR breaks backwards compat. for payment metadata users, we'll probably want to have the breakage happen before we start using payment metadata in LDK Node (i.e. lightningdevkit/ldk-node#899). Feel free to object, but for that reason I'm adding this to the 0.3 milestone. |
`payment_metadata` is a separate concept at the BOLT 11 layer (similar to payment secret, but arbitrary-sized) and at the BOLT 12 layer, so referring to payment information as "payment metadata" is confusing. Instead, use simply "payment info".
When payment_metadata is set in a BOLT 11 invoice, users expect to receive it back as-is in the payment onion. In order to ensure it isn't tampered with, they presumably will add an HMAC, or worse, not add one and forget that it can be tampered with. Instead, here we include it in the HMAC computation for the payment secret. This ensures that the sender must relay the correct metadata for the payment to be accepted by the receiver, binding the metadata to the payment cryptographically. The metadata is only included in the HMAC when present, so existing payments without metadata continue to verify correctly. However, this does break receiving payments with metadata today. On an upgrade this seems acceptable to me given we have seen almost no use of payment metadata in practice. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
cff21e1 to
971de9d
Compare
|
Rebased and ~addressed feedback. |
971de9d to
4bf195c
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4528 +/- ##
==========================================
+ Coverage 86.11% 86.13% +0.01%
==========================================
Files 157 157
Lines 108772 108823 +51
Branches 108772 108823 +51
==========================================
+ Hits 93668 93730 +62
+ Misses 12487 12478 -9
+ Partials 2617 2615 -2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|