Skip to content

Commit 8239045

Browse files
committed
Add some basic test coverage of monitor payment data reloading
1 parent b3bfecd commit 8239045

File tree

2 files changed

+183
-13
lines changed

2 files changed

+183
-13
lines changed

lightning/src/ln/functional_tests.rs

+37-9
Original file line numberDiff line numberDiff line change
@@ -4151,7 +4151,7 @@ fn mpp_failure() {
41514151
fail_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], false, payment_hash);
41524152
}
41534153

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

41734173
// Route a payment, but force-close the channel before the HTLC fulfill message arrives at
41744174
// nodes[0].
4175-
let (payment_preimage, _, _) = route_payment(&nodes[0], &[&nodes[1]], 10000000);
4175+
let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &[&nodes[1]], 10000000);
41764176
nodes[0].node.force_close_channel(&nodes[0].node.list_channels()[0].channel_id).unwrap();
41774177
check_closed_broadcast!(nodes[0], true);
41784178
check_added_monitors!(nodes[0], 1);
@@ -4188,6 +4188,7 @@ fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool) {
41884188
assert_eq!(node_txn[0], node_txn[1]);
41894189
check_spends!(node_txn[1], funding_tx);
41904190
check_spends!(node_txn[2], node_txn[1]);
4191+
let timeout_txn = vec![node_txn[2].clone()];
41914192

41924193
assert!(nodes[1].node.claim_funds(payment_preimage));
41934194
check_added_monitors!(nodes[1], 1);
@@ -4202,15 +4203,30 @@ fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool) {
42024203
header.prev_blockhash = nodes[0].best_block_hash();
42034204
connect_block(&nodes[0], &Block { header, txdata: vec![node_txn[1].clone()]});
42044205

4206+
if confirm_commitment_tx {
4207+
connect_blocks(&nodes[0], BREAKDOWN_TIMEOUT as u32 - 1);
4208+
}
4209+
4210+
header.prev_blockhash = nodes[0].best_block_hash();
4211+
let claim_block = Block { header, txdata: if payment_timeout { timeout_txn } else { claim_txn } };
4212+
4213+
if payment_timeout {
4214+
assert!(confirm_commitment_tx); // Otherwise we're spending below our CSV!
4215+
connect_block(&nodes[0], &claim_block);
4216+
connect_blocks(&nodes[0], ANTI_REORG_DELAY - 2);
4217+
}
4218+
42054219
// Now connect the HTLC claim transaction with the ChainMonitor-generated ChannelMonitor update
42064220
// returning TemporaryFailure. This should cause the claim event to never make its way to the
42074221
// ChannelManager.
42084222
chanmon_cfgs[0].persister.non_update_monitor_persistences.lock().unwrap().clear();
42094223
chanmon_cfgs[0].persister.set_update_ret(Err(ChannelMonitorUpdateErr::TemporaryFailure));
42104224

4211-
header.prev_blockhash = nodes[0].best_block_hash();
4212-
let claim_block = Block { header, txdata: claim_txn };
4213-
connect_block(&nodes[0], &claim_block);
4225+
if payment_timeout {
4226+
connect_blocks(&nodes[0], 1);
4227+
} else {
4228+
connect_block(&nodes[0], &claim_block);
4229+
}
42144230

42154231
let funding_txo = OutPoint { txid: funding_tx.txid(), index: 0 };
42164232
let mon_updates: Vec<_> = chanmon_cfgs[0].persister.non_update_monitor_persistences.lock().unwrap()
@@ -4232,7 +4248,11 @@ fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool) {
42324248
let mut chan_0_monitor_serialized = test_utils::TestVecWriter(Vec::new());
42334249
get_monitor!(nodes[0], chan_id).write(&mut chan_0_monitor_serialized).unwrap();
42344250
nodes[0].chain_monitor.chain_monitor.channel_monitor_updated(funding_txo, mon_updates[0]);
4235-
expect_payment_sent!(nodes[0], payment_preimage);
4251+
if payment_timeout {
4252+
expect_payment_failed!(nodes[0], payment_hash, true);
4253+
} else {
4254+
expect_payment_sent!(nodes[0], payment_preimage);
4255+
}
42364256

42374257
// If we persist the ChannelManager after we get the PaymentSent event, we shouldn't get it
42384258
// twice.
@@ -4273,7 +4293,11 @@ fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool) {
42734293
if persist_manager_post_event {
42744294
assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
42754295
} else {
4276-
expect_payment_sent!(nodes[0], payment_preimage);
4296+
if payment_timeout {
4297+
expect_payment_failed!(nodes[0], payment_hash, true);
4298+
} else {
4299+
expect_payment_sent!(nodes[0], payment_preimage);
4300+
}
42774301
}
42784302

42794303
// Note that if we re-connect the block which exposed nodes[0] to the payment preimage (but
@@ -4286,8 +4310,12 @@ fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool) {
42864310

42874311
#[test]
42884312
fn test_dup_htlc_onchain_fails_on_reload() {
4289-
do_test_dup_htlc_onchain_fails_on_reload(true);
4290-
do_test_dup_htlc_onchain_fails_on_reload(false);
4313+
do_test_dup_htlc_onchain_fails_on_reload(true, true, true);
4314+
do_test_dup_htlc_onchain_fails_on_reload(true, true, false);
4315+
do_test_dup_htlc_onchain_fails_on_reload(true, false, false);
4316+
do_test_dup_htlc_onchain_fails_on_reload(false, true, true);
4317+
do_test_dup_htlc_onchain_fails_on_reload(false, true, false);
4318+
do_test_dup_htlc_onchain_fails_on_reload(false, false, false);
42914319
}
42924320

42934321
#[test]

lightning/src/ln/payment_tests.rs

+146-4
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,23 @@
1111
//! serialization ordering between ChannelManager/ChannelMonitors and ensuring we can still retry
1212
//! payments thereafter.
1313
14+
use chain::Watch;
15+
use chain::channelmonitor::ChannelMonitor;
1416
use ln::{PaymentPreimage, PaymentHash};
15-
use ln::channelmanager::{PaymentId, PaymentSendFailure};
16-
use routing::router::get_route;
17+
use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, PaymentId, PaymentSendFailure};
1718
use ln::features::{InitFeatures, InvoiceFeatures};
1819
use ln::msgs;
19-
use ln::msgs::ChannelMessageHandler;
20+
use ln::msgs::{ChannelMessageHandler, ErrorAction};
21+
use routing::router::get_route;
2022
use util::test_utils;
21-
use util::events::{Event, MessageSendEvent, MessageSendEventsProvider};
23+
use util::events::{ClosureReason, Event, MessageSendEvent, MessageSendEventsProvider};
2224
use util::errors::APIError;
25+
use util::enforcing_trait_impls::EnforcingSigner;
26+
use util::ser::{ReadableArgs, Writeable};
2327

