@@ -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,26 @@ 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 allow specifying a number of dummy hops
92+ pub fn new_with_dummy_hops < ES : Deref , T : secp256k1:: Signing + secp256k1:: Verification > (
93+ intermediate_nodes : & [ MessageForwardNode ] , recipient_node_id : PublicKey ,
94+ dummy_hop_count : usize , local_node_receive_key : ReceiveAuthKey , context : MessageContext ,
95+ entropy_source : ES , secp_ctx : & Secp256k1 < T > ,
96+ ) -> Result < Self , ( ) >
7797 where
7898 ES :: Target : EntropySource ,
7999 {
@@ -91,6 +111,7 @@ impl BlindedMessagePath {
91111 secp_ctx,
92112 intermediate_nodes,
93113 recipient_node_id,
114+ dummy_hop_count,
94115 context,
95116 & blinding_secret,
96117 local_node_receive_key,
@@ -638,15 +659,24 @@ impl_writeable_tlv_based!(DNSResolverContext, {
638659/// to pad message blinded path's [`BlindedHop`]
639660pub ( crate ) const MESSAGE_PADDING_ROUND_OFF : usize = 100 ;
640661
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 ( crate ) const MAX_DUMMY_HOPS_COUNT : usize = 10 ;
666+
641667/// Construct blinded onion message hops for the given `intermediate_nodes` and `recipient_node_id`.
642668pub ( super ) fn blinded_hops < T : secp256k1:: Signing + secp256k1:: Verification > (
643669 secp_ctx : & Secp256k1 < T > , intermediate_nodes : & [ MessageForwardNode ] ,
644- recipient_node_id : PublicKey , context : MessageContext , session_priv : & SecretKey ,
645- 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 ,
646672) -> Result < Vec < BlindedHop > , secp256k1:: Error > {
673+ let dummy_count = cmp:: min ( dummy_hop_count, MAX_DUMMY_HOPS_COUNT ) ;
647674 let pks = intermediate_nodes
648675 . iter ( )
649676 . map ( |node| ( node. node_id , None ) )
677+ . chain (
678+ core:: iter:: repeat ( ( recipient_node_id, Some ( local_node_receive_key) ) ) . take ( dummy_count) ,
679+ )
650680 . chain ( core:: iter:: once ( ( recipient_node_id, Some ( local_node_receive_key) ) ) ) ;
651681 let is_compact = intermediate_nodes. iter ( ) . any ( |node| node. short_channel_id . is_some ( ) ) ;
652682
@@ -661,6 +691,7 @@ pub(super) fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>(
661691 . map ( |next_hop| {
662692 ControlTlvs :: Forward ( ForwardTlvs { next_hop, next_blinding_override : None } )
663693 } )
694+ . chain ( ( 0 ..dummy_count) . map ( |_| ControlTlvs :: Dummy ( DummyTlv { } ) ) )
664695 . chain ( core:: iter:: once ( ControlTlvs :: Receive ( ReceiveTlvs { context : Some ( context) } ) ) ) ;
665696
666697 if is_compact {
0 commit comments