Skip to content

Commit 5b490c0

Browse files
committed
sim_node/feat: Test payment failure returns correct hop index of failure
This commit asserts that payment failure on each hop returns the correct hop index where failure occured. On payment failure, this ensures the correct index of hop where failure occured is reported to scorer.
1 parent ccb91ec commit 5b490c0

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

simln-lib/src/sim_node.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2068,6 +2068,65 @@ mod tests {
20682068
));
20692069
}
20702070

2071+
#[tokio::test]
2072+
async fn test_payment_failure_returns_correct_hop_index_of_failure() {
2073+
let chan_capacity = 500_000_000;
2074+
let test_kit =
2075+
DispatchPaymentTestKit::new(chan_capacity, vec![], CustomRecords::default()).await;
2076+
2077+
let mut node = SimNode::new(
2078+
node_info(test_kit.nodes[0], String::default()),
2079+
Arc::new(Mutex::new(test_kit.graph)),
2080+
test_kit.routing_graph.clone(),
2081+
Arc::new(SystemClock {}),
2082+
)
2083+
.unwrap();
2084+
2085+
let route = build_route_from_hops(
2086+
&test_kit.nodes[0],
2087+
&[test_kit.nodes[1], test_kit.nodes[2], test_kit.nodes[3]],
2088+
&RouteParameters {
2089+
payment_params: PaymentParameters::from_node_id(*test_kit.nodes.last().unwrap(), 0)
2090+
.with_max_total_cltv_expiry_delta(u32::MAX)
2091+
.with_max_path_count(1)
2092+
.with_max_channel_saturation_power_of_half(1),
2093+
final_value_msat: 20_000,
2094+
max_total_routing_fee_msat: None,
2095+
},
2096+
&test_kit.routing_graph,
2097+
&WrappedLog {},
2098+
&[0; 32],
2099+
)
2100+
.unwrap();
2101+
2102+
// We are altering the route to make sure that we fail at each hop in turn.
2103+
// We will assert that the failure index returned is the index of the hop that we altered.
2104+
// This is done by setting the CLTV expiry delta to a value that will cause the payment to fail at that hop.
2105+
// The last hop will always succeed, so we only test the first n-1 hops.
2106+
for i in 0..route.paths[0].hops.len() - 1 {
2107+
let mut route_clone = route.clone();
2108+
// Alter route_clone to make payment fail on this hop.
2109+
route_clone.paths[0].hops[i].cltv_expiry_delta = 39;
2110+
2111+
let preimage = PaymentPreimage(rand::random());
2112+
let payment_hash = preimage.into();
2113+
let send_result = node.send_to_route(route_clone, payment_hash, None).await;
2114+
2115+
assert!(send_result.is_ok());
2116+
2117+
let (_, shutdown_listener) = triggered::trigger();
2118+
let result = node
2119+
.track_payment(&payment_hash, shutdown_listener)
2120+
.await
2121+
.unwrap();
2122+
2123+
assert!(matches!(
2124+
result.payment_outcome,
2125+
PaymentOutcome::IndexFailure(idx) if idx == i
2126+
));
2127+
}
2128+
}
2129+
20712130
mock! {
20722131
#[derive(Debug)]
20732132
TestInterceptor{}

0 commit comments

Comments
 (0)