Skip to content

Commit ee9afd3

Browse files
committed
Add a payment_metadata field to RecipientOnionFields
This adds the new `payment_metadata` to `RecipientOnionFields`, passing the metadata from BOLT11 invoices through the send pipeline and finally copying them info the onion when sending HTLCs. This completes send-side support for the new payment metadata feature.
1 parent a90a35b commit ee9afd3

File tree

4 files changed

+26
-6
lines changed

4 files changed

+26
-6
lines changed

lightning-invoice/src/payment.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,10 @@ fn pay_invoice_using_amount<P: Deref>(
145145
payer: P
146146
) -> Result<(), PaymentError> where P::Target: Payer {
147147
let payment_hash = PaymentHash((*invoice.payment_hash()).into_inner());
148-
let payment_secret = Some(*invoice.payment_secret());
149-
let recipient_onion = RecipientOnionFields { payment_secret };
148+
let recipient_onion = RecipientOnionFields {
149+
payment_secret: Some(*invoice.payment_secret()),
150+
payment_metadata: invoice.payment_metadata().map(|v| v.clone()),
151+
};
150152
let mut payment_params = PaymentParameters::from_node_id(invoice.recover_payee_pub_key(),
151153
invoice.min_final_cltv_expiry_delta() as u32)
152154
.with_expiry_time(expiry_time_from_unix_epoch(invoice).as_secs())

lightning/src/ln/channelmanager.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7603,6 +7603,7 @@ where
76037603
session_privs: [session_priv_bytes].iter().map(|a| *a).collect(),
76047604
payment_hash: htlc.payment_hash,
76057605
payment_secret: None, // only used for retries, and we'll never retry on startup
7606+
payment_metadata: None, // only used for retries, and we'll never retry on startup
76067607
keysend_preimage: None, // only used for retries, and we'll never retry on startup
76077608
pending_amt_msat: path_amt,
76087609
pending_fee_msat: Some(path_fee),

lightning/src/ln/onion_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ pub(super) fn build_onion_payloads(path: &Vec<RouteHop>, total_msat: u64, mut re
170170
total_msat,
171171
})
172172
} else { None },
173-
payment_metadata: None,
173+
payment_metadata: recipient_onion.payment_metadata.take(),
174174
keysend_preimage: *keysend_preimage,
175175
}
176176
} else {

lightning/src/ln/outbound_payment.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ pub(crate) enum PendingOutboundPayment {
4646
session_privs: HashSet<[u8; 32]>,
4747
payment_hash: PaymentHash,
4848
payment_secret: Option<PaymentSecret>,
49+
payment_metadata: Option<Vec<u8>>,
4950
keysend_preimage: Option<PaymentPreimage>,
5051
pending_amt_msat: u64,
5152
/// Used to track the fee paid. Only present if the payment was serialized on 0.0.103+.
@@ -422,14 +423,27 @@ pub struct RecipientOnionFields {
422423
/// receives, thus you should generally never be providing a secret here for spontaneous
423424
/// payments.
424425
pub payment_secret: Option<PaymentSecret>,
426+
/// The payment metadata serves a similar purpose as [`Self::payment_secret`] but is of
427+
/// arbitrary length. This gives recipients substantially more flexibility to receive
428+
/// additional data.
429+
///
430+
/// In LDK, while the [`Self::payment_secret`] is fixed based on an internal authentication
431+
/// scheme to authenticate received payments against expected payments and invoices, this field
432+
/// is not used in LDK for received payments, and can be used to store arbitrary data in
433+
/// invoices which will be received with the payment.
434+
///
435+
/// Note that this field was added to the lightning specification more recently than
436+
/// [`Self::payment_secret`] and while nearly all lightning senders support secrets, metadata
437+
/// may not be supported as universally.
438+
pub payment_metadata: Option<Vec<u8>>,
425439
}
426440

427441
impl RecipientOnionFields {
428442
/// Creates a [`RecipientOnionFields`] from only a [`PaymentSecret`]. This is the most common
429443
/// set of onion fields for today's BOLT11 invoices - most nodes require a [`PaymentSecret`]
430444
/// but do not require or provide any further data.
431445
pub fn secret_only(payment_secret: PaymentSecret) -> Self {
432-
Self { payment_secret: Some(payment_secret) }
446+
Self { payment_secret: Some(payment_secret), payment_metadata: None }
433447
}
434448

435449
/// Creates a new [`RecipientOnionFields`] with no fields. This generally does not create
@@ -438,7 +452,7 @@ impl RecipientOnionFields {
438452
///
439453
/// [`ChannelManager::send_spontaneous_payment`]: super::channelmanager::ChannelManager::send_spontaneous_payment
440454
pub fn spontaneous_empty() -> Self {
441-
Self { payment_secret: None }
455+
Self { payment_secret: None, payment_metadata: None }
442456
}
443457
}
444458

@@ -719,7 +733,7 @@ impl OutboundPayments {
719733
hash_map::Entry::Occupied(mut payment) => {
720734
let res = match payment.get() {
721735
PendingOutboundPayment::Retryable {
722-
total_msat, keysend_preimage, payment_secret, pending_amt_msat, ..
736+
total_msat, keysend_preimage, payment_secret, payment_metadata, pending_amt_msat, ..
723737
} => {
724738
let retry_amt_msat: u64 = route.paths.iter().map(|path| path.last().unwrap().fee_msat).sum();
725739
if retry_amt_msat + *pending_amt_msat > *total_msat * (100 + RETRY_OVERFLOW_PERCENTAGE) / 100 {
@@ -729,6 +743,7 @@ impl OutboundPayments {
729743
}
730744
(*total_msat, RecipientOnionFields {
731745
payment_secret: *payment_secret,
746+
payment_metadata: payment_metadata.clone(),
732747
}, *keysend_preimage)
733748
},
734749
PendingOutboundPayment::Legacy { .. } => {
@@ -912,6 +927,7 @@ impl OutboundPayments {
912927
pending_fee_msat: Some(0),
913928
payment_hash,
914929
payment_secret: recipient_onion.payment_secret,
930+
payment_metadata: recipient_onion.payment_metadata,
915931
keysend_preimage,
916932
starting_block_height: best_block_height,
917933
total_msat: route.get_total_amount(),
@@ -1345,6 +1361,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
13451361
(4, payment_secret, option),
13461362
(5, keysend_preimage, option),
13471363
(6, total_msat, required),
1364+
(7, payment_metadata, option),
13481365
(8, pending_amt_msat, required),
13491366
(10, starting_block_height, required),
13501367
(not_written, retry_strategy, (static_value, None)),

0 commit comments

Comments
 (0)