Skip to content

Commit f5ca346

Browse files
committed
Fix commitment transaction number/per_commitment_point tracking
1 parent 0940db2 commit f5ca346

File tree

1 file changed

+19
-14
lines changed

1 file changed

+19
-14
lines changed

src/ln/channel.rs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,8 @@ pub struct Channel {
285285
their_delayed_payment_basepoint: PublicKey,
286286
their_htlc_basepoint: PublicKey,
287287
their_cur_commitment_point: PublicKey,
288+
289+
their_prev_commitment_point: Option<PublicKey>,
288290
their_node_id: PublicKey,
289291

290292
their_shutdown_scriptpubkey: Option<Script>,
@@ -413,6 +415,8 @@ impl Channel {
413415
their_delayed_payment_basepoint: PublicKey::new(),
414416
their_htlc_basepoint: PublicKey::new(),
415417
their_cur_commitment_point: PublicKey::new(),
418+
419+
their_prev_commitment_point: None,
416420
their_node_id: their_node_id,
417421

418422
their_shutdown_scriptpubkey: None,
@@ -534,6 +538,8 @@ impl Channel {
534538
their_delayed_payment_basepoint: msg.delayed_payment_basepoint,
535539
their_htlc_basepoint: msg.htlc_basepoint,
536540
their_cur_commitment_point: msg.first_per_commitment_point,
541+
542+
their_prev_commitment_point: None,
537543
their_node_id: their_node_id,
538544

539545
their_shutdown_scriptpubkey: None,
@@ -1183,6 +1189,8 @@ impl Channel {
11831189
self.channel_state = ChannelState::FundingSent as u32;
11841190
let funding_txo = self.channel_monitor.get_funding_txo().unwrap();
11851191
self.channel_id = funding_txo.0.into_be() ^ Uint256::from_u64(funding_txo.1 as u64).unwrap(); //TODO: or le?
1192+
self.cur_remote_commitment_transaction_number -= 1;
1193+
self.cur_local_commitment_transaction_number -= 1;
11861194

11871195
Ok(msgs::FundingSigned {
11881196
channel_id: self.channel_id,
@@ -1199,7 +1207,7 @@ impl Channel {
11991207
if self.channel_state != ChannelState::FundingCreated as u32 {
12001208
return Err(HandleError{err: "Received funding_signed in strange state!", msg: None});
12011209
}
1202-
if self.channel_monitor.get_min_seen_secret() != (1 << 48) || self.cur_remote_commitment_transaction_number != (1 << 48) - 1 || self.cur_local_commitment_transaction_number != (1 << 48) - 1 {
1210+
if self.channel_monitor.get_min_seen_secret() != (1 << 48) || self.cur_remote_commitment_transaction_number != (1 << 48) - 2 || self.cur_local_commitment_transaction_number != (1 << 48) - 1 {
12031211
panic!("Should not have advanced channel commitment tx numbers prior to funding_created");
12041212
}
12051213

@@ -1213,6 +1221,7 @@ impl Channel {
12131221
secp_call!(self.secp_ctx.verify(&local_sighash, &msg.signature, &self.their_funding_pubkey), "Invalid funding_signed signature from peer");
12141222

12151223
self.channel_state = ChannelState::FundingSent as u32;
1224+
self.cur_local_commitment_transaction_number -= 1;
12161225

12171226
Ok(())
12181227
}
@@ -1227,13 +1236,7 @@ impl Channel {
12271236
return Err(HandleError{err: "Peer sent a funding_locked at a strange time", msg: None});
12281237
}
12291238

1230-
//TODO: Note that this must be a duplicate of the previous commitment point they sent us,
1231-
//as otherwise we will have a commitment transaction that they can't revoke (well, kinda,
1232-
//they can by sending two revoke_and_acks back-to-back, but not really). This appears to be
1233-
//a protocol oversight, but I assume I'm just missing something.
1234-
if self.their_cur_commitment_point != msg.next_per_commitment_point {
1235-
return Err(HandleError{err: "Non-duplicate next_per_commitment_point in funding_locked", msg: None});
1236-
}
1239+
self.their_prev_commitment_point = Some(self.their_cur_commitment_point);
12371240
self.their_cur_commitment_point = msg.next_per_commitment_point;
12381241
Ok(())
12391242
}
@@ -1407,9 +1410,7 @@ impl Channel {
14071410
}
14081411

14091412
let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number - 1)).unwrap();
1410-
let per_commitment_secret = chan_utils::build_commitment_secret(self.local_keys.commitment_seed, self.cur_local_commitment_transaction_number);
1411-
1412-
//TODO: Store htlc keys in our channel_watcher
1413+
let per_commitment_secret = chan_utils::build_commitment_secret(self.local_keys.commitment_seed, self.cur_local_commitment_transaction_number + 1);
14131414

14141415
// Update state now that we've passed all the can-fail calls...
14151416

@@ -1527,16 +1528,19 @@ impl Channel {
15271528
if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) {
15281529
return Err(HandleError{err: "Got revoke/ACK message when channel was not in an operational state", msg: None});
15291530
}
1530-
if PublicKey::from_secret_key(&self.secp_ctx, &secp_call!(SecretKey::from_slice(&self.secp_ctx, &msg.per_commitment_secret), "Peer provided an invalid per_commitment_secret")).unwrap() != self.their_cur_commitment_point {
1531-
return Err(HandleError{err: "Got a revoke commitment secret which didn't correspond to their current pubkey", msg: None});
1531+
if let Some(their_prev_commitment_point) = self.their_prev_commitment_point {
1532+
if PublicKey::from_secret_key(&self.secp_ctx, &secp_call!(SecretKey::from_slice(&self.secp_ctx, &msg.per_commitment_secret), "Peer provided an invalid per_commitment_secret")).unwrap() != their_prev_commitment_point {
1533+
return Err(HandleError{err: "Got a revoke commitment secret which didn't correspond to their current pubkey", msg: None});
1534+
}
15321535
}
1533-
self.channel_monitor.provide_secret(self.cur_remote_commitment_transaction_number, msg.per_commitment_secret)?;
1536+
self.channel_monitor.provide_secret(self.cur_remote_commitment_transaction_number + 1, msg.per_commitment_secret)?;
15341537

15351538
// Update state now that we've passed all the can-fail calls...
15361539
// (note that we may still fail to generate the new commitment_signed message, but that's
15371540
// OK, we step the channel here and *then* if the new generation fails we can fail the
15381541
// channel based on that, but stepping stuff here should be safe either way.
15391542
self.channel_state &= !(ChannelState::AwaitingRemoteRevoke as u32);
1543+
self.their_prev_commitment_point = Some(self.their_cur_commitment_point);
15401544
self.their_cur_commitment_point = msg.next_per_commitment_point;
15411545
self.cur_remote_commitment_transaction_number -= 1;
15421546

@@ -2058,6 +2062,7 @@ impl Channel {
20582062
self.channel_state = ChannelState::FundingCreated as u32;
20592063
let funding_txo = self.channel_monitor.get_funding_txo().unwrap();
20602064
self.channel_id = funding_txo.0.into_be() ^ Uint256::from_u64(funding_txo.1 as u64).unwrap(); //TODO: or le?
2065+
self.cur_remote_commitment_transaction_number -= 1;
20612066

20622067
Ok(msgs::FundingCreated {
20632068
temporary_channel_id: temporary_channel_id,

0 commit comments

Comments
 (0)