@@ -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,
@@ -635,15 +659,24 @@ impl_writeable_tlv_based!(DNSResolverContext, {
635659/// to pad message blinded path's [`BlindedHop`]
636660pub ( crate ) const MESSAGE_PADDING_ROUND_OFF : usize = 100 ;
637661
662+ /// The maximum number of dummy hops that can be added to a blinded path.
663+ /// This is to prevent paths from becoming too long and potentially causing
664+ /// issues with message processing or routing.
665+ pub const MAX_DUMMY_HOPS_COUNT : usize = 10 ;
666+
638667/// Construct blinded onion message hops for the given `intermediate_nodes` and `recipient_node_id`.
639668pub ( super ) fn blinded_hops < T : secp256k1:: Signing + secp256k1:: Verification > (
640669 secp_ctx : & Secp256k1 < T > , intermediate_nodes : & [ MessageForwardNode ] ,
641- recipient_node_id : PublicKey , context : MessageContext , session_priv : & SecretKey ,
642- local_node_receive_key : ReceiveAuthKey ,
670+ recipient_node_id : PublicKey , dummy_hop_count : usize , context : MessageContext ,
671+ session_priv : & SecretKey , local_node_receive_key : ReceiveAuthKey ,
643672) -> Result < Vec < BlindedHop > , secp256k1:: Error > {
673+ let dummy_count = cmp:: min ( dummy_hop_count, MAX_DUMMY_HOPS_COUNT ) ;
644674 let pks = intermediate_nodes
645675 . iter ( )
646676 . map ( |node| ( node. node_id , None ) )
677+ . chain (
678+ core:: iter:: repeat ( ( recipient_node_id, Some ( local_node_receive_key) ) ) . take ( dummy_count) ,
679+ )
647680 . chain ( core:: iter:: once ( ( recipient_node_id, Some ( local_node_receive_key) ) ) ) ;
648681 let is_compact = intermediate_nodes. iter ( ) . any ( |node| node. short_channel_id . is_some ( ) ) ;
649682
@@ -658,6 +691,7 @@ pub(super) fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>(
658691 . map ( |next_hop| {
659692 ControlTlvs :: Forward ( ForwardTlvs { next_hop, next_blinding_override : None } )
660693 } )
694+ . chain ( ( 0 ..dummy_count) . map ( |_| ControlTlvs :: Dummy ) )
661695 . chain ( core:: iter:: once ( ControlTlvs :: Receive ( ReceiveTlvs { context : Some ( context) } ) ) ) ;
662696
663697 if is_compact {
0 commit comments