Skip to content

Commit e7facb1

Browse files
committed
Unset Channel::is_usable if mon update is blocking funding_locked
If we have not yet sent `funding_locked` only because of a pending channel monitor update, we shouldn't consider a channel `is_usable`. This has a number of downstream effects, including not attempting to route payments through the channel, not sending private `channel_update` messages to our counterparty, or sending channel_announcement messages if our couterparty has already signed for it. We further gate generation of `node_announcement`s on `is_usable`, preventing generation of those or `announcement_signatures` until we've sent our `funding_locked`. Finally, `during_funding_monitor_fail` is updated to test a case where we see the funding transaction lock in but have a pending monitor update failure, then receive `funding_locked` from our counterparty and ensure we don't generate the above messages until after the monitor update completes.
1 parent 0243f21 commit e7facb1

File tree

2 files changed

+28
-16
lines changed

2 files changed

+28
-16
lines changed

lightning/src/ln/chanmon_update_fail_tests.rs

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1789,9 +1789,9 @@ fn monitor_update_claim_fail_no_response() {
17891789
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2);
17901790
}
17911791

1792-
// confirm_a_first and restore_b_before_conf are wholly unrelated to earlier bools and
17931792
// restore_b_before_conf has no meaning if !confirm_a_first
1794-
fn do_during_funding_monitor_fail(confirm_a_first: bool, restore_b_before_conf: bool) {
1793+
// restore_b_before_lock has no meaning if confirm_a_first
1794+
fn do_during_funding_monitor_fail(confirm_a_first: bool, restore_b_before_conf: bool, restore_b_before_lock: bool) {
17951795
// Test that if the monitor update generated by funding_transaction_generated fails we continue
17961796
// the channel setup happily after the update is restored.
17971797
let chanmon_cfgs = create_chanmon_cfgs(2);
@@ -1833,6 +1833,8 @@ fn do_during_funding_monitor_fail(confirm_a_first: bool, restore_b_before_conf:
18331833
if confirm_a_first {
18341834
confirm_transaction(&nodes[0], &funding_tx);
18351835
nodes[1].node.handle_funding_locked(&nodes[0].node.get_our_node_id(), &get_event_msg!(nodes[0], MessageSendEvent::SendFundingLocked, nodes[1].node.get_our_node_id()));
1836+
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
1837+
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
18361838
} else {
18371839
assert!(!restore_b_before_conf);
18381840
confirm_transaction(&nodes[1], &funding_tx);
@@ -1851,20 +1853,32 @@ fn do_during_funding_monitor_fail(confirm_a_first: bool, restore_b_before_conf:
18511853
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
18521854
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
18531855
}
1856+
if !confirm_a_first && !restore_b_before_lock {
1857+
confirm_transaction(&nodes[0], &funding_tx);
1858+
nodes[1].node.handle_funding_locked(&nodes[0].node.get_our_node_id(), &get_event_msg!(nodes[0], MessageSendEvent::SendFundingLocked, nodes[1].node.get_our_node_id()));
1859+
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
1860+
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
1861+
}
18541862

18551863
chanmon_cfgs[1].persister.set_update_ret(Ok(()));
18561864
let (outpoint, latest_update, _) = nodes[1].chain_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone();
18571865
nodes[1].chain_monitor.chain_monitor.force_channel_monitor_updated(outpoint, latest_update);
18581866
check_added_monitors!(nodes[1], 0);
18591867

18601868
let (channel_id, (announcement, as_update, bs_update)) = if !confirm_a_first {
1861-
nodes[0].node.handle_funding_locked(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendFundingLocked, nodes[0].node.get_our_node_id()));
1862-
1863-
confirm_transaction(&nodes[0], &funding_tx);
1864-
let (funding_locked, channel_id) = create_chan_between_nodes_with_value_confirm_second(&nodes[1], &nodes[0]);
1865-
(channel_id, create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &funding_locked))
1869+
if !restore_b_before_lock {
1870+
let (funding_locked, channel_id) = create_chan_between_nodes_with_value_confirm_second(&nodes[0], &nodes[1]);
1871+
(channel_id, create_chan_between_nodes_with_value_b(&nodes[1], &nodes[0], &funding_locked))
1872+
} else {
1873+
nodes[0].node.handle_funding_locked(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendFundingLocked, nodes[0].node.get_our_node_id()));
1874+
confirm_transaction(&nodes[0], &funding_tx);
1875+
let (funding_locked, channel_id) = create_chan_between_nodes_with_value_confirm_second(&nodes[1], &nodes[0]);
1876+
(channel_id, create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &funding_locked))
1877+
}
18661878
} else {
18671879
if restore_b_before_conf {
1880+
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
1881+
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
18681882
confirm_transaction(&nodes[1], &funding_tx);
18691883
}
18701884
let (funding_locked, channel_id) = create_chan_between_nodes_with_value_confirm_second(&nodes[0], &nodes[1]);
@@ -1884,9 +1898,10 @@ fn do_during_funding_monitor_fail(confirm_a_first: bool, restore_b_before_conf:
18841898

18851899
#[test]
18861900
fn during_funding_monitor_fail() {
1887-
do_during_funding_monitor_fail(true, true);
1888-
do_during_funding_monitor_fail(true, false);
1889-
do_during_funding_monitor_fail(false, false);
1901+
do_during_funding_monitor_fail(true, true, false);
1902+
do_during_funding_monitor_fail(true, false, false);
1903+
do_during_funding_monitor_fail(false, false, false);
1904+
do_during_funding_monitor_fail(false, false, true);
18901905
}
18911906

18921907
#[test]

lightning/src/ln/channel.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4259,7 +4259,7 @@ impl<Signer: Sign> Channel<Signer> {
42594259
/// Allowed in any state (including after shutdown)
42604260
pub fn is_usable(&self) -> bool {
42614261
let mask = ChannelState::ChannelFunded as u32 | BOTH_SIDES_SHUTDOWN_MASK;
4262-
(self.channel_state & mask) == (ChannelState::ChannelFunded as u32)
4262+
(self.channel_state & mask) == (ChannelState::ChannelFunded as u32) && !self.monitor_pending_funding_locked
42634263
}
42644264

42654265
/// Returns true if this channel is currently available for use. This is a superset of
@@ -4670,11 +4670,8 @@ impl<Signer: Sign> Channel<Signer> {
46704670
if !self.config.announced_channel {
46714671
return Err(ChannelError::Ignore("Channel is not available for public announcements".to_owned()));
46724672
}
4673-
if self.channel_state & (ChannelState::ChannelFunded as u32) == 0 {
4674-
return Err(ChannelError::Ignore("Cannot get a ChannelAnnouncement until the channel funding has been locked".to_owned()));
4675-
}
4676-
if (self.channel_state & (ChannelState::LocalShutdownSent as u32 | ChannelState::ShutdownComplete as u32)) != 0 {
4677-
return Err(ChannelError::Ignore("Cannot get a ChannelAnnouncement once the channel is closing".to_owned()));
4673+
if !self.is_usable() {
4674+
return Err(ChannelError::Ignore("Cannot get a ChannelAnnouncement if the channel is not currently usable".to_owned()));
46784675
}
46794676

46804677
let were_node_one = node_id.serialize()[..] < self.counterparty_node_id.serialize()[..];

0 commit comments

Comments
 (0)