Skip to content

Commit cb1db61

Browse files
committed
Fix spurious panic on receipt of a block while awaiting funding
When we receive a block we always test if we should send our channel_ready via `check_get_channel_ready`. If the channel in question requires confirmations, we quickly return if the funding transaction has not yet confirmed (or even been defined), however for 0conf channels the checks are necessarily more involved. In any case, we wish to panic if the funding transaction has confirmations prior to when it should have been broadcasted. This is useful as it is easy for users to violate our broadcast-time invariants without noticing and the panic gives us an opportunity to catch it. Sadly, in the case of 0conf channels, if we hadn't yet seen the funding transaction at all but receive a block we would hit this sanity check as we don't check whether there are actually funding transaction confirmations prior to panicing.
1 parent 4905df8 commit cb1db61

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

lightning/src/ln/channel.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4755,6 +4755,9 @@ impl<Signer: Sign> Channel<Signer> {
47554755
}
47564756

47574757
fn check_get_channel_ready(&mut self, height: u32) -> Option<msgs::ChannelReady> {
4758+
// Called:
4759+
// * always when a new block/transactions are confirmed with the new height
4760+
// * when funding is signed with a height of 0
47584761
if self.funding_tx_confirmation_height == 0 && self.minimum_depth != Some(0) {
47594762
return None;
47604763
}
@@ -4780,7 +4783,7 @@ impl<Signer: Sign> Channel<Signer> {
47804783
// We got a reorg but not enough to trigger a force close, just ignore.
47814784
false
47824785
} else {
4783-
if self.channel_state < ChannelState::ChannelFunded as u32 {
4786+
if self.funding_tx_confirmation_height != 0 && self.channel_state < ChannelState::ChannelFunded as u32 {
47844787
// We should never see a funding transaction on-chain until we've received
47854788
// funding_signed (if we're an outbound channel), or seen funding_generated (if we're
47864789
// an inbound channel - before that we have no known funding TXID). The fuzzer,

lightning/src/ln/priv_short_conf_tests.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,3 +1021,45 @@ fn test_zero_conf_accept_reject() {
10211021
_ => panic!(),
10221022
}
10231023
}
1024+
1025+
#[test]
1026+
fn test_connect_before_funding() {
1027+
// Tests for a particularly dumb explicit panic that existed prior to 0.0.111 for 0conf
1028+
// channels. If we received a block while awaiting funding for 0-conf channels we'd hit an
1029+
// explicit panic when deciding if we should broadcast our channel_ready message.
1030+
let chanmon_cfgs = create_chanmon_cfgs(2);
1031+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
1032+
1033+
let mut manually_accept_conf = test_default_channel_config();
1034+
manually_accept_conf.manually_accept_inbound_channels = true;
1035+
1036+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, Some(manually_accept_conf)]);
1037+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
1038+
1039+
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 10_001, 42, None).unwrap();
1040+
let open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
1041+
1042+
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &open_channel);
1043+
let events = nodes[1].node.get_and_clear_pending_events();
1044+
assert_eq!(events.len(), 1);
1045+
match events[0] {
1046+
Event::OpenChannelRequest { temporary_channel_id, .. } => {
1047+
nodes[1].node.accept_inbound_channel_from_trusted_peer_0conf(&temporary_channel_id, &nodes[0].node.get_our_node_id(), 0).unwrap();
1048+
},
1049+
_ => panic!("Unexpected event"),
1050+
};
1051+
1052+
let mut accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
1053+
assert_eq!(accept_channel.minimum_depth, 0);
1054+
nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &accept_channel);
1055+
1056+
let events = nodes[0].node.get_and_clear_pending_events();
1057+
assert_eq!(events.len(), 1);
1058+
match events[0] {
1059+
Event::FundingGenerationReady { .. } => {},
1060+
_ => panic!("Unexpected event"),
1061+
}
1062+
1063+
connect_blocks(&nodes[0], 1);
1064+
connect_blocks(&nodes[1], 1);
1065+
}

0 commit comments

Comments
 (0)