Skip to content

Commit 161eca7

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 7b0eed4 commit 161eca7

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
@@ -244,21 +244,34 @@ pub struct RecipientOnionFields {
244244
/// receives, thus you should generally never be providing a secret here for spontaneous
245245
/// payments.
246246
pub payment_secret: Option<PaymentSecret>,
247+
/// The payment metadata serves a similar purpose as [`Self::payment_secret`] but is of
248+
/// arbitrary length. This gives recipients substantially more flexibility to receive
249+
/// additional data.
250+
///
251+
/// In LDK, while the [`Self::payment_secret`] is fixed based on an internal authentication
252+
/// scheme to authenticate received payments against expected payments and invoices, this field
253+
/// is not used in LDK for received payments, and can be used to store arbitrary data in
254+
/// invoices which will be received with the payment.
255+
///
256+
/// Note that this field was added to the lightning specification more recently than
257+
/// [`Self::payment_secret`] and while nearly all lightning senders support secrets, metadata
258+
/// may not be supported as universally.
259+
pub payment_metadata: Option<Vec<u8>>,
247260
}
248261

249262
impl RecipientOnionFields {
250263
/// Creates a [`RecipientOnionFields`] from only a [`PaymentSecret`]. This is the most common
251264
/// set of onion fields for today's BOLT11 invoices - most nodes require a [`PaymentSecret`]
252265
/// but do not require or provide any further data.
253266
pub fn secret_only(payment_secret: PaymentSecret) -> Self {
254-
Self { payment_secret: Some(payment_secret) }
267+
Self { payment_secret: Some(payment_secret), payment_metadata: None }
255268
}
256269

257270
/// Creates a new [`RecipientOnionFields`] with no fields. This generally does not create
258271
/// payable HTLCs except for spontaneous payments, i.e. this should generally only be used for
259272
/// calls to [`ChannelManager::send_spontaneous_payment`].
260273
pub fn spontaneous_empty() -> Self {
261-
Self { payment_secret: None }
274+
Self { payment_secret: None, payment_metadata: None }
262275
}
263276
}
264277

@@ -7651,6 +7664,7 @@ where
76517664
session_privs: [session_priv_bytes].iter().map(|a| *a).collect(),
76527665
payment_hash: htlc.payment_hash,
76537666
payment_secret: None, // only used for retries, and we'll never retry on startup
7667+
payment_metadata: None, // only used for retries, and we'll never retry on startup
76547668
keysend_preimage: None, // only used for retries, and we'll never retry on startup
76557669
pending_amt_msat: path_amt,
76567670
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(),
@@ -1307,6 +1310,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
13071310
(4, payment_secret, option),
13081311
(5, keysend_preimage, option),
13091312
(6, total_msat, required),
1313+
(7, payment_metadata, option),
13101314
(8, pending_amt_msat, required),
13111315
(10, starting_block_height, required),
13121316
(not_written, retry_strategy, (static_value, None)),

0 commit comments

Comments
 (0)