Skip to content

Commit 17089b2

Browse files
committed
Handle fallible release_commitment_secret
1 parent eb32016 commit 17089b2

File tree

4 files changed

+30
-21
lines changed

4 files changed

+30
-21
lines changed

lightning/src/ln/channel.rs

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5499,26 +5499,35 @@ impl<SP: Deref> Channel<SP> where
54995499

55005500
fn get_last_revoke_and_ack<L: Deref>(&mut self, logger: &L) -> Option<msgs::RevokeAndACK> where L::Target: Logger {
55015501
debug_assert!(self.context.holder_commitment_point.transaction_number() <= INITIAL_COMMITMENT_NUMBER - 2);
5502-
let per_commitment_secret = self.context.holder_signer.as_ref().release_commitment_secret(self.context.holder_commitment_point.transaction_number() + 2);
5503-
if let HolderCommitmentPoint::Available { transaction_number: _, current, next: _ } = self.context.holder_commitment_point {
5502+
let per_commitment_secret = self.context.holder_signer.as_ref()
5503+
.release_commitment_secret(self.context.holder_commitment_point.transaction_number() + 2).ok();
5504+
if let (HolderCommitmentPoint::Available { current, .. }, Some(per_commitment_secret)) =
5505+
(self.context.holder_commitment_point, per_commitment_secret) {
55045506
self.context.signer_pending_revoke_and_ack = false;
5505-
Some(msgs::RevokeAndACK {
5507+
return Some(msgs::RevokeAndACK {
55065508
channel_id: self.context.channel_id,
55075509
per_commitment_secret,
55085510
next_per_commitment_point: current,
55095511
#[cfg(taproot)]
55105512
next_local_nonce: None,
55115513
})
5512-
} else {
5513-
#[cfg(not(async_signing))] {
5514-
panic!("Holder commitment point must be Available when generating revoke_and_ack");
5515-
}
5516-
#[cfg(async_signing)] {
5517-
log_trace!(logger, "Last revoke-and-ack pending in channel {} for sequence {} because the next per-commitment point is not available",
5518-
&self.context.channel_id(), self.context.holder_commitment_point.transaction_number());
5519-
self.context.signer_pending_revoke_and_ack = true;
5520-
None
5521-
}
5514+
}
5515+
5516+
if !self.context.holder_commitment_point.is_available() {
5517+
log_trace!(logger, "Last revoke-and-ack pending in channel {} for sequence {} because the next per-commitment point is not available",
5518+
&self.context.channel_id(), self.context.holder_commitment_point.transaction_number());
5519+
}
5520+
if per_commitment_secret.is_none() {
5521+
log_trace!(logger, "Last revoke-and-ack pending in channel {} for sequence {} because the next per-commitment secret for {} is not available",
5522+
&self.context.channel_id(), self.context.holder_commitment_point.transaction_number(),
5523+
self.context.holder_commitment_point.transaction_number() + 2);
5524+
}
5525+
#[cfg(not(async_signing))] {
5526+
panic!("Holder commitment point and per commitment secret must be available when generating revoke_and_ack");
5527+
}
5528+
#[cfg(async_signing)] {
5529+
self.context.signer_pending_revoke_and_ack = true;
5530+
None
55225531
}
55235532
}
55245533

lightning/src/ln/functional_tests.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,7 +1474,7 @@ fn test_fee_spike_violation_fails_htlc() {
14741474

14751475
let pubkeys = chan_signer.as_ref().pubkeys();
14761476
(pubkeys.revocation_basepoint, pubkeys.htlc_basepoint,
1477-
chan_signer.as_ref().release_commitment_secret(INITIAL_COMMITMENT_NUMBER),
1477+
chan_signer.as_ref().release_commitment_secret(INITIAL_COMMITMENT_NUMBER).unwrap(),
14781478
chan_signer.as_ref().get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - 2, &secp_ctx).unwrap(),
14791479
chan_signer.as_ref().pubkeys().funding_pubkey)
14801480
};
@@ -7860,15 +7860,15 @@ fn test_counterparty_raa_skip_no_crash() {
78607860

78617861
// Make signer believe we got a counterparty signature, so that it allows the revocation
78627862
keys.as_ecdsa().unwrap().get_enforcement_state().last_holder_commitment -= 1;
7863-
per_commitment_secret = keys.as_ref().release_commitment_secret(INITIAL_COMMITMENT_NUMBER);
7863+
per_commitment_secret = keys.as_ref().release_commitment_secret(INITIAL_COMMITMENT_NUMBER).unwrap();
78647864

78657865
// Must revoke without gaps
78667866
keys.as_ecdsa().unwrap().get_enforcement_state().last_holder_commitment -= 1;
7867-
keys.as_ref().release_commitment_secret(INITIAL_COMMITMENT_NUMBER - 1);
7867+
keys.as_ref().release_commitment_secret(INITIAL_COMMITMENT_NUMBER - 1).unwrap();
78687868

78697869
keys.as_ecdsa().unwrap().get_enforcement_state().last_holder_commitment -= 1;
78707870
next_per_commitment_point = PublicKey::from_secret_key(&Secp256k1::new(),
7871-
&SecretKey::from_slice(&keys.as_ref().release_commitment_secret(INITIAL_COMMITMENT_NUMBER - 2)).unwrap());
7871+
&SecretKey::from_slice(&keys.as_ref().release_commitment_secret(INITIAL_COMMITMENT_NUMBER - 2).unwrap()).unwrap());
78727872
}
78737873

78747874
nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(),

lightning/src/sign/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,7 @@ pub trait ChannelSigner {
749749
///
750750
/// Note that the commitment number starts at `(1 << 48) - 1` and counts backwards.
751751
// TODO: return a Result so we can signal a validation error
752-
fn release_commitment_secret(&self, idx: u64) -> [u8; 32];
752+
fn release_commitment_secret(&self, idx: u64) -> Result<[u8; 32], ()>;
753753

754754
/// Validate the counterparty's signatures on the holder commitment transaction and HTLCs.
755755
///
@@ -1358,8 +1358,8 @@ impl ChannelSigner for InMemorySigner {
13581358
Ok(PublicKey::from_secret_key(secp_ctx, &commitment_secret))
13591359
}
13601360

1361-
fn release_commitment_secret(&self, idx: u64) -> [u8; 32] {
1362-
chan_utils::build_commitment_secret(&self.commitment_seed, idx)
1361+
fn release_commitment_secret(&self, idx: u64) -> Result<[u8; 32], ()> {
1362+
Ok(chan_utils::build_commitment_secret(&self.commitment_seed, idx))
13631363
}
13641364

13651365
fn validate_holder_commitment(

lightning/src/util/test_channel_signer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ impl ChannelSigner for TestChannelSigner {
172172
self.inner.get_per_commitment_point(idx, secp_ctx)
173173
}
174174

175-
fn release_commitment_secret(&self, idx: u64) -> [u8; 32] {
175+
fn release_commitment_secret(&self, idx: u64) -> Result<[u8; 32], ()> {
176176
{
177177
let mut state = self.state.lock().unwrap();
178178
assert!(idx == state.last_holder_revoked_commitment || idx == state.last_holder_revoked_commitment - 1, "can only revoke the current or next unrevoked commitment - trying {}, last revoked {}", idx, state.last_holder_revoked_commitment);

0 commit comments

Comments
 (0)