Skip to content

Commit 418d59d

Browse files
committed
Only mark all mon updates complete if there are no blocked updates
In `handle_new_monitor_update!`, we correctly check that the channel doesn't have any blocked monitor updates pending before calling `handle_monitor_update_completion!` (which calls `Channel::monitor_updating_restored`, which in turn assumes that all generated `ChannelMonitorUpdate`s, including blocked ones, have completed). We, however, did not do the same check at several other places where we called `handle_monitor_update_completion!`. Specifically, after a monitor update completes during reload (processed via a `BackgroundEvent` or when monitor update completes async, we didn't check if there were any blocked monitor updates before completing). Here we add the missing check, as well as an assertion in `Channel::monitor_updating_restored`.
1 parent 257ebad commit 418d59d

File tree

4 files changed

+89
-20
lines changed

4 files changed

+89
-20
lines changed

lightning/src/ln/chanmon_update_fail_tests.rs

Lines changed: 64 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3410,20 +3410,29 @@ fn test_inbound_reload_without_init_mon() {
34103410
do_test_inbound_reload_without_init_mon(false, false);
34113411
}
34123412

3413-
#[test]
3414-
fn test_blocked_chan_preimage_release() {
3413+
#[derive(PartialEq, Eq)]
3414+
enum BlockedUpdateComplMode {
3415+
Async,
3416+
AtReload,
3417+
Sync,
3418+
}
3419+
3420+
fn do_test_blocked_chan_preimage_release(completion_mode: BlockedUpdateComplMode) {
34153421
// Test that even if a channel's `ChannelMonitorUpdate` flow is blocked waiting on an event to
34163422
// be handled HTLC preimage `ChannelMonitorUpdate`s will still go out.
34173423
let chanmon_cfgs = create_chanmon_cfgs(3);
34183424
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
3425+
let persister;
3426+
let new_chain_mon;
34193427
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
3428+
let nodes_1_reload;
34203429
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
34213430

34223431
let node_a_id = nodes[0].node.get_our_node_id();
34233432
let node_b_id = nodes[1].node.get_our_node_id();
34243433
let node_c_id = nodes[2].node.get_our_node_id();
34253434

3426-
create_announced_chan_between_nodes(&nodes, 0, 1);
3435+
let chan_id_1 = create_announced_chan_between_nodes(&nodes, 0, 1).2;
34273436
let chan_id_2 = create_announced_chan_between_nodes(&nodes, 1, 2).2;
34283437

34293438
send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 5_000_000);
@@ -3456,29 +3465,64 @@ fn test_blocked_chan_preimage_release() {
34563465
expect_payment_claimed!(nodes[0], payment_hash_2, 1_000_000);
34573466

34583467
let as_htlc_fulfill_updates = get_htlc_update_msgs!(nodes[0], node_b_id);
3468+
if completion_mode != BlockedUpdateComplMode::Sync {
3469+
// We use to incorrectly handle monitor update completion in cases where we completed a
3470+
// monitor update async or after reload. We test both based on the `completion_mode`.
3471+
chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
3472+
}
34593473
nodes[1]
34603474
.node
34613475
.handle_update_fulfill_htlc(node_a_id, &as_htlc_fulfill_updates.update_fulfill_htlcs[0]);
34623476
check_added_monitors(&nodes[1], 1); // We generate only a preimage monitor update
34633477
assert!(get_monitor!(nodes[1], chan_id_2).get_stored_preimages().contains_key(&payment_hash_2));
34643478
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
3479+
if completion_mode == BlockedUpdateComplMode::AtReload {
3480+
let node_ser = nodes[1].node.encode();
3481+
let chan_mon_0 = get_monitor!(nodes[1], chan_id_1).encode();
3482+
let chan_mon_1 = get_monitor!(nodes[1], chan_id_2).encode();
3483+
3484+
let mons = &[&chan_mon_0[..], &chan_mon_1[..]];
3485+
reload_node!(nodes[1], &node_ser, mons, persister, new_chain_mon, nodes_1_reload);
3486+
3487+
nodes[0].node.peer_disconnected(node_b_id);
3488+
nodes[2].node.peer_disconnected(node_b_id);
3489+
3490+
let mut a_b_reconnect = ReconnectArgs::new(&nodes[0], &nodes[1]);
3491+
a_b_reconnect.pending_htlc_claims.1 = 1;
3492+
// Note that we will expect no final RAA monitor update in
3493+
// `commitment_signed_dance_through_cp_raa` during the reconnect, matching the below case.
3494+
reconnect_nodes(a_b_reconnect);
3495+
reconnect_nodes(ReconnectArgs::new(&nodes[2], &nodes[1]));
3496+
} else if completion_mode == BlockedUpdateComplMode::Async {
3497+
let (latest_update, _) = get_latest_mon_update_id(&nodes[1], chan_id_2);
3498+
nodes[1]
3499+
.chain_monitor
3500+
.chain_monitor
3501+
.channel_monitor_updated(chan_id_2, latest_update)
3502+
.unwrap();
3503+
}
34653504

34663505
// Finish the CS dance between nodes[0] and nodes[1]. Note that until the event handling, the
34673506
// update_fulfill_htlc + CS is held, even though the preimage is already on disk for the
34683507
// channel.
3469-
nodes[1]
3470-
.node
3471-
.handle_commitment_signed_batch_test(node_a_id, &as_htlc_fulfill_updates.commitment_signed);
3472-
check_added_monitors(&nodes[1], 1);
3473-
let (a, raa) = do_main_commitment_signed_dance(&nodes[1], &nodes[0], false);
3474-
assert!(a.is_none());
3508+
// Note that when completing as a side effect of a reload we completed the CS dance in
3509+
// `reconnect_nodes` above.
3510+
if completion_mode != BlockedUpdateComplMode::AtReload {
3511+
nodes[1].node.handle_commitment_signed_batch_test(
3512+
node_a_id,
3513+
&as_htlc_fulfill_updates.commitment_signed,
3514+
);
3515+
check_added_monitors(&nodes[1], 1);
3516+
let (a, raa) = do_main_commitment_signed_dance(&nodes[1], &nodes[0], false);
3517+
assert!(a.is_none());
34753518

3476-
nodes[1].node.handle_revoke_and_ack(node_a_id, &raa);
3477-
check_added_monitors(&nodes[1], 0);
3478-
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
3519+
nodes[1].node.handle_revoke_and_ack(node_a_id, &raa);
3520+
check_added_monitors(&nodes[1], 0);
3521+
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
3522+
}
34793523

34803524
let events = nodes[1].node.get_and_clear_pending_events();
3481-
assert_eq!(events.len(), 3);
3525+
assert_eq!(events.len(), 3, "{events:?}");
34823526
if let Event::PaymentSent { .. } = events[0] {
34833527
} else {
34843528
panic!();
@@ -3508,6 +3552,13 @@ fn test_blocked_chan_preimage_release() {
35083552
expect_payment_sent(&nodes[2], payment_preimage_2, None, true, true);
35093553
}
35103554

3555+
#[test]
3556+
fn test_blocked_chan_preimage_release() {
3557+
do_test_blocked_chan_preimage_release(BlockedUpdateComplMode::AtReload);
3558+
do_test_blocked_chan_preimage_release(BlockedUpdateComplMode::Sync);
3559+
do_test_blocked_chan_preimage_release(BlockedUpdateComplMode::Async);
3560+
}
3561+
35113562
fn do_test_inverted_mon_completion_order(
35123563
with_latest_manager: bool, complete_bc_commitment_dance: bool,
35133564
) {

lightning/src/ln/channel.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7925,6 +7925,7 @@ where
79257925
{
79267926
assert!(self.context.channel_state.is_monitor_update_in_progress());
79277927
self.context.channel_state.clear_monitor_update_in_progress();
7928+
assert_eq!(self.blocked_monitor_updates_pending(), 0);
79287929

79297930
// If we're past (or at) the AwaitingChannelReady stage on an outbound (or V2-established) channel,
79307931
// try to (re-)broadcast the funding transaction as we may have declined to broadcast it when we

lightning/src/ln/channelmanager.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6934,7 +6934,9 @@ where
69346934
.get_mut(&channel_id)
69356935
.and_then(Channel::as_funded_mut)
69366936
{
6937-
handle_monitor_update_completion!(self, peer_state_lock, peer_state, per_peer_state, chan);
6937+
if chan.blocked_monitor_updates_pending() == 0 {
6938+
handle_monitor_update_completion!(self, peer_state_lock, peer_state, per_peer_state, chan);
6939+
}
69386940
} else {
69396941
let update_actions = peer_state.monitor_update_blocked_actions
69406942
.remove(&channel_id).unwrap_or(Vec::new());
@@ -8226,8 +8228,12 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
82268228
.and_then(Channel::as_funded_mut)
82278229
{
82288230
if chan.is_awaiting_monitor_update() {
8229-
log_trace!(logger, "Channel is open and awaiting update, resuming it");
8230-
handle_monitor_update_completion!(self, peer_state_lock, peer_state, per_peer_state, chan);
8231+
if chan.blocked_monitor_updates_pending() == 0 {
8232+
log_trace!(logger, "Channel is open and awaiting update, resuming it");
8233+
handle_monitor_update_completion!(self, peer_state_lock, peer_state, per_peer_state, chan);
8234+
} else {
8235+
log_trace!(logger, "Channel is open and awaiting update, leaving it blocked due to a blocked monitor update");
8236+
}
82318237
} else {
82328238
log_trace!(logger, "Channel is open but not awaiting update");
82338239
}

lightning/src/ln/quiescence_tests.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -254,15 +254,26 @@ fn test_quiescence_waits_for_async_signer_and_monitor_update() {
254254

255255
// We have two updates pending:
256256
{
257-
let chain_monitor = &nodes[0].chain_monitor;
257+
let test_chain_mon = &nodes[0].chain_monitor;
258258
let (_, latest_update) =
259-
chain_monitor.latest_monitor_update_id.lock().unwrap().get(&chan_id).unwrap().clone();
259+
test_chain_mon.latest_monitor_update_id.lock().unwrap().get(&chan_id).unwrap().clone();
260260
let chain_monitor = &nodes[0].chain_monitor.chain_monitor;
261261
// One for the latest commitment transaction update from the last `revoke_and_ack`
262262
chain_monitor.channel_monitor_updated(chan_id, latest_update).unwrap();
263-
expect_payment_sent(&nodes[0], preimage, None, true, true);
263+
expect_payment_sent(&nodes[0], preimage, None, false, true);
264+
265+
let (_, new_latest_update) =
266+
test_chain_mon.latest_monitor_update_id.lock().unwrap().get(&chan_id).unwrap().clone();
267+
assert_eq!(new_latest_update, latest_update + 1);
264268
// One for the commitment secret update from the last `revoke_and_ack`
265-
chain_monitor.channel_monitor_updated(chan_id, latest_update + 1).unwrap();
269+
chain_monitor.channel_monitor_updated(chan_id, new_latest_update).unwrap();
270+
// Once that update completes, we'll get the `PaymentPathSuccessful` event
271+
let events = nodes[0].node.get_and_clear_pending_events();
272+
assert_eq!(events.len(), 1);
273+
if let Event::PaymentPathSuccessful { .. } = &events[0] {
274+
} else {
275+
panic!("{events:?}");
276+
}
266277
}
267278

268279
// With the updates completed, we can now become quiescent.

0 commit comments

Comments
 (0)