@@ -1564,9 +1564,13 @@ fn add_random_cltv_offset(route: &mut Route, payment_params: &PaymentParameters,
1564
1564
for path in route. paths . iter_mut ( ) {
1565
1565
let mut shadow_ctlv_expiry_delta_offset: u32 = 0 ;
1566
1566
1567
- // Mark all nodes on the actual path as visited to avoid looping random walks.
1568
- let mut visited_nodes: Vec < NodeId > = path. iter ( )
1569
- . map ( |h| NodeId :: from_pubkey ( & h. pubkey ) ) . collect ( ) ;
1567
+ // Remember the last three nodes of the random walk and avoid looping back on them.
1568
+ // Init with the last three nodes from the actual path, if possible.
1569
+ let last_id = NodeId :: from_pubkey ( & path. last ( ) . unwrap ( ) . pubkey ) ;
1570
+ let second_last_id = NodeId :: from_pubkey ( & path. get ( path. len ( ) . saturating_sub ( 2 ) ) . unwrap ( ) . pubkey ) ;
1571
+ let third_last_id = NodeId :: from_pubkey ( & path. get ( path. len ( ) . saturating_sub ( 3 ) ) . unwrap ( ) . pubkey ) ;
1572
+ let mut nodes_to_avoid: [ NodeId ; 3 ] = [ third_last_id, second_last_id, last_id] ;
1573
+ let mut nodes_ring_index = 0 ;
1570
1574
1571
1575
// Choose the last publicly known node as the starting point for the random walk.
1572
1576
let mut cur_hop: Option < NodeId > = None ;
@@ -1599,8 +1603,9 @@ fn add_random_cltv_offset(route: &mut Route, payment_params: &PaymentParameters,
1599
1603
. and_then ( |index| cur_node. channels . get ( index) )
1600
1604
. and_then ( |id| network_channels. get ( id) ) {
1601
1605
random_channel. as_directed_from ( & cur_node_id) . map ( |( dir_info, next_id) | {
1602
- if !visited_nodes. contains ( next_id) {
1603
- visited_nodes. push ( * next_id) ;
1606
+ if !nodes_to_avoid. iter ( ) . any ( |x| x == next_id) {
1607
+ nodes_to_avoid[ nodes_ring_index] = * next_id;
1608
+ nodes_ring_index = ( nodes_ring_index + 1 ) % 3 ;
1604
1609
dir_info. direction ( ) . map ( |channel_update_info| {
1605
1610
random_hop_offset = channel_update_info. cltv_expiry_delta . into ( ) ;
1606
1611
cur_hop = Some ( * next_id) ;
0 commit comments