@@ -2180,6 +2180,10 @@ fn add_random_cltv_offset(route: &mut Route, payment_params: &PaymentParameters,
21802180 shadow_ctlv_expiry_delta_offset = cmp:: min ( shadow_ctlv_expiry_delta_offset, max_path_offset) ;
21812181
21822182 // Add 'shadow' CLTV offset to the final hop
2183+ if let Some ( tail) = path. blinded_tail . as_mut ( ) {
2184+ tail. excess_final_cltv_expiry_delta = tail. excess_final_cltv_expiry_delta
2185+ . checked_add ( shadow_ctlv_expiry_delta_offset) . unwrap_or ( tail. excess_final_cltv_expiry_delta ) ;
2186+ }
21832187 if let Some ( last_hop) = path. hops . last_mut ( ) {
21842188 last_hop. cltv_expiry_delta = last_hop. cltv_expiry_delta
21852189 . checked_add ( shadow_ctlv_expiry_delta_offset) . unwrap_or ( last_hop. cltv_expiry_delta ) ;
@@ -5872,6 +5876,50 @@ mod tests {
58725876 assert_eq ! ( * inflight_htlcs. 0 . get( & ( 42 , true ) ) . unwrap( ) , 301 ) ;
58735877 assert_eq ! ( * inflight_htlcs. 0 . get( & ( 43 , false ) ) . unwrap( ) , 201 ) ;
58745878 }
5879+
5880+ #[ test]
5881+ fn blinded_path_cltv_shadow_offset ( ) {
5882+ // Make sure we add a shadow offset when sending to blinded paths.
5883+ let blinded_path = BlindedPath {
5884+ introduction_node_id : ln_test_utils:: pubkey ( 43 ) ,
5885+ blinding_point : ln_test_utils:: pubkey ( 44 ) ,
5886+ blinded_hops : vec ! [
5887+ BlindedHop { blinded_node_id: ln_test_utils:: pubkey( 45 ) , encrypted_payload: Vec :: new( ) } ,
5888+ BlindedHop { blinded_node_id: ln_test_utils:: pubkey( 46 ) , encrypted_payload: Vec :: new( ) }
5889+ ] ,
5890+ } ;
5891+ let mut route = Route { paths : vec ! [ Path {
5892+ hops: vec![ RouteHop {
5893+ pubkey: ln_test_utils:: pubkey( 42 ) ,
5894+ node_features: NodeFeatures :: empty( ) ,
5895+ short_channel_id: 42 ,
5896+ channel_features: ChannelFeatures :: empty( ) ,
5897+ fee_msat: 100 ,
5898+ cltv_expiry_delta: 0 ,
5899+ } ,
5900+ RouteHop {
5901+ pubkey: blinded_path. introduction_node_id,
5902+ node_features: NodeFeatures :: empty( ) ,
5903+ short_channel_id: 43 ,
5904+ channel_features: ChannelFeatures :: empty( ) ,
5905+ fee_msat: 1 ,
5906+ cltv_expiry_delta: 0 ,
5907+ }
5908+ ] ,
5909+ blinded_tail: Some ( BlindedTail {
5910+ hops: blinded_path. blinded_hops,
5911+ blinding_point: blinded_path. blinding_point,
5912+ excess_final_cltv_expiry_delta: 0 ,
5913+ final_value_msat: 200 ,
5914+ } ) ,
5915+ } ] , payment_params : None } ;
5916+
5917+ let payment_params = PaymentParameters :: from_node_id ( ln_test_utils:: pubkey ( 47 ) , 18 ) ;
5918+ let ( _, network_graph, _, _, _) = build_line_graph ( ) ;
5919+ add_random_cltv_offset ( & mut route, & payment_params, & network_graph. read_only ( ) , & [ 0 ; 32 ] ) ;
5920+ assert_eq ! ( route. paths[ 0 ] . blinded_tail. as_ref( ) . unwrap( ) . excess_final_cltv_expiry_delta, 40 ) ;
5921+ assert_eq ! ( route. paths[ 0 ] . hops. last( ) . unwrap( ) . cltv_expiry_delta, 40 ) ;
5922+ }
58755923}
58765924
58775925#[ cfg( all( test, not( feature = "no-std" ) ) ) ]
0 commit comments