@@ -824,7 +824,7 @@ async fn handle_intercepted_htlc(
824824 shutdown_listener : Listener ,
825825) -> Result < Result < CustomRecords , ForwardingError > , CriticalError > {
826826 if interceptors. is_empty ( ) {
827- return Ok ( Ok ( HashMap :: new ( ) ) ) ;
827+ return Ok ( Ok ( request . incoming_custom_records ) ) ;
828828 }
829829
830830 let mut attached_custom_records: CustomRecords = HashMap :: new ( ) ;
@@ -925,6 +925,9 @@ pub struct SimGraph {
925925 /// trigger a shutdown signal to other interceptors.
926926 interceptors : Vec < Arc < dyn Interceptor > > ,
927927
928+ /// Custom records that will be added to the first outgoing HTLC in a payment.
929+ default_custom_records : CustomRecords ,
930+
928931 /// Shutdown signal that can be used to trigger a shutdown if a critical error occurs. Listener
929932 /// can be used to listen for shutdown signals coming from upstream.
930933 shutdown_signal : ( Trigger , Listener ) ,
@@ -936,6 +939,7 @@ impl SimGraph {
936939 graph_channels : Vec < SimulatedChannel > ,
937940 tasks : TaskTracker ,
938941 interceptors : Vec < Arc < dyn Interceptor > > ,
942+ default_custom_records : CustomRecords ,
939943 shutdown_signal : ( Trigger , Listener ) ,
940944 ) -> Result < Self , SimulationError > {
941945 let mut nodes: HashMap < PublicKey , Vec < u64 > > = HashMap :: new ( ) ;
@@ -971,6 +975,7 @@ impl SimGraph {
971975 channels : Arc :: new ( Mutex :: new ( channels) ) ,
972976 tasks,
973977 interceptors,
978+ default_custom_records,
974979 shutdown_signal,
975980 } )
976981 }
@@ -1098,6 +1103,7 @@ impl SimNetwork for SimGraph {
10981103 payment_hash,
10991104 sender,
11001105 interceptors : self . interceptors . clone ( ) ,
1106+ custom_records : self . default_custom_records . clone ( ) ,
11011107 shutdown_signal : self . shutdown_signal . clone ( ) ,
11021108 } ) ) ;
11031109 }
@@ -1149,13 +1155,14 @@ async fn add_htlcs(
11491155 route : Path ,
11501156 payment_hash : PaymentHash ,
11511157 interceptors : Vec < Arc < dyn Interceptor > > ,
1158+ custom_records : CustomRecords ,
11521159 shutdown_listener : Listener ,
11531160) -> Result < Result < ( ) , ( Option < usize > , ForwardingError ) > , CriticalError > {
11541161 let mut outgoing_node = source;
11551162 let mut outgoing_amount = route. fee_msat ( ) + route. final_value_msat ( ) ;
11561163 let mut outgoing_cltv = route. hops . iter ( ) . map ( |hop| hop. cltv_expiry_delta ) . sum ( ) ;
11571164
1158- let mut incoming_custom_records = HashMap :: new ( ) ;
1165+ let mut incoming_custom_records = custom_records ;
11591166
11601167 // Tracks the hop index that we need to remove htlcs from on payment completion (both success and failure).
11611168 // Given a payment from A to C, over the route A -- B -- C, this index has the following meanings:
@@ -1237,7 +1244,7 @@ async fn add_htlcs(
12371244 forwarding_node : hop. pubkey ,
12381245 payment_hash,
12391246 incoming_htlc : incoming_htlc. clone ( ) ,
1240- incoming_custom_records : incoming_custom_records . clone ( ) ,
1247+ incoming_custom_records,
12411248 outgoing_channel_id : next_scid,
12421249 incoming_amount_msat : outgoing_amount,
12431250 outgoing_amount_msat : outgoing_amount - hop. fee_msat ,
@@ -1345,6 +1352,7 @@ struct PropagatePaymentRequest {
13451352 payment_hash : PaymentHash ,
13461353 sender : Sender < Result < PaymentResult , LightningError > > ,
13471354 interceptors : Vec < Arc < dyn Interceptor > > ,
1355+ custom_records : CustomRecords ,
13481356 shutdown_signal : ( Trigger , Listener ) ,
13491357}
13501358
@@ -1359,6 +1367,7 @@ async fn propagate_payment(request: PropagatePaymentRequest) {
13591367 request. route . clone ( ) ,
13601368 request. payment_hash ,
13611369 request. interceptors . clone ( ) ,
1370+ request. custom_records ,
13621371 request. shutdown_signal . 1 ,
13631372 )
13641373 . await
@@ -1964,7 +1973,11 @@ mod tests {
19641973 /// Alice (100) --- (0) Bob (100) --- (0) Carol (100) --- (0) Dave
19651974 ///
19661975 /// The nodes pubkeys in this chain of channels are provided in-order for easy access.
1967- async fn new ( capacity : u64 , interceptors : Vec < Arc < dyn Interceptor > > ) -> Self {
1976+ async fn new (
1977+ capacity : u64 ,
1978+ interceptors : Vec < Arc < dyn Interceptor > > ,
1979+ custom_records : CustomRecords ,
1980+ ) -> Self {
19681981 let shutdown_signal = triggered:: trigger ( ) ;
19691982 let channels = create_simulated_channels ( 3 , capacity) ;
19701983 let routing_graph = Arc :: new (
@@ -1991,6 +2004,7 @@ mod tests {
19912004 channels. clone ( ) ,
19922005 TaskTracker :: new ( ) ,
19932006 interceptors,
2007+ custom_records,
19942008 shutdown_signal,
19952009 )
19962010 . expect ( "could not create test graph" ) ,
@@ -2071,7 +2085,8 @@ mod tests {
20712085 #[ tokio:: test]
20722086 async fn test_successful_dispatch ( ) {
20732087 let chan_capacity = 500_000_000 ;
2074- let mut test_kit = DispatchPaymentTestKit :: new ( chan_capacity, vec ! [ ] ) . await ;
2088+ let mut test_kit =
2089+ DispatchPaymentTestKit :: new ( chan_capacity, vec ! [ ] , CustomRecords :: default ( ) ) . await ;
20752090
20762091 // Send a payment that should succeed from Alice -> Dave.
20772092 let mut amt = 20_000 ;
@@ -2136,7 +2151,8 @@ mod tests {
21362151 #[ tokio:: test]
21372152 async fn test_successful_multi_hop ( ) {
21382153 let chan_capacity = 500_000_000 ;
2139- let mut test_kit = DispatchPaymentTestKit :: new ( chan_capacity, vec ! [ ] ) . await ;
2154+ let mut test_kit =
2155+ DispatchPaymentTestKit :: new ( chan_capacity, vec ! [ ] , CustomRecords :: default ( ) ) . await ;
21402156
21412157 // Send a payment that should succeed from Alice -> Dave.
21422158 let amt = 20_000 ;
@@ -2166,7 +2182,8 @@ mod tests {
21662182 #[ tokio:: test]
21672183 async fn test_single_hop_payments ( ) {
21682184 let chan_capacity = 500_000_000 ;
2169- let mut test_kit = DispatchPaymentTestKit :: new ( chan_capacity, vec ! [ ] ) . await ;
2185+ let mut test_kit =
2186+ DispatchPaymentTestKit :: new ( chan_capacity, vec ! [ ] , CustomRecords :: default ( ) ) . await ;
21702187
21712188 // Send a single hop payment from Alice -> Bob, it will succeed because Alice has all the liquidity.
21722189 let amt = 150_000 ;
@@ -2198,7 +2215,8 @@ mod tests {
21982215 #[ tokio:: test]
21992216 async fn test_multi_hop_faiulre ( ) {
22002217 let chan_capacity = 500_000_000 ;
2201- let mut test_kit = DispatchPaymentTestKit :: new ( chan_capacity, vec ! [ ] ) . await ;
2218+ let mut test_kit =
2219+ DispatchPaymentTestKit :: new ( chan_capacity, vec ! [ ] , CustomRecords :: default ( ) ) . await ;
22022220
22032221 // Drain liquidity between Bob and Carol to force failures on Bob's outgoing linke.
22042222 test_kit
@@ -2244,7 +2262,7 @@ mod tests {
22442262 channel_id : ShortChannelID ( 0 ) ,
22452263 index : 0 ,
22462264 } ,
2247- incoming_custom_records : CustomRecords :: new ( ) ,
2265+ incoming_custom_records : CustomRecords :: default ( ) ,
22482266 outgoing_channel_id : None ,
22492267 incoming_amount_msat : 0 ,
22502268 outgoing_amount_msat : 0 ,
@@ -2406,7 +2424,8 @@ mod tests {
24062424 . returning ( |_| Ok ( ( ) ) ) ;
24072425
24082426 let mock_1 = Arc :: new ( mock_interceptor_1) ;
2409- let mut test_kit = DispatchPaymentTestKit :: new ( 500_000_000 , vec ! [ mock_1] ) . await ;
2427+ let mut test_kit =
2428+ DispatchPaymentTestKit :: new ( 500_000_000 , vec ! [ mock_1] , CustomRecords :: default ( ) ) . await ;
24102429 let ( _, result) = test_kit
24112430 . send_test_payment ( test_kit. nodes [ 0 ] , test_kit. nodes [ 3 ] , 150_000_000 )
24122431 . await ;
@@ -2427,4 +2446,40 @@ mod tests {
24272446 test_kit. graph . tasks . close ( ) ;
24282447 test_kit. graph . tasks . wait ( ) . await ;
24292448 }
2449+
2450+ /// Tests custom records set for interceptors in multi-hop payment.
2451+ #[ tokio:: test]
2452+ async fn test_custom_records ( ) {
2453+ let custom_records = HashMap :: from ( [ ( 1000 , vec ! [ 1 ] ) ] ) ;
2454+
2455+ let mut mock_interceptor_1 = MockTestInterceptor :: new ( ) ;
2456+ let custom_records_clone = custom_records. clone ( ) ;
2457+ mock_interceptor_1
2458+ . expect_intercept_htlc ( )
2459+ . withf ( move |req : & InterceptRequest | {
2460+ // Check custom records passed to interceptor are the default ones set.
2461+ req. incoming_custom_records == custom_records_clone
2462+ } )
2463+ . returning ( |_| Ok ( Ok ( CustomRecords :: default ( ) ) ) ) ; // Set empty records for 2nd hop.
2464+ mock_interceptor_1
2465+ . expect_notify_resolution ( )
2466+ . returning ( |_| Ok ( ( ) ) )
2467+ . times ( 2 ) ;
2468+
2469+ mock_interceptor_1
2470+ . expect_intercept_htlc ( )
2471+ . withf ( move |req : & InterceptRequest | {
2472+ // On this 2nd hop, the custom records should be empty.
2473+ req. incoming_custom_records == CustomRecords :: default ( )
2474+ } )
2475+ . returning ( |_| Ok ( Ok ( CustomRecords :: default ( ) ) ) ) ;
2476+
2477+ let chan_capacity = 500_000_000 ;
2478+ let mock_1: Arc < dyn Interceptor > = Arc :: new ( mock_interceptor_1) ;
2479+ let mut test_kit =
2480+ DispatchPaymentTestKit :: new ( chan_capacity, vec ! [ mock_1] , custom_records) . await ;
2481+ let _ = test_kit
2482+ . send_test_payment ( test_kit. nodes [ 0 ] , test_kit. nodes [ 2 ] , 150_000 )
2483+ . await ;
2484+ }
24302485}
0 commit comments