Skip to content

Commit dcc7e84

Browse files
committed
Fix channel_reestablish generation/handling around next_remote.
1 parent 26a7192 commit dcc7e84

File tree

2 files changed

+44
-13
lines changed

2 files changed

+44
-13
lines changed

src/ln/channel.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2289,7 +2289,8 @@ impl Channel {
22892289
return Err(ChannelError::Close("Peer sent a loose channel_reestablish not after reconnect"));
22902290
}
22912291

2292-
if msg.next_local_commitment_number >= INITIAL_COMMITMENT_NUMBER || msg.next_remote_commitment_number >= INITIAL_COMMITMENT_NUMBER {
2292+
if msg.next_local_commitment_number >= INITIAL_COMMITMENT_NUMBER || msg.next_remote_commitment_number >= INITIAL_COMMITMENT_NUMBER ||
2293+
msg.next_local_commitment_number == 0 {
22932294
return Err(ChannelError::Close("Peer sent a garbage channel_reestablish"));
22942295
}
22952296

@@ -2304,15 +2305,15 @@ impl Channel {
23042305
})
23052306
} else { None };
23062307

2307-
if self.channel_state & (ChannelState::FundingSent as u32 | ChannelState::OurFundingLocked as u32) == ChannelState::FundingSent as u32 {
2308-
// Short circuit the whole handler as there is nothing we can resend them
2309-
return Ok((None, None, None, None, RAACommitmentOrder::CommitmentFirst, shutdown_msg));
2310-
}
2311-
2312-
if msg.next_local_commitment_number == 0 || msg.next_remote_commitment_number == 0 {
2313-
if self.channel_state & (ChannelState::FundingSent as u32) != ChannelState::FundingSent as u32 {
2314-
return Err(ChannelError::Close("Peer sent a pre-funding channel_reestablish after we exchanged funding_locked"));
2308+
if self.channel_state & (ChannelState::FundingSent as u32) == ChannelState::FundingSent as u32 {
2309+
if self.channel_state & ChannelState::OurFundingLocked as u32 == 0 {
2310+
if msg.next_remote_commitment_number != 0 {
2311+
return Err(ChannelError::Close("Peer claimed they saw a revoke_and_ack but we haven't sent funding_locked yet"));
2312+
}
2313+
// Short circuit the whole handler as there is nothing we can resend them
2314+
return Ok((None, None, None, None, RAACommitmentOrder::CommitmentFirst, shutdown_msg));
23152315
}
2316+
23162317
// We have OurFundingLocked set!
23172318
let next_per_commitment_secret = self.build_local_commitment_secret(self.cur_local_commitment_transaction_number);
23182319
let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &next_per_commitment_secret);
@@ -2322,11 +2323,11 @@ impl Channel {
23222323
}), None, None, None, RAACommitmentOrder::CommitmentFirst, shutdown_msg));
23232324
}
23242325

2325-
let required_revoke = if msg.next_remote_commitment_number == INITIAL_COMMITMENT_NUMBER - self.cur_local_commitment_transaction_number {
2326+
let required_revoke = if msg.next_remote_commitment_number + 1 == INITIAL_COMMITMENT_NUMBER - self.cur_local_commitment_transaction_number {
23262327
// Remote isn't waiting on any RevokeAndACK from us!
23272328
// Note that if we need to repeat our FundingLocked we'll do that in the next if block.
23282329
None
2329-
} else if msg.next_remote_commitment_number == (INITIAL_COMMITMENT_NUMBER - 1) - self.cur_local_commitment_transaction_number {
2330+
} else if msg.next_remote_commitment_number + 1 == (INITIAL_COMMITMENT_NUMBER - 1) - self.cur_local_commitment_transaction_number {
23302331
if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) != 0 {
23312332
self.monitor_pending_revoke_and_ack = true;
23322333
None
@@ -3053,11 +3054,16 @@ impl Channel {
30533054
/// self.remove_uncommitted_htlcs_and_mark_paused()'d
30543055
pub fn get_channel_reestablish(&self) -> msgs::ChannelReestablish {
30553056
assert_eq!(self.channel_state & ChannelState::PeerDisconnected as u32, ChannelState::PeerDisconnected as u32);
3057+
assert_ne!(self.cur_remote_commitment_transaction_number, INITIAL_COMMITMENT_NUMBER);
30563058
msgs::ChannelReestablish {
30573059
channel_id: self.channel_id(),
30583060
next_local_commitment_number: INITIAL_COMMITMENT_NUMBER - self.cur_local_commitment_transaction_number,
3059-
next_remote_commitment_number: INITIAL_COMMITMENT_NUMBER - self.cur_remote_commitment_transaction_number -
3060-
if self.channel_state & (ChannelState::FundingSent as u32 | ChannelState::OurFundingLocked as u32) == (ChannelState::FundingSent as u32) { 1 } else { 0 },
3061+
// We have to set next_remote_commitment_number to the next revoke_and_ack we expect to
3062+
// receive, not the next commitment_signed we expect to send. So we have to drop this
3063+
// by 1. Note that if cur_remote_commitment_transaction_number is
3064+
// INITIAL_COMMITMENT_NUMBER we will have dropped this channel on disconnect as it
3065+
// hasn't yet reached FundingSent.
3066+
next_remote_commitment_number: INITIAL_COMMITMENT_NUMBER - self.cur_remote_commitment_transaction_number - 1,
30613067
data_loss_protect: None,
30623068
}
30633069
}

src/ln/channelmanager.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6315,6 +6315,31 @@ mod tests {
63156315
node_b.node.peer_connected(&node_a.node.get_our_node_id());
63166316
let reestablish_2 = get_chan_reestablish_msgs!(node_b, node_a);
63176317

6318+
if send_funding_locked.0 {
6319+
// If a expects a funding_locked, it better not think it has received a revoke_and_ack
6320+
// from b
6321+
for reestablish in reestablish_1.iter() {
6322+
assert_eq!(reestablish.next_remote_commitment_number, 0);
6323+
}
6324+
}
6325+
if send_funding_locked.1 {
6326+
// If b expects a funding_locked, it better not think it has received a revoke_and_ack
6327+
// from a
6328+
for reestablish in reestablish_2.iter() {
6329+
assert_eq!(reestablish.next_remote_commitment_number, 0);
6330+
}
6331+
}
6332+
if send_funding_locked.0 || send_funding_locked.1 {
6333+
// If we expect any funding_locked's, both sides better have set
6334+
// next_local_commitment_number to 1
6335+
for reestablish in reestablish_1.iter() {
6336+
assert_eq!(reestablish.next_local_commitment_number, 1);
6337+
}
6338+
for reestablish in reestablish_2.iter() {
6339+
assert_eq!(reestablish.next_local_commitment_number, 1);
6340+
}
6341+
}
6342+
63186343
let mut resp_1 = Vec::new();
63196344
for msg in reestablish_1 {
63206345
node_b.node.handle_channel_reestablish(&node_a.node.get_our_node_id(), &msg).unwrap();

0 commit comments

Comments
 (0)