Skip to content

Commit 64ed1a1

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 bd2b85e commit 64ed1a1

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_info = RecipientOnionFields { payment_secret };
148+
let recipient_info = 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: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,21 +233,34 @@ pub struct RecipientOnionFields {
233233
/// receives, thus you should generally never be providing a secret here for spontaneous
234234
/// payments.
235235
pub payment_secret: Option<PaymentSecret>,
236+
/// The payment metadata serves a similar purpose as [`Self::payment_secret`] but is of
237+
/// arbitrary length. This gives recipients substantially more flexibility to receive
238+
/// additional data.
239+
///
240+
/// In LDK, while the [`Self::payment_secret`] is fixed based on an internal authentication
241+
/// scheme to authenticate received payments against expected payments and invoices, this field
242+
/// is not used in LDK for received payments, and can be used to store arbitrary data in
243+
/// invoices which will be received with the payment.
244+
///
245+
/// Note that this field was added to the lightning specification more recently than
246+
/// [`Self::payment_secret`] and while nearly all lightning senders support secrets, metadata
247+
/// may not be supported as universally.
248+
pub payment_metadata: Option<Vec<u8>>,
236249
}
237250

238251
impl RecipientOnionFields {
239252
/// Creates a [`RecipientOnionFields`] from only a [`PaymentSecret`]. This is the most common
240253
/// set of onion fields for today's BOLT11 invoices - most nodes require a [`PaymentSecret`]
241254
/// but do not require or provide any further data.
242255
pub fn secret_only(payment_secret: PaymentSecret) -> Self {
243-
Self { payment_secret: Some(payment_secret) }
256+
Self { payment_secret: Some(payment_secret), payment_metadata: None }
244257
}
245258

246259
/// Creates a new [`RecipientOnionFields`] with no fields. This generally does not create
247260
/// payable HTLCs except for spontaneous payments, i.e. this should generally only be used for
248261
/// calls to [`ChannelManager::send_spontaneous_payment`].
249262
pub fn spontaneous_empty() -> Self {
250-
Self { payment_secret: None }
263+
Self { payment_secret: None, payment_metadata: None }
251264
}
252265
}
253266

@@ -7593,6 +7606,7 @@ where
75937606
session_privs: [session_priv_bytes].iter().map(|a| *a).collect(),
75947607
payment_hash: htlc.payment_hash,
75957608
payment_secret: None, // only used for retries, and we'll never retry on startup
7609+
payment_metadata: None, // only used for retries, and we'll never retry on startup
75967610
keysend_preimage: None, // only used for retries, and we'll never retry on startup
75977611
pending_amt_msat: path_amt,
75987612
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: 5 additions & 1 deletion
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+.
@@ -681,7 +682,7 @@ impl OutboundPayments {
681682
hash_map::Entry::Occupied(mut payment) => {
682683
let res = match payment.get() {
683684
PendingOutboundPayment::Retryable {
684-
total_msat, keysend_preimage, payment_secret, pending_amt_msat, ..
685+
total_msat, keysend_preimage, payment_secret, payment_metadata, pending_amt_msat, ..
685686
} => {
686687
let retry_amt_msat: u64 = route.paths.iter().map(|path| path.last().unwrap().fee_msat).sum();
687688
if retry_amt_msat + *pending_amt_msat > *total_msat * (100 + RETRY_OVERFLOW_PERCENTAGE) / 100 {
@@ -691,6 +692,7 @@ impl OutboundPayments {
691692
}
692693
(*total_msat, RecipientOnionFields {
693694
payment_secret: *payment_secret,
695+
payment_metadata: payment_metadata.clone(),
694696
}, *keysend_preimage)
695697
},
696698
PendingOutboundPayment::Legacy { .. } => {
@@ -874,6 +876,7 @@ impl OutboundPayments {
874876
pending_fee_msat: Some(0),
875877
payment_hash,
876878
payment_secret: recipient_onion.payment_secret,
879+
payment_metadata: recipient_onion.payment_metadata,
877880
keysend_preimage,
878881
starting_block_height: best_block_height,
879882
total_msat: route.get_total_amount(),
@@ -1308,6 +1311,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
13081311
(4, payment_secret, option),
13091312
(5, keysend_preimage, option),
13101313
(6, total_msat, required),
1314+
(7, payment_metadata, option),
13111315
(8, pending_amt_msat, required),
13121316
(10, starting_block_height, required),
13131317
(not_written, retry_strategy, (static_value, None)),

0 commit comments

Comments
 (0)