Commit to payment_metadata in inbound payment HMAC#4528
Commit to payment_metadata in inbound payment HMAC#4528TheBlueMatt wants to merge 2 commits intolightningdevkit:mainfrom
Conversation
TheBlueMatt
commented
Mar 31, 2026
`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>
|
👋 Thanks for assigning @tnull as a reviewer! |
Review SummaryInline comments posted:
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?
|
@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. |