Skip to content

Commit 1619d08

Browse files
authored
Merge pull request #491 from TheBlueMatt/2020-02-one-conf-lock
Fix one-confirmation funding_locked generation
2 parents b7f4f76 + ff24530 commit 1619d08

File tree

3 files changed

+88
-42
lines changed

3 files changed

+88
-42
lines changed

lightning/src/ln/channel.rs

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2987,49 +2987,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
29872987
pub fn block_connected(&mut self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], indexes_of_txn_matched: &[u32]) -> Result<Option<msgs::FundingLocked>, msgs::ErrorMessage> {
29882988
let non_shutdown_state = self.channel_state & (!MULTI_STATE_FLAGS);
29892989
if header.bitcoin_hash() != self.last_block_connected {
2990-
self.last_block_connected = header.bitcoin_hash();
2991-
self.channel_monitor.last_block_hash = self.last_block_connected;
29922990
if self.funding_tx_confirmations > 0 {
29932991
self.funding_tx_confirmations += 1;
2994-
if self.funding_tx_confirmations == self.minimum_depth as u64 {
2995-
let need_commitment_update = if non_shutdown_state == ChannelState::FundingSent as u32 {
2996-
self.channel_state |= ChannelState::OurFundingLocked as u32;
2997-
true
2998-
} else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32) {
2999-
self.channel_state = ChannelState::ChannelFunded as u32 | (self.channel_state & MULTI_STATE_FLAGS);
3000-
self.channel_update_count += 1;
3001-
true
3002-
} else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::OurFundingLocked as u32) {
3003-
// We got a reorg but not enough to trigger a force close, just update
3004-
// funding_tx_confirmed_in and return.
3005-
false
3006-
} else if self.channel_state < ChannelState::ChannelFunded as u32 {
3007-
panic!("Started confirming a channel in a state pre-FundingSent?: {}", self.channel_state);
3008-
} else {
3009-
// We got a reorg but not enough to trigger a force close, just update
3010-
// funding_tx_confirmed_in and return.
3011-
false
3012-
};
3013-
self.funding_tx_confirmed_in = Some(header.bitcoin_hash());
3014-
3015-
//TODO: Note that this must be a duplicate of the previous commitment point they sent us,
3016-
//as otherwise we will have a commitment transaction that they can't revoke (well, kinda,
3017-
//they can by sending two revoke_and_acks back-to-back, but not really). This appears to be
3018-
//a protocol oversight, but I assume I'm just missing something.
3019-
if need_commitment_update {
3020-
if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) == 0 {
3021-
let next_per_commitment_secret = self.build_local_commitment_secret(self.cur_local_commitment_transaction_number);
3022-
let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &next_per_commitment_secret);
3023-
return Ok(Some(msgs::FundingLocked {
3024-
channel_id: self.channel_id,
3025-
next_per_commitment_point: next_per_commitment_point,
3026-
}));
3027-
} else {
3028-
self.monitor_pending_funding_locked = true;
3029-
return Ok(None);
3030-
}
3031-
}
3032-
}
30332992
}
30342993
}
30352994
if non_shutdown_state & !(ChannelState::TheirFundingLocked as u32) == ChannelState::FundingSent as u32 {
@@ -3072,6 +3031,51 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
30723031
}
30733032
}
30743033
}
3034+
if header.bitcoin_hash() != self.last_block_connected {
3035+
self.last_block_connected = header.bitcoin_hash();
3036+
self.channel_monitor.last_block_hash = self.last_block_connected;
3037+
if self.funding_tx_confirmations > 0 {
3038+
if self.funding_tx_confirmations == self.minimum_depth as u64 {
3039+
let need_commitment_update = if non_shutdown_state == ChannelState::FundingSent as u32 {
3040+
self.channel_state |= ChannelState::OurFundingLocked as u32;
3041+
true
3042+
} else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32) {
3043+
self.channel_state = ChannelState::ChannelFunded as u32 | (self.channel_state & MULTI_STATE_FLAGS);
3044+
self.channel_update_count += 1;
3045+
true
3046+
} else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::OurFundingLocked as u32) {
3047+
// We got a reorg but not enough to trigger a force close, just update
3048+
// funding_tx_confirmed_in and return.
3049+
false
3050+
} else if self.channel_state < ChannelState::ChannelFunded as u32 {
3051+
panic!("Started confirming a channel in a state pre-FundingSent?: {}", self.channel_state);
3052+
} else {
3053+
// We got a reorg but not enough to trigger a force close, just update
3054+
// funding_tx_confirmed_in and return.
3055+
false
3056+
};
3057+
self.funding_tx_confirmed_in = Some(header.bitcoin_hash());
3058+
3059+
//TODO: Note that this must be a duplicate of the previous commitment point they sent us,
3060+
//as otherwise we will have a commitment transaction that they can't revoke (well, kinda,
3061+
//they can by sending two revoke_and_acks back-to-back, but not really). This appears to be
3062+
//a protocol oversight, but I assume I'm just missing something.
3063+
if need_commitment_update {
3064+
if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) == 0 {
3065+
let next_per_commitment_secret = self.build_local_commitment_secret(self.cur_local_commitment_transaction_number);
3066+
let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &next_per_commitment_secret);
3067+
return Ok(Some(msgs::FundingLocked {
3068+
channel_id: self.channel_id,
3069+
next_per_commitment_point: next_per_commitment_point,
3070+
}));
3071+
} else {
3072+
self.monitor_pending_funding_locked = true;
3073+
return Ok(None);
3074+
}
3075+
}
3076+
}
3077+
}
3078+
}
30753079
Ok(None)
30763080
}
30773081

