Skip to content

Commit 212ee86

Browse files
Support verifying payment_secrets for inbound static invoice payments
Add a new payment type for this, because normally the payment hash is factored into the payment secrets we create for invoices, but static invoices don't have a payment hash since they are paid via keysend.
1 parent 74aae2e commit 212ee86

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

lightning/src/ln/inbound_payment.rs

+33
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ enum Method {
9898
UserPaymentHash = 1,
9999
LdkPaymentHashCustomFinalCltv = 2,
100100
UserPaymentHashCustomFinalCltv = 3,
101+
SpontaneousPayment = 4,
101102
}
102103

103104
impl Method {
@@ -107,6 +108,7 @@ impl Method {
107108
bits if bits == Method::UserPaymentHash as u8 => Ok(Method::UserPaymentHash),
108109
bits if bits == Method::LdkPaymentHashCustomFinalCltv as u8 => Ok(Method::LdkPaymentHashCustomFinalCltv),
109110
bits if bits == Method::UserPaymentHashCustomFinalCltv as u8 => Ok(Method::UserPaymentHashCustomFinalCltv),
111+
bits if bits == Method::SpontaneousPayment as u8 => Ok(Method::SpontaneousPayment),
110112
unknown => Err(unknown),
111113
}
112114
}
@@ -186,6 +188,26 @@ pub fn create_from_hash(keys: &ExpandedKey, min_value_msat: Option<u64>, payment
186188
Ok(construct_payment_secret(&iv_bytes, &metadata_bytes, &keys.metadata_key))
187189
}
188190

191+
#[cfg(async_payments)]
192+
pub(super) fn create_for_spontaneous_payment(
193+
keys: &ExpandedKey, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32,
194+
current_time: u64, min_final_cltv_expiry_delta: Option<u16>
195+
) -> Result<PaymentSecret, ()> {
196+
let metadata_bytes = construct_metadata_bytes(
197+
min_value_msat, Method::SpontaneousPayment, invoice_expiry_delta_secs, current_time,
198+
min_final_cltv_expiry_delta
199+
)?;
200+
201+
let mut hmac = HmacEngine::<Sha256>::new(&keys.offers_base_key);
202+
hmac.input(&metadata_bytes);
203+
let hmac_bytes = Hmac::from_engine(hmac).to_byte_array();
204+
205+
let mut iv_bytes = [0 as u8; IV_LEN];
206+
iv_bytes.copy_from_slice(&hmac_bytes[..IV_LEN]);
207+
208+
Ok(construct_payment_secret(&iv_bytes, &metadata_bytes, &keys.metadata_key))
209+
}
210+
189211
fn construct_metadata_bytes(min_value_msat: Option<u64>, payment_type: Method,
190212
invoice_expiry_delta_secs: u32, highest_seen_timestamp: u64, min_final_cltv_expiry_delta: Option<u16>) -> Result<[u8; METADATA_LEN], ()> {
191213
if min_value_msat.is_some() && min_value_msat.unwrap() > MAX_VALUE_MSAT {
@@ -315,6 +337,14 @@ pub(super) fn verify<L: Deref>(payment_hash: PaymentHash, payment_data: &msgs::F
315337
}
316338
}
317339
},
340+
Ok(Method::SpontaneousPayment) => {
341+
let mut hmac = HmacEngine::<Sha256>::new(&keys.offers_base_key);
342+
hmac.input(&metadata_bytes[..]);
343+
if !fixed_time_eq(&iv_bytes, &Hmac::from_engine(hmac).to_byte_array().split_at_mut(IV_LEN).0) {
344+
log_trace!(logger, "Failing async payment HTLC with sender-generated payment_hash {}: unexpected payment_secret", &payment_hash);
345+
return Err(())
346+
}
347+
},
318348
Err(unknown_bits) => {
319349
log_trace!(logger, "Failing HTLC with payment hash {} due to unknown payment type {}", &payment_hash, unknown_bits);
320350
return Err(());
@@ -360,6 +390,9 @@ pub(super) fn get_payment_preimage(payment_hash: PaymentHash, payment_secret: Pa
360390
Ok(Method::UserPaymentHash) | Ok(Method::UserPaymentHashCustomFinalCltv) => Err(APIError::APIMisuseError {
361391
err: "Expected payment type to be LdkPaymentHash, instead got UserPaymentHash".to_string()
362392
}),
393+
Ok(Method::SpontaneousPayment) => Err(APIError::APIMisuseError {
394+
err: "Can't extract payment preimage for spontaneous payments".to_string()
395+
}),
363396
Err(other) => Err(APIError::APIMisuseError { err: format!("Unknown payment type: {}", other) }),
364397
}
365398
}

0 commit comments

Comments
 (0)