Skip to content

Commit 552e9cb

Browse files
committed
Allow get_per_commitment_point to fail.
This changes `ChannelSigner::get_per_commitment_point` to return a `Result<PublicKey, ()`, which means that it can fail. Similarly, it changes `ChannelSigner::release_commitment_secret`. In order to accomodate failure at the callsites that otherwise assumed it was infallible, we cache the next per-commitment point each time the state advances in the `ChannelContext` and change the callsites to instead use the cached value.
1 parent 61d896d commit 552e9cb

File tree

6 files changed

+102
-49
lines changed

6 files changed

+102
-49
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2752,9 +2752,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
27522752
},
27532753
commitment_txid: htlc.commitment_txid,
27542754
per_commitment_number: htlc.per_commitment_number,
2755-
per_commitment_point: self.onchain_tx_handler.signer.get_per_commitment_point(
2756-
htlc.per_commitment_number, &self.onchain_tx_handler.secp_ctx,
2757-
),
2755+
per_commitment_point: htlc.per_commitment_point,
27582756
htlc: htlc.htlc,
27592757
preimage: htlc.preimage,
27602758
counterparty_sig: htlc.counterparty_sig,

lightning/src/chain/onchaintx.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ pub(crate) struct ExternalHTLCClaim {
179179
pub(crate) htlc: HTLCOutputInCommitment,
180180
pub(crate) preimage: Option<PaymentPreimage>,
181181
pub(crate) counterparty_sig: Signature,
182+
pub(crate) per_commitment_point: bitcoin::secp256k1::PublicKey,
182183
}
183184

184185
// Represents the different types of claims for which events are yielded externally to satisfy said
@@ -1188,9 +1189,16 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
11881189
})
11891190
.map(|(htlc_idx, htlc)| {
11901191
let counterparty_htlc_sig = holder_commitment.counterparty_htlc_sigs[htlc_idx];
1192+
1193+
// TODO(waterson) fallible: move this somewhere!
1194+
let per_commitment_point = self.signer.get_per_commitment_point(
1195+
trusted_tx.commitment_number(), &self.secp_ctx,
1196+
).unwrap();
1197+
11911198
ExternalHTLCClaim {
11921199
commitment_txid: trusted_tx.txid(),
11931200
per_commitment_number: trusted_tx.commitment_number(),
1201+
per_commitment_point: per_commitment_point,
11941202
htlc: htlc.clone(),
11951203
preimage: *preimage,
11961204
counterparty_sig: counterparty_htlc_sig,

lightning/src/ln/channel.rs

Lines changed: 70 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use crate::chain::BestBlock;
3535
use crate::chain::chaininterface::{FeeEstimator, ConfirmationTarget, LowerBoundedFeeEstimator};
3636
use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, LATENCY_GRACE_PERIOD_BLOCKS, CLOSED_CHANNEL_UPDATE_ID};
3737
use crate::chain::transaction::{OutPoint, TransactionData};
38-
use crate::sign::{EcdsaChannelSigner, WriteableEcdsaChannelSigner, EntropySource, ChannelSigner, SignerProvider, NodeSigner, Recipient};
38+
use crate::sign::{EcdsaChannelSigner, WriteableEcdsaChannelSigner, EntropySource, ChannelSigner, SignerProvider, NodeSigner, Recipient, SignerError};
3939
use crate::events::ClosureReason;
4040
use crate::routing::gossip::NodeId;
4141
use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer, VecWriter};
@@ -670,6 +670,13 @@ pub(super) struct ChannelContext<SP: Deref> where SP::Target: SignerProvider {
670670
// cost of others, but should really just be changed.
671671

672672
cur_holder_commitment_transaction_number: u64,
673+
674+
// The commitment point corresponding to `cur_holder_commitment_transaction_number`, which is the
675+
// *next* state. We recompute it each time the state changes because the state changes in places
676+
// that might be fallible: in particular, if the commitment point must be fetched from a remote
677+
// source, we want to ensure it happens at a point where we can actually fail somewhat gracefully;
678+
// i.e., force-closing a channel is better than a panic!
679+
next_per_commitment_point: PublicKey,
673680
cur_counterparty_commitment_transaction_number: u64,
674681
value_to_self_msat: u64, // Excluding all pending_htlcs, excluding fees
675682
pending_inbound_htlcs: Vec<InboundHTLCOutput>,
@@ -1446,13 +1453,14 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
14461453
/// our counterparty!)
14471454
/// The result is a transaction which we can revoke broadcastership of (ie a "local" transaction)
14481455
/// TODO Some magic rust shit to compile-time check this?
1449-
fn build_holder_transaction_keys(&self, commitment_number: u64) -> TxCreationKeys {
1450-
let per_commitment_point = self.holder_signer.as_ref().get_per_commitment_point(commitment_number, &self.secp_ctx);
1456+
fn build_holder_transaction_keys(&self) -> TxCreationKeys {
14511457
let delayed_payment_base = &self.get_holder_pubkeys().delayed_payment_basepoint;
14521458
let htlc_basepoint = &self.get_holder_pubkeys().htlc_basepoint;
14531459
let counterparty_pubkeys = self.get_counterparty_pubkeys();
14541460

1455-
TxCreationKeys::derive_new(&self.secp_ctx, &per_commitment_point, delayed_payment_base, htlc_basepoint, &counterparty_pubkeys.revocation_basepoint, &counterparty_pubkeys.htlc_basepoint)
1461+
TxCreationKeys::derive_new(
1462+
&self.secp_ctx, &self.next_per_commitment_point, delayed_payment_base, htlc_basepoint,
1463+
&counterparty_pubkeys.revocation_basepoint, &counterparty_pubkeys.htlc_basepoint)
14561464
}
14571465

14581466
#[inline]
@@ -2499,7 +2507,12 @@ impl<SP: Deref> Channel<SP> where
24992507
log_trace!(logger, "Initial counterparty tx for channel {} is: txid {} tx {}",
25002508
&self.context.channel_id(), counterparty_initial_bitcoin_tx.txid, encode::serialize_hex(&counterparty_initial_bitcoin_tx.transaction));
25012509

2502-
let holder_signer = self.context.build_holder_transaction_keys(self.context.cur_holder_commitment_transaction_number);
2510+
self.context.next_per_commitment_point =
2511+
self.context.holder_signer.as_ref().get_per_commitment_point(
2512+
self.context.cur_holder_commitment_transaction_number, &self.context.secp_ctx
2513+
).map_err(|_| ChannelError::Close("Unable to generate commitment point".to_owned()))?;
2514+
2515+
let holder_signer = self.context.build_holder_transaction_keys();
25032516
let initial_commitment_tx = self.context.build_commitment_transaction(self.context.cur_holder_commitment_transaction_number, &holder_signer, true, false, logger).tx;
25042517
{
25052518
let trusted_tx = initial_commitment_tx.trust();
@@ -2549,6 +2562,11 @@ impl<SP: Deref> Channel<SP> where
25492562
assert_eq!(self.context.channel_state & (ChannelState::MonitorUpdateInProgress as u32), 0); // We have no had any monitor(s) yet to fail update!
25502563
self.context.channel_state = ChannelState::FundingSent as u32;
25512564
self.context.cur_holder_commitment_transaction_number -= 1;
2565+
self.context.next_per_commitment_point =
2566+
self.context.holder_signer.as_ref().get_per_commitment_point(
2567+
self.context.cur_holder_commitment_transaction_number, &self.context.secp_ctx
2568+
).map_err(|_| ChannelError::Close("Unable to generate commitment point".to_owned()))?;
2569+
25522570
self.context.cur_counterparty_commitment_transaction_number -= 1;
25532571

25542572
log_info!(logger, "Received funding_signed from peer for channel {}", &self.context.channel_id());
@@ -2870,7 +2888,7 @@ impl<SP: Deref> Channel<SP> where
28702888

28712889
let funding_script = self.context.get_funding_redeemscript();
28722890

2873-
let keys = self.context.build_holder_transaction_keys(self.context.cur_holder_commitment_transaction_number);
2891+
let keys = self.context.build_holder_transaction_keys();
28742892

28752893
let commitment_stats = self.context.build_commitment_transaction(self.context.cur_holder_commitment_transaction_number, &keys, true, false, logger);
28762894
let commitment_txid = {
@@ -3034,6 +3052,11 @@ impl<SP: Deref> Channel<SP> where
30343052
};
30353053

30363054
self.context.cur_holder_commitment_transaction_number -= 1;
3055+
self.context.next_per_commitment_point =
3056+
self.context.holder_signer.as_ref().get_per_commitment_point(
3057+
self.context.cur_holder_commitment_transaction_number, &self.context.secp_ctx
3058+
).map_err(|_| ChannelError::Close("Unable to generate commitment point".to_owned()))?;
3059+
30373060
// Note that if we need_commitment & !AwaitingRemoteRevoke we'll call
30383061
// build_commitment_no_status_check() next which will reset this to RAAFirst.
30393062
self.context.resend_order = RAACommitmentOrder::CommitmentFirst;
@@ -3512,7 +3535,7 @@ impl<SP: Deref> Channel<SP> where
35123535
// Before proposing a feerate update, check that we can actually afford the new fee.
35133536
let inbound_stats = self.context.get_inbound_pending_htlc_stats(Some(feerate_per_kw));
35143537
let outbound_stats = self.context.get_outbound_pending_htlc_stats(Some(feerate_per_kw));
3515-
let keys = self.context.build_holder_transaction_keys(self.context.cur_holder_commitment_transaction_number);
3538+
let keys = self.context.build_holder_transaction_keys();
35163539
let commitment_stats = self.context.build_commitment_transaction(self.context.cur_holder_commitment_transaction_number, &keys, true, true, logger);
35173540
let buffer_fee_msat = commit_tx_fee_sat(feerate_per_kw, commitment_stats.num_nondust_htlcs + outbound_stats.on_holder_tx_holding_cell_htlcs_count as usize + CONCURRENT_INBOUND_HTLC_FEE_BUFFER as usize, self.context.get_channel_type()) * 1000;
35183541
let holder_balance_msat = commitment_stats.local_balance_msat - outbound_stats.holding_cell_msat;
@@ -3693,10 +3716,9 @@ impl<SP: Deref> Channel<SP> where
36933716
assert!(!self.context.is_outbound() || self.context.minimum_depth == Some(0),
36943717
"Funding transaction broadcast by the local client before it should have - LDK didn't do it!");
36953718
self.context.monitor_pending_channel_ready = false;
3696-
let next_per_commitment_point = self.context.holder_signer.as_ref().get_per_commitment_point(self.context.cur_holder_commitment_transaction_number, &self.context.secp_ctx);
36973719
Some(msgs::ChannelReady {
36983720
channel_id: self.context.channel_id(),
3699-
next_per_commitment_point,
3721+
next_per_commitment_point: self.context.next_per_commitment_point,
37003722
short_channel_id_alias: Some(self.context.outbound_scid_alias),
37013723
})
37023724
} else { None };
@@ -3775,12 +3797,13 @@ impl<SP: Deref> Channel<SP> where
37753797
}
37763798

37773799
fn get_last_revoke_and_ack(&self) -> msgs::RevokeAndACK {
3778-
let next_per_commitment_point = self.context.holder_signer.as_ref().get_per_commitment_point(self.context.cur_holder_commitment_transaction_number, &self.context.secp_ctx);
3779-
let per_commitment_secret = self.context.holder_signer.as_ref().release_commitment_secret(self.context.cur_holder_commitment_transaction_number + 2);
3800+
// TODO(waterson): fallible!
3801+
let per_commitment_secret = self.context.holder_signer.as_ref().release_commitment_secret(self.context.cur_holder_commitment_transaction_number + 2)
3802+
.expect("release_per_commitment failed");
37803803
msgs::RevokeAndACK {
37813804
channel_id: self.context.channel_id,
37823805
per_commitment_secret,
3783-
next_per_commitment_point,
3806+
next_per_commitment_point: self.context.next_per_commitment_point,
37843807
#[cfg(taproot)]
37853808
next_local_nonce: None,
37863809
}
@@ -3890,7 +3913,9 @@ impl<SP: Deref> Channel<SP> where
38903913
}
38913914

38923915
if msg.next_remote_commitment_number > 0 {
3893-
let expected_point = self.context.holder_signer.as_ref().get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - msg.next_remote_commitment_number + 1, &self.context.secp_ctx);
3916+
let state_index = INITIAL_COMMITMENT_NUMBER - msg.next_remote_commitment_number + 1;
3917+
let expected_point = self.context.holder_signer.as_ref().get_per_commitment_point(state_index, &self.context.secp_ctx)
3918+
.map_err(|_| ChannelError::Close(format!("Unable to retrieve per-commitment point for state {state_index}")))?;
38943919
let given_secret = SecretKey::from_slice(&msg.your_last_per_commitment_secret)
38953920
.map_err(|_| ChannelError::Close("Peer sent a garbage channel_reestablish with unparseable secret key".to_owned()))?;
38963921
if expected_point != PublicKey::from_secret_key(&self.context.secp_ctx, &given_secret) {
@@ -3949,11 +3974,10 @@ impl<SP: Deref> Channel<SP> where
39493974
}
39503975

39513976
// We have OurChannelReady set!
3952-
let next_per_commitment_point = self.context.holder_signer.as_ref().get_per_commitment_point(self.context.cur_holder_commitment_transaction_number, &self.context.secp_ctx);
39533977
return Ok(ReestablishResponses {
39543978
channel_ready: Some(msgs::ChannelReady {
39553979
channel_id: self.context.channel_id(),
3956-
next_per_commitment_point,
3980+
next_per_commitment_point: self.context.next_per_commitment_point,
39573981
short_channel_id_alias: Some(self.context.outbound_scid_alias),
39583982
}),
39593983
raa: None, commitment_update: None,
@@ -3989,10 +4013,9 @@ impl<SP: Deref> Channel<SP> where
39894013

39904014
let channel_ready = if msg.next_local_commitment_number == 1 && INITIAL_COMMITMENT_NUMBER - self.context.cur_holder_commitment_transaction_number == 1 {
39914015
// We should never have to worry about MonitorUpdateInProgress resending ChannelReady
3992-
let next_per_commitment_point = self.context.holder_signer.as_ref().get_per_commitment_point(self.context.cur_holder_commitment_transaction_number, &self.context.secp_ctx);
39934016
Some(msgs::ChannelReady {
39944017
channel_id: self.context.channel_id(),
3995-
next_per_commitment_point,
4018+
next_per_commitment_point: self.context.next_per_commitment_point,
39964019
short_channel_id_alias: Some(self.context.outbound_scid_alias),
39974020
})
39984021
} else { None };
@@ -4685,13 +4708,13 @@ impl<SP: Deref> Channel<SP> where
46854708
if need_commitment_update {
46864709
if self.context.channel_state & (ChannelState::MonitorUpdateInProgress as u32) == 0 {
46874710
if self.context.channel_state & (ChannelState::PeerDisconnected as u32) == 0 {
4688-
let next_per_commitment_point =
4689-
self.context.holder_signer.as_ref().get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - 1, &self.context.secp_ctx);
4690-
return Some(msgs::ChannelReady {
4691-
channel_id: self.context.channel_id,
4692-
next_per_commitment_point,
4693-
short_channel_id_alias: Some(self.context.outbound_scid_alias),
4694-
});
4711+
if let Ok(next_per_commitment_point) = self.context.holder_signer.as_ref().get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - 1, &self.context.secp_ctx) {
4712+
return Some(msgs::ChannelReady {
4713+
channel_id: self.context.channel_id,
4714+
next_per_commitment_point,
4715+
short_channel_id_alias: Some(self.context.outbound_scid_alias),
4716+
});
4717+
}
46954718
}
46964719
} else {
46974720
self.context.monitor_pending_channel_ready = true;
@@ -5641,6 +5664,9 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
56415664

56425665
let temporary_channel_id = ChannelId::temporary_from_entropy_source(entropy_source);
56435666

5667+
let next_per_commitment_point = holder_signer.get_per_commitment_point(INITIAL_COMMITMENT_NUMBER, &secp_ctx)
5668+
.map_err(|_| APIError::ChannelUnavailable { err: "Unable to generate initial commitment point".to_owned()})?;
5669+
56445670
Ok(Self {
56455671
context: ChannelContext {
56465672
user_id,
@@ -5669,6 +5695,7 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
56695695
destination_script,
56705696

56715697
cur_holder_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
5698+
next_per_commitment_point,
56725699
cur_counterparty_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
56735700
value_to_self_msat,
56745701

@@ -5910,7 +5937,6 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
59105937
panic!("Tried to send an open_channel for a channel that has already advanced");
59115938
}
59125939

5913-
let first_per_commitment_point = self.context.holder_signer.as_ref().get_per_commitment_point(self.context.cur_holder_commitment_transaction_number, &self.context.secp_ctx);
59145940
let keys = self.context.get_holder_pubkeys();
59155941

59165942
msgs::OpenChannel {
@@ -5930,7 +5956,7 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
59305956
payment_point: keys.payment_point,
59315957
delayed_payment_basepoint: keys.delayed_payment_basepoint,
59325958
htlc_basepoint: keys.htlc_basepoint,
5933-
first_per_commitment_point,
5959+
first_per_commitment_point: self.context.next_per_commitment_point,
59345960
channel_flags: if self.context.config.announced_channel {1} else {0},
59355961
shutdown_scriptpubkey: Some(match &self.context.shutdown_scriptpubkey {
59365962
Some(script) => script.clone().into_inner(),
@@ -6279,6 +6305,8 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
62796305
} else {
62806306
Some(cmp::max(config.channel_handshake_config.minimum_depth, 1))
62816307
};
6308+
let next_per_commitment_point = holder_signer.get_per_commitment_point(INITIAL_COMMITMENT_NUMBER, &secp_ctx)
6309+
.map_err(|_| ChannelError::Close("Unable to generate initial commitment point".to_owned()))?;
62826310

62836311
let chan = Self {
62846312
context: ChannelContext {
@@ -6307,6 +6335,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
63076335
destination_script,
63086336

63096337
cur_holder_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
6338+
next_per_commitment_point,
63106339
cur_counterparty_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
63116340
value_to_self_msat: msg.push_msat,
63126341

@@ -6437,7 +6466,6 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
64376466
///
64386467
/// [`msgs::AcceptChannel`]: crate::ln::msgs::AcceptChannel
64396468
fn generate_accept_channel_message(&self) -> msgs::AcceptChannel {
6440-
let first_per_commitment_point = self.context.holder_signer.as_ref().get_per_commitment_point(self.context.cur_holder_commitment_transaction_number, &self.context.secp_ctx);
64416469
let keys = self.context.get_holder_pubkeys();
64426470

64436471
msgs::AcceptChannel {
@@ -6454,7 +6482,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
64546482
payment_point: keys.payment_point,
64556483
delayed_payment_basepoint: keys.delayed_payment_basepoint,
64566484
htlc_basepoint: keys.htlc_basepoint,
6457-
first_per_commitment_point,
6485+
first_per_commitment_point: self.context.next_per_commitment_point,
64586486
shutdown_scriptpubkey: Some(match &self.context.shutdown_scriptpubkey {
64596487
Some(script) => script.clone().into_inner(),
64606488
None => Builder::new().into_script(),
@@ -6477,7 +6505,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
64776505
fn funding_created_signature<L: Deref>(&mut self, sig: &Signature, logger: &L) -> Result<(CommitmentTransaction, CommitmentTransaction, Signature), ChannelError> where L::Target: Logger {
64786506
let funding_script = self.context.get_funding_redeemscript();
64796507

6480-
let keys = self.context.build_holder_transaction_keys(self.context.cur_holder_commitment_transaction_number);
6508+
let keys = self.context.build_holder_transaction_keys();
64816509
let initial_commitment_tx = self.context.build_commitment_transaction(self.context.cur_holder_commitment_transaction_number, &keys, true, false, logger).tx;
64826510
{
64836511
let trusted_tx = initial_commitment_tx.trust();
@@ -6591,6 +6619,13 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
65916619
self.context.cur_counterparty_commitment_transaction_number -= 1;
65926620
self.context.cur_holder_commitment_transaction_number -= 1;
65936621

6622+
let next_per_commitment_point_result = self.context.holder_signer.as_ref().get_per_commitment_point(
6623+
self.context.cur_holder_commitment_transaction_number, &self.context.secp_ctx);
6624+
if next_per_commitment_point_result.is_err() {
6625+
return Err((self, ChannelError::Close("Unable to generate commitment point".to_owned())));
6626+
}
6627+
self.context.next_per_commitment_point = next_per_commitment_point_result.unwrap();
6628+
65946629
log_info!(logger, "Generated funding_signed for peer for channel {}", &self.context.channel_id());
65956630

65966631
// Promote the channel to a full-fledged one now that we have updated the state and have a
@@ -7345,6 +7380,11 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
73457380
let mut secp_ctx = Secp256k1::new();
73467381
secp_ctx.seeded_randomize(&entropy_source.get_secure_random_bytes());
73477382

7383+
// If we weren't able to load the next_per_commitment_point, ask the signer for it now.
7384+
let next_per_commitment_point = holder_signer.get_per_commitment_point(
7385+
cur_holder_commitment_transaction_number, &secp_ctx
7386+
).map_err(|_| DecodeError::Io(io::ErrorKind::Other))?;
7387+
73487388
// `user_id` used to be a single u64 value. In order to remain backwards
73497389
// compatible with versions prior to 0.0.113, the u128 is serialized as two
73507390
// separate u64 values.
@@ -7397,6 +7437,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
73977437
destination_script,
73987438

73997439
cur_holder_commitment_transaction_number,
7440+
next_per_commitment_point,
74007441
cur_counterparty_commitment_transaction_number,
74017442
value_to_self_msat,
74027443

0 commit comments

Comments
 (0)