@@ -31,9 +31,9 @@ use crate::types::payment::PaymentHash;
3131use crate :: util:: scid_utils;
3232use crate :: util:: ser:: { FixedLengthReader , LengthReadableArgs , Readable , Writeable , Writer } ;
3333
34- use core:: mem;
3534use core:: ops:: Deref ;
3635use core:: time:: Duration ;
36+ use core:: { cmp, mem} ;
3737
3838/// A blinded path to be used for sending or receiving a message, hiding the identity of the
3939/// recipient.
@@ -74,6 +74,29 @@ impl BlindedMessagePath {
7474 local_node_receive_key : ReceiveAuthKey , context : MessageContext , entropy_source : ES ,
7575 secp_ctx : & Secp256k1 < T > ,
7676 ) -> Result < Self , ( ) >
77+ where
78+ ES :: Target : EntropySource ,
79+ {
80+ BlindedMessagePath :: new_with_dummy_hops (
81+ intermediate_nodes,
82+ recipient_node_id,
83+ 0 ,
84+ local_node_receive_key,
85+ context,
86+ entropy_source,
87+ secp_ctx,
88+ )
89+ }
90+
91+ /// Same as [`BlindedMessagePath::new`], but allows specifying a number of dummy hops.
92+ ///
93+ /// Note:
94+ /// At most [`MAX_DUMMY_HOPS_COUNT`] dummy hops can be added to the blinded path.
95+ pub fn new_with_dummy_hops < ES : Deref , T : secp256k1:: Signing + secp256k1:: Verification > (
96+ intermediate_nodes : & [ MessageForwardNode ] , recipient_node_id : PublicKey ,
97+ dummy_hop_count : usize , local_node_receive_key : ReceiveAuthKey , context : MessageContext ,
98+ entropy_source : ES , secp_ctx : & Secp256k1 < T > ,
99+ ) -> Result < Self , ( ) >
77100 where
78101 ES :: Target : EntropySource ,
79102 {
@@ -91,6 +114,7 @@ impl BlindedMessagePath {
91114 secp_ctx,
92115 intermediate_nodes,
93116 recipient_node_id,
117+ dummy_hop_count,
94118 context,
95119 & blinding_secret,
96120 local_node_receive_key,
@@ -638,15 +662,24 @@ impl_writeable_tlv_based!(DNSResolverContext, {
638662/// to pad message blinded path's [`BlindedHop`]
639663pub ( crate ) const MESSAGE_PADDING_ROUND_OFF : usize = 100 ;
640664
665+ /// The maximum number of dummy hops that can be added to a blinded path.
666+ /// This is to prevent paths from becoming too long and potentially causing
667+ /// issues with message processing or routing.
668+ pub const MAX_DUMMY_HOPS_COUNT : usize = 10 ;
669+
641670/// Construct blinded onion message hops for the given `intermediate_nodes` and `recipient_node_id`.
642671pub ( super ) fn blinded_hops < T : secp256k1:: Signing + secp256k1:: Verification > (
643672 secp_ctx : & Secp256k1 < T > , intermediate_nodes : & [ MessageForwardNode ] ,
644- recipient_node_id : PublicKey , context : MessageContext , session_priv : & SecretKey ,
645- local_node_receive_key : ReceiveAuthKey ,
673+ recipient_node_id : PublicKey , dummy_hop_count : usize , context : MessageContext ,
674+ session_priv : & SecretKey , local_node_receive_key : ReceiveAuthKey ,
646675) -> Result < Vec < BlindedHop > , secp256k1:: Error > {
676+ let dummy_count = cmp:: min ( dummy_hop_count, MAX_DUMMY_HOPS_COUNT ) ;
647677 let pks = intermediate_nodes
648678 . iter ( )
649679 . map ( |node| ( node. node_id , None ) )
680+ . chain (
681+ core:: iter:: repeat ( ( recipient_node_id, Some ( local_node_receive_key) ) ) . take ( dummy_count) ,
682+ )
650683 . chain ( core:: iter:: once ( ( recipient_node_id, Some ( local_node_receive_key) ) ) ) ;
651684 let is_compact = intermediate_nodes. iter ( ) . any ( |node| node. short_channel_id . is_some ( ) ) ;
652685
@@ -661,6 +694,7 @@ pub(super) fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>(
661694 . map ( |next_hop| {
662695 ControlTlvs :: Forward ( ForwardTlvs { next_hop, next_blinding_override : None } )
663696 } )
697+ . chain ( ( 0 ..dummy_count) . map ( |_| ControlTlvs :: Dummy ( DummyTlv { } ) ) )
664698 . chain ( core:: iter:: once ( ControlTlvs :: Receive ( ReceiveTlvs { context : Some ( context) } ) ) ) ;
665699
666700 if is_compact {
0 commit comments