@@ -824,7 +824,7 @@ async fn handle_intercepted_htlc(
824
824
shutdown_listener : Listener ,
825
825
) -> Result < Result < CustomRecords , ForwardingError > , CriticalError > {
826
826
if interceptors. is_empty ( ) {
827
- return Ok ( Ok ( HashMap :: new ( ) ) ) ;
827
+ return Ok ( Ok ( request . incoming_custom_records ) ) ;
828
828
}
829
829
830
830
let mut attached_custom_records: CustomRecords = HashMap :: new ( ) ;
@@ -925,6 +925,9 @@ pub struct SimGraph {
925
925
/// trigger a shutdown signal to other interceptors.
926
926
interceptors : Vec < Arc < dyn Interceptor > > ,
927
927
928
+ /// Custom records that will be added to the first outgoing HTLC in a payment.
929
+ default_custom_records : CustomRecords ,
930
+
928
931
/// Shutdown signal that can be used to trigger a shutdown if a critical error occurs. Listener
929
932
/// can be used to listen for shutdown signals coming from upstream.
930
933
shutdown_signal : ( Trigger , Listener ) ,
@@ -936,6 +939,7 @@ impl SimGraph {
936
939
graph_channels : Vec < SimulatedChannel > ,
937
940
tasks : TaskTracker ,
938
941
interceptors : Vec < Arc < dyn Interceptor > > ,
942
+ default_custom_records : CustomRecords ,
939
943
shutdown_signal : ( Trigger , Listener ) ,
940
944
) -> Result < Self , SimulationError > {
941
945
let mut nodes: HashMap < PublicKey , Vec < u64 > > = HashMap :: new ( ) ;
@@ -971,6 +975,7 @@ impl SimGraph {
971
975
channels : Arc :: new ( Mutex :: new ( channels) ) ,
972
976
tasks,
973
977
interceptors,
978
+ default_custom_records,
974
979
shutdown_signal,
975
980
} )
976
981
}
@@ -1098,6 +1103,7 @@ impl SimNetwork for SimGraph {
1098
1103
payment_hash,
1099
1104
sender,
1100
1105
interceptors : self . interceptors . clone ( ) ,
1106
+ custom_records : self . default_custom_records . clone ( ) ,
1101
1107
shutdown_signal : self . shutdown_signal . clone ( ) ,
1102
1108
} ) ) ;
1103
1109
}
@@ -1149,13 +1155,14 @@ async fn add_htlcs(
1149
1155
route : Path ,
1150
1156
payment_hash : PaymentHash ,
1151
1157
interceptors : Vec < Arc < dyn Interceptor > > ,
1158
+ custom_records : CustomRecords ,
1152
1159
shutdown_listener : Listener ,
1153
1160
) -> Result < Result < ( ) , ( Option < usize > , ForwardingError ) > , CriticalError > {
1154
1161
let mut outgoing_node = source;
1155
1162
let mut outgoing_amount = route. fee_msat ( ) + route. final_value_msat ( ) ;
1156
1163
let mut outgoing_cltv = route. hops . iter ( ) . map ( |hop| hop. cltv_expiry_delta ) . sum ( ) ;
1157
1164
1158
- let mut incoming_custom_records = HashMap :: new ( ) ;
1165
+ let mut incoming_custom_records = custom_records ;
1159
1166
1160
1167
// Tracks the hop index that we need to remove htlcs from on payment completion (both success and failure).
1161
1168
// 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(
1237
1244
forwarding_node : hop. pubkey ,
1238
1245
payment_hash,
1239
1246
incoming_htlc : incoming_htlc. clone ( ) ,
1240
- incoming_custom_records : incoming_custom_records . clone ( ) ,
1247
+ incoming_custom_records,
1241
1248
outgoing_channel_id : next_scid,
1242
1249
incoming_amount_msat : outgoing_amount,
1243
1250
outgoing_amount_msat : outgoing_amount - hop. fee_msat ,
@@ -1345,6 +1352,7 @@ struct PropagatePaymentRequest {
1345
1352
payment_hash : PaymentHash ,
1346
1353
sender : Sender < Result < PaymentResult , LightningError > > ,
1347
1354
interceptors : Vec < Arc < dyn Interceptor > > ,
1355
+ custom_records : CustomRecords ,
1348
1356
shutdown_signal : ( Trigger , Listener ) ,
1349
1357
}
1350
1358
@@ -1359,6 +1367,7 @@ async fn propagate_payment(request: PropagatePaymentRequest) {
1359
1367
request. route . clone ( ) ,
1360
1368
request. payment_hash ,
1361
1369
request. interceptors . clone ( ) ,
1370
+ request. custom_records ,
1362
1371
request. shutdown_signal . 1 ,
1363
1372
)
1364
1373
. await
@@ -1964,7 +1973,11 @@ mod tests {
1964
1973
/// Alice (100) --- (0) Bob (100) --- (0) Carol (100) --- (0) Dave
1965
1974
///
1966
1975
/// 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 {
1968
1981
let shutdown_signal = triggered:: trigger ( ) ;
1969
1982
let channels = create_simulated_channels ( 3 , capacity) ;
1970
1983
let routing_graph = Arc :: new (
@@ -1991,6 +2004,7 @@ mod tests {
1991
2004
channels. clone ( ) ,
1992
2005
TaskTracker :: new ( ) ,
1993
2006
interceptors,
2007
+ custom_records,
1994
2008
shutdown_signal,
1995
2009
)
1996
2010
. expect ( "could not create test graph" ) ,
@@ -2071,7 +2085,8 @@ mod tests {
2071
2085
#[ tokio:: test]
2072
2086
async fn test_successful_dispatch ( ) {
2073
2087
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 ;
2075
2090
2076
2091
// Send a payment that should succeed from Alice -> Dave.
2077
2092
let mut amt = 20_000 ;
@@ -2136,7 +2151,8 @@ mod tests {
2136
2151
#[ tokio:: test]
2137
2152
async fn test_successful_multi_hop ( ) {
2138
2153
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 ;
2140
2156
2141
2157
// Send a payment that should succeed from Alice -> Dave.
2142
2158
let amt = 20_000 ;
@@ -2166,7 +2182,8 @@ mod tests {
2166
2182
#[ tokio:: test]
2167
2183
async fn test_single_hop_payments ( ) {
2168
2184
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 ;
2170
2187
2171
2188
// Send a single hop payment from Alice -> Bob, it will succeed because Alice has all the liquidity.
2172
2189
let amt = 150_000 ;
@@ -2198,7 +2215,8 @@ mod tests {
2198
2215
#[ tokio:: test]
2199
2216
async fn test_multi_hop_faiulre ( ) {
2200
2217
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 ;
2202
2220
2203
2221
// Drain liquidity between Bob and Carol to force failures on Bob's outgoing linke.
2204
2222
test_kit
@@ -2244,7 +2262,7 @@ mod tests {
2244
2262
channel_id : ShortChannelID ( 0 ) ,
2245
2263
index : 0 ,
2246
2264
} ,
2247
- incoming_custom_records : CustomRecords :: new ( ) ,
2265
+ incoming_custom_records : CustomRecords :: default ( ) ,
2248
2266
outgoing_channel_id : None ,
2249
2267
incoming_amount_msat : 0 ,
2250
2268
outgoing_amount_msat : 0 ,
@@ -2406,7 +2424,8 @@ mod tests {
2406
2424
. returning ( |_| Ok ( ( ) ) ) ;
2407
2425
2408
2426
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 ;
2410
2429
let ( _, result) = test_kit
2411
2430
. send_test_payment ( test_kit. nodes [ 0 ] , test_kit. nodes [ 3 ] , 150_000_000 )
2412
2431
. await ;
@@ -2427,4 +2446,40 @@ mod tests {
2427
2446
test_kit. graph . tasks . close ( ) ;
2428
2447
test_kit. graph . tasks . wait ( ) . await ;
2429
2448
}
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
+ }
2430
2485
}
0 commit comments