mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-02-24 23:08:36 +01:00
Add PaymentContext to payment::ReceiveTlvs
Providing LDK-specific data in a BlindedPath allows for the data to be received with the corresponding payment. This is useful as it can then be surfaced in PaymentClaimable events where the user may correlated with an Offer, for instance. Define a PaymentContext enum for including various context (e.g., offer, refund, static invoice).
This commit is contained in:
parent
12c3a24beb
commit
c881538478
4 changed files with 61 additions and 6 deletions
|
@ -53,6 +53,8 @@ pub struct ReceiveTlvs {
|
|||
pub payment_secret: PaymentSecret,
|
||||
/// Constraints for the receiver of this payment.
|
||||
pub payment_constraints: PaymentConstraints,
|
||||
/// Context for the receiver of this payment.
|
||||
pub payment_context: PaymentContext,
|
||||
}
|
||||
|
||||
/// Data to construct a [`BlindedHop`] for sending a payment over.
|
||||
|
@ -97,6 +99,27 @@ pub struct PaymentConstraints {
|
|||
pub htlc_minimum_msat: u64,
|
||||
}
|
||||
|
||||
/// The context of an inbound payment, which is included in a [`BlindedPath`] via [`ReceiveTlvs`]
|
||||
/// and surfaced in [`PaymentPurpose`].
|
||||
///
|
||||
/// [`BlindedPath`]: crate::blinded_path::BlindedPath
|
||||
/// [`PaymentPurpose`]: crate::events::PaymentPurpose
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum PaymentContext {
|
||||
/// The payment context was unknown.
|
||||
Unknown(UnknownPaymentContext),
|
||||
}
|
||||
|
||||
/// An unknown payment context.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct UnknownPaymentContext(());
|
||||
|
||||
impl PaymentContext {
|
||||
pub(crate) fn unknown() -> Self {
|
||||
PaymentContext::Unknown(UnknownPaymentContext(()))
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<CounterpartyForwardingInfo> for PaymentRelay {
|
||||
type Error = ();
|
||||
|
||||
|
@ -137,7 +160,8 @@ impl Writeable for ReceiveTlvs {
|
|||
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
|
||||
encode_tlv_stream!(w, {
|
||||
(12, self.payment_constraints, required),
|
||||
(65536, self.payment_secret, required)
|
||||
(65536, self.payment_secret, required),
|
||||
(65537, self.payment_context, required)
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
@ -163,11 +187,14 @@ impl Readable for BlindedPaymentTlvs {
|
|||
(12, payment_constraints, required),
|
||||
(14, features, option),
|
||||
(65536, payment_secret, option),
|
||||
(65537, payment_context, (default_value, PaymentContext::unknown())),
|
||||
});
|
||||
let _padding: Option<utils::Padding> = _padding;
|
||||
|
||||
if let Some(short_channel_id) = scid {
|
||||
if payment_secret.is_some() { return Err(DecodeError::InvalidValue) }
|
||||
if payment_secret.is_some() {
|
||||
return Err(DecodeError::InvalidValue)
|
||||
}
|
||||
Ok(BlindedPaymentTlvs::Forward(ForwardTlvs {
|
||||
short_channel_id,
|
||||
payment_relay: payment_relay.ok_or(DecodeError::InvalidValue)?,
|
||||
|
@ -179,6 +206,7 @@ impl Readable for BlindedPaymentTlvs {
|
|||
Ok(BlindedPaymentTlvs::Receive(ReceiveTlvs {
|
||||
payment_secret: payment_secret.ok_or(DecodeError::InvalidValue)?,
|
||||
payment_constraints: payment_constraints.0.unwrap(),
|
||||
payment_context: payment_context.0.unwrap(),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
@ -309,10 +337,27 @@ impl Readable for PaymentConstraints {
|
|||
}
|
||||
}
|
||||
|
||||
impl_writeable_tlv_based_enum!(PaymentContext,
|
||||
;
|
||||
(0, Unknown),
|
||||
);
|
||||
|
||||
impl Writeable for UnknownPaymentContext {
|
||||
fn write<W: Writer>(&self, _w: &mut W) -> Result<(), io::Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Readable for UnknownPaymentContext {
|
||||
fn read<R: io::Read>(_r: &mut R) -> Result<Self, DecodeError> {
|
||||
Ok(UnknownPaymentContext(()))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use bitcoin::secp256k1::PublicKey;
|
||||
use crate::blinded_path::payment::{ForwardNode, ForwardTlvs, ReceiveTlvs, PaymentConstraints, PaymentRelay};
|
||||
use crate::blinded_path::payment::{ForwardNode, ForwardTlvs, ReceiveTlvs, PaymentConstraints, PaymentContext, PaymentRelay};
|
||||
use crate::ln::PaymentSecret;
|
||||
use crate::ln::features::BlindedHopFeatures;
|
||||
use crate::ln::functional_test_utils::TEST_FINAL_CLTV;
|
||||
|
@ -361,6 +406,7 @@ mod tests {
|
|||
max_cltv_expiry: 0,
|
||||
htlc_minimum_msat: 1,
|
||||
},
|
||||
payment_context: PaymentContext::unknown(),
|
||||
};
|
||||
let htlc_maximum_msat = 100_000;
|
||||
let blinded_payinfo = super::compute_payinfo(&intermediate_nodes[..], &recv_tlvs, htlc_maximum_msat, 12).unwrap();
|
||||
|
@ -379,6 +425,7 @@ mod tests {
|
|||
max_cltv_expiry: 0,
|
||||
htlc_minimum_msat: 1,
|
||||
},
|
||||
payment_context: PaymentContext::unknown(),
|
||||
};
|
||||
let blinded_payinfo = super::compute_payinfo(&[], &recv_tlvs, 4242, TEST_FINAL_CLTV as u16).unwrap();
|
||||
assert_eq!(blinded_payinfo.fee_base_msat, 0);
|
||||
|
@ -432,6 +479,7 @@ mod tests {
|
|||
max_cltv_expiry: 0,
|
||||
htlc_minimum_msat: 3,
|
||||
},
|
||||
payment_context: PaymentContext::unknown(),
|
||||
};
|
||||
let htlc_maximum_msat = 100_000;
|
||||
let blinded_payinfo = super::compute_payinfo(&intermediate_nodes[..], &recv_tlvs, htlc_maximum_msat, TEST_FINAL_CLTV as u16).unwrap();
|
||||
|
@ -482,6 +530,7 @@ mod tests {
|
|||
max_cltv_expiry: 0,
|
||||
htlc_minimum_msat: 1,
|
||||
},
|
||||
payment_context: PaymentContext::unknown(),
|
||||
};
|
||||
let htlc_minimum_msat = 3798;
|
||||
assert!(super::compute_payinfo(&intermediate_nodes[..], &recv_tlvs, htlc_minimum_msat - 1, TEST_FINAL_CLTV as u16).is_err());
|
||||
|
@ -536,6 +585,7 @@ mod tests {
|
|||
max_cltv_expiry: 0,
|
||||
htlc_minimum_msat: 1,
|
||||
},
|
||||
payment_context: PaymentContext::unknown(),
|
||||
};
|
||||
|
||||
let blinded_payinfo = super::compute_payinfo(&intermediate_nodes[..], &recv_tlvs, 10_000, TEST_FINAL_CLTV as u16).unwrap();
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
|
||||
use crate::blinded_path::BlindedPath;
|
||||
use crate::blinded_path::payment::{ForwardNode, ForwardTlvs, PaymentConstraints, PaymentRelay, ReceiveTlvs};
|
||||
use crate::blinded_path::payment::{ForwardNode, ForwardTlvs, PaymentConstraints, PaymentContext, PaymentRelay, ReceiveTlvs};
|
||||
use crate::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PaymentFailureReason};
|
||||
use crate::ln::PaymentSecret;
|
||||
use crate::ln::channelmanager;
|
||||
|
@ -63,6 +63,7 @@ fn blinded_payment_path(
|
|||
htlc_minimum_msat:
|
||||
intro_node_min_htlc_opt.unwrap_or_else(|| channel_upds.last().unwrap().htlc_minimum_msat),
|
||||
},
|
||||
payment_context: PaymentContext::unknown(),
|
||||
};
|
||||
let mut secp_ctx = Secp256k1::new();
|
||||
BlindedPath::new_for_payment(
|
||||
|
@ -108,6 +109,7 @@ fn do_one_hop_blinded_path(success: bool) {
|
|||
max_cltv_expiry: u32::max_value(),
|
||||
htlc_minimum_msat: chan_upd.htlc_minimum_msat,
|
||||
},
|
||||
payment_context: PaymentContext::unknown(),
|
||||
};
|
||||
let mut secp_ctx = Secp256k1::new();
|
||||
let blinded_path = BlindedPath::one_hop_for_payment(
|
||||
|
@ -151,6 +153,7 @@ fn mpp_to_one_hop_blinded_path() {
|
|||
max_cltv_expiry: u32::max_value(),
|
||||
htlc_minimum_msat: chan_upd_1_3.htlc_minimum_msat,
|
||||
},
|
||||
payment_context: PaymentContext::unknown(),
|
||||
};
|
||||
let blinded_path = BlindedPath::one_hop_for_payment(
|
||||
nodes[3].node.get_our_node_id(), payee_tlvs, TEST_FINAL_CLTV as u16,
|
||||
|
@ -1281,6 +1284,7 @@ fn custom_tlvs_to_blinded_path() {
|
|||
max_cltv_expiry: u32::max_value(),
|
||||
htlc_minimum_msat: chan_upd.htlc_minimum_msat,
|
||||
},
|
||||
payment_context: PaymentContext::unknown(),
|
||||
};
|
||||
let mut secp_ctx = Secp256k1::new();
|
||||
let blinded_path = BlindedPath::one_hop_for_payment(
|
||||
|
|
|
@ -32,7 +32,7 @@ use bitcoin::secp256k1::Secp256k1;
|
|||
use bitcoin::{secp256k1, Sequence};
|
||||
|
||||
use crate::blinded_path::{BlindedPath, NodeIdLookUp};
|
||||
use crate::blinded_path::payment::{PaymentConstraints, ReceiveTlvs};
|
||||
use crate::blinded_path::payment::{PaymentConstraints, PaymentContext, ReceiveTlvs};
|
||||
use crate::chain;
|
||||
use crate::chain::{Confirm, ChannelMonitorUpdateStatus, Watch, BestBlock};
|
||||
use crate::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator, LowerBoundedFeeEstimator};
|
||||
|
@ -8995,6 +8995,7 @@ where
|
|||
max_cltv_expiry,
|
||||
htlc_minimum_msat: 1,
|
||||
},
|
||||
payment_context: PaymentContext::unknown(),
|
||||
};
|
||||
self.router.create_blinded_payment_paths(
|
||||
payee_node_id, first_hops, payee_tlvs, amount_msats, secp_ctx
|
||||
|
|
|
@ -2713,7 +2713,7 @@ impl<NS: Deref> ReadableArgs<(Option<PublicKey>, &NS)> for InboundOnionPayload w
|
|||
})
|
||||
},
|
||||
ChaChaPolyReadAdapter { readable: BlindedPaymentTlvs::Receive(ReceiveTlvs {
|
||||
payment_secret, payment_constraints
|
||||
payment_secret, payment_constraints, payment_context: _
|
||||
})} => {
|
||||
if total_msat.unwrap_or(0) > MAX_VALUE_MSAT { return Err(DecodeError::InvalidValue) }
|
||||
Ok(Self::BlindedReceive {
|
||||
|
|
Loading…
Add table
Reference in a new issue