lightning/src/ln/channelmanager.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1268,7 +1268,10 @@ impl<ChanSigner: ChannelKeys, M: Deref> ChannelManager<ChanSigner, M> where M::T
12681268
}
12691269

12701270
fn get_announcement_sigs(&self, chan: &Channel<ChanSigner>) -> Option<msgs::AnnouncementSignatures> {
1271-
if !chan.should_announce() { return None }
1271+
if !chan.should_announce() {
1272+
log_trace!(self, "Can't send announcement_signatures for private channel {}", log_bytes!(chan.channel_id()));
1273+
return None
1274+
}
12721275

12731276
let (announcement, our_bitcoin_sig) = match chan.get_channel_announcement(self.get_our_node_id(), self.genesis_hash.clone()) {
12741277
Ok(res) => res,
@@ -1984,6 +1987,7 @@ impl<ChanSigner: ChannelKeys, M: Deref> ChannelManager<ChanSigner, M> where M::T
19841987
}
19851988
try_chan_entry!(self, chan.get_mut().funding_locked(&msg), channel_state, chan);
19861989
if let Some(announcement_sigs) = self.get_announcement_sigs(chan.get()) {
1990+
log_trace!(self, "Sending announcement_signatures for {} in response to funding_locked", log_bytes!(chan.get().channel_id()));
19871991
// If we see locking block before receiving remote funding_locked, we broadcast our
19881992
// announcement_sigs at remote funding_locked reception. If we receive remote
19891993
// funding_locked before seeing locking block, we broadcast our announcement_sigs at locking
@@ -2578,10 +2582,13 @@ impl<ChanSigner: ChannelKeys, M: Deref + Sync + Send> ChainListener for ChannelM
25782582
msg: funding_locked,
25792583
});
25802584
if let Some(announcement_sigs) = self.get_announcement_sigs(channel) {
2585+
log_trace!(self, "Sending funding_locked and announcement_signatures for {}", log_bytes!(channel.channel_id()));
25812586
pending_msg_events.push(events::MessageSendEvent::SendAnnouncementSignatures {
25822587
node_id: channel.get_their_node_id(),
25832588
msg: announcement_sigs,
25842589
});
2590+
} else {
2591+
log_trace!(self, "Sending funding_locked WITHOUT announcement_signatures for {}", log_bytes!(channel.channel_id()));
25852592
}
25862593
short_to_id.insert(channel.get_short_channel_id().unwrap(), channel.channel_id());
25872594
} else if let Err(e) = chan_res {

lightning/src/ln/functional_tests.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,41 @@ fn test_multi_flight_update_fee() {
378378
check_added_monitors!(nodes[1], 1);
379379
}
380380

381+
#[test]
382+
fn test_1_conf_open() {
383+
// Previously, if the minium_depth config was set to 1, we'd never send a funding_locked. This
384+
// tests that we properly send one in that case.
385+
let mut alice_config = UserConfig::default();
386+
alice_config.own_channel_config.minimum_depth = 1;
387+
alice_config.channel_options.announced_channel = true;
388+
alice_config.peer_channel_config_limits.force_announced_channel_preference = false;
389+
let mut bob_config = UserConfig::default();
390+
bob_config.own_channel_config.minimum_depth = 1;
391+
bob_config.channel_options.announced_channel = true;
392+
bob_config.peer_channel_config_limits.force_announced_channel_preference = false;
393+
let node_cfgs = create_node_cfgs(2);
394+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(alice_config), Some(bob_config)]);
395+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
396+
397+
let tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 100000, 10001, InitFeatures::supported(), InitFeatures::supported());
398+
assert!(nodes[0].chain_monitor.does_match_tx(&tx));
399+
assert!(nodes[1].chain_monitor.does_match_tx(&tx));
400+
401+
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
402+
nodes[1].block_notifier.block_connected_checked(&header, 1, &[&tx; 1], &[tx.version; 1]);
403+
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()));
404+
405+
nodes[0].block_notifier.block_connected_checked(&header, 1, &[&tx; 1], &[tx.version; 1]);
406+
let (funding_locked, _) = create_chan_between_nodes_with_value_confirm_second(&nodes[1], &nodes[0]);
407+
let (announcement, as_update, bs_update) = create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &funding_locked);
408+
409+
for node in nodes {
410+
assert!(node.router.handle_channel_announcement(&announcement).unwrap());
411+
node.router.handle_channel_update(&as_update).unwrap();
412+
node.router.handle_channel_update(&bs_update).unwrap();
413+
}
414+
}
415+
381416
#[test]
382417
fn test_update_fee_vanilla() {
383418
let node_cfgs = create_node_cfgs(2);

0 commit comments

Comments
 (0)