Skip to content

Commit 32a35a1

Browse files
committed
Test rejection of Trampoline forwards
In the next PR, we will be adding support for forwarding payments between Trampoline hops. Until we do that, forwarding payments need to be rejected, which we test in this commit.
1 parent b24f58a commit 32a35a1

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed

lightning/src/ln/blinded_payment_tests.rs

+119
Original file line numberDiff line numberDiff line change
@@ -2342,3 +2342,122 @@ fn test_trampoline_unblinded_receive() {
23422342
claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage);
23432343
}
23442344

2345+
#[test]
2346+
fn test_trampoline_forward_rejection() {
2347+
const TOTAL_NODE_COUNT: usize = 3;
2348+
2349+
let chanmon_cfgs = create_chanmon_cfgs(TOTAL_NODE_COUNT);
2350+
let node_cfgs = create_node_cfgs(TOTAL_NODE_COUNT, &chanmon_cfgs);
2351+
let node_chanmgrs = create_node_chanmgrs(TOTAL_NODE_COUNT, &node_cfgs, &vec![None; TOTAL_NODE_COUNT]);
2352+
let mut nodes = create_network(TOTAL_NODE_COUNT, &node_cfgs, &node_chanmgrs);
2353+
2354+
let (_, _, chan_id_alice_bob, _) = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 0);
2355+
let (_, _, chan_id_bob_carol, _) = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 1_000_000, 0);
2356+
2357+
for i in 0..TOTAL_NODE_COUNT { // connect all nodes' blocks
2358+
connect_blocks(&nodes[i], (TOTAL_NODE_COUNT as u32) * CHAN_CONFIRM_DEPTH + 1 - nodes[i].best_block_info().1);
2359+
}
2360+
2361+
let alice_node_id = nodes[0].node().get_our_node_id();
2362+
let bob_node_id = nodes[1].node().get_our_node_id();
2363+
let carol_node_id = nodes[2].node().get_our_node_id();
2364+
2365+
let alice_bob_scid = nodes[0].node().list_channels().iter().find(|c| c.channel_id == chan_id_alice_bob).unwrap().short_channel_id.unwrap();
2366+
let bob_carol_scid = nodes[1].node().list_channels().iter().find(|c| c.channel_id == chan_id_bob_carol).unwrap().short_channel_id.unwrap();
2367+
2368+
let amt_msat = 1000;
2369+
let (payment_preimage, payment_hash, _) = get_payment_preimage_hash(&nodes[2], Some(amt_msat), None);
2370+
2371+
let route = Route {
2372+
paths: vec![Path {
2373+
hops: vec![
2374+
// Bob
2375+
RouteHop {
2376+
pubkey: bob_node_id,
2377+
node_features: NodeFeatures::empty(),
2378+
short_channel_id: alice_bob_scid,
2379+
channel_features: ChannelFeatures::empty(),
2380+
fee_msat: 1000,
2381+
cltv_expiry_delta: 48,
2382+
maybe_announced_channel: false,
2383+
},
2384+
2385+
// Carol
2386+
RouteHop {
2387+
pubkey: carol_node_id,
2388+
node_features: NodeFeatures::empty(),
2389+
short_channel_id: bob_carol_scid,
2390+
channel_features: ChannelFeatures::empty(),
2391+
fee_msat: 0,
2392+
cltv_expiry_delta: 48,
2393+
maybe_announced_channel: false,
2394+
}
2395+
],
2396+
blinded_tail: Some(BlindedTail {
2397+
trampoline_hops: vec![
2398+
// Carol
2399+
TrampolineHop {
2400+
pubkey: carol_node_id,
2401+
node_features: Features::empty(),
2402+
fee_msat: amt_msat,
2403+
cltv_expiry_delta: 24,
2404+
},
2405+
2406+
// Alice (unreachable)
2407+
TrampolineHop {
2408+
pubkey: alice_node_id,
2409+
node_features: Features::empty(),
2410+
fee_msat: amt_msat,
2411+
cltv_expiry_delta: 24,
2412+
},
2413+
],
2414+
hops: vec![BlindedHop{
2415+
// Fake public key
2416+
blinded_node_id: alice_node_id,
2417+
encrypted_payload: vec![],
2418+
}],
2419+
blinding_point: alice_node_id,
2420+
excess_final_cltv_expiry_delta: 39,
2421+
final_value_msat: amt_msat,
2422+
})
2423+
}],
2424+
route_params: None,
2425+
};
2426+
2427+
nodes[0].node.send_payment_with_route(route.clone(), payment_hash, RecipientOnionFields::spontaneous_empty(), PaymentId(payment_hash.0)).unwrap();
2428+
2429+
check_added_monitors!(&nodes[0], 1);
2430+
2431+
// pass_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], amt_msat, payment_hash, payment_secret);
2432+
2433+
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
2434+
assert_eq!(events.len(), 1);
2435+
let first_message_event = remove_first_msg_event_to_node(&nodes[1].node.get_our_node_id(), &mut events);
2436+
2437+
let route: &[&Node] = &[&nodes[1], &nodes[2]];
2438+
let args = PassAlongPathArgs::new(&nodes[0], route, amt_msat, payment_hash, first_message_event)
2439+
.with_payment_preimage(payment_preimage)
2440+
.without_claimable_event()
2441+
.expect_failure(HTLCDestination::FailedPayment { payment_hash });
2442+
do_pass_along_path(args);
2443+
2444+
{
2445+
let unblinded_node_updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
2446+
nodes[1].node.handle_update_fail_htlc(
2447+
nodes[2].node.get_our_node_id(), &unblinded_node_updates.update_fail_htlcs[0]
2448+
);
2449+
do_commitment_signed_dance(&nodes[1], &nodes[2], &unblinded_node_updates.commitment_signed, true, false);
2450+
}
2451+
{
2452+
let unblinded_node_updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
2453+
nodes[0].node.handle_update_fail_htlc(
2454+
nodes[1].node.get_our_node_id(), &unblinded_node_updates.update_fail_htlcs[0]
2455+
);
2456+
do_commitment_signed_dance(&nodes[0], &nodes[1], &unblinded_node_updates.commitment_signed, false, false);
2457+
}
2458+
{
2459+
let payment_failed_conditions = PaymentFailedConditions::new()
2460+
.expected_htlc_error_data(0x4000 | 10, &[0; 0]);
2461+
expect_payment_failed_conditions(&nodes[0], payment_hash, false, payment_failed_conditions);
2462+
}
2463+
}

0 commit comments

Comments
 (0)