Skip to content

Commit 342b78b

Browse files
committed
Add functional test for inflight HTLC tracking with ChanManager
1 parent b71d821 commit 342b78b

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed

lightning/src/ln/payment_tests.rs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ use bitcoin::network::constants::Network;
3232
use crate::prelude::*;
3333

3434
use crate::ln::functional_test_utils::*;
35+
use crate::routing::gossip::NodeId;
3536

3637
#[test]
3738
fn retry_single_path_payment() {
@@ -1239,3 +1240,109 @@ fn abandoned_send_payment_idempotent() {
12391240
pass_along_route(&nodes[0], &[&[&nodes[1]]], 100_000, second_payment_hash, second_payment_secret);
12401241
claim_payment(&nodes[0], &[&nodes[1]], second_payment_preimage);
12411242
}
1243+
1244+
1245+
#[test]
1246+
fn test_trivial_inflight_htlc_tracking(){
1247+
// In this test, we test three scenarios:
1248+
// (1) Sending + claiming a payment successfully should return `None` when querying InFlightHtlcs
1249+
// (2) Sending a payment without claiming it shoudl return the payment's value (500000) when querying InFlightHtlcs
1250+
// (3) After we claim the payment sent in (2), InFlightHtlcs should return `None` for the query.
1251+
let chanmon_cfgs = create_chanmon_cfgs(2);
1252+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
1253+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
1254+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
1255+
1256+
let (_, _, chan_id, _) = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
1257+
1258+
// Send and claim the payment. Inflight HTLCs should be empty.
1259+
send_payment(&nodes[0], &vec!(&nodes[1])[..], 500000);
1260+
{
1261+
let inflight_htlcs = node_chanmgrs[0].compute_inflight_htlcs();
1262+
1263+
let channel_lock = nodes[0].node.channel_state.lock().unwrap();
1264+
let channel = channel_lock.by_id.get(&chan_id).unwrap();
1265+
1266+
let used_liquidity = inflight_htlcs.used_liquidity_msat(
1267+
&NodeId::from_pubkey(&nodes[0].node.get_our_node_id()) ,
1268+
&NodeId::from_pubkey(&nodes[1].node.get_our_node_id()),
1269+
channel.get_short_channel_id().unwrap()
1270+
);
1271+
1272+
assert_eq!(used_liquidity, None);
1273+
}
1274+
1275+
// Send the payment, but do not claim it. Our inflight HTLCs should contain the pending payment.
1276+
let (payment_preimage, _, _) = route_payment(&nodes[0], &vec!(&nodes[1])[..], 500000);
1277+
{
1278+
let inflight_htlcs = node_chanmgrs[0].compute_inflight_htlcs();
1279+
1280+
let channel_lock = nodes[0].node.channel_state.lock().unwrap();
1281+
let channel = channel_lock.by_id.get(&chan_id).unwrap();
1282+
1283+
let used_liquidity = inflight_htlcs.used_liquidity_msat(
1284+
&NodeId::from_pubkey(&nodes[0].node.get_our_node_id()) ,
1285+
&NodeId::from_pubkey(&nodes[1].node.get_our_node_id()),
1286+
channel.get_short_channel_id().unwrap()
1287+
);
1288+
1289+
assert_eq!(used_liquidity, Some(500000));
1290+
}
1291+
1292+
// Now, let's claim the payment. This should result in the used liquidity to return `None`.
1293+
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage);
1294+
1295+
{
1296+
let inflight_htlcs = node_chanmgrs[0].compute_inflight_htlcs();
1297+
1298+
let channel_lock = nodes[0].node.channel_state.lock().unwrap();
1299+
let channel = channel_lock.by_id.get(&chan_id).unwrap();
1300+
1301+
let used_liquidity = inflight_htlcs.used_liquidity_msat(
1302+
&NodeId::from_pubkey(&nodes[0].node.get_our_node_id()) ,
1303+
&NodeId::from_pubkey(&nodes[1].node.get_our_node_id()),
1304+
channel.get_short_channel_id().unwrap()
1305+
);
1306+
1307+
assert_eq!(used_liquidity, None);
1308+
}
1309+
}
1310+
1311+
#[test]
1312+
fn test_holding_cell_inflight_htlcs() {
1313+
let chanmon_cfgs = create_chanmon_cfgs(2);
1314+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
1315+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
1316+
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
1317+
let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features()).2;
1318+
1319+
let (route, payment_hash_1, _, payment_secret_1) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
1320+
let (_, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[1]);
1321+
1322+
// Queue up two payments - one will be delivered right away, one immediately goes into the
1323+
// holding cell as nodes[0] is AwaitingRAA.
1324+
{
1325+
nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1), PaymentId(payment_hash_1.0)).unwrap();
1326+
check_added_monitors!(nodes[0], 1);
1327+
nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2), PaymentId(payment_hash_2.0)).unwrap();
1328+
check_added_monitors!(nodes[0], 0);
1329+
}
1330+
1331+
let inflight_htlcs = node_chanmgrs[0].compute_inflight_htlcs();
1332+
1333+
{
1334+
let channel_lock = nodes[0].node.channel_state.lock().unwrap();
1335+
let channel = channel_lock.by_id.get(&channel_id).unwrap();
1336+
1337+
let used_liquidity = inflight_htlcs.used_liquidity_msat(
1338+
&NodeId::from_pubkey(&nodes[0].node.get_our_node_id()) ,
1339+
&NodeId::from_pubkey(&nodes[1].node.get_our_node_id()),
1340+
channel.get_short_channel_id().unwrap()
1341+
);
1342+
1343+
assert_eq!(used_liquidity, Some(2000000));
1344+
}
1345+
1346+
// Clear pending events so test doesn't throw a "Had excess message on node..." error
1347+
nodes[0].node.get_and_clear_pending_msg_events();
1348+
}

0 commit comments

Comments
 (0)