2428
use bitcoin::hashes::sha256::Hash as Sha256;
2529
use bitcoin::hashes::Hash;
30+
use bitcoin::BlockHash;
2631

2732
use prelude::*;
2833

@@ -252,3 +257,140 @@ fn no_pending_leak_on_initial_send_failure() {
252257

253258
assert!(!nodes[0].node.has_pending_payments());
254259
}
260+
261+
#[test]
262+
fn retry_with_no_persist() {
263+
// If we send a pending payment and `send_payment` returns success, we should always either
264+
// return a payment failure event or a payment success event, and on failure the payment should
265+
// be retryable.
266+
// In order to do so when the ChannelManager isn't immediately persisted (which is normal - its
267+
// always persisted asynchronously), the ChannelManager has to reload some payment data from
268+
// ChannelMonitor(s) in some cases. This tests that reloading.
269+
let chanmon_cfgs = create_chanmon_cfgs(3);
270+
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
271+
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
272+
let persister: test_utils::TestPersister;
273+
let new_chain_monitor: test_utils::TestChainMonitor;
274+
let nodes_0_deserialized: ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>;
275+
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
276+
277+
let chan_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).2;
278+
create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::known(), InitFeatures::known());
279+
280+
// Serialize the ChannelManager prior to sending the payment
281+
let nodes_0_serialized = nodes[0].node.encode();
282+
283+
let (route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], 100_000);
284+
let payment_id = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap();
285+
check_added_monitors!(nodes[0], 1);
286+
287+
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
288+
assert_eq!(events.len(), 1);
289+
let payment_event = SendEvent::from_event(events.pop().unwrap());
290+
assert_eq!(payment_event.node_id, nodes[1].node.get_our_node_id());
291+
292+
// We relay the payment to nodes[1] while its disconnected from nodes[2], causing the payment
293+
// to be returned immediately to nodes[0], without having nodes[2] fail the inbound payment
294+
// which would prevent retry.
295+
nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id(), false);
296+
nodes[2].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
297+
298+
nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]);
299+
commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false, true);
300+
// nodes[1] now immediately fails the HTLC as the next-hop channel is disconnected
301+
let _ = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
302+
303+
reconnect_nodes(&nodes[1], &nodes[2], (true, true), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
304+
305+
// The ChannelMonitor should always be the latest version, as we're required to persist it
306+
// during the `commitment_signed_dance!()`.
307+
let mut chan_0_monitor_serialized = test_utils::TestVecWriter(Vec::new());
308+
get_monitor!(nodes[0], chan_id).write(&mut chan_0_monitor_serialized).unwrap();
309+
310+
persister = test_utils::TestPersister::new();
311+
let keys_manager = &chanmon_cfgs[0].keys_manager;
312+
new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), nodes[0].logger, node_cfgs[0].fee_estimator, &persister, keys_manager);
313+
nodes[0].chain_monitor = &new_chain_monitor;
314+
let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..];
315+
let (_, mut chan_0_monitor) = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(
316+
&mut chan_0_monitor_read, keys_manager).unwrap();
317+
assert!(chan_0_monitor_read.is_empty());
318+
319+
let mut nodes_0_read = &nodes_0_serialized[..];
320+
let (_, nodes_0_deserialized_tmp) = {
321+
let mut channel_monitors = HashMap::new();
322+
channel_monitors.insert(chan_0_monitor.get_funding_txo().0, &mut chan_0_monitor);
323+
<(BlockHash, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
324+
default_config: test_default_channel_config(),
325+
keys_manager,
326+
fee_estimator: node_cfgs[0].fee_estimator,
327+
chain_monitor: nodes[0].chain_monitor,
328+
tx_broadcaster: nodes[0].tx_broadcaster.clone(),
329+
logger: nodes[0].logger,
330+
channel_monitors,
331+
}).unwrap()
332+
};
333+
nodes_0_deserialized = nodes_0_deserialized_tmp;
334+
assert!(nodes_0_read.is_empty());
335+
336+
assert!(nodes[0].chain_monitor.watch_channel(chan_0_monitor.get_funding_txo().0, chan_0_monitor).is_ok());
337+
nodes[0].node = &nodes_0_deserialized;
338+
check_added_monitors!(nodes[0], 1);
339+
340+
// On reload, the ChannelManager should realize it is stale compared to the ChannelMonitor and
341+
// force-close the channel.
342+
check_closed_event!(nodes[0], 1, ClosureReason::OutdatedChannelManager);
343+
assert!(nodes[0].node.list_channels().is_empty());
344+
assert!(nodes[0].node.has_pending_payments());
345+
let as_commitment_tx = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
346+
assert_eq!(as_commitment_tx.len(), 1);
347+
348+
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
349+
nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known()});
350+
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
351+
352+
// Now nodes[1] should send a channel reestablish, which nodes[0] will respond to with an
353+
// error, as the channel has hit the chain.
354+
nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known()});
355+
let bs_reestablish = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id());
356+
nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &bs_reestablish);
357+
let as_err = nodes[0].node.get_and_clear_pending_msg_events();
358+
assert_eq!(as_err.len(), 1);
359+
match as_err[0] {
360+
MessageSendEvent::HandleError { node_id, action: msgs::ErrorAction::SendErrorMessage { ref msg } } => {
361+
assert_eq!(node_id, nodes[1].node.get_our_node_id());
362+
nodes[1].node.handle_error(&nodes[0].node.get_our_node_id(), msg);
363+
check_closed_event!(nodes[1], 1, ClosureReason::CounterpartyForceClosed { peer_msg: "Failed to find corresponding channel".to_string() });
364+
check_added_monitors!(nodes[1], 1);
365+
assert_eq!(nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0).len(), 1);
366+
},
367+
_ => panic!("Unexpected event"),
368+
}
369+
check_closed_broadcast!(nodes[1], false);
370+
371+
// Create a new channel on which to retry the payment before we fail the payment via the
372+
// HTLC-Timeout transaction. This avoids ChannelManager timing out the payment due to us
373+
// connecting several blocks while creating the channel (implying time has passed).
374+
create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
375+
assert_eq!(nodes[0].node.list_usable_channels().len(), 1);
376+
377+
mine_transaction(&nodes[0], &as_commitment_tx[0]);
378+
connect_blocks(&nodes[0], TEST_FINAL_CLTV*4 + 20);
379+
let as_htlc_timeout_tx = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
380+
assert_eq!(as_htlc_timeout_tx.len(), 1);
381+
confirm_transaction(&nodes[0], &as_htlc_timeout_tx[0]);
382+
nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().clear();
383+
expect_payment_failed!(nodes[0], payment_hash, false);
384+
385+
// Finally, retry the payment (which was reloaded from the ChannelMonitor when nodes[0] was
386+
// reloaded) via a route over the new channel, which work without issue and eventually be
387+
// received and claimed at the recipient just like any other payment.
388+
let (new_route, _, _, _) = get_route_and_payment_hash!(nodes[0], nodes[2], 100_000);
389+
390+
nodes[0].node.retry_payment(&new_route, payment_id).unwrap();
391+
check_added_monitors!(nodes[0], 1);
392+
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
393+
assert_eq!(events.len(), 1);
394+
pass_along_path(&nodes[0], &[&nodes[1], &nodes[2]], 100_000, payment_hash, Some(payment_secret), events.pop().unwrap(), true, None);
395+
claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], false, payment_preimage);
396+
}

0 commit comments

Comments
 (0)