Skip to content

Commit 5296a4a

Browse files
committed
Add some basic test coverage of monitor payment data reloading
1 parent fe660c5 commit 5296a4a

File tree

4 files changed

+241
-20
lines changed

4 files changed

+241
-20
lines changed

lightning/src/ln/functional_test_utils.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use chain::{BestBlock, Confirm, Listen, Watch};
1414
use chain::channelmonitor::ChannelMonitor;
1515
use chain::transaction::OutPoint;
1616
use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
17-
use ln::channelmanager::{ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure};
17+
use ln::channelmanager::{ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, PaymentId};
1818
use routing::network_graph::{NetGraphMsgHandler, NetworkGraph};
1919
use routing::router::{Route, get_route};
2020
use routing::scorer::Scorer;
@@ -1156,10 +1156,11 @@ macro_rules! expect_payment_failed {
11561156
}
11571157
}
11581158

1159-
pub fn send_along_route_with_secret<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_paths: &[&[&Node<'a, 'b, 'c>]], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: PaymentSecret) {
1160-
origin_node.node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
1159+
pub fn send_along_route_with_secret<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_paths: &[&[&Node<'a, 'b, 'c>]], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: PaymentSecret) -> PaymentId {
1160+
let payment_id = origin_node.node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
11611161
check_added_monitors!(origin_node, expected_paths.len());
11621162
pass_along_route(origin_node, expected_paths, recv_value, our_payment_hash, our_payment_secret);
1163+
payment_id
11631164
}
11641165

11651166
pub fn pass_along_path<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_path: &[&Node<'a, 'b, 'c>], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: Option<PaymentSecret>, ev: MessageSendEvent, payment_received_expected: bool, expected_preimage: Option<PaymentPreimage>) {
@@ -1222,10 +1223,10 @@ pub fn pass_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_rou
12221223
}
12231224
}
12241225

1225-
pub fn send_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash, PaymentSecret) {
1226+
pub fn send_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash, PaymentSecret, PaymentId) {
12261227
let (our_payment_preimage, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(expected_route.last().unwrap());
1227-
send_along_route_with_secret(origin_node, route, &[expected_route], recv_value, our_payment_hash, our_payment_secret);
1228-
(our_payment_preimage, our_payment_hash, our_payment_secret)
1228+
let payment_id = send_along_route_with_secret(origin_node, route, &[expected_route], recv_value, our_payment_hash, our_payment_secret);
1229+
(our_payment_preimage, our_payment_hash, our_payment_secret, payment_id)
12291230
}
12301231

12311232
pub fn claim_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_paths: &[&[&Node<'a, 'b, 'c>]], skip_last: bool, our_payment_preimage: PaymentPreimage) {
@@ -1339,7 +1340,8 @@ pub fn route_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route:
13391340
assert_eq!(hop.pubkey, node.node.get_our_node_id());
13401341
}
13411342

1342-
send_along_route(origin_node, route, expected_route, recv_value)
1343+
let res = send_along_route(origin_node, route, expected_route, recv_value);
1344+
(res.0, res.1, res.2)
13431345
}
13441346

13451347
pub fn route_over_limit<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) {

lightning/src/ln/functional_tests.rs

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3689,7 +3689,7 @@ fn test_funding_peer_disconnect() {
36893689
nodes[0].net_graph_msg_handler.handle_channel_update(&as_update).unwrap();
36903690

36913691
let (route, _, _, _) = get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
3692-
let (payment_preimage, _, _) = send_along_route(&nodes[0], route, &[&nodes[1]], 1000000);
3692+
let payment_preimage = send_along_route(&nodes[0], route, &[&nodes[1]], 1000000).0;
36933693
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage);
36943694

36953695
// Check that after deserialization and reconnection we can still generate an identical
@@ -4100,7 +4100,7 @@ fn test_no_txn_manager_serialize_deserialize() {
41004100
send_payment(&nodes[0], &[&nodes[1]], 1000000);
41014101
}
41024102

4103-
fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool) {
4103+
fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool, confirm_commitment_tx: bool, payment_timeout: bool) {
41044104
// When a Channel is closed, any outbound HTLCs which were relayed through it are simply
41054105
// dropped when the Channel is. From there, the ChannelManager relies on the ChannelMonitor
41064106
// having a copy of the relevant fail-/claim-back data and processes the HTLC fail/claim when
@@ -4121,7 +4121,7 @@ fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool) {
41214121

41224122
// Route a payment, but force-close the channel before the HTLC fulfill message arrives at
41234123
// nodes[0].
4124-
let (payment_preimage, _, _) = route_payment(&nodes[0], &[&nodes[1]], 10000000);
4124+
let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &[&nodes[1]], 10000000);
41254125
nodes[0].node.force_close_channel(&nodes[0].node.list_channels()[0].channel_id).unwrap();
41264126
check_closed_broadcast!(nodes[0], true);
41274127
check_added_monitors!(nodes[0], 1);
@@ -4137,6 +4137,7 @@ fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool) {
41374137
assert_eq!(node_txn[0], node_txn[1]);
41384138
check_spends!(node_txn[1], funding_tx);
41394139
check_spends!(node_txn[2], node_txn[1]);
4140+
let timeout_txn = vec![node_txn[2].clone()];
41404141

41414142
assert!(nodes[1].node.claim_funds(payment_preimage));
41424143
check_added_monitors!(nodes[1], 1);
@@ -4151,15 +4152,30 @@ fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool) {
41514152
header.prev_blockhash = nodes[0].best_block_hash();
41524153
connect_block(&nodes[0], &Block { header, txdata: vec![node_txn[1].clone()]});
41534154

4155+
if confirm_commitment_tx {
4156+
connect_blocks(&nodes[0], BREAKDOWN_TIMEOUT as u32 - 1);
4157+
}
4158+
4159+
header.prev_blockhash = nodes[0].best_block_hash();
4160+
let claim_block = Block { header, txdata: if payment_timeout { timeout_txn } else { claim_txn } };
4161+
4162+
if payment_timeout {
4163+
assert!(confirm_commitment_tx); // Otherwise we're spending below our CSV!
4164+
connect_block(&nodes[0], &claim_block);
4165+
connect_blocks(&nodes[0], ANTI_REORG_DELAY - 2);
4166+
}
4167+
41544168
// Now connect the HTLC claim transaction with the ChainMonitor-generated ChannelMonitor update
41554169
// returning TemporaryFailure. This should cause the claim event to never make its way to the
41564170
// ChannelManager.
41574171
chanmon_cfgs[0].persister.chain_sync_monitor_persistences.lock().unwrap().clear();
41584172
chanmon_cfgs[0].persister.set_update_ret(Err(ChannelMonitorUpdateErr::TemporaryFailure));
41594173

4160-
header.prev_blockhash = nodes[0].best_block_hash();
4161-
let claim_block = Block { header, txdata: claim_txn };
4162-
connect_block(&nodes[0], &claim_block);
4174+
if payment_timeout {
4175+
connect_blocks(&nodes[0], 1);
4176+
} else {
4177+
connect_block(&nodes[0], &claim_block);
4178+
}
41634179

41644180
let funding_txo = OutPoint { txid: funding_tx.txid(), index: 0 };
41654181
let mon_updates: Vec<_> = chanmon_cfgs[0].persister.chain_sync_monitor_persistences.lock().unwrap()
@@ -4181,7 +4197,11 @@ fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool) {
41814197
let mut chan_0_monitor_serialized = test_utils::TestVecWriter(Vec::new());
41824198
get_monitor!(nodes[0], chan_id).write(&mut chan_0_monitor_serialized).unwrap();
41834199
nodes[0].chain_monitor.chain_monitor.channel_monitor_updated(funding_txo, mon_updates[0]).unwrap();
4184-
expect_payment_sent!(nodes[0], payment_preimage);
4200+
if payment_timeout {
4201+
expect_payment_failed!(nodes[0], payment_hash, true);
4202+
} else {
4203+
expect_payment_sent!(nodes[0], payment_preimage);
4204+
}
41854205

41864206
// If we persist the ChannelManager after we get the PaymentSent event, we shouldn't get it
41874207
// twice.
@@ -4221,6 +4241,8 @@ fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool) {
42214241

42224242
if persist_manager_post_event {
42234243
assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
4244+
} else if payment_timeout {
4245+
expect_payment_failed!(nodes[0], payment_hash, true);
42244246
} else {
42254247
expect_payment_sent!(nodes[0], payment_preimage);
42264248
}
@@ -4235,8 +4257,12 @@ fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool) {
42354257

42364258
#[test]
42374259
fn test_dup_htlc_onchain_fails_on_reload() {
4238-
do_test_dup_htlc_onchain_fails_on_reload(true);
4239-
do_test_dup_htlc_onchain_fails_on_reload(false);
4260+
do_test_dup_htlc_onchain_fails_on_reload(true, true, true);
4261+
do_test_dup_htlc_onchain_fails_on_reload(true, true, false);
4262+
do_test_dup_htlc_onchain_fails_on_reload(true, false, false);
4263+
do_test_dup_htlc_onchain_fails_on_reload(false, true, true);
4264+
do_test_dup_htlc_onchain_fails_on_reload(false, true, false);
4265+
do_test_dup_htlc_onchain_fails_on_reload(false, false, false);
42404266
}
42414267

42424268
#[test]

lightning/src/ln/onion_route_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ fn test_onion_failure() {
479479

480480
// Test a positive test-case with one extra msat, meeting the minimum.
481481
bogus_route.paths[0][route_len-1].fee_msat = amt_to_forward + 1;
482-
let (preimage, _, _) = send_along_route(&nodes[0], bogus_route, &[&nodes[1], &nodes[2]], amt_to_forward+1);
482+
let preimage = send_along_route(&nodes[0], bogus_route, &[&nodes[1], &nodes[2]], amt_to_forward+1).0;
483483
claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], preimage);
484484

485485
//TODO: with new config API, we will be able to generate both valid and

0 commit comments

Comments
 (0)