Skip to content

Commit 9161953

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 58a5592 commit 9161953

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
@@ -1816,9 +1816,9 @@ fn monitor_update_claim_fail_no_response() {
18161816
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2);
18171817
}
18181818

1819-
// confirm_a_first and restore_b_before_conf are wholly unrelated to earlier bools and
18201819
// restore_b_before_conf has no meaning if !confirm_a_first
1821-
fn do_during_funding_monitor_fail(confirm_a_first: bool, restore_b_before_conf: bool) {
1820+
// restore_b_before_lock has no meaning if confirm_a_first
1821+
fn do_during_funding_monitor_fail(confirm_a_first: bool, restore_b_before_conf: bool, restore_b_before_lock: bool) {
18221822
// Test that if the monitor update generated by funding_transaction_generated fails we continue
18231823
// the channel setup happily after the update is restored.
18241824
let chanmon_cfgs = create_chanmon_cfgs(2);
@@ -1860,6 +1860,8 @@ fn do_during_funding_monitor_fail(confirm_a_first: bool, restore_b_before_conf:
18601860
if confirm_a_first {
18611861
confirm_transaction(&nodes[0], &funding_tx);
18621862
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()));
1863+
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
1864+
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
18631865
} else {
18641866
assert!(!restore_b_before_conf);
18651867
confirm_transaction(&nodes[1], &funding_tx);
@@ -1878,20 +1880,32 @@ fn do_during_funding_monitor_fail(confirm_a_first: bool, restore_b_before_conf:
18781880
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
18791881
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
18801882
}
1883+
if !confirm_a_first && !restore_b_before_lock {
1884+
confirm_transaction(&nodes[0], &funding_tx);
1885+
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()));
1886+
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
1887+
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
1888+
}
18811889

18821890
chanmon_cfgs[1].persister.set_update_ret(Ok(()));
18831891
let (outpoint, latest_update, _) = nodes[1].chain_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone();
18841892
nodes[1].chain_monitor.chain_monitor.force_channel_monitor_updated(outpoint, latest_update);
18851893
check_added_monitors!(nodes[1], 0);
18861894

18871895
let (channel_id, (announcement, as_update, bs_update)) = if !confirm_a_first {
1888-
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()));
1889-
1890-
confirm_transaction(&nodes[0], &funding_tx);
1891-
let (funding_locked, channel_id) = create_chan_between_nodes_with_value_confirm_second(&nodes[1], &nodes[0]);
1892-
(channel_id, create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &funding_locked))
1896+
if !restore_b_before_lock {
1897+
let (funding_locked, channel_id) = create_chan_between_nodes_with_value_confirm_second(&nodes[0], &nodes[1]);
1898+
(channel_id, create_chan_between_nodes_with_value_b(&nodes[1], &nodes[0], &funding_locked))
1899+
} else {
1900+
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()));
1901+
confirm_transaction(&nodes[0], &funding_tx);
1902+
let (funding_locked, channel_id) = create_chan_between_nodes_with_value_confirm_second(&nodes[1], &nodes[0]);
1903+
(channel_id, create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &funding_locked))
1904+
}
18931905
} else {
18941906
if restore_b_before_conf {
1907+
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
1908+
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
18951909
confirm_transaction(&nodes[1], &funding_tx);
18961910
}
18971911
let (funding_locked, channel_id) = create_chan_between_nodes_with_value_confirm_second(&nodes[0], &nodes[1]);
@@ -1911,9 +1925,10 @@ fn do_during_funding_monitor_fail(confirm_a_first: bool, restore_b_before_conf:
19111925

19121926
#[test]
19131927
fn during_funding_monitor_fail() {
1914-
do_during_funding_monitor_fail(true, true);
1915-
do_during_funding_monitor_fail(true, false);
1916-
do_during_funding_monitor_fail(false, false);
1928+
do_during_funding_monitor_fail(true, true, false);
1929+
do_during_funding_monitor_fail(true, false, false);
1930+
do_during_funding_monitor_fail(false, false, false);
1931+
do_during_funding_monitor_fail(false, false, true);
19171932
}
19181933

19191934
#[test]

lightning/src/ln/channel.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4092,7 +4092,7 @@ impl<Signer: Sign> Channel<Signer> {
40924092
/// Allowed in any state (including after shutdown)
40934093
pub fn is_usable(&self) -> bool {
40944094
let mask = ChannelState::ChannelFunded as u32 | BOTH_SIDES_SHUTDOWN_MASK;
4095-
(self.channel_state & mask) == (ChannelState::ChannelFunded as u32)
4095+
(self.channel_state & mask) == (ChannelState::ChannelFunded as u32) && !self.monitor_pending_funding_locked
40964096
}
40974097

40984098
/// Returns true if this channel is currently available for use. This is a superset of
@@ -4500,11 +4500,8 @@ impl<Signer: Sign> Channel<Signer> {
45004500
if !self.config.announced_channel {
45014501
return Err(ChannelError::Ignore("Channel is not available for public announcements".to_owned()));
45024502
}
4503-
if self.channel_state & (ChannelState::ChannelFunded as u32) == 0 {
4504-
return Err(ChannelError::Ignore("Cannot get a ChannelAnnouncement until the channel funding has been locked".to_owned()));
4505-
}
4506-
if (self.channel_state & (ChannelState::LocalShutdownSent as u32 | ChannelState::ShutdownComplete as u32)) != 0 {
4507-
return Err(ChannelError::Ignore("Cannot get a ChannelAnnouncement once the channel is closing".to_owned()));
4503+
if !self.is_usable() {
4504+
return Err(ChannelError::Ignore("Cannot get a ChannelAnnouncement if the channel is not currently usable".to_owned()));
45084505
}
45094506

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

0 commit comments

Comments
 (0)