@@ -26,7 +26,7 @@ use crate::offers::invoice_request::InvoiceRequestFields;
2626use crate :: offers:: offer:: OfferId ;
2727use crate :: routing:: gossip:: { NodeId , ReadOnlyNetworkGraph } ;
2828use crate :: sign:: { EntropySource , NodeSigner , Recipient } ;
29- use crate :: util:: ser:: { FixedLengthReader , LengthReadableArgs , HighZeroBytesDroppedBigSize , Readable , Writeable , Writer } ;
29+ use crate :: util:: ser:: { FixedLengthReader , LengthReadableArgs , HighZeroBytesDroppedBigSize , Readable , WithoutLength , Writeable , Writer } ;
3030
3131use core:: mem;
3232use core:: ops:: Deref ;
@@ -201,6 +201,9 @@ pub struct ForwardTlvs {
201201 ///
202202 /// [`BlindedHop::encrypted_payload`]: crate::blinded_path::BlindedHop::encrypted_payload
203203 pub features : BlindedHopFeatures ,
204+ /// Set if this [`BlindedPaymentPath`] is concatenated to another, to indicate the
205+ /// [`BlindedPaymentPath::blinding_point`] of the appended blinded path.
206+ pub next_blinding_override : Option < PublicKey > ,
204207}
205208
206209/// Data to construct a [`BlindedHop`] for receiving a payment. This payload is custom to LDK and
@@ -234,7 +237,7 @@ enum BlindedPaymentTlvsRef<'a> {
234237/// Parameters for relaying over a given [`BlindedHop`].
235238///
236239/// [`BlindedHop`]: crate::blinded_path::BlindedHop
237- #[ derive( Clone , Debug ) ]
240+ #[ derive( Clone , Debug , PartialEq ) ]
238241pub struct PaymentRelay {
239242 /// Number of blocks subtracted from an incoming HTLC's `cltv_expiry` for this [`BlindedHop`].
240243 pub cltv_expiry_delta : u16 ,
@@ -248,7 +251,7 @@ pub struct PaymentRelay {
248251/// Constraints for relaying over a given [`BlindedHop`].
249252///
250253/// [`BlindedHop`]: crate::blinded_path::BlindedHop
251- #[ derive( Clone , Debug ) ]
254+ #[ derive( Clone , Debug , PartialEq ) ]
252255pub struct PaymentConstraints {
253256 /// The maximum total CLTV that is acceptable when relaying a payment over this [`BlindedHop`].
254257 pub max_cltv_expiry : u32 ,
@@ -341,7 +344,7 @@ impl Writeable for ForwardTlvs {
341344 fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
342345 let features_opt =
343346 if self . features == BlindedHopFeatures :: empty ( ) { None }
344- else { Some ( & self . features ) } ;
347+ else { Some ( WithoutLength ( & self . features ) ) } ;
345348 encode_tlv_stream ! ( w, {
346349 ( 2 , self . short_channel_id, required) ,
347350 ( 10 , self . payment_relay, required) ,
@@ -379,9 +382,10 @@ impl Readable for BlindedPaymentTlvs {
379382 _init_and_read_tlv_stream ! ( r, {
380383 ( 1 , _padding, option) ,
381384 ( 2 , scid, option) ,
385+ ( 8 , next_blinding_override, option) ,
382386 ( 10 , payment_relay, option) ,
383387 ( 12 , payment_constraints, required) ,
384- ( 14 , features, option) ,
388+ ( 14 , features, ( option, encoding : ( BlindedHopFeatures , WithoutLength ) ) ) ,
385389 ( 65536 , payment_secret, option) ,
386390 ( 65537 , payment_context, ( default_value, PaymentContext :: unknown( ) ) ) ,
387391 } ) ;
@@ -395,6 +399,7 @@ impl Readable for BlindedPaymentTlvs {
395399 short_channel_id,
396400 payment_relay : payment_relay. ok_or ( DecodeError :: InvalidValue ) ?,
397401 payment_constraints : payment_constraints. 0 . unwrap ( ) ,
402+ next_blinding_override,
398403 features : features. unwrap_or_else ( BlindedHopFeatures :: empty) ,
399404 } ) )
400405 } else {
@@ -602,6 +607,7 @@ mod tests {
602607 max_cltv_expiry: 0 ,
603608 htlc_minimum_msat: 100 ,
604609 } ,
610+ next_blinding_override: None ,
605611 features: BlindedHopFeatures :: empty( ) ,
606612 } ,
607613 htlc_maximum_msat: u64 :: max_value( ) ,
@@ -618,6 +624,7 @@ mod tests {
618624 max_cltv_expiry: 0 ,
619625 htlc_minimum_msat: 1_000 ,
620626 } ,
627+ next_blinding_override: None ,
621628 features: BlindedHopFeatures :: empty( ) ,
622629 } ,
623630 htlc_maximum_msat: u64 :: max_value( ) ,
@@ -675,6 +682,7 @@ mod tests {
675682 max_cltv_expiry: 0 ,
676683 htlc_minimum_msat: 1 ,
677684 } ,
685+ next_blinding_override: None ,
678686 features: BlindedHopFeatures :: empty( ) ,
679687 } ,
680688 htlc_maximum_msat: u64 :: max_value( )
@@ -691,6 +699,7 @@ mod tests {
691699 max_cltv_expiry: 0 ,
692700 htlc_minimum_msat: 2_000 ,
693701 } ,
702+ next_blinding_override: None ,
694703 features: BlindedHopFeatures :: empty( ) ,
695704 } ,
696705 htlc_maximum_msat: u64 :: max_value( )
@@ -726,6 +735,7 @@ mod tests {
726735 max_cltv_expiry: 0 ,
727736 htlc_minimum_msat: 5_000 ,
728737 } ,
738+ next_blinding_override: None ,
729739 features: BlindedHopFeatures :: empty( ) ,
730740 } ,
731741 htlc_maximum_msat: u64 :: max_value( )
@@ -742,6 +752,7 @@ mod tests {
742752 max_cltv_expiry: 0 ,
743753 htlc_minimum_msat: 2_000 ,
744754 } ,
755+ next_blinding_override: None ,
745756 features: BlindedHopFeatures :: empty( ) ,
746757 } ,
747758 htlc_maximum_msat: u64 :: max_value( )
@@ -781,6 +792,7 @@ mod tests {
781792 max_cltv_expiry: 0 ,
782793 htlc_minimum_msat: 1 ,
783794 } ,
795+ next_blinding_override: None ,
784796 features: BlindedHopFeatures :: empty( ) ,
785797 } ,
786798 htlc_maximum_msat: 5_000 ,
@@ -797,6 +809,7 @@ mod tests {
797809 max_cltv_expiry: 0 ,
798810 htlc_minimum_msat: 1 ,
799811 } ,
812+ next_blinding_override: None ,
800813 features: BlindedHopFeatures :: empty( ) ,
801814 } ,
802815 htlc_maximum_msat: 10_000
0 commit comments