Skip to content

Commit 2539e40

Browse files
committed
Separate out the methods that would apply to any channel into a ChannelSigner, leaving the implementation-dependent ones in EcdsaChannelSigner.
1 parent d06ccab commit 2539e40

File tree

6 files changed

+69
-54
lines changed

6 files changed

+69
-54
lines changed

lightning/src/chain/keysinterface.rs

Lines changed: 55 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ pub struct DelayedPaymentOutputDescriptor {
7575
/// The revocation point specific to the commitment transaction which was broadcast. Used to
7676
/// derive the witnessScript for this output.
7777
pub revocation_pubkey: PublicKey,
78-
/// Arbitrary identification information returned by a call to [`EcdsaChannelSigner::channel_keys_id`].
78+
/// Arbitrary identification information returned by a call to [`ChannelSigner::channel_keys_id`].
7979
/// This may be useful in re-deriving keys used in the channel to spend the output.
8080
pub channel_keys_id: [u8; 32],
8181
/// The value of the channel which this output originated from, possibly indirectly.
@@ -107,7 +107,7 @@ pub struct StaticPaymentOutputDescriptor {
107107
pub outpoint: OutPoint,
108108
/// The output which is referenced by the given outpoint.
109109
pub output: TxOut,
110-
/// Arbitrary identification information returned by a call to [`EcdsaChannelSigner::channel_keys_id`].
110+
/// Arbitrary identification information returned by a call to [`ChannelSigner::channel_keys_id`].
111111
/// This may be useful in re-deriving keys used in the channel to spend the output.
112112
pub channel_keys_id: [u8; 32],
113113
/// The value of the channel which this transactions spends.
@@ -172,15 +172,15 @@ pub enum SpendableOutputDescriptor {
172172
///
173173
/// To derive the delayed payment key which is used to sign this input, you must pass the
174174
/// holder [`InMemorySigner::delayed_payment_base_key`] (i.e., the private key which corresponds to the
175-
/// [`ChannelPublicKeys::delayed_payment_basepoint`] in [`EcdsaChannelSigner::pubkeys`]) and the provided
175+
/// [`ChannelPublicKeys::delayed_payment_basepoint`] in [`ChannelSigner::pubkeys`]) and the provided
176176
/// [`DelayedPaymentOutputDescriptor::per_commitment_point`] to [`chan_utils::derive_private_key`]. The public key can be
177177
/// generated without the secret key using [`chan_utils::derive_public_key`] and only the
178-
/// [`ChannelPublicKeys::delayed_payment_basepoint`] which appears in [`EcdsaChannelSigner::pubkeys`].
178+
/// [`ChannelPublicKeys::delayed_payment_basepoint`] which appears in [`ChannelSigner::pubkeys`].
179179
///
180180
/// To derive the [`DelayedPaymentOutputDescriptor::revocation_pubkey`] provided here (which is
181181
/// used in the witness script generation), you must pass the counterparty
182182
/// [`ChannelPublicKeys::revocation_basepoint`] (which appears in the call to
183-
/// [`EcdsaChannelSigner::provide_channel_parameters`]) and the provided
183+
/// [`ChannelSigner::provide_channel_parameters`]) and the provided
184184
/// [`DelayedPaymentOutputDescriptor::per_commitment_point`] to
185185
/// [`chan_utils::derive_public_revocation_key`].
186186
///
@@ -191,7 +191,7 @@ pub enum SpendableOutputDescriptor {
191191
/// [`chan_utils::get_revokeable_redeemscript`].
192192
DelayedPaymentOutput(DelayedPaymentOutputDescriptor),
193193
/// An output to a P2WPKH, spendable exclusively by our payment key (i.e., the private key
194-
/// which corresponds to the `payment_point` in [`EcdsaChannelSigner::pubkeys`]). The witness
194+
/// which corresponds to the `payment_point` in [`ChannelSigner::pubkeys`]). The witness
195195
/// in the spending input is, thus, simply:
196196
/// ```bitcoin
197197
/// <BIP 143 signature> <payment key>
@@ -212,18 +212,14 @@ impl_writeable_tlv_based_enum!(SpendableOutputDescriptor,
212212
(2, StaticPaymentOutput),
213213
);
214214

215-
/// A trait to sign Lightning channel transactions as described in
216-
/// [BOLT 3](https://github.com/lightning/bolts/blob/master/03-transactions.md).
217-
///
218-
/// Signing services could be implemented on a hardware wallet and should implement signing
219-
/// policies in order to be secure. Please refer to the [VLS Policy
220-
/// Controls](https://gitlab.com/lightning-signer/validating-lightning-signer/-/blob/main/docs/policy-controls.md)
221-
/// for an example of such policies.
222-
pub trait EcdsaChannelSigner {
215+
/// A trait to handle Lightning channel key material without concretizing the channel type or
216+
/// the signature mechanism.
217+
pub trait ChannelSigner {
223218
/// Gets the per-commitment point for a specific commitment number
224219
///
225220
/// Note that the commitment number starts at `(1 << 48) - 1` and counts backwards.
226221
fn get_per_commitment_point(&self, idx: u64, secp_ctx: &Secp256k1<secp256k1::All>) -> PublicKey;
222+
227223
/// Gets the commitment secret for a specific commitment number as part of the revocation process
228224
///
229225
/// An external signer implementation should error here if the commitment was already signed
@@ -234,6 +230,7 @@ pub trait EcdsaChannelSigner {
234230
/// Note that the commitment number starts at `(1 << 48) - 1` and counts backwards.
235231
// TODO: return a Result so we can signal a validation error
236232
fn release_commitment_secret(&self, idx: u64) -> [u8; 32];
233+
237234
/// Validate the counterparty's signatures on the holder commitment transaction and HTLCs.
238235
///
239236
/// This is required in order for the signer to make sure that releasing a commitment
@@ -249,12 +246,35 @@ pub trait EcdsaChannelSigner {
249246
/// irrelevant or duplicate preimages.
250247
fn validate_holder_commitment(&self, holder_tx: &HolderCommitmentTransaction,
251248
preimages: Vec<PaymentPreimage>) -> Result<(), ()>;
249+
252250
/// Returns the holder's channel public keys and basepoints.
253251
fn pubkeys(&self) -> &ChannelPublicKeys;
252+
254253
/// Returns an arbitrary identifier describing the set of keys which are provided back to you in
255254
/// some [`SpendableOutputDescriptor`] types. This should be sufficient to identify this
256255
/// [`EcdsaChannelSigner`] object uniquely and lookup or re-derive its keys.
257256
fn channel_keys_id(&self) -> [u8; 32];
257+
258+
/// Set the counterparty static channel data, including basepoints,
259+
/// `counterparty_selected`/`holder_selected_contest_delay` and funding outpoint.
260+
///
261+
/// This data is static, and will never change for a channel once set. For a given [`ChannelSigner`]
262+
/// instance, LDK will call this method exactly once - either immediately after construction
263+
/// (not including if done via [`SignerProvider::read_chan_signer`]) or when the funding
264+
/// information has been generated.
265+
///
266+
/// channel_parameters.is_populated() MUST be true.
267+
fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters);
268+
}
269+
270+
/// A trait to sign Lightning channel transactions as described in
271+
/// [BOLT 3](https://github.com/lightning/bolts/blob/master/03-transactions.md).
272+
///
273+
/// Signing services could be implemented on a hardware wallet and should implement signing
274+
/// policies in order to be secure. Please refer to the [VLS Policy
275+
/// Controls](https://gitlab.com/lightning-signer/validating-lightning-signer/-/blob/main/docs/policy-controls.md)
276+
/// for an example of such policies.
277+
pub trait EcdsaChannelSigner: ChannelSigner {
258278
/// Create a signature for a counterparty's commitment transaction and associated HTLC transactions.
259279
///
260280
/// Note that if signing fails or is rejected, the channel will be force-closed.
@@ -395,16 +415,6 @@ pub trait EcdsaChannelSigner {
395415
fn sign_channel_announcement_with_funding_key(
396416
&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>
397417
) -> Result<Signature, ()>;
398-
/// Set the counterparty static channel data, including basepoints,
399-
/// `counterparty_selected`/`holder_selected_contest_delay` and funding outpoint.
400-
///
401-
/// This data is static, and will never change for a channel once set. For a given [`EcdsaChannelSigner`]
402-
/// instance, LDK will call this method exactly once - either immediately after construction
403-
/// (not including if done via [`SignerProvider::read_chan_signer`]) or when the funding
404-
/// information has been generated.
405-
///
406-
/// channel_parameters.is_populated() MUST be true.
407-
fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters);
408418
}
409419

410420
/// A writeable signer.
@@ -511,7 +521,7 @@ pub trait SignerProvider {
511521
/// To derive a new `Signer`, a fresh `channel_keys_id` should be obtained through
512522
/// [`SignerProvider::generate_channel_keys_id`]. Otherwise, an existing `Signer` can be
513523
/// re-derived from its `channel_keys_id`, which can be obtained through its trait method
514-
/// [`EcdsaChannelSigner::channel_keys_id`].
524+
/// [`ChannelSigner::channel_keys_id`].
515525
fn derive_channel_signer(&self, channel_value_satoshis: u64, channel_keys_id: [u8; 32]) -> Self::Signer;
516526

517527
/// Reads a [`Signer`] for this [`SignerProvider`] from the given input stream.
@@ -620,38 +630,38 @@ impl InMemorySigner {
620630

621631
/// Returns the counterparty's pubkeys.
622632
///
623-
/// Will panic if [`EcdsaChannelSigner::provide_channel_parameters`] has not been called before.
633+
/// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
624634
pub fn counterparty_pubkeys(&self) -> &ChannelPublicKeys { &self.get_channel_parameters().counterparty_parameters.as_ref().unwrap().pubkeys }
625635
/// Returns the `contest_delay` value specified by our counterparty and applied on holder-broadcastable
626636
/// transactions, i.e., the amount of time that we have to wait to recover our funds if we
627637
/// broadcast a transaction.
628638
///
629-
/// Will panic if [`EcdsaChannelSigner::provide_channel_parameters`] has not been called before.
639+
/// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
630640
pub fn counterparty_selected_contest_delay(&self) -> u16 { self.get_channel_parameters().counterparty_parameters.as_ref().unwrap().selected_contest_delay }
631641
/// Returns the `contest_delay` value specified by us and applied on transactions broadcastable
632642
/// by our counterparty, i.e., the amount of time that they have to wait to recover their funds
633643
/// if they broadcast a transaction.
634644
///
635-
/// Will panic if [`EcdsaChannelSigner::provide_channel_parameters`] has not been called before.
645+
/// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
636646
pub fn holder_selected_contest_delay(&self) -> u16 { self.get_channel_parameters().holder_selected_contest_delay }
637647
/// Returns whether the holder is the initiator.
638648
///
639-
/// Will panic if [`EcdsaChannelSigner::provide_channel_parameters`] has not been called before.
649+
/// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
640650
pub fn is_outbound(&self) -> bool { self.get_channel_parameters().is_outbound_from_holder }
641651
/// Funding outpoint
642652
///
643-
/// Will panic if [`EcdsaChannelSigner::provide_channel_parameters`] has not been called before.
653+
/// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
644654
pub fn funding_outpoint(&self) -> &OutPoint { self.get_channel_parameters().funding_outpoint.as_ref().unwrap() }
645655
/// Returns a [`ChannelTransactionParameters`] for this channel, to be used when verifying or
646656
/// building transactions.
647657
///
648-
/// Will panic if [`EcdsaChannelSigner::provide_channel_parameters`] has not been called before.
658+
/// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
649659
pub fn get_channel_parameters(&self) -> &ChannelTransactionParameters {
650660
self.channel_parameters.as_ref().unwrap()
651661
}
652662
/// Returns whether anchors should be used.
653663
///
654-
/// Will panic if [`EcdsaChannelSigner::provide_channel_parameters`] has not been called before.
664+
/// Will panic if [`ChannelSigner::provide_channel_parameters`] has not been called before.
655665
pub fn opt_anchors(&self) -> bool {
656666
self.get_channel_parameters().opt_anchors.is_some()
657667
}
@@ -725,7 +735,7 @@ impl InMemorySigner {
725735
}
726736
}
727737

728-
impl EcdsaChannelSigner for InMemorySigner {
738+
impl ChannelSigner for InMemorySigner {
729739
fn get_per_commitment_point(&self, idx: u64, secp_ctx: &Secp256k1<secp256k1::All>) -> PublicKey {
730740
let commitment_secret = SecretKey::from_slice(&chan_utils::build_commitment_secret(&self.commitment_seed, idx)).unwrap();
731741
PublicKey::from_secret_key(secp_ctx, &commitment_secret)
@@ -743,6 +753,18 @@ impl EcdsaChannelSigner for InMemorySigner {
743753

744754
fn channel_keys_id(&self) -> [u8; 32] { self.channel_keys_id }
745755

756+
fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters) {
757+
assert!(self.channel_parameters.is_none() || self.channel_parameters.as_ref().unwrap() == channel_parameters);
758+
if self.channel_parameters.is_some() {
759+
// The channel parameters were already set and they match, return early.
760+
return;
761+
}
762+
assert!(channel_parameters.is_populated(), "Channel parameters must be fully populated");
763+
self.channel_parameters = Some(channel_parameters.clone());
764+
}
765+
}
766+
767+
impl EcdsaChannelSigner for InMemorySigner {
746768
fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction, _preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<(Signature, Vec<Signature>), ()> {
747769
let trusted_tx = commitment_tx.trust();
748770
let keys = trusted_tx.keys();
@@ -871,16 +893,6 @@ impl EcdsaChannelSigner for InMemorySigner {
871893
let msghash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]);
872894
Ok(sign(secp_ctx, &msghash, &self.funding_key))
873895
}
874-
875-
fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters) {
876-
assert!(self.channel_parameters.is_none() || self.channel_parameters.as_ref().unwrap() == channel_parameters);
877-
if self.channel_parameters.is_some() {
878-
// The channel parameters were already set and they match, return early.
879-
return;
880-
}
881-
assert!(channel_parameters.is_populated(), "Channel parameters must be fully populated");
882-
self.channel_parameters = Some(channel_parameters.clone());
883-
}
884896
}
885897

886898
const SERIALIZATION_VERSION: u8 = 1;

lightning/src/chain/onchaintx.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use bitcoin::hash_types::{Txid, BlockHash};
2121
use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
2222
use bitcoin::secp256k1;
2323

24-
use crate::chain::keysinterface::{EcdsaChannelSigner, EntropySource, SignerProvider};
24+
use crate::chain::keysinterface::{ChannelSigner, EntropySource, SignerProvider};
2525
use crate::ln::msgs::DecodeError;
2626
use crate::ln::PaymentPreimage;
2727
#[cfg(anchors)]

lightning/src/ln/chan_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1635,7 +1635,7 @@ mod tests {
16351635
use crate::ln::chan_utils::{get_htlc_redeemscript, get_to_countersignatory_with_anchors_redeemscript, CommitmentTransaction, TxCreationKeys, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, HTLCOutputInCommitment};
16361636
use bitcoin::secp256k1::{PublicKey, SecretKey, Secp256k1};
16371637
use crate::util::test_utils;
1638-
use crate::chain::keysinterface::{EcdsaChannelSigner, SignerProvider};
1638+
use crate::chain::keysinterface::{ChannelSigner, SignerProvider};
16391639
use bitcoin::{Network, Txid};
16401640
use bitcoin::hashes::Hash;
16411641
use crate::ln::PaymentHash;

lightning/src/ln/channel.rs

Lines changed: 2 additions & 2 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};
3737
use crate::chain::transaction::{OutPoint, TransactionData};
38-
use crate::chain::keysinterface::{Sign, EntropySource, EcdsaChannelSigner, SignerProvider, NodeSigner, Recipient};
38+
use crate::chain::keysinterface::{Sign, EntropySource, ChannelSigner, SignerProvider, NodeSigner, Recipient};
3939
use crate::util::events::ClosureReason;
4040
use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer, VecWriter};
4141
use crate::util::logger::Logger;
@@ -6871,7 +6871,7 @@ mod tests {
68716871
use crate::ln::chan_utils::{htlc_success_tx_weight, htlc_timeout_tx_weight};
68726872
use crate::chain::BestBlock;
68736873
use crate::chain::chaininterface::{FeeEstimator, LowerBoundedFeeEstimator, ConfirmationTarget};
6874-
use crate::chain::keysinterface::{EcdsaChannelSigner, InMemorySigner, EntropySource, SignerProvider};
6874+
use crate::chain::keysinterface::{ChannelSigner, InMemorySigner, EntropySource, SignerProvider};
68756875
use crate::chain::transaction::OutPoint;
68766876
use crate::util::config::UserConfig;
68776877
use crate::util::enforcing_trait_impls::EnforcingSigner;

lightning/src/ln/functional_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::chain::chaininterface::LowerBoundedFeeEstimator;
1717
use crate::chain::channelmonitor;
1818
use crate::chain::channelmonitor::{CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY};
1919
use crate::chain::transaction::OutPoint;
20-
use crate::chain::keysinterface::{EcdsaChannelSigner, EntropySource};
20+
use crate::chain::keysinterface::{ChannelSigner, EcdsaChannelSigner, EntropySource};
2121
use crate::ln::{PaymentPreimage, PaymentSecret, PaymentHash};
2222
use crate::ln::channel::{commitment_tx_base_weight, COMMITMENT_TX_WEIGHT_PER_HTLC, CONCURRENT_INBOUND_HTLC_FEE_BUFFER, FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE, MIN_AFFORDABLE_HTLC_COUNT};
2323
use crate::ln::channelmanager::{self, PaymentId, RAACommitmentOrder, PaymentSendFailure, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA};

lightning/src/util/enforcing_trait_impls.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
use crate::ln::channel::{ANCHOR_OUTPUT_VALUE_SATOSHI, MIN_CHAN_DUST_LIMIT_SATOSHIS};
1111
use crate::ln::chan_utils::{HTLCOutputInCommitment, ChannelPublicKeys, HolderCommitmentTransaction, CommitmentTransaction, ChannelTransactionParameters, TrustedCommitmentTransaction, ClosingTransaction};
1212
use crate::ln::{chan_utils, msgs, PaymentPreimage};
13-
use crate::chain::keysinterface::{Sign, InMemorySigner, EcdsaChannelSigner};
13+
use crate::chain::keysinterface::{Sign, InMemorySigner, ChannelSigner, EcdsaChannelSigner};
1414

1515
use crate::prelude::*;
1616
use core::cmp;
@@ -90,7 +90,7 @@ impl EnforcingSigner {
9090
}
9191
}
9292

93-
impl EcdsaChannelSigner for EnforcingSigner {
93+
impl ChannelSigner for EnforcingSigner {
9494
fn get_per_commitment_point(&self, idx: u64, secp_ctx: &Secp256k1<secp256k1::All>) -> PublicKey {
9595
self.inner.get_per_commitment_point(idx, secp_ctx)
9696
}
@@ -114,8 +114,15 @@ impl EcdsaChannelSigner for EnforcingSigner {
114114
}
115115

116116
fn pubkeys(&self) -> &ChannelPublicKeys { self.inner.pubkeys() }
117+
117118
fn channel_keys_id(&self) -> [u8; 32] { self.inner.channel_keys_id() }
118119

120+
fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters) {
121+
self.inner.provide_channel_parameters(channel_parameters)
122+
}
123+
}
124+
125+
impl EcdsaChannelSigner for EnforcingSigner {
119126
fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction, preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<(Signature, Vec<Signature>), ()> {
120127
self.verify_counterparty_commitment_tx(commitment_tx, secp_ctx);
121128

@@ -228,10 +235,6 @@ impl EcdsaChannelSigner for EnforcingSigner {
228235
) -> Result<Signature, ()> {
229236
self.inner.sign_channel_announcement_with_funding_key(msg, secp_ctx)
230237
}
231-
232-
fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters) {
233-
self.inner.provide_channel_parameters(channel_parameters)
234-
}
235238
}
236239

237240
impl Sign for EnforcingSigner {}

0 commit comments

Comments
 (0)