Skip to content

Commit 89747dc

Browse files
authored
Merge pull request #1678 from TheBlueMatt/2022-08-funding-locked-mon-persist-fail
Handle async initial ChannelMonitor persistence failing on restart
2 parents 31042ab + 958601f commit 89747dc

File tree

4 files changed

+317
-44
lines changed

4 files changed

+317
-44
lines changed

lightning/src/ln/chanmon_update_fail_tests.rs

+226-7
Original file line numberDiff line numberDiff line change
@@ -2238,11 +2238,12 @@ fn do_channel_holding_cell_serialize(disconnect: bool, reload_a: bool) {
22382238
let (route, payment_hash_1, payment_preimage_1, payment_secret_1) = get_route_and_payment_hash!(&nodes[0], nodes[1], 100000);
22392239
let (payment_preimage_2, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(&nodes[1]);
22402240

2241-
// Do a really complicated dance to get an HTLC into the holding cell, with MonitorUpdateFailed
2242-
// set but AwaitingRemoteRevoke unset. When this test was written, any attempts to send an HTLC
2243-
// while MonitorUpdateFailed is set are immediately failed-backwards. Thus, the only way to get
2244-
// an AddHTLC into the holding cell is to add it while AwaitingRemoteRevoke is set but
2245-
// MonitorUpdateFailed is unset, and then swap the flags.
2241+
// Do a really complicated dance to get an HTLC into the holding cell, with
2242+
// MonitorUpdateInProgress set but AwaitingRemoteRevoke unset. When this test was written, any
2243+
// attempts to send an HTLC while MonitorUpdateInProgress is set are immediately
2244+
// failed-backwards. Thus, the only way to get an AddHTLC into the holding cell is to add it
2245+
// while AwaitingRemoteRevoke is set but MonitorUpdateInProgress is unset, and then swap the
2246+
// flags.
22462247
//
22472248
// We do this by:
22482249
// a) routing a payment from node B to node A,
@@ -2255,8 +2256,8 @@ fn do_channel_holding_cell_serialize(disconnect: bool, reload_a: bool) {
22552256
// e) delivering A's commitment_signed from (b) and the resulting B revoke_and_ack message,
22562257
// clearing AwaitingRemoteRevoke on node A.
22572258
//
2258-
// Note that because, at the end, MonitorUpdateFailed is still set, the HTLC generated in (c)
2259-
// will not be freed from the holding cell.
2259+
// Note that because, at the end, MonitorUpdateInProgress is still set, the HTLC generated in
2260+
// (c) will not be freed from the holding cell.
22602261
let (payment_preimage_0, payment_hash_0, _) = route_payment(&nodes[1], &[&nodes[0]], 100_000);
22612262

22622263
nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)).unwrap();
@@ -2745,3 +2746,221 @@ fn double_temp_error() {
27452746
commitment_signed_dance!(nodes[0], nodes[1], commitment_signed_b2, false);
27462747
expect_payment_sent!(nodes[0], payment_preimage_2);
27472748
}
2749+
2750+
fn do_test_outbound_reload_without_init_mon(use_0conf: bool) {
2751+
// Test that if the monitor update generated in funding_signed is stored async and we restart
2752+
// with the latest ChannelManager but the ChannelMonitor persistence never completed we happily
2753+
// drop the channel and move on.
2754+
let chanmon_cfgs = create_chanmon_cfgs(2);
2755+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
2756+
2757+
let persister: test_utils::TestPersister;
2758+
let new_chain_monitor: test_utils::TestChainMonitor;
2759+
let nodes_0_deserialized: ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>;
2760+
2761+
let mut chan_config = test_default_channel_config();
2762+
chan_config.manually_accept_inbound_channels = true;
2763+
chan_config.channel_handshake_limits.trust_own_funding_0conf = true;
2764+
2765+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(chan_config), Some(chan_config)]);
2766+
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
2767+
2768+
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 43, None).unwrap();
2769+
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()));
2770+
2771+
let events = nodes[1].node.get_and_clear_pending_events();
2772+
assert_eq!(events.len(), 1);
2773+
match events[0] {
2774+
Event::OpenChannelRequest { temporary_channel_id, .. } => {
2775+
if use_0conf {
2776+
nodes[1].node.accept_inbound_channel_from_trusted_peer_0conf(&temporary_channel_id, &nodes[0].node.get_our_node_id(), 0).unwrap();
2777+
} else {
2778+
nodes[1].node.accept_inbound_channel(&temporary_channel_id, &nodes[0].node.get_our_node_id(), 0).unwrap();
2779+
}
2780+
},
2781+
_ => panic!("Unexpected event"),
2782+
};
2783+
2784+
nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
2785+
2786+
let (temporary_channel_id, funding_tx, ..) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 43);
2787+
2788+
nodes[0].node.funding_transaction_generated(&temporary_channel_id, &nodes[1].node.get_our_node_id(), funding_tx.clone()).unwrap();
2789+
check_added_monitors!(nodes[0], 0);
2790+
2791+
let funding_created_msg = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id());
2792+
nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created_msg);
2793+
check_added_monitors!(nodes[1], 1);
2794+
2795+
let bs_signed_locked = nodes[1].node.get_and_clear_pending_msg_events();
2796+
assert_eq!(bs_signed_locked.len(), if use_0conf { 2 } else { 1 });
2797+
match &bs_signed_locked[0] {
2798+
MessageSendEvent::SendFundingSigned { msg, .. } => {
2799+
chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
2800+
2801+
nodes[0].node.handle_funding_signed(&nodes[1].node.get_our_node_id(), &msg);
2802+
check_added_monitors!(nodes[0], 1);
2803+
}
2804+
_ => panic!("Unexpected event"),
2805+
}
2806+
if use_0conf {
2807+
match &bs_signed_locked[1] {
2808+
MessageSendEvent::SendChannelReady { msg, .. } => {
2809+
nodes[0].node.handle_channel_ready(&nodes[1].node.get_our_node_id(), &msg);
2810+
}
2811+
_ => panic!("Unexpected event"),
2812+
}
2813+
}
2814+
2815+
assert!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().is_empty());
2816+
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
2817+
assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
2818+
2819+
// nodes[0] is now waiting on the first ChannelMonitor persistence to complete in order to
2820+
// broadcast the funding transaction. If nodes[0] restarts at this point with the
2821+
// ChannelMonitor lost, we should simply discard the channel.
2822+
2823+
// The test framework checks that watched_txn/outputs match the monitor set, which they will
2824+
// not, so we have to clear them here.
2825+
nodes[0].chain_source.watched_txn.lock().unwrap().clear();
2826+
nodes[0].chain_source.watched_outputs.lock().unwrap().clear();
2827+
2828+
let nodes_0_serialized = nodes[0].node.encode();
2829+
persister = test_utils::TestPersister::new();
2830+
let keys_manager = &chanmon_cfgs[0].keys_manager;
2831+
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);
2832+
nodes[0].chain_monitor = &new_chain_monitor;
2833+
2834+
let mut nodes_0_read = &nodes_0_serialized[..];
2835+
let config = UserConfig::default();
2836+
nodes_0_deserialized = {
2837+
<(BlockHash, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
2838+
default_config: config,
2839+
keys_manager,
2840+
fee_estimator: node_cfgs[0].fee_estimator,
2841+
chain_monitor: nodes[0].chain_monitor,
2842+
tx_broadcaster: nodes[0].tx_broadcaster.clone(),
2843+
logger: nodes[0].logger,
2844+
channel_monitors: HashMap::new(),
2845+
}).unwrap().1
2846+
};
2847+
nodes[0].node = &nodes_0_deserialized;
2848+
assert!(nodes_0_read.is_empty());
2849+
2850+
check_closed_event!(nodes[0], 1, ClosureReason::DisconnectedPeer);
2851+
assert!(nodes[0].node.list_channels().is_empty());
2852+
}
2853+
2854+
#[test]
2855+
fn test_outbound_reload_without_init_mon() {
2856+
do_test_outbound_reload_without_init_mon(true);
2857+
do_test_outbound_reload_without_init_mon(false);
2858+
}
2859+
2860+
fn do_test_inbound_reload_without_init_mon(use_0conf: bool, lock_commitment: bool) {
2861+
// Test that if the monitor update generated by funding_transaction_generated is stored async
2862+
// and we restart with the latest ChannelManager but the ChannelMonitor persistence never
2863+
// completed we happily drop the channel and move on.
2864+
let chanmon_cfgs = create_chanmon_cfgs(2);
2865+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
2866+
2867+
let persister: test_utils::TestPersister;
2868+
let new_chain_monitor: test_utils::TestChainMonitor;
2869+
let nodes_1_deserialized: ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>;
2870+
2871+
let mut chan_config = test_default_channel_config();
2872+
chan_config.manually_accept_inbound_channels = true;
2873+
chan_config.channel_handshake_limits.trust_own_funding_0conf = true;
2874+
2875+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(chan_config), Some(chan_config)]);
2876+
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
2877+
2878+
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 43, None).unwrap();
2879+
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), channelmanager::provided_init_features(), &get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()));
2880+
2881+
let events = nodes[1].node.get_and_clear_pending_events();
2882+
assert_eq!(events.len(), 1);
2883+
match events[0] {
2884+
Event::OpenChannelRequest { temporary_channel_id, .. } => {
2885+
if use_0conf {
2886+
nodes[1].node.accept_inbound_channel_from_trusted_peer_0conf(&temporary_channel_id, &nodes[0].node.get_our_node_id(), 0).unwrap();
2887+
} else {
2888+
nodes[1].node.accept_inbound_channel(&temporary_channel_id, &nodes[0].node.get_our_node_id(), 0).unwrap();
2889+
}
2890+
},
2891+
_ => panic!("Unexpected event"),
2892+
};
2893+
2894+
nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), channelmanager::provided_init_features(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
2895+
2896+
let (temporary_channel_id, funding_tx, ..) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 43);
2897+
2898+
nodes[0].node.funding_transaction_generated(&temporary_channel_id, &nodes[1].node.get_our_node_id(), funding_tx.clone()).unwrap();
2899+
check_added_monitors!(nodes[0], 0);
2900+
2901+
let funding_created_msg = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id());
2902+
chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
2903+
nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created_msg);
2904+
check_added_monitors!(nodes[1], 1);
2905+
2906+
// nodes[1] happily sends its funding_signed even though its awaiting the persistence of the
2907+
// initial ChannelMonitor, but it will decline to send its channel_ready even if the funding
2908+
// transaction is confirmed.
2909+
let funding_signed_msg = get_event_msg!(nodes[1], MessageSendEvent::SendFundingSigned, nodes[0].node.get_our_node_id());
2910+
2911+
nodes[0].node.handle_funding_signed(&nodes[1].node.get_our_node_id(), &funding_signed_msg);
2912+
check_added_monitors!(nodes[0], 1);
2913+
2914+
let as_funding_tx = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
2915+
if lock_commitment {
2916+
confirm_transaction(&nodes[0], &as_funding_tx[0]);
2917+
confirm_transaction(&nodes[1], &as_funding_tx[0]);
2918+
}
2919+
if use_0conf || lock_commitment {
2920+
let as_ready = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReady, nodes[1].node.get_our_node_id());
2921+
nodes[1].node.handle_channel_ready(&nodes[0].node.get_our_node_id(), &as_ready);
2922+
}
2923+
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
2924+
2925+
// nodes[1] is now waiting on the first ChannelMonitor persistence to complete in order to
2926+
// move the channel to ready (or is waiting on the funding transaction to confirm). If nodes[1]
2927+
// restarts at this point with the ChannelMonitor lost, we should simply discard the channel.
2928+
2929+
// The test framework checks that watched_txn/outputs match the monitor set, which they will
2930+
// not, so we have to clear them here.
2931+
nodes[1].chain_source.watched_txn.lock().unwrap().clear();
2932+
nodes[1].chain_source.watched_outputs.lock().unwrap().clear();
2933+
2934+
let nodes_1_serialized = nodes[1].node.encode();
2935+
persister = test_utils::TestPersister::new();
2936+
let keys_manager = &chanmon_cfgs[1].keys_manager;
2937+
new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[1].chain_source), nodes[1].tx_broadcaster.clone(), nodes[1].logger, node_cfgs[1].fee_estimator, &persister, keys_manager);
2938+
nodes[1].chain_monitor = &new_chain_monitor;
2939+
2940+
let mut nodes_1_read = &nodes_1_serialized[..];
2941+
let config = UserConfig::default();
2942+
nodes_1_deserialized = {
2943+
<(BlockHash, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_1_read, ChannelManagerReadArgs {
2944+
default_config: config,
2945+
keys_manager,
2946+
fee_estimator: node_cfgs[1].fee_estimator,
2947+
chain_monitor: nodes[1].chain_monitor,
2948+
tx_broadcaster: nodes[1].tx_broadcaster.clone(),
2949+
logger: nodes[1].logger,
2950+
channel_monitors: HashMap::new(),
2951+
}).unwrap().1
2952+
};
2953+
nodes[1].node = &nodes_1_deserialized;
2954+
assert!(nodes_1_read.is_empty());
2955+
2956+
check_closed_event!(nodes[1], 1, ClosureReason::DisconnectedPeer);
2957+
assert!(nodes[1].node.list_channels().is_empty());
2958+
}
2959+
2960+
#[test]
2961+
fn test_inbound_reload_without_init_mon() {
2962+
do_test_inbound_reload_without_init_mon(true, true);
2963+
do_test_inbound_reload_without_init_mon(true, false);
2964+
do_test_inbound_reload_without_init_mon(false, true);
2965+
do_test_inbound_reload_without_init_mon(false, false);
2966+
}

0 commit comments

Comments
 (0)