Skip to content

Commit b9a76e9

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 8f02430 commit b9a76e9

File tree

6 files changed

+97
-44
lines changed

6 files changed

+97
-44
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2631,9 +2631,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
26312631
},
26322632
commitment_txid: htlc.commitment_txid,
26332633
per_commitment_number: htlc.per_commitment_number,
2634-
per_commitment_point: self.onchain_tx_handler.signer.get_per_commitment_point(
2635-
htlc.per_commitment_number, &self.onchain_tx_handler.secp_ctx,
2636-
),
2634+
per_commitment_point: htlc.per_commitment_point,
26372635
htlc: htlc.htlc,
26382636
preimage: htlc.preimage,
26392637
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::{WriteableEcdsaChannelSigner, EntropySource, ChannelSigner, SignerProvider, NodeSigner, Recipient};
38+
use crate::sign::{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};
@@ -666,6 +666,13 @@ pub(super) struct ChannelContext<Signer: ChannelSigner> {
666666
// cost of others, but should really just be changed.
667667

668668
cur_holder_commitment_transaction_number: u64,
669+
670+
// The commitment point corresponding to `cur_holder_commitment_transaction_number`, which is the
671+
// *next* state. We recompute it each time the state changes because the state changes in places
672+
// that might be fallible: in particular, if the commitment point must be fetched from a remote
673+
// source, we want to ensure it happens at a point where we can actually fail somewhat gracefully;
674+
// i.e., force-closing a channel is better than a panic!
675+
next_per_commitment_point: PublicKey,
669676
cur_counterparty_commitment_transaction_number: u64,
670677
value_to_self_msat: u64, // Excluding all pending_htlcs, excluding fees
671678
pending_inbound_htlcs: Vec<InboundHTLCOutput>,
@@ -1441,13 +1448,14 @@ impl<Signer: ChannelSigner> ChannelContext<Signer> {
14411448
/// our counterparty!)
14421449
/// The result is a transaction which we can revoke broadcastership of (ie a "local" transaction)
14431450
/// TODO Some magic rust shit to compile-time check this?
1444-
fn build_holder_transaction_keys(&self, commitment_number: u64) -> TxCreationKeys {
1445-
let per_commitment_point = self.holder_signer.get_per_commitment_point(commitment_number, &self.secp_ctx);
1451+
fn build_holder_transaction_keys(&self) -> TxCreationKeys {
14461452
let delayed_payment_base = &self.get_holder_pubkeys().delayed_payment_basepoint;
14471453
let htlc_basepoint = &self.get_holder_pubkeys().htlc_basepoint;
14481454
let counterparty_pubkeys = self.get_counterparty_pubkeys();
14491455

1450-
TxCreationKeys::derive_new(&self.secp_ctx, &per_commitment_point, delayed_payment_base, htlc_basepoint, &counterparty_pubkeys.revocation_basepoint, &counterparty_pubkeys.htlc_basepoint)
1456+
TxCreationKeys::derive_new(
1457+
&self.secp_ctx, &self.next_per_commitment_point, delayed_payment_base, htlc_basepoint,
1458+
&counterparty_pubkeys.revocation_basepoint, &counterparty_pubkeys.htlc_basepoint)
14511459
}
14521460

14531461
#[inline]
@@ -2492,7 +2500,12 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
24922500
log_trace!(logger, "Initial counterparty tx for channel {} is: txid {} tx {}",
24932501
log_bytes!(self.context.channel_id()), counterparty_initial_bitcoin_tx.txid, encode::serialize_hex(&counterparty_initial_bitcoin_tx.transaction));
24942502

2495-
let holder_signer = self.context.build_holder_transaction_keys(self.context.cur_holder_commitment_transaction_number);
2503+
self.context.next_per_commitment_point =
2504+
self.context.holder_signer.get_per_commitment_point(
2505+
self.context.cur_holder_commitment_transaction_number, &self.context.secp_ctx
2506+
).map_err(|_| ChannelError::Close("Unable to generate commitment point".to_owned()))?;
2507+
2508+
let holder_signer = self.context.build_holder_transaction_keys();
24962509
let initial_commitment_tx = self.context.build_commitment_transaction(self.context.cur_holder_commitment_transaction_number, &holder_signer, true, false, logger).tx;
24972510
{
24982511
let trusted_tx = initial_commitment_tx.trust();
@@ -2536,6 +2549,11 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
25362549
assert_eq!(self.context.channel_state & (ChannelState::MonitorUpdateInProgress as u32), 0); // We have no had any monitor(s) yet to fail update!
25372550
self.context.channel_state = ChannelState::FundingSent as u32;
25382551
self.context.cur_holder_commitment_transaction_number -= 1;
2552+
self.context.next_per_commitment_point =
2553+
self.context.holder_signer.get_per_commitment_point(
2554+
self.context.cur_holder_commitment_transaction_number, &self.context.secp_ctx
2555+
).map_err(|_| ChannelError::Close("Unable to generate commitment point".to_owned()))?;
2556+
25392557
self.context.cur_counterparty_commitment_transaction_number -= 1;
25402558

25412559
log_info!(logger, "Received funding_signed from peer for channel {}", log_bytes!(self.context.channel_id()));
@@ -2857,7 +2875,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
28572875

28582876
let funding_script = self.context.get_funding_redeemscript();
28592877

2860-
let keys = self.context.build_holder_transaction_keys(self.context.cur_holder_commitment_transaction_number);
2878+
let keys = self.context.build_holder_transaction_keys();
28612879

28622880
let commitment_stats = self.context.build_commitment_transaction(self.context.cur_holder_commitment_transaction_number, &keys, true, false, logger);
28632881
let commitment_txid = {
@@ -3021,6 +3039,11 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
30213039
};
30223040

30233041
self.context.cur_holder_commitment_transaction_number -= 1;
3042+
self.context.next_per_commitment_point =
3043+
self.context.holder_signer.get_per_commitment_point(
3044+
self.context.cur_holder_commitment_transaction_number, &self.context.secp_ctx
3045+
).map_err(|_| ChannelError::Close("Unable to generate commitment point".to_owned()))?;
3046+
30243047
// Note that if we need_commitment & !AwaitingRemoteRevoke we'll call
30253048
// build_commitment_no_status_check() next which will reset this to RAAFirst.
30263049
self.context.resend_order = RAACommitmentOrder::CommitmentFirst;
@@ -3496,7 +3519,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
34963519
// Before proposing a feerate update, check that we can actually afford the new fee.
34973520
let inbound_stats = self.context.get_inbound_pending_htlc_stats(Some(feerate_per_kw));
34983521
let outbound_stats = self.context.get_outbound_pending_htlc_stats(Some(feerate_per_kw));
3499-
let keys = self.context.build_holder_transaction_keys(self.context.cur_holder_commitment_transaction_number);
3522+
let keys = self.context.build_holder_transaction_keys();
35003523
let commitment_stats = self.context.build_commitment_transaction(self.context.cur_holder_commitment_transaction_number, &keys, true, true, logger);
35013524
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;
35023525
let holder_balance_msat = commitment_stats.local_balance_msat - outbound_stats.holding_cell_msat;
@@ -3677,10 +3700,9 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
36773700
assert!(!self.context.is_outbound() || self.context.minimum_depth == Some(0),
36783701
"Funding transaction broadcast by the local client before it should have - LDK didn't do it!");
36793702
self.context.monitor_pending_channel_ready = false;
3680-
let next_per_commitment_point = self.context.holder_signer.get_per_commitment_point(self.context.cur_holder_commitment_transaction_number, &self.context.secp_ctx);
36813703
Some(msgs::ChannelReady {
36823704
channel_id: self.context.channel_id(),
3683-
next_per_commitment_point,
3705+
next_per_commitment_point: self.context.next_per_commitment_point,
36843706
short_channel_id_alias: Some(self.context.outbound_scid_alias),
36853707
})
36863708
} else { None };
@@ -3759,12 +3781,13 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
37593781
}
37603782

37613783
fn get_last_revoke_and_ack(&self) -> msgs::RevokeAndACK {
3762-
let next_per_commitment_point = self.context.holder_signer.get_per_commitment_point(self.context.cur_holder_commitment_transaction_number, &self.context.secp_ctx);
3763-
let per_commitment_secret = self.context.holder_signer.release_commitment_secret(self.context.cur_holder_commitment_transaction_number + 2);
3784+
// TODO(waterson): fallible!
3785+
let per_commitment_secret = self.context.holder_signer.release_commitment_secret(self.context.cur_holder_commitment_transaction_number + 2)
3786+
.expect("release_per_commitment failed");
37643787
msgs::RevokeAndACK {
37653788
channel_id: self.context.channel_id,
37663789
per_commitment_secret,
3767-
next_per_commitment_point,
3790+
next_per_commitment_point: self.context.next_per_commitment_point,
37683791
#[cfg(taproot)]
37693792
next_local_nonce: None,
37703793
}
@@ -3874,7 +3897,9 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
38743897
}
38753898

38763899
if msg.next_remote_commitment_number > 0 {
3877-
let expected_point = self.context.holder_signer.get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - msg.next_remote_commitment_number + 1, &self.context.secp_ctx);
3900+
let state_index = INITIAL_COMMITMENT_NUMBER - msg.next_remote_commitment_number + 1;
3901+
let expected_point = self.context.holder_signer.get_per_commitment_point(state_index, &self.context.secp_ctx)
3902+
.map_err(|_| ChannelError::Close(format!("Unable to retrieve per-commitment point for state {state_index}")))?;
38783903
let given_secret = SecretKey::from_slice(&msg.your_last_per_commitment_secret)
38793904
.map_err(|_| ChannelError::Close("Peer sent a garbage channel_reestablish with unparseable secret key".to_owned()))?;
38803905
if expected_point != PublicKey::from_secret_key(&self.context.secp_ctx, &given_secret) {
@@ -3933,11 +3958,10 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
39333958
}
39343959

39353960
// We have OurChannelReady set!
3936-
let next_per_commitment_point = self.context.holder_signer.get_per_commitment_point(self.context.cur_holder_commitment_transaction_number, &self.context.secp_ctx);
39373961
return Ok(ReestablishResponses {
39383962
channel_ready: Some(msgs::ChannelReady {
39393963
channel_id: self.context.channel_id(),
3940-
next_per_commitment_point,
3964+
next_per_commitment_point: self.context.next_per_commitment_point,
39413965
short_channel_id_alias: Some(self.context.outbound_scid_alias),
39423966
}),
39433967
raa: None, commitment_update: None,
@@ -3973,10 +3997,9 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
39733997

39743998
let channel_ready = if msg.next_local_commitment_number == 1 && INITIAL_COMMITMENT_NUMBER - self.context.cur_holder_commitment_transaction_number == 1 {
39753999
// We should never have to worry about MonitorUpdateInProgress resending ChannelReady
3976-
let next_per_commitment_point = self.context.holder_signer.get_per_commitment_point(self.context.cur_holder_commitment_transaction_number, &self.context.secp_ctx);
39774000
Some(msgs::ChannelReady {
39784001
channel_id: self.context.channel_id(),
3979-
next_per_commitment_point,
4002+
next_per_commitment_point: self.context.next_per_commitment_point,
39804003
short_channel_id_alias: Some(self.context.outbound_scid_alias),
39814004
})
39824005
} else { None };
@@ -4662,13 +4685,13 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
46624685
if need_commitment_update {
46634686
if self.context.channel_state & (ChannelState::MonitorUpdateInProgress as u32) == 0 {
46644687
if self.context.channel_state & (ChannelState::PeerDisconnected as u32) == 0 {
4665-
let next_per_commitment_point =
4666-
self.context.holder_signer.get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - 1, &self.context.secp_ctx);
4667-
return Some(msgs::ChannelReady {
4668-
channel_id: self.context.channel_id,
4669-
next_per_commitment_point,
4670-
short_channel_id_alias: Some(self.context.outbound_scid_alias),
4671-
});
4688+
if let Ok(next_per_commitment_point) = self.context.holder_signer.get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - 1, &self.context.secp_ctx) {
4689+
return Some(msgs::ChannelReady {
4690+
channel_id: self.context.channel_id,
4691+
next_per_commitment_point,
4692+
short_channel_id_alias: Some(self.context.outbound_scid_alias),
4693+
});
4694+
}
46724695
}
46734696
} else {
46744697
self.context.monitor_pending_channel_ready = true;
@@ -5597,6 +5620,9 @@ impl<Signer: WriteableEcdsaChannelSigner> OutboundV1Channel<Signer> {
55975620

55985621
let temporary_channel_id = entropy_source.get_secure_random_bytes();
55995622

5623+
let next_per_commitment_point = holder_signer.get_per_commitment_point(INITIAL_COMMITMENT_NUMBER, &secp_ctx)
5624+
.map_err(|_| APIError::ChannelUnavailable { err: "Unable to generate initial commitment point".to_owned()})?;
5625+
56005626
Ok(Self {
56015627
context: ChannelContext {
56025628
user_id,
@@ -5625,6 +5651,7 @@ impl<Signer: WriteableEcdsaChannelSigner> OutboundV1Channel<Signer> {
56255651
destination_script,
56265652

56275653
cur_holder_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
5654+
next_per_commitment_point,
56285655
cur_counterparty_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
56295656
value_to_self_msat,
56305657

@@ -5861,7 +5888,6 @@ impl<Signer: WriteableEcdsaChannelSigner> OutboundV1Channel<Signer> {
58615888
panic!("Tried to send an open_channel for a channel that has already advanced");
58625889
}
58635890

5864-
let first_per_commitment_point = self.context.holder_signer.get_per_commitment_point(self.context.cur_holder_commitment_transaction_number, &self.context.secp_ctx);
58655891
let keys = self.context.get_holder_pubkeys();
58665892

58675893
msgs::OpenChannel {
@@ -5881,7 +5907,7 @@ impl<Signer: WriteableEcdsaChannelSigner> OutboundV1Channel<Signer> {
58815907
payment_point: keys.payment_point,
58825908
delayed_payment_basepoint: keys.delayed_payment_basepoint,
58835909
htlc_basepoint: keys.htlc_basepoint,
5884-
first_per_commitment_point,
5910+
first_per_commitment_point: self.context.next_per_commitment_point,
58855911
channel_flags: if self.context.config.announced_channel {1} else {0},
58865912
shutdown_scriptpubkey: Some(match &self.context.shutdown_scriptpubkey {
58875913
Some(script) => script.clone().into_inner(),
@@ -6231,6 +6257,8 @@ impl<Signer: WriteableEcdsaChannelSigner> InboundV1Channel<Signer> {
62316257
} else {
62326258
Some(cmp::max(config.channel_handshake_config.minimum_depth, 1))
62336259
};
6260+
let next_per_commitment_point = holder_signer.get_per_commitment_point(INITIAL_COMMITMENT_NUMBER, &secp_ctx)
6261+
.map_err(|_| ChannelError::Close("Unable to generate initial commitment point".to_owned()))?;
62346262

62356263
let chan = Self {
62366264
context: ChannelContext {
@@ -6259,6 +6287,7 @@ impl<Signer: WriteableEcdsaChannelSigner> InboundV1Channel<Signer> {
62596287
destination_script,
62606288

62616289
cur_holder_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
6290+
next_per_commitment_point,
62626291
cur_counterparty_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
62636292
value_to_self_msat: msg.push_msat,
62646293

@@ -6389,7 +6418,6 @@ impl<Signer: WriteableEcdsaChannelSigner> InboundV1Channel<Signer> {
63896418
///
63906419
/// [`msgs::AcceptChannel`]: crate::ln::msgs::AcceptChannel
63916420
fn generate_accept_channel_message(&self) -> msgs::AcceptChannel {
6392-
let first_per_commitment_point = self.context.holder_signer.get_per_commitment_point(self.context.cur_holder_commitment_transaction_number, &self.context.secp_ctx);
63936421
let keys = self.context.get_holder_pubkeys();
63946422

63956423
msgs::AcceptChannel {
@@ -6406,7 +6434,7 @@ impl<Signer: WriteableEcdsaChannelSigner> InboundV1Channel<Signer> {
64066434
payment_point: keys.payment_point,
64076435
delayed_payment_basepoint: keys.delayed_payment_basepoint,
64086436
htlc_basepoint: keys.htlc_basepoint,
6409-
first_per_commitment_point,
6437+
first_per_commitment_point: self.context.next_per_commitment_point,
64106438
shutdown_scriptpubkey: Some(match &self.context.shutdown_scriptpubkey {
64116439
Some(script) => script.clone().into_inner(),
64126440
None => Builder::new().into_script(),
@@ -6429,7 +6457,7 @@ impl<Signer: WriteableEcdsaChannelSigner> InboundV1Channel<Signer> {
64296457
fn funding_created_signature<L: Deref>(&mut self, sig: &Signature, logger: &L) -> Result<(Txid, CommitmentTransaction, Signature), ChannelError> where L::Target: Logger {
64306458
let funding_script = self.context.get_funding_redeemscript();
64316459

6432-
let keys = self.context.build_holder_transaction_keys(self.context.cur_holder_commitment_transaction_number);
6460+
let keys = self.context.build_holder_transaction_keys();
64336461
let initial_commitment_tx = self.context.build_commitment_transaction(self.context.cur_holder_commitment_transaction_number, &keys, true, false, logger).tx;
64346462
{
64356463
let trusted_tx = initial_commitment_tx.trust();
@@ -6534,6 +6562,13 @@ impl<Signer: WriteableEcdsaChannelSigner> InboundV1Channel<Signer> {
65346562
self.context.cur_counterparty_commitment_transaction_number -= 1;
65356563
self.context.cur_holder_commitment_transaction_number -= 1;
65366564

6565+
let next_per_commitment_point_result = self.context.holder_signer.get_per_commitment_point(
6566+
self.context.cur_holder_commitment_transaction_number, &self.context.secp_ctx);
6567+
if next_per_commitment_point_result.is_err() {
6568+
return Err((self, ChannelError::Close("Unable to generate commitment point".to_owned())));
6569+
}
6570+
self.context.next_per_commitment_point = next_per_commitment_point_result.unwrap();
6571+
65376572
log_info!(logger, "Generated funding_signed for peer for channel {}", log_bytes!(self.context.channel_id()));
65386573

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

7325+
// If we weren't able to load the next_per_commitment_point, ask the signer for it now.
7326+
let next_per_commitment_point = holder_signer.get_per_commitment_point(
7327+
cur_holder_commitment_transaction_number, &secp_ctx
7328+
).map_err(|_| DecodeError::Io(io::ErrorKind::Other))?;
7329+
72907330
// `user_id` used to be a single u64 value. In order to remain backwards
72917331
// compatible with versions prior to 0.0.113, the u128 is serialized as two
72927332
// separate u64 values.
@@ -7339,6 +7379,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
73397379
destination_script,
73407380

73417381
cur_holder_commitment_transaction_number,
7382+
next_per_commitment_point,
73427383
cur_counterparty_commitment_transaction_number,
73437384
value_to_self_msat,
73447385

0 commit comments

Comments
 (0)