Skip to content

Commit 3718da0

Browse files
authored
Merge pull request #3504 from shaavan/i3381a
Introduce check for dangling RAA blockers in test_utils
2 parents 8588943 + 45aa824 commit 3718da0

File tree

3 files changed

+90
-19
lines changed

3 files changed

+90
-19
lines changed

lightning/src/ln/chanmon_update_fail_tests.rs

+62-19
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::chain::channelmonitor::{ANTI_REORG_DELAY, ChannelMonitor};
1919
use crate::chain::transaction::OutPoint;
2020
use crate::chain::{ChannelMonitorUpdateStatus, Listen, Watch};
2121
use crate::events::{Event, MessageSendEvent, MessageSendEventsProvider, PaymentPurpose, ClosureReason, HTLCDestination};
22-
use crate::ln::channelmanager::{RAACommitmentOrder, PaymentSendFailure, PaymentId, RecipientOnionFields};
22+
use crate::ln::channelmanager::{PaymentId, PaymentSendFailure, RAACommitmentOrder, RecipientOnionFields};
2323
use crate::ln::channel::AnnouncementSigsState;
2424
use crate::ln::msgs;
2525
use crate::ln::types::ChannelId;
@@ -3312,22 +3312,25 @@ fn do_test_durable_preimages_on_closed_channel(close_chans_before_reload: bool,
33123312

33133313
reconnect_nodes(reconnect_args);
33143314

3315-
// Once the blocked `ChannelMonitorUpdate` *finally* completes, the pending
3316-
// `PaymentForwarded` event will finally be released.
3317-
let (outpoint, ab_update_id, _) = nodes[1].chain_monitor.latest_monitor_update_id.lock().unwrap().get(&chan_id_ab).unwrap().clone();
3318-
nodes[1].chain_monitor.chain_monitor.force_channel_monitor_updated(outpoint, ab_update_id);
3319-
3320-
// If the A<->B channel was closed before we reload, we'll replay the claim against it on
3321-
// reload, causing the `PaymentForwarded` event to get replayed.
3322-
let evs = nodes[1].node.get_and_clear_pending_events();
3323-
assert_eq!(evs.len(), if close_chans_before_reload { 2 } else { 1 });
3324-
for ev in evs {
3325-
if let Event::PaymentForwarded { .. } = ev { }
3326-
else {
3327-
panic!();
3328-
}
3315+
}
3316+
3317+
// Once the blocked `ChannelMonitorUpdate` *finally* completes, the pending
3318+
// `PaymentForwarded` event will finally be released.
3319+
let (outpoint, ab_update_id, _) = nodes[1].chain_monitor.latest_monitor_update_id.lock().unwrap().get(&chan_id_ab).unwrap().clone();
3320+
nodes[1].chain_monitor.chain_monitor.force_channel_monitor_updated(outpoint, ab_update_id);
3321+
3322+
// If the A<->B channel was closed before we reload, we'll replay the claim against it on
3323+
// reload, causing the `PaymentForwarded` event to get replayed.
3324+
let evs = nodes[1].node.get_and_clear_pending_events();
3325+
assert_eq!(evs.len(), if close_chans_before_reload { 2 } else { 1 });
3326+
for ev in evs {
3327+
if let Event::PaymentForwarded { .. } = ev { }
3328+
else {
3329+
panic!();
33293330
}
3331+
}
33303332

3333+
if !close_chans_before_reload || close_only_a {
33313334
// Once we call `process_pending_events` the final `ChannelMonitor` for the B<->C channel
33323335
// will fly, removing the payment preimage from it.
33333336
check_added_monitors(&nodes[1], 1);
@@ -3548,8 +3551,11 @@ fn do_test_glacial_peer_cant_hang(hold_chan_a: bool) {
35483551
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
35493552
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
35503553

3551-
create_announced_chan_between_nodes(&nodes, 0, 1);
3552-
create_announced_chan_between_nodes(&nodes, 1, 2);
3554+
let node_a_id = nodes[0].node.get_our_node_id();
3555+
let node_c_id = nodes[2].node.get_our_node_id();
3556+
3557+
let chan_id_ab = create_announced_chan_between_nodes(&nodes, 0, 1).2;
3558+
let _chan_id_bc = create_announced_chan_between_nodes(&nodes, 1, 2).2;
35533559

35543560
// Route a payment from A, through B, to C, then claim it on C. Replay the
35553561
// `update_fulfill_htlc` twice on B to check that B doesn't hang.
@@ -3561,7 +3567,7 @@ fn do_test_glacial_peer_cant_hang(hold_chan_a: bool) {
35613567

35623568
let cs_updates = get_htlc_update_msgs(&nodes[2], &nodes[1].node.get_our_node_id());
35633569
if hold_chan_a {
3564-
// The first update will be on the A <-> B channel, which we allow to complete.
3570+
// The first update will be on the A <-> B channel, which we optionally allow to complete.
35653571
chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
35663572
}
35673573
nodes[1].node.handle_update_fulfill_htlc(nodes[2].node.get_our_node_id(), &cs_updates.update_fulfill_htlcs[0]);
@@ -3588,14 +3594,51 @@ fn do_test_glacial_peer_cant_hang(hold_chan_a: bool) {
35883594
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
35893595
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
35903596

3591-
let (route, payment_hash_2, _, payment_secret_2) = get_route_and_payment_hash!(&nodes[1], nodes[2], 1_000_000);
3597+
let (route, payment_hash_2, payment_preimage_2, payment_secret_2) =
3598+
get_route_and_payment_hash!(&nodes[1], nodes[2], 1_000_000);
35923599

3600+
// With the A<->B preimage persistence not yet complete, the B<->C channel is stuck
3601+
// waiting.
35933602
nodes[1].node.send_payment_with_route(route, payment_hash_2,
35943603
RecipientOnionFields::secret_only(payment_secret_2), PaymentId(payment_hash_2.0)).unwrap();
35953604
check_added_monitors(&nodes[1], 0);
35963605

35973606
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
35983607
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
3608+
3609+
// ...but once we complete the A<->B channel preimage persistence, the B<->C channel
3610+
// unlocks and we send both peers commitment updates.
3611+
let (outpoint, ab_update_id, _) = nodes[1].chain_monitor.latest_monitor_update_id.lock().unwrap().get(&chan_id_ab).unwrap().clone();
3612+
assert!(nodes[1].chain_monitor.chain_monitor.channel_monitor_updated(outpoint, ab_update_id).is_ok());
3613+
3614+
let mut msg_events = nodes[1].node.get_and_clear_pending_msg_events();
3615+
assert_eq!(msg_events.len(), 2);
3616+
check_added_monitors(&nodes[1], 2);
3617+
3618+
let mut c_update = msg_events.iter()
3619+
.filter(|ev| matches!(ev, MessageSendEvent::UpdateHTLCs { node_id, .. } if *node_id == node_c_id))
3620+
.cloned().collect::<Vec<_>>();
3621+
let a_filtermap = |ev| if let MessageSendEvent::UpdateHTLCs { node_id, updates } = ev {
3622+
if node_id == node_a_id {
3623+
Some(updates)
3624+
} else {
3625+
None
3626+
}
3627+
} else {
3628+
None
3629+
};
3630+
let a_update = msg_events.drain(..).filter_map(|ev| a_filtermap(ev)).collect::<Vec<_>>();
3631+
3632+
assert_eq!(a_update.len(), 1);
3633+
assert_eq!(c_update.len(), 1);
3634+
3635+
nodes[0].node.handle_update_fulfill_htlc(nodes[1].node.get_our_node_id(), &a_update[0].update_fulfill_htlcs[0]);
3636+
commitment_signed_dance!(nodes[0], nodes[1], a_update[0].commitment_signed, false);
3637+
expect_payment_sent(&nodes[0], payment_preimage, None, true, true);
3638+
expect_payment_forwarded!(nodes[1], nodes[0], nodes[2], Some(1000), false, false);
3639+
3640+
pass_along_path(&nodes[1], &[&nodes[2]], 1_000_000, payment_hash_2, Some(payment_secret_2), c_update.pop().unwrap(), true, None);
3641+
claim_payment(&nodes[1], &[&nodes[2]], payment_preimage_2);
35993642
}
36003643
}
36013644

lightning/src/ln/channelmanager.rs

+23
Original file line numberDiff line numberDiff line change
@@ -10604,6 +10604,29 @@ where
1060410604
self.pending_outbound_payments.clear_pending_payments()
1060510605
}
1060610606

10607+
#[cfg(any(test, feature = "_test_utils"))]
10608+
pub(crate) fn get_and_clear_pending_raa_blockers(
10609+
&self,
10610+
) -> Vec<(ChannelId, Vec<RAAMonitorUpdateBlockingAction>)> {
10611+
let per_peer_state = self.per_peer_state.read().unwrap();
10612+
let mut pending_blockers = Vec::new();
10613+
10614+
for (_peer_pubkey, peer_state_mutex) in per_peer_state.iter() {
10615+
let mut peer_state = peer_state_mutex.lock().unwrap();
10616+
10617+
for (chan_id, actions) in peer_state.actions_blocking_raa_monitor_updates.iter() {
10618+
// Only collect the non-empty actions into `pending_blockers`.
10619+
if !actions.is_empty() {
10620+
pending_blockers.push((chan_id.clone(), actions.clone()));
10621+
}
10622+
}
10623+
10624+
peer_state.actions_blocking_raa_monitor_updates.clear();
10625+
}
10626+
10627+
pending_blockers
10628+
}
10629+
1060710630
/// When something which was blocking a channel from updating its [`ChannelMonitor`] (e.g. an
1060810631
/// [`Event`] being handled) completes, this should be called to restore the channel to normal
1060910632
/// operation. It will double-check that nothing *else* is also blocking the same channel from

lightning/src/ln/functional_test_utils.rs

+5
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,11 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> {
652652
panic!("Had {} excess added monitors on node {}", added_monitors.len(), self.logger.id);
653653
}
654654

655+
let raa_blockers = self.node.get_and_clear_pending_raa_blockers();
656+
if !raa_blockers.is_empty() {
657+
panic!( "Had excess RAA blockers on node {}: {:?}", self.logger.id, raa_blockers);
658+
}
659+
655660
// Check that if we serialize the network graph, we can deserialize it again.
656661
let network_graph = {
657662
let mut w = test_utils::TestVecWriter(Vec::new());

0 commit comments

Comments
 (0)