From 27b9794beddbef6f0cf844d4fc7afed0226c765f Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Mon, 21 Aug 2023 22:37:58 -0700 Subject: [PATCH 1/5] Rename SignerProvider's Signer to EcdsaSigner. --- fuzz/src/chanmon_consistency.rs | 6 ++-- fuzz/src/full_stack.rs | 4 +-- fuzz/src/onion_message.rs | 4 +-- lightning-background-processor/src/lib.rs | 12 +++---- lightning-block-sync/src/init.rs | 8 ++--- lightning-invoice/src/utils.rs | 14 ++++----- lightning/src/chain/channelmonitor.rs | 4 +-- lightning/src/chain/onchaintx.rs | 2 +- lightning/src/events/bump_transaction.rs | 2 +- lightning/src/ln/channel.rs | 20 ++++++------ lightning/src/ln/channelmanager.rs | 38 +++++++++++------------ lightning/src/sign/mod.rs | 24 +++++++------- lightning/src/util/persist.rs | 26 ++++++++-------- lightning/src/util/test_utils.rs | 10 +++--- 14 files changed, 87 insertions(+), 87 deletions(-) diff --git a/fuzz/src/chanmon_consistency.rs b/fuzz/src/chanmon_consistency.rs index dcfc7cf61c1..22491bdf0b7 100644 --- a/fuzz/src/chanmon_consistency.rs +++ b/fuzz/src/chanmon_consistency.rs @@ -230,14 +230,14 @@ impl NodeSigner for KeyProvider { } impl SignerProvider for KeyProvider { - type Signer = TestChannelSigner; + type EcdsaSigner = TestChannelSigner; fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32] { let id = self.rand_bytes_id.fetch_add(1, atomic::Ordering::Relaxed) as u8; [id; 32] } - fn derive_channel_signer(&self, channel_value_satoshis: u64, channel_keys_id: [u8; 32]) -> Self::Signer { + fn derive_channel_signer(&self, channel_value_satoshis: u64, channel_keys_id: [u8; 32]) -> Self::EcdsaSigner { let secp_ctx = Secp256k1::signing_only(); let id = channel_keys_id[0]; let keys = InMemorySigner::new( @@ -256,7 +256,7 @@ impl SignerProvider for KeyProvider { TestChannelSigner::new_with_revoked(keys, revoked_commitment, false) } - fn read_chan_signer(&self, buffer: &[u8]) -> Result { + fn read_chan_signer(&self, buffer: &[u8]) -> Result { let mut reader = std::io::Cursor::new(buffer); let inner: InMemorySigner = ReadableArgs::read(&mut reader, self)?; diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index 4111067edac..49d67650681 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -340,7 +340,7 @@ impl NodeSigner for KeyProvider { } impl SignerProvider for KeyProvider { - type Signer = TestChannelSigner; + type EcdsaSigner = TestChannelSigner; fn generate_channel_keys_id(&self, inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32] { let ctr = self.counter.fetch_add(1, Ordering::Relaxed) as u8; @@ -348,7 +348,7 @@ impl SignerProvider for KeyProvider { [ctr; 32] } - fn derive_channel_signer(&self, channel_value_satoshis: u64, channel_keys_id: [u8; 32]) -> Self::Signer { + fn derive_channel_signer(&self, channel_value_satoshis: u64, channel_keys_id: [u8; 32]) -> Self::EcdsaSigner { let secp_ctx = Secp256k1::signing_only(); let ctr = channel_keys_id[0]; let (inbound, state) = self.signer_state.borrow().get(&ctr).unwrap().clone(); diff --git a/fuzz/src/onion_message.rs b/fuzz/src/onion_message.rs index b40975068e1..6ddee84c085 100644 --- a/fuzz/src/onion_message.rs +++ b/fuzz/src/onion_message.rs @@ -189,11 +189,11 @@ impl NodeSigner for KeyProvider { } impl SignerProvider for KeyProvider { - type Signer = TestChannelSigner; + type EcdsaSigner = TestChannelSigner; fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32] { unreachable!() } - fn derive_channel_signer(&self, _channel_value_satoshis: u64, _channel_keys_id: [u8; 32]) -> Self::Signer { + fn derive_channel_signer(&self, _channel_value_satoshis: u64, _channel_keys_id: [u8; 32]) -> Self::EcdsaSigner { unreachable!() } diff --git a/lightning-background-processor/src/lib.rs b/lightning-background-processor/src/lib.rs index 76252324efc..e4f2ebfb6a9 100644 --- a/lightning-background-processor/src/lib.rs +++ b/lightning-background-processor/src/lib.rs @@ -599,7 +599,7 @@ pub async fn process_events_async< EventHandlerFuture: core::future::Future, EventHandler: Fn(Event) -> EventHandlerFuture, PS: 'static + Deref + Send, - M: 'static + Deref::Signer, CF, T, F, L, P>> + Send + Sync, + M: 'static + Deref::EcdsaSigner, CF, T, F, L, P>> + Send + Sync, CM: 'static + Deref> + Send + Sync, PGS: 'static + Deref> + Send + Sync, RGS: 'static + Deref> + Send, @@ -617,7 +617,7 @@ pub async fn process_events_async< where UL::Target: 'static + UtxoLookup, CF::Target: 'static + chain::Filter, - CW::Target: 'static + chain::Watch<::Signer>, + CW::Target: 'static + chain::Watch<::EcdsaSigner>, T::Target: 'static + BroadcasterInterface, ES::Target: 'static + EntropySource, NS::Target: 'static + NodeSigner, @@ -625,7 +625,7 @@ where F::Target: 'static + FeeEstimator, R::Target: 'static + Router, L::Target: 'static + Logger, - P::Target: 'static + Persist<::Signer>, + P::Target: 'static + Persist<::EcdsaSigner>, PS::Target: 'static + Persister<'a, CW, T, ES, NS, SP, F, R, L, SC>, { let mut should_break = false; @@ -738,7 +738,7 @@ impl BackgroundProcessor { P: 'static + Deref + Send + Sync, EH: 'static + EventHandler + Send, PS: 'static + Deref + Send, - M: 'static + Deref::Signer, CF, T, F, L, P>> + Send + Sync, + M: 'static + Deref::EcdsaSigner, CF, T, F, L, P>> + Send + Sync, CM: 'static + Deref> + Send + Sync, PGS: 'static + Deref> + Send + Sync, RGS: 'static + Deref> + Send, @@ -753,7 +753,7 @@ impl BackgroundProcessor { where UL::Target: 'static + UtxoLookup, CF::Target: 'static + chain::Filter, - CW::Target: 'static + chain::Watch<::Signer>, + CW::Target: 'static + chain::Watch<::EcdsaSigner>, T::Target: 'static + BroadcasterInterface, ES::Target: 'static + EntropySource, NS::Target: 'static + NodeSigner, @@ -761,7 +761,7 @@ impl BackgroundProcessor { F::Target: 'static + FeeEstimator, R::Target: 'static + Router, L::Target: 'static + Logger, - P::Target: 'static + Persist<::Signer>, + P::Target: 'static + Persist<::EcdsaSigner>, PS::Target: 'static + Persister<'a, CW, T, ES, NS, SP, F, R, L, SC>, { let stop_thread = Arc::new(AtomicBool::new(false)); diff --git a/lightning-block-sync/src/init.rs b/lightning-block-sync/src/init.rs index df113fb012a..8cb0ff70a2e 100644 --- a/lightning-block-sync/src/init.rs +++ b/lightning-block-sync/src/init.rs @@ -69,10 +69,10 @@ BlockSourceResult where B::Target: BlockSource { /// R: Router, /// L: Logger, /// C: chain::Filter, -/// P: chainmonitor::Persist, +/// P: chainmonitor::Persist, /// >( /// block_source: &B, -/// chain_monitor: &ChainMonitor, +/// chain_monitor: &ChainMonitor, /// config: UserConfig, /// entropy_source: &ES, /// node_signer: &NS, @@ -85,7 +85,7 @@ BlockSourceResult where B::Target: BlockSource { /// ) { /// // Read a serialized channel monitor paired with the block hash when it was persisted. /// let serialized_monitor = "..."; -/// let (monitor_block_hash, mut monitor) = <(BlockHash, ChannelMonitor)>::read( +/// let (monitor_block_hash, mut monitor) = <(BlockHash, ChannelMonitor)>::read( /// &mut Cursor::new(&serialized_monitor), (entropy_source, signer_provider)).unwrap(); /// /// // Read the channel manager paired with the block hash when it was persisted. @@ -103,7 +103,7 @@ BlockSourceResult where B::Target: BlockSource { /// config, /// vec![&mut monitor], /// ); -/// <(BlockHash, ChannelManager<&ChainMonitor, &T, &ES, &NS, &SP, &F, &R, &L>)>::read( +/// <(BlockHash, ChannelManager<&ChainMonitor, &T, &ES, &NS, &SP, &F, &R, &L>)>::read( /// &mut Cursor::new(&serialized_manager), read_args).unwrap() /// }; /// diff --git a/lightning-invoice/src/utils.rs b/lightning-invoice/src/utils.rs index 9930b545662..ed016be3f8e 100644 --- a/lightning-invoice/src/utils.rs +++ b/lightning-invoice/src/utils.rs @@ -335,7 +335,7 @@ pub fn create_invoice_from_channelmanager, ) -> Result> where - M::Target: chain::Watch<::Signer>, + M::Target: chain::Watch<::EcdsaSigner>, T::Target: BroadcasterInterface, ES::Target: EntropySource, NS::Target: NodeSigner, @@ -376,7 +376,7 @@ pub fn create_invoice_from_channelmanager_with_description_hash, ) -> Result> where - M::Target: chain::Watch<::Signer>, + M::Target: chain::Watch<::EcdsaSigner>, T::Target: BroadcasterInterface, ES::Target: EntropySource, NS::Target: NodeSigner, @@ -406,7 +406,7 @@ pub fn create_invoice_from_channelmanager_with_description_hash_and_duration_sin duration_since_epoch: Duration, invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option, ) -> Result> where - M::Target: chain::Watch<::Signer>, + M::Target: chain::Watch<::EcdsaSigner>, T::Target: BroadcasterInterface, ES::Target: EntropySource, NS::Target: NodeSigner, @@ -431,7 +431,7 @@ pub fn create_invoice_from_channelmanager_and_duration_since_epoch, ) -> Result> where - M::Target: chain::Watch<::Signer>, + M::Target: chain::Watch<::EcdsaSigner>, T::Target: BroadcasterInterface, ES::Target: EntropySource, NS::Target: NodeSigner, @@ -455,7 +455,7 @@ fn _create_invoice_from_channelmanager_and_duration_since_epoch, ) -> Result> where - M::Target: chain::Watch<::Signer>, + M::Target: chain::Watch<::EcdsaSigner>, T::Target: BroadcasterInterface, ES::Target: EntropySource, NS::Target: NodeSigner, @@ -488,7 +488,7 @@ pub fn create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_ invoice_expiry_delta_secs: u32, payment_hash: PaymentHash, min_final_cltv_expiry_delta: Option, ) -> Result> where - M::Target: chain::Watch<::Signer>, + M::Target: chain::Watch<::EcdsaSigner>, T::Target: BroadcasterInterface, ES::Target: EntropySource, NS::Target: NodeSigner, @@ -518,7 +518,7 @@ fn _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_has payment_secret: PaymentSecret, min_final_cltv_expiry_delta: Option, ) -> Result> where - M::Target: chain::Watch<::Signer>, + M::Target: chain::Watch<::EcdsaSigner>, T::Target: BroadcasterInterface, ES::Target: EntropySource, NS::Target: NodeSigner, diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index 82af154315f..8d22ab35443 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -4177,7 +4177,7 @@ where const MAX_ALLOC_SIZE: usize = 64*1024; impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP)> - for (BlockHash, ChannelMonitor) { + for (BlockHash, ChannelMonitor) { fn read(reader: &mut R, args: (&'a ES, &'b SP)) -> Result { macro_rules! unwrap_obj { ($key: expr) => { @@ -4363,7 +4363,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP return Err(DecodeError::InvalidValue); } } - let onchain_tx_handler: OnchainTxHandler = ReadableArgs::read( + let onchain_tx_handler: OnchainTxHandler = ReadableArgs::read( reader, (entropy_source, signer_provider, channel_value_satoshis, channel_keys_id) )?; diff --git a/lightning/src/chain/onchaintx.rs b/lightning/src/chain/onchaintx.rs index c28c572e6b5..30553ed7853 100644 --- a/lightning/src/chain/onchaintx.rs +++ b/lightning/src/chain/onchaintx.rs @@ -339,7 +339,7 @@ impl OnchainTxHandler } } -impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP, u64, [u8; 32])> for OnchainTxHandler { +impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP, u64, [u8; 32])> for OnchainTxHandler { fn read(reader: &mut R, args: (&'a ES, &'b SP, u64, [u8; 32])) -> Result { let entropy_source = args.0; let signer_provider = args.1; diff --git a/lightning/src/events/bump_transaction.rs b/lightning/src/events/bump_transaction.rs index 7c6cc6c6a56..2c056401540 100644 --- a/lightning/src/events/bump_transaction.rs +++ b/lightning/src/events/bump_transaction.rs @@ -92,7 +92,7 @@ impl AnchorDescriptor { /// Derives the channel signer required to sign the anchor input. pub fn derive_channel_signer(&self, signer_provider: &SP) -> S where - SP::Target: SignerProvider + SP::Target: SignerProvider { let mut signer = signer_provider.derive_channel_signer( self.channel_derivation_parameters.value_satoshis, diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index dacf561573f..cf543b32d22 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -647,7 +647,7 @@ pub(super) enum ChannelPhase where SP::Target: SignerProvider { impl<'a, SP: Deref> ChannelPhase where SP::Target: SignerProvider, - ::Signer: ChannelSigner, + ::EcdsaSigner: ChannelSigner, { pub fn context(&'a self) -> &'a ChannelContext { match self { @@ -725,7 +725,7 @@ pub(super) struct ChannelContext where SP::Target: SignerProvider { latest_monitor_update_id: u64, - holder_signer: ChannelSignerType<::Signer>, + holder_signer: ChannelSignerType<::EcdsaSigner>, shutdown_scriptpubkey: Option, destination_script: ScriptBuf, @@ -1095,7 +1095,7 @@ impl ChannelContext where SP::Target: SignerProvider { /// Returns the holder signer for this channel. #[cfg(test)] - pub fn get_signer(&self) -> &ChannelSignerType<::Signer> { + pub fn get_signer(&self) -> &ChannelSignerType<::EcdsaSigner> { return &self.holder_signer } @@ -2273,7 +2273,7 @@ struct CommitmentTxInfoCached { impl Channel where SP::Target: SignerProvider, - ::Signer: WriteableEcdsaChannelSigner + ::EcdsaSigner: WriteableEcdsaChannelSigner { fn check_remote_fee( channel_type: &ChannelTypeFeatures, fee_estimator: &LowerBoundedFeeEstimator, @@ -2669,7 +2669,7 @@ impl Channel where /// If this call is successful, broadcast the funding transaction (and not before!) pub fn funding_signed( &mut self, msg: &msgs::FundingSigned, best_block: BestBlock, signer_provider: &SP, logger: &L - ) -> Result::Signer>, ChannelError> + ) -> Result::EcdsaSigner>, ChannelError> where L::Target: Logger { @@ -4801,7 +4801,7 @@ impl Channel where } #[cfg(test)] - pub fn get_signer(&self) -> &ChannelSignerType<::Signer> { + pub fn get_signer(&self) -> &ChannelSignerType<::EcdsaSigner> { &self.context.holder_signer } @@ -6822,7 +6822,7 @@ impl InboundV1Channel where SP::Target: SignerProvider { pub fn funding_created( mut self, msg: &msgs::FundingCreated, best_block: BestBlock, signer_provider: &SP, logger: &L - ) -> Result<(Channel, Option, ChannelMonitor<::Signer>), (Self, ChannelError)> + ) -> Result<(Channel, Option, ChannelMonitor<::EcdsaSigner>), (Self, ChannelError)> where L::Target: Logger { @@ -7862,17 +7862,17 @@ use crate::ln::channelmanager::{self, HTLCSource, PaymentId}; } impl SignerProvider for Keys { - type Signer = InMemorySigner; + type EcdsaSigner = InMemorySigner; fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32] { self.signer.channel_keys_id() } - fn derive_channel_signer(&self, _channel_value_satoshis: u64, _channel_keys_id: [u8; 32]) -> Self::Signer { + fn derive_channel_signer(&self, _channel_value_satoshis: u64, _channel_keys_id: [u8; 32]) -> Self::EcdsaSigner { self.signer.clone() } - fn read_chan_signer(&self, _data: &[u8]) -> Result { panic!(); } + fn read_chan_signer(&self, _data: &[u8]) -> Result { panic!(); } fn get_destination_script(&self, _channel_keys_id: [u8; 32]) -> Result { let secp_ctx = Secp256k1::signing_only(); diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 3f6277b44bb..724c0d77ec6 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -922,7 +922,7 @@ pub trait AChannelManager { /// A type implementing [`WriteableEcdsaChannelSigner`]. type Signer: WriteableEcdsaChannelSigner + Sized; /// A type implementing [`SignerProvider`] for [`Self::Signer`]. - type SignerProvider: SignerProvider + ?Sized; + type SignerProvider: SignerProvider + ?Sized; /// A type that may be dereferenced to [`Self::SignerProvider`]. type SP: Deref; /// A type implementing [`FeeEstimator`]. @@ -944,7 +944,7 @@ pub trait AChannelManager { impl AChannelManager for ChannelManager where - M::Target: chain::Watch<::Signer>, + M::Target: chain::Watch<::EcdsaSigner>, T::Target: BroadcasterInterface, ES::Target: EntropySource, NS::Target: NodeSigner, @@ -961,7 +961,7 @@ where type ES = ES; type NodeSigner = NS::Target; type NS = NS; - type Signer = ::Signer; + type Signer = ::EcdsaSigner; type SignerProvider = SP::Target; type SP = SP; type FeeEstimator = F::Target; @@ -1069,7 +1069,7 @@ where // pub struct ChannelManager where - M::Target: chain::Watch<::Signer>, + M::Target: chain::Watch<::EcdsaSigner>, T::Target: BroadcasterInterface, ES::Target: EntropySource, NS::Target: NodeSigner, @@ -2284,7 +2284,7 @@ macro_rules! process_events_body { impl ChannelManager where - M::Target: chain::Watch<::Signer>, + M::Target: chain::Watch<::EcdsaSigner>, T::Target: BroadcasterInterface, ES::Target: EntropySource, NS::Target: NodeSigner, @@ -8143,7 +8143,7 @@ fn check_incoming_htlc_cltv( impl MessageSendEventsProvider for ChannelManager where - M::Target: chain::Watch<::Signer>, + M::Target: chain::Watch<::EcdsaSigner>, T::Target: BroadcasterInterface, ES::Target: EntropySource, NS::Target: NodeSigner, @@ -8205,7 +8205,7 @@ where impl EventsProvider for ChannelManager where - M::Target: chain::Watch<::Signer>, + M::Target: chain::Watch<::EcdsaSigner>, T::Target: BroadcasterInterface, ES::Target: EntropySource, NS::Target: NodeSigner, @@ -8226,7 +8226,7 @@ where impl chain::Listen for ChannelManager where - M::Target: chain::Watch<::Signer>, + M::Target: chain::Watch<::EcdsaSigner>, T::Target: BroadcasterInterface, ES::Target: EntropySource, NS::Target: NodeSigner, @@ -8268,7 +8268,7 @@ where impl chain::Confirm for ChannelManager where - M::Target: chain::Watch<::Signer>, + M::Target: chain::Watch<::EcdsaSigner>, T::Target: BroadcasterInterface, ES::Target: EntropySource, NS::Target: NodeSigner, @@ -8369,7 +8369,7 @@ where impl ChannelManager where - M::Target: chain::Watch<::Signer>, + M::Target: chain::Watch<::EcdsaSigner>, T::Target: BroadcasterInterface, ES::Target: EntropySource, NS::Target: NodeSigner, @@ -8613,7 +8613,7 @@ where impl ChannelMessageHandler for ChannelManager where - M::Target: chain::Watch<::Signer>, + M::Target: chain::Watch<::EcdsaSigner>, T::Target: BroadcasterInterface, ES::Target: EntropySource, NS::Target: NodeSigner, @@ -9167,7 +9167,7 @@ where impl OffersMessageHandler for ChannelManager where - M::Target: chain::Watch<::Signer>, + M::Target: chain::Watch<::EcdsaSigner>, T::Target: BroadcasterInterface, ES::Target: EntropySource, NS::Target: NodeSigner, @@ -9764,7 +9764,7 @@ impl_writeable_tlv_based!(PendingInboundPayment, { impl Writeable for ChannelManager where - M::Target: chain::Watch<::Signer>, + M::Target: chain::Watch<::EcdsaSigner>, T::Target: BroadcasterInterface, ES::Target: EntropySource, NS::Target: NodeSigner, @@ -10068,7 +10068,7 @@ impl_writeable_tlv_based_enum!(ChannelShutdownState, /// [`ChainMonitor`]: crate::chain::chainmonitor::ChainMonitor pub struct ChannelManagerReadArgs<'a, M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref> where - M::Target: chain::Watch<::Signer>, + M::Target: chain::Watch<::EcdsaSigner>, T::Target: BroadcasterInterface, ES::Target: EntropySource, NS::Target: NodeSigner, @@ -10127,13 +10127,13 @@ where /// this struct. /// /// This is not exported to bindings users because we have no HashMap bindings - pub channel_monitors: HashMap::Signer>>, + pub channel_monitors: HashMap::EcdsaSigner>>, } impl<'a, M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref> ChannelManagerReadArgs<'a, M, T, ES, NS, SP, F, R, L> where - M::Target: chain::Watch<::Signer>, + M::Target: chain::Watch<::EcdsaSigner>, T::Target: BroadcasterInterface, ES::Target: EntropySource, NS::Target: NodeSigner, @@ -10146,7 +10146,7 @@ where /// HashMap for you. This is primarily useful for C bindings where it is not practical to /// populate a HashMap directly from C. pub fn new(entropy_source: ES, node_signer: NS, signer_provider: SP, fee_estimator: F, chain_monitor: M, tx_broadcaster: T, router: R, logger: L, default_config: UserConfig, - mut channel_monitors: Vec<&'a mut ChannelMonitor<::Signer>>) -> Self { + mut channel_monitors: Vec<&'a mut ChannelMonitor<::EcdsaSigner>>) -> Self { Self { entropy_source, node_signer, signer_provider, fee_estimator, chain_monitor, tx_broadcaster, router, logger, default_config, channel_monitors: channel_monitors.drain(..).map(|monitor| { (monitor.get_funding_txo().0, monitor) }).collect() @@ -10159,7 +10159,7 @@ where impl<'a, M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref> ReadableArgs> for (BlockHash, Arc>) where - M::Target: chain::Watch<::Signer>, + M::Target: chain::Watch<::EcdsaSigner>, T::Target: BroadcasterInterface, ES::Target: EntropySource, NS::Target: NodeSigner, @@ -10177,7 +10177,7 @@ where impl<'a, M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref> ReadableArgs> for (BlockHash, ChannelManager) where - M::Target: chain::Watch<::Signer>, + M::Target: chain::Watch<::EcdsaSigner>, T::Target: BroadcasterInterface, ES::Target: EntropySource, NS::Target: NodeSigner, diff --git a/lightning/src/sign/mod.rs b/lightning/src/sign/mod.rs index 17501603e97..9314124f790 100644 --- a/lightning/src/sign/mod.rs +++ b/lightning/src/sign/mod.rs @@ -534,7 +534,7 @@ impl HTLCDescriptor { /// Derives the channel signer required to sign the HTLC input. pub fn derive_channel_signer(&self, signer_provider: &SP) -> S where - SP::Target: SignerProvider + SP::Target: SignerProvider { let mut signer = signer_provider.derive_channel_signer( self.channel_derivation_parameters.value_satoshis, @@ -865,9 +865,9 @@ pub trait NodeSigner { /// A trait that can return signer instances for individual channels. pub trait SignerProvider { /// A type which implements [`WriteableEcdsaChannelSigner`] which will be returned by [`Self::derive_channel_signer`]. - type Signer : WriteableEcdsaChannelSigner; + type EcdsaSigner: WriteableEcdsaChannelSigner; - /// Generates a unique `channel_keys_id` that can be used to obtain a [`Self::Signer`] through + /// Generates a unique `channel_keys_id` that can be used to obtain a [`Self::EcdsaSigner`] through /// [`SignerProvider::derive_channel_signer`]. The `user_channel_id` is provided to allow /// implementations of [`SignerProvider`] to maintain a mapping between itself and the generated /// `channel_keys_id`. @@ -881,7 +881,7 @@ pub trait SignerProvider { /// [`SignerProvider::generate_channel_keys_id`]. Otherwise, an existing `Signer` can be /// re-derived from its `channel_keys_id`, which can be obtained through its trait method /// [`ChannelSigner::channel_keys_id`]. - fn derive_channel_signer(&self, channel_value_satoshis: u64, channel_keys_id: [u8; 32]) -> Self::Signer; + fn derive_channel_signer(&self, channel_value_satoshis: u64, channel_keys_id: [u8; 32]) -> Self::EcdsaSigner; /// Reads a [`Signer`] for this [`SignerProvider`] from the given input stream. /// This is only called during deserialization of other objects which contain @@ -893,10 +893,10 @@ pub trait SignerProvider { /// This method is slowly being phased out -- it will only be called when reading objects /// written by LDK versions prior to 0.0.113. /// - /// [`Signer`]: Self::Signer + /// [`Signer`]: Self::EcdsaSigner /// [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager - fn read_chan_signer(&self, reader: &[u8]) -> Result; + fn read_chan_signer(&self, reader: &[u8]) -> Result; /// Get a script pubkey which we send funds to when claiming on-chain contestable outputs. /// @@ -1779,7 +1779,7 @@ impl NodeSigner for KeysManager { } impl SignerProvider for KeysManager { - type Signer = InMemorySigner; + type EcdsaSigner = InMemorySigner; fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, user_channel_id: u128) -> [u8; 32] { let child_idx = self.channel_child_index.fetch_add(1, Ordering::AcqRel); @@ -1797,11 +1797,11 @@ impl SignerProvider for KeysManager { id } - fn derive_channel_signer(&self, channel_value_satoshis: u64, channel_keys_id: [u8; 32]) -> Self::Signer { + fn derive_channel_signer(&self, channel_value_satoshis: u64, channel_keys_id: [u8; 32]) -> Self::EcdsaSigner { self.derive_channel_keys(channel_value_satoshis, &channel_keys_id) } - fn read_chan_signer(&self, reader: &[u8]) -> Result { + fn read_chan_signer(&self, reader: &[u8]) -> Result { InMemorySigner::read(&mut io::Cursor::new(reader), self) } @@ -1898,17 +1898,17 @@ impl NodeSigner for PhantomKeysManager { } impl SignerProvider for PhantomKeysManager { - type Signer = InMemorySigner; + type EcdsaSigner = InMemorySigner; fn generate_channel_keys_id(&self, inbound: bool, channel_value_satoshis: u64, user_channel_id: u128) -> [u8; 32] { self.inner.generate_channel_keys_id(inbound, channel_value_satoshis, user_channel_id) } - fn derive_channel_signer(&self, channel_value_satoshis: u64, channel_keys_id: [u8; 32]) -> Self::Signer { + fn derive_channel_signer(&self, channel_value_satoshis: u64, channel_keys_id: [u8; 32]) -> Self::EcdsaSigner { self.inner.derive_channel_signer(channel_value_satoshis, channel_keys_id) } - fn read_chan_signer(&self, reader: &[u8]) -> Result { + fn read_chan_signer(&self, reader: &[u8]) -> Result { self.inner.read_chan_signer(reader) } diff --git a/lightning/src/util/persist.rs b/lightning/src/util/persist.rs index 9928597fb8a..823ebc548bf 100644 --- a/lightning/src/util/persist.rs +++ b/lightning/src/util/persist.rs @@ -132,7 +132,7 @@ pub trait KVStore { /// Trait that handles persisting a [`ChannelManager`], [`NetworkGraph`], and [`WriteableScore`] to disk. pub trait Persister<'a, M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref, S: WriteableScore<'a>> - where M::Target: 'static + chain::Watch<::Signer>, + where M::Target: 'static + chain::Watch<::EcdsaSigner>, T::Target: 'static + BroadcasterInterface, ES::Target: 'static + EntropySource, NS::Target: 'static + NodeSigner, @@ -153,7 +153,7 @@ pub trait Persister<'a, M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: impl<'a, A: KVStore, M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, L: Deref, S: WriteableScore<'a>> Persister<'a, M, T, ES, NS, SP, F, R, L, S> for A - where M::Target: 'static + chain::Watch<::Signer>, + where M::Target: 'static + chain::Watch<::EcdsaSigner>, T::Target: 'static + BroadcasterInterface, ES::Target: 'static + EntropySource, NS::Target: 'static + NodeSigner, @@ -221,7 +221,7 @@ impl Persist( kv_store: K, entropy_source: ES, signer_provider: SP, -) -> Result::Signer>)>, io::Error> +) -> Result::EcdsaSigner>)>, io::Error> where K::Target: KVStore, ES::Target: EntropySource + Sized, @@ -246,7 +246,7 @@ where io::Error::new(io::ErrorKind::InvalidData, "Invalid tx index in stored key") })?; - match <(BlockHash, ChannelMonitor<::Signer>)>::read( + match <(BlockHash, ChannelMonitor<::EcdsaSigner>)>::read( &mut io::Cursor::new( kv_store.read(CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE, CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE, &stored_key)?), (&*entropy_source, &*signer_provider), @@ -334,9 +334,9 @@ where /// [`MonitorUpdatingPersister::read_all_channel_monitors_with_updates`]. Alternatively, users can /// list channel monitors themselves and load channels individually using /// [`MonitorUpdatingPersister::read_channel_monitor_with_updates`]. -/// +/// /// ## EXTREMELY IMPORTANT -/// +/// /// It is extremely important that your [`KVStore::read`] implementation uses the /// [`io::ErrorKind::NotFound`] variant correctly: that is, when a file is not found, and _only_ in /// that circumstance (not when there is really a permissions error, for example). This is because @@ -385,7 +385,7 @@ where /// consolidation will frequently occur with fewer updates than what you set here; this number /// is merely the maximum that may be stored. When setting this value, consider that for higher /// values of `maximum_pending_updates`: - /// + /// /// - [`MonitorUpdatingPersister`] will tend to write more [`ChannelMonitorUpdate`]s than /// [`ChannelMonitor`]s, approaching one [`ChannelMonitor`] write for every /// `maximum_pending_updates` [`ChannelMonitorUpdate`]s. @@ -414,7 +414,7 @@ where /// documentation for [`MonitorUpdatingPersister`]. pub fn read_all_channel_monitors_with_updates( &self, broadcaster: &B, fee_estimator: &F, - ) -> Result::Signer>)>, io::Error> + ) -> Result::EcdsaSigner>)>, io::Error> where B::Target: BroadcasterInterface, F::Target: FeeEstimator, @@ -448,12 +448,12 @@ where /// /// The correct `monitor_key` would be: /// `deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef_1` - /// + /// /// Loading a large number of monitors will be faster if done in parallel. You can use this /// function to accomplish this. Take care to limit the number of parallel readers. pub fn read_channel_monitor_with_updates( &self, broadcaster: &B, fee_estimator: &F, monitor_key: String, - ) -> Result<(BlockHash, ChannelMonitor<::Signer>), io::Error> + ) -> Result<(BlockHash, ChannelMonitor<::EcdsaSigner>), io::Error> where B::Target: BroadcasterInterface, F::Target: FeeEstimator, @@ -494,7 +494,7 @@ where /// Read a channel monitor. fn read_monitor( &self, monitor_name: &MonitorName, - ) -> Result<(BlockHash, ChannelMonitor<::Signer>), io::Error> { + ) -> Result<(BlockHash, ChannelMonitor<::EcdsaSigner>), io::Error> { let outpoint: OutPoint = monitor_name.try_into()?; let mut monitor_cursor = io::Cursor::new(self.kv_store.read( CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE, @@ -505,7 +505,7 @@ where if monitor_cursor.get_ref().starts_with(MONITOR_UPDATING_PERSISTER_PREPEND_SENTINEL) { monitor_cursor.set_position(MONITOR_UPDATING_PERSISTER_PREPEND_SENTINEL.len() as u64); } - match <(BlockHash, ChannelMonitor<::Signer>)>::read( + match <(BlockHash, ChannelMonitor<::EcdsaSigner>)>::read( &mut monitor_cursor, (&*self.entropy_source, &*self.signer_provider), ) { @@ -594,7 +594,7 @@ where } } -impl +impl Persist for MonitorUpdatingPersister where K::Target: KVStore, diff --git a/lightning/src/util/test_utils.rs b/lightning/src/util/test_utils.rs index 4512dab8cc5..b46f14681d8 100644 --- a/lightning/src/util/test_utils.rs +++ b/lightning/src/util/test_utils.rs @@ -175,13 +175,13 @@ impl EntropySource for OnlyReadsKeysInterface { fn get_secure_random_bytes(&self) -> [u8; 32] { [0; 32] }} impl SignerProvider for OnlyReadsKeysInterface { - type Signer = TestChannelSigner; + type EcdsaSigner = TestChannelSigner; fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32] { unreachable!(); } - fn derive_channel_signer(&self, _channel_value_satoshis: u64, _channel_keys_id: [u8; 32]) -> Self::Signer { unreachable!(); } + fn derive_channel_signer(&self, _channel_value_satoshis: u64, _channel_keys_id: [u8; 32]) -> Self::EcdsaSigner { unreachable!(); } - fn read_chan_signer(&self, mut reader: &[u8]) -> Result { + fn read_chan_signer(&self, mut reader: &[u8]) -> Result { let inner: InMemorySigner = ReadableArgs::read(&mut reader, self)?; let state = Arc::new(Mutex::new(EnforcementState::new())); @@ -1096,7 +1096,7 @@ impl NodeSigner for TestKeysInterface { } impl SignerProvider for TestKeysInterface { - type Signer = TestChannelSigner; + type EcdsaSigner = TestChannelSigner; fn generate_channel_keys_id(&self, inbound: bool, channel_value_satoshis: u64, user_channel_id: u128) -> [u8; 32] { self.backing.generate_channel_keys_id(inbound, channel_value_satoshis, user_channel_id) @@ -1108,7 +1108,7 @@ impl SignerProvider for TestKeysInterface { TestChannelSigner::new_with_revoked(keys, state, self.disable_revocation_policy_check) } - fn read_chan_signer(&self, buffer: &[u8]) -> Result { + fn read_chan_signer(&self, buffer: &[u8]) -> Result { let mut reader = io::Cursor::new(buffer); let inner: InMemorySigner = ReadableArgs::read(&mut reader, self)?; From f862aa9f5f95b89b3d202f425669a4c7dfcdce3e Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Sat, 6 May 2023 21:13:53 -0700 Subject: [PATCH 2/5] Introduce TaprootSigner trait. For Taproot support, we need to define an alternative trait to EcdsaChannelSigner. This trait will be implemented by all signers that wish to support Taproot channels. --- lightning/src/sign/mod.rs | 3 + lightning/src/sign/taproot.rs | 149 ++++++++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 lightning/src/sign/taproot.rs diff --git a/lightning/src/sign/mod.rs b/lightning/src/sign/mod.rs index 9314124f790..a21a68f19c7 100644 --- a/lightning/src/sign/mod.rs +++ b/lightning/src/sign/mod.rs @@ -61,6 +61,9 @@ use crate::util::invoice::construct_invoice_preimage; pub(crate) mod type_resolver; +#[cfg(taproot)] +pub mod taproot; + /// Used as initial key material, to be expanded into multiple secret keys (but not to be used /// directly). This is used within LDK to encrypt/decrypt inbound payment data. /// diff --git a/lightning/src/sign/taproot.rs b/lightning/src/sign/taproot.rs new file mode 100644 index 00000000000..2c9eb697046 --- /dev/null +++ b/lightning/src/sign/taproot.rs @@ -0,0 +1,149 @@ +//! Defines a Taproot-specific signer type. + +use bitcoin::blockdata::transaction::Transaction; +use bitcoin::secp256k1; +use bitcoin::secp256k1::{PublicKey, schnorr::Signature, Secp256k1, SecretKey}; + +use musig2::types::{PartialSignature, PublicNonce}; + +use crate::ln::chan_utils::{ClosingTransaction, CommitmentTransaction, HolderCommitmentTransaction, HTLCOutputInCommitment}; +use crate::ln::msgs::PartialSignatureWithNonce; +use crate::ln::PaymentPreimage; +use crate::sign::{ChannelSigner, HTLCDescriptor}; + +/// A Taproot-specific signer type that defines signing-related methods that are either unique to +/// Taproot or have argument or return types that differ from the ones an ECDSA signer would be +/// expected to have. +pub trait TaprootChannelSigner: ChannelSigner { + /// Generate a local nonce pair, which requires committing to ahead of time. + /// The counterparty needs the public nonce generated herein to compute a partial signature. + fn generate_local_nonce_pair(&self, commitment_number: u64, secp_ctx: &Secp256k1) -> PublicNonce; + + /// Create a signature for a counterparty's commitment transaction and associated HTLC transactions. + /// + /// Note that if signing fails or is rejected, the channel will be force-closed. + /// + /// Policy checks should be implemented in this function, including checking the amount + /// sent to us and checking the HTLCs. + /// + /// The preimages of outgoing HTLCs that were fulfilled since the last commitment are provided. + /// A validating signer should ensure that an HTLC output is removed only when the matching + /// preimage is provided, or when the value to holder is restored. + /// + /// Note that all the relevant preimages will be provided, but there may also be additional + /// irrelevant or duplicate preimages. + // + // TODO: Document the things someone using this interface should enforce before signing. + fn partially_sign_counterparty_commitment(&self, counterparty_nonce: PublicNonce, + commitment_tx: &CommitmentTransaction, preimages: Vec, + secp_ctx: &Secp256k1, + ) -> Result<(PartialSignatureWithNonce, Vec), ()>; + + /// Creates a signature for a holder's commitment transaction. + /// + /// This will be called + /// - with a non-revoked `commitment_tx`. + /// - with the latest `commitment_tx` when we initiate a force-close. + /// + /// This may be called multiple times for the same transaction. + /// + /// An external signer implementation should check that the commitment has not been revoked. + /// + // TODO: Document the things someone using this interface should enforce before signing. + fn finalize_holder_commitment(&self, commitment_number: u64, + commitment_tx: &HolderCommitmentTransaction, + counterparty_partial_signature: PartialSignatureWithNonce, + secp_ctx: &Secp256k1 + ) -> Result; + + /// Create a signature for the given input in a transaction spending an HTLC transaction output + /// or a commitment transaction `to_local` output when our counterparty broadcasts an old state. + /// + /// A justice transaction may claim multiple outputs at the same time if timelocks are + /// similar, but only a signature for the input at index `input` should be signed for here. + /// It may be called multiple times for same output(s) if a fee-bump is needed with regards + /// to an upcoming timelock expiration. + /// + /// Amount is value of the output spent by this input, committed to in the BIP 341 signature. + /// + /// `per_commitment_key` is revocation secret which was provided by our counterparty when they + /// revoked the state which they eventually broadcast. It's not a _holder_ secret key and does + /// not allow the spending of any funds by itself (you need our holder `revocation_secret` to do + /// so). + fn sign_justice_revoked_output(&self, justice_tx: &Transaction, input: usize, amount: u64, + per_commitment_key: &SecretKey, secp_ctx: &Secp256k1, + ) -> Result; + + /// Create a signature for the given input in a transaction spending a commitment transaction + /// HTLC output when our counterparty broadcasts an old state. + /// + /// A justice transaction may claim multiple outputs at the same time if timelocks are + /// similar, but only a signature for the input at index `input` should be signed for here. + /// It may be called multiple times for same output(s) if a fee-bump is needed with regards + /// to an upcoming timelock expiration. + /// + /// `amount` is the value of the output spent by this input, committed to in the BIP 341 + /// signature. + /// + /// `per_commitment_key` is revocation secret which was provided by our counterparty when they + /// revoked the state which they eventually broadcast. It's not a _holder_ secret key and does + /// not allow the spending of any funds by itself (you need our holder revocation_secret to do + /// so). + /// + /// `htlc` holds HTLC elements (hash, timelock), thus changing the format of the witness script + /// (which is committed to in the BIP 341 signatures). + fn sign_justice_revoked_htlc(&self, justice_tx: &Transaction, input: usize, amount: u64, + per_commitment_key: &SecretKey, htlc: &HTLCOutputInCommitment, + secp_ctx: &Secp256k1) -> Result; + + /// Computes the signature for a commitment transaction's HTLC output used as an input within + /// `htlc_tx`, which spends the commitment transaction at index `input`. The signature returned + /// must be be computed using [`TapSighashType::Default`]. + /// + /// Note that this may be called for HTLCs in the penultimate commitment transaction if a + /// [`ChannelMonitor`] [replica](https://github.com/lightningdevkit/rust-lightning/blob/main/GLOSSARY.md#monitor-replicas) + /// broadcasts it before receiving the update for the latest commitment transaction. + /// + /// + /// [`TapSighashType::Default`]: bitcoin::sighash::TapSighashType::Default + /// [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor + fn sign_holder_htlc_transaction(&self, htlc_tx: &Transaction, input: usize, + htlc_descriptor: &HTLCDescriptor, secp_ctx: &Secp256k1, + ) -> Result; + + /// Create a signature for a claiming transaction for a HTLC output on a counterparty's commitment + /// transaction, either offered or received. + /// + /// Such a transaction may claim multiples offered outputs at same time if we know the + /// preimage for each when we create it, but only the input at index `input` should be + /// signed for here. It may be called multiple times for same output(s) if a fee-bump is + /// needed with regards to an upcoming timelock expiration. + /// + /// `witness_script` is either an offered or received script as defined in BOLT3 for HTLC + /// outputs. + /// + /// `amount` is value of the output spent by this input, committed to in the BIP 341 signature. + /// + /// `per_commitment_point` is the dynamic point corresponding to the channel state + /// detected onchain. It has been generated by our counterparty and is used to derive + /// channel state keys, which are then included in the witness script and committed to in the + /// BIP 341 signature. + fn sign_counterparty_htlc_transaction(&self, htlc_tx: &Transaction, input: usize, amount: u64, + per_commitment_point: &PublicKey, htlc: &HTLCOutputInCommitment, + secp_ctx: &Secp256k1) -> Result; + + /// Create a signature for a (proposed) closing transaction. + /// + /// Note that, due to rounding, there may be one "missing" satoshi, and either party may have + /// chosen to forgo their output as dust. + fn partially_sign_closing_transaction(&self, closing_tx: &ClosingTransaction, + secp_ctx: &Secp256k1) -> Result; + + /// Computes the signature for a commitment transaction's anchor output used as an + /// input within `anchor_tx`, which spends the commitment transaction, at index `input`. + fn sign_holder_anchor_input( + &self, anchor_tx: &Transaction, input: usize, secp_ctx: &Secp256k1, + ) -> Result; + + // TODO: sign channel announcement +} From c6bcf75848cf6b0f0d1f873e211a711697c2b80a Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Sun, 5 Nov 2023 21:36:59 -0800 Subject: [PATCH 3/5] Add TaprootSigner variant to SignerProvider. Previously, SignerProvider was not laid out to support multiple signer types. However, with the distinction between ECDSA and Taproot signers, we now need to account for SignerProviders needing to support both. This approach does mean that if ever we introduced another signer type in the future, all implementers of SignerProvider would need to add it as an associated type, and would also need to write a set of dummy implementations for any Signer trait they do not wish to support. For the time being, the TaprootSigner associated type is cfg-gated. --- fuzz/src/chanmon_consistency.rs | 2 + fuzz/src/full_stack.rs | 2 + fuzz/src/onion_message.rs | 2 + lightning/src/ln/channel.rs | 2 + lightning/src/sign/mod.rs | 54 +++++++++++++++++++++ lightning/src/util/test_channel_signer.rs | 57 +++++++++++++++++++++-- lightning/src/util/test_utils.rs | 4 ++ 7 files changed, 118 insertions(+), 5 deletions(-) diff --git a/fuzz/src/chanmon_consistency.rs b/fuzz/src/chanmon_consistency.rs index 22491bdf0b7..f654908771f 100644 --- a/fuzz/src/chanmon_consistency.rs +++ b/fuzz/src/chanmon_consistency.rs @@ -231,6 +231,8 @@ impl NodeSigner for KeyProvider { impl SignerProvider for KeyProvider { type EcdsaSigner = TestChannelSigner; + #[cfg(taproot)] + type TaprootSigner = TestChannelSigner; fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32] { let id = self.rand_bytes_id.fetch_add(1, atomic::Ordering::Relaxed) as u8; diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index 49d67650681..57c78e76d6b 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -341,6 +341,8 @@ impl NodeSigner for KeyProvider { impl SignerProvider for KeyProvider { type EcdsaSigner = TestChannelSigner; + #[cfg(taproot)] + type TaprootSigner = TestChannelSigner; fn generate_channel_keys_id(&self, inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32] { let ctr = self.counter.fetch_add(1, Ordering::Relaxed) as u8; diff --git a/fuzz/src/onion_message.rs b/fuzz/src/onion_message.rs index 6ddee84c085..13de5005cf8 100644 --- a/fuzz/src/onion_message.rs +++ b/fuzz/src/onion_message.rs @@ -190,6 +190,8 @@ impl NodeSigner for KeyProvider { impl SignerProvider for KeyProvider { type EcdsaSigner = TestChannelSigner; + #[cfg(taproot)] + type TaprootSigner = TestChannelSigner; fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32] { unreachable!() } diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index cf543b32d22..157103fea26 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -7863,6 +7863,8 @@ use crate::ln::channelmanager::{self, HTLCSource, PaymentId}; impl SignerProvider for Keys { type EcdsaSigner = InMemorySigner; + #[cfg(taproot)] + type TaprootSigner = InMemorySigner; fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32] { self.signer.channel_keys_id() diff --git a/lightning/src/sign/mod.rs b/lightning/src/sign/mod.rs index a21a68f19c7..a2740bc3558 100644 --- a/lightning/src/sign/mod.rs +++ b/lightning/src/sign/mod.rs @@ -29,6 +29,8 @@ use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::hashes::sha256d::Hash as Sha256dHash; use bitcoin::hash_types::WPubkeyHash; +#[cfg(taproot)] +use bitcoin::secp256k1::All; use bitcoin::secp256k1::{KeyPair, PublicKey, Scalar, Secp256k1, SecretKey, Signing}; use bitcoin::secp256k1::ecdh::SharedSecret; use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature}; @@ -44,6 +46,8 @@ use crate::ln::{chan_utils, PaymentPreimage}; use crate::ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, HolderCommitmentTransaction, ChannelTransactionParameters, CommitmentTransaction, ClosingTransaction}; use crate::ln::channel_keys::{DelayedPaymentBasepoint, DelayedPaymentKey, HtlcKey, HtlcBasepoint, RevocationKey, RevocationBasepoint}; use crate::ln::msgs::{UnsignedChannelAnnouncement, UnsignedGossipMessage}; +#[cfg(taproot)] +use crate::ln::msgs::PartialSignatureWithNonce; use crate::ln::script::ShutdownScript; use crate::offers::invoice::UnsignedBolt12Invoice; use crate::offers::invoice_request::UnsignedInvoiceRequest; @@ -52,9 +56,13 @@ use crate::prelude::*; use core::convert::TryInto; use core::ops::Deref; use core::sync::atomic::{AtomicUsize, Ordering}; +#[cfg(taproot)] +use musig2::types::{PartialSignature, PublicNonce, SecretNonce}; use crate::io::{self, Error}; use crate::ln::features::ChannelTypeFeatures; use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT}; +#[cfg(taproot)] +use crate::sign::taproot::TaprootChannelSigner; use crate::util::atomic_counter::AtomicCounter; use crate::util::chacha20::ChaCha20; use crate::util::invoice::construct_invoice_preimage; @@ -869,6 +877,9 @@ pub trait NodeSigner { pub trait SignerProvider { /// A type which implements [`WriteableEcdsaChannelSigner`] which will be returned by [`Self::derive_channel_signer`]. type EcdsaSigner: WriteableEcdsaChannelSigner; + #[cfg(taproot)] + /// A type which implements [`TaprootChannelSigner`] + type TaprootSigner: TaprootChannelSigner; /// Generates a unique `channel_keys_id` that can be used to obtain a [`Self::EcdsaSigner`] through /// [`SignerProvider::derive_channel_signer`]. The `user_channel_id` is provided to allow @@ -1380,6 +1391,45 @@ impl EcdsaChannelSigner for InMemorySigner { } } +#[cfg(taproot)] +impl TaprootChannelSigner for InMemorySigner { + fn generate_local_nonce_pair(&self, commitment_number: u64, secp_ctx: &Secp256k1) -> PublicNonce { + todo!() + } + + fn partially_sign_counterparty_commitment(&self, counterparty_nonce: PublicNonce, commitment_tx: &CommitmentTransaction, preimages: Vec, secp_ctx: &Secp256k1) -> Result<(PartialSignatureWithNonce, Vec), ()> { + todo!() + } + + fn finalize_holder_commitment(&self, commitment_number: u64, commitment_tx: &HolderCommitmentTransaction, counterparty_partial_signature: PartialSignatureWithNonce, secp_ctx: &Secp256k1) -> Result { + todo!() + } + + fn sign_justice_revoked_output(&self, justice_tx: &Transaction, input: usize, amount: u64, per_commitment_key: &SecretKey, secp_ctx: &Secp256k1) -> Result { + todo!() + } + + fn sign_justice_revoked_htlc(&self, justice_tx: &Transaction, input: usize, amount: u64, per_commitment_key: &SecretKey, htlc: &HTLCOutputInCommitment, secp_ctx: &Secp256k1) -> Result { + todo!() + } + + fn sign_holder_htlc_transaction(&self, htlc_tx: &Transaction, input: usize, htlc_descriptor: &HTLCDescriptor, secp_ctx: &Secp256k1) -> Result { + todo!() + } + + fn sign_counterparty_htlc_transaction(&self, htlc_tx: &Transaction, input: usize, amount: u64, per_commitment_point: &PublicKey, htlc: &HTLCOutputInCommitment, secp_ctx: &Secp256k1) -> Result { + todo!() + } + + fn partially_sign_closing_transaction(&self, closing_tx: &ClosingTransaction, secp_ctx: &Secp256k1) -> Result { + todo!() + } + + fn sign_holder_anchor_input(&self, anchor_tx: &Transaction, input: usize, secp_ctx: &Secp256k1) -> Result { + todo!() + } +} + const SERIALIZATION_VERSION: u8 = 1; const MIN_SERIALIZATION_VERSION: u8 = 1; @@ -1783,6 +1833,8 @@ impl NodeSigner for KeysManager { impl SignerProvider for KeysManager { type EcdsaSigner = InMemorySigner; + #[cfg(taproot)] + type TaprootSigner = InMemorySigner; fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, user_channel_id: u128) -> [u8; 32] { let child_idx = self.channel_child_index.fetch_add(1, Ordering::AcqRel); @@ -1902,6 +1954,8 @@ impl NodeSigner for PhantomKeysManager { impl SignerProvider for PhantomKeysManager { type EcdsaSigner = InMemorySigner; + #[cfg(taproot)] + type TaprootSigner = InMemorySigner; fn generate_channel_keys_id(&self, inbound: bool, channel_value_satoshis: u64, user_channel_id: u128) -> [u8; 32] { self.inner.generate_channel_keys_id(inbound, channel_value_satoshis, user_channel_id) diff --git a/lightning/src/util/test_channel_signer.rs b/lightning/src/util/test_channel_signer.rs index 9c6a1e30224..3e0ca970e12 100644 --- a/lightning/src/util/test_channel_signer.rs +++ b/lightning/src/util/test_channel_signer.rs @@ -24,12 +24,20 @@ use bitcoin::sighash; use bitcoin::sighash::EcdsaSighashType; use bitcoin::secp256k1; +#[cfg(taproot)] +use bitcoin::secp256k1::All; use bitcoin::secp256k1::{SecretKey, PublicKey}; use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature}; +#[cfg(taproot)] +use musig2::types::{PartialSignature, PublicNonce, SecretNonce}; use crate::sign::HTLCDescriptor; use crate::util::ser::{Writeable, Writer}; use crate::io::Error; use crate::ln::features::ChannelTypeFeatures; +#[cfg(taproot)] +use crate::ln::msgs::PartialSignatureWithNonce; +#[cfg(taproot)] +use crate::sign::taproot::TaprootChannelSigner; /// Initial value for revoked commitment downward counter pub const INITIAL_REVOKED_COMMITMENT_NUMBER: u64 = 1 << 48; @@ -201,11 +209,11 @@ impl EcdsaChannelSigner for TestChannelSigner { } fn sign_justice_revoked_output(&self, justice_tx: &Transaction, input: usize, amount: u64, per_commitment_key: &SecretKey, secp_ctx: &Secp256k1) -> Result { - Ok(self.inner.sign_justice_revoked_output(justice_tx, input, amount, per_commitment_key, secp_ctx).unwrap()) + Ok(EcdsaChannelSigner::sign_justice_revoked_output(&self.inner, justice_tx, input, amount, per_commitment_key, secp_ctx).unwrap()) } fn sign_justice_revoked_htlc(&self, justice_tx: &Transaction, input: usize, amount: u64, per_commitment_key: &SecretKey, htlc: &HTLCOutputInCommitment, secp_ctx: &Secp256k1) -> Result { - Ok(self.inner.sign_justice_revoked_htlc(justice_tx, input, amount, per_commitment_key, htlc, secp_ctx).unwrap()) + Ok(EcdsaChannelSigner::sign_justice_revoked_htlc(&self.inner, justice_tx, input, amount, per_commitment_key, htlc, secp_ctx).unwrap()) } fn sign_holder_htlc_transaction( @@ -241,11 +249,11 @@ impl EcdsaChannelSigner for TestChannelSigner { &hash_to_message!(sighash.as_byte_array()), &htlc_descriptor.counterparty_sig, &countersignatory_htlc_key.to_public_key() ).unwrap(); } - Ok(self.inner.sign_holder_htlc_transaction(htlc_tx, input, htlc_descriptor, secp_ctx).unwrap()) + Ok(EcdsaChannelSigner::sign_holder_htlc_transaction(&self.inner, htlc_tx, input, htlc_descriptor, secp_ctx).unwrap()) } fn sign_counterparty_htlc_transaction(&self, htlc_tx: &Transaction, input: usize, amount: u64, per_commitment_point: &PublicKey, htlc: &HTLCOutputInCommitment, secp_ctx: &Secp256k1) -> Result { - Ok(self.inner.sign_counterparty_htlc_transaction(htlc_tx, input, amount, per_commitment_point, htlc, secp_ctx).unwrap()) + Ok(EcdsaChannelSigner::sign_counterparty_htlc_transaction(&self.inner, htlc_tx, input, amount, per_commitment_point, htlc, secp_ctx).unwrap()) } fn sign_closing_transaction(&self, closing_tx: &ClosingTransaction, secp_ctx: &Secp256k1) -> Result { @@ -261,7 +269,7 @@ impl EcdsaChannelSigner for TestChannelSigner { // As long as our minimum dust limit is enforced and is greater than our anchor output // value, an anchor output can only have an index within [0, 1]. assert!(anchor_tx.input[input].previous_output.vout == 0 || anchor_tx.input[input].previous_output.vout == 1); - self.inner.sign_holder_anchor_input(anchor_tx, input, secp_ctx) + EcdsaChannelSigner::sign_holder_anchor_input(&self.inner, anchor_tx, input, secp_ctx) } fn sign_channel_announcement_with_funding_key( @@ -273,6 +281,45 @@ impl EcdsaChannelSigner for TestChannelSigner { impl WriteableEcdsaChannelSigner for TestChannelSigner {} +#[cfg(taproot)] +impl TaprootChannelSigner for TestChannelSigner { + fn generate_local_nonce_pair(&self, commitment_number: u64, secp_ctx: &Secp256k1) -> PublicNonce { + todo!() + } + + fn partially_sign_counterparty_commitment(&self, counterparty_nonce: PublicNonce, commitment_tx: &CommitmentTransaction, preimages: Vec, secp_ctx: &Secp256k1) -> Result<(PartialSignatureWithNonce, Vec), ()> { + todo!() + } + + fn finalize_holder_commitment(&self, commitment_number: u64, commitment_tx: &HolderCommitmentTransaction, counterparty_partial_signature: PartialSignatureWithNonce, secp_ctx: &Secp256k1) -> Result { + todo!() + } + + fn sign_justice_revoked_output(&self, justice_tx: &Transaction, input: usize, amount: u64, per_commitment_key: &SecretKey, secp_ctx: &Secp256k1) -> Result { + todo!() + } + + fn sign_justice_revoked_htlc(&self, justice_tx: &Transaction, input: usize, amount: u64, per_commitment_key: &SecretKey, htlc: &HTLCOutputInCommitment, secp_ctx: &Secp256k1) -> Result { + todo!() + } + + fn sign_holder_htlc_transaction(&self, htlc_tx: &Transaction, input: usize, htlc_descriptor: &HTLCDescriptor, secp_ctx: &Secp256k1) -> Result { + todo!() + } + + fn sign_counterparty_htlc_transaction(&self, htlc_tx: &Transaction, input: usize, amount: u64, per_commitment_point: &PublicKey, htlc: &HTLCOutputInCommitment, secp_ctx: &Secp256k1) -> Result { + todo!() + } + + fn partially_sign_closing_transaction(&self, closing_tx: &ClosingTransaction, secp_ctx: &Secp256k1) -> Result { + todo!() + } + + fn sign_holder_anchor_input(&self, anchor_tx: &Transaction, input: usize, secp_ctx: &Secp256k1) -> Result { + todo!() + } +} + impl Writeable for TestChannelSigner { fn write(&self, writer: &mut W) -> Result<(), Error> { // TestChannelSigner has two fields - `inner` ([`InMemorySigner`]) and `state` diff --git a/lightning/src/util/test_utils.rs b/lightning/src/util/test_utils.rs index b46f14681d8..c9563f42f0e 100644 --- a/lightning/src/util/test_utils.rs +++ b/lightning/src/util/test_utils.rs @@ -176,6 +176,8 @@ impl EntropySource for OnlyReadsKeysInterface { impl SignerProvider for OnlyReadsKeysInterface { type EcdsaSigner = TestChannelSigner; + #[cfg(taproot)] + type TaprootSigner = TestChannelSigner; fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32] { unreachable!(); } @@ -1097,6 +1099,8 @@ impl NodeSigner for TestKeysInterface { impl SignerProvider for TestKeysInterface { type EcdsaSigner = TestChannelSigner; + #[cfg(taproot)] + type TaprootSigner = TestChannelSigner; fn generate_channel_keys_id(&self, inbound: bool, channel_value_satoshis: u64, user_channel_id: u128) -> [u8; 32] { self.backing.generate_channel_keys_id(inbound, channel_value_satoshis, user_channel_id) From de4dd95d29f242820615ace081d5f3d1e3386ff8 Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Sun, 5 Nov 2023 21:51:15 -0800 Subject: [PATCH 4/5] Reparametrize ChannelSignerType by SignerProvider. ChannelSignerType is an enum that contains variants of all currently supported signer types. Given that those signer types are enumerated as associated types in multiple places, it is prudent to denote one type as the authority on signer types. SignerProvider seemed like the best option. Thus, instead of ChannelSignerType declaring the associated types itself, it simply uses their definitions from SignerProvider. --- lightning/src/ln/channel.rs | 38 ++++++++++++++++++++--------- lightning/src/sign/taproot.rs | 1 + lightning/src/sign/type_resolver.rs | 29 ++++++++++++++-------- 3 files changed, 47 insertions(+), 21 deletions(-) diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 157103fea26..38c605515cc 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -725,7 +725,7 @@ pub(super) struct ChannelContext where SP::Target: SignerProvider { latest_monitor_update_id: u64, - holder_signer: ChannelSignerType<::EcdsaSigner>, + holder_signer: ChannelSignerType, shutdown_scriptpubkey: Option, destination_script: ScriptBuf, @@ -1095,7 +1095,7 @@ impl ChannelContext where SP::Target: SignerProvider { /// Returns the holder signer for this channel. #[cfg(test)] - pub fn get_signer(&self) -> &ChannelSignerType<::EcdsaSigner> { + pub fn get_signer(&self) -> &ChannelSignerType { return &self.holder_signer } @@ -2142,7 +2142,9 @@ impl ChannelContext where SP::Target: SignerProvider { ChannelSignerType::Ecdsa(ecdsa) => { ecdsa.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), &self.secp_ctx) .map(|(sig, _)| sig).ok()? - } + }, + // TODO (taproot|arik) + _ => todo!() }; if self.signer_pending_funding { @@ -2194,7 +2196,9 @@ impl ChannelContext where SP::Target: SignerProvider { // We sign "counterparty" commitment transaction, allowing them to broadcast the tx if they wish. (counterparty_initial_commitment_tx, funding_signed) - } + }, + // TODO (taproot|arik) + _ => todo!() } } } @@ -3485,7 +3489,9 @@ impl Channel where self.context.cur_counterparty_commitment_transaction_number + 1, &secret ).map_err(|_| ChannelError::Close("Failed to validate revocation from peer".to_owned()))?; - } + }, + // TODO (taproot|arik) + _ => todo!() }; self.context.commitment_secrets.provide_secret(self.context.cur_counterparty_commitment_transaction_number + 1, msg.per_commitment_secret) @@ -4438,7 +4444,9 @@ impl Channel where max_fee_satoshis: our_max_fee, }), }), None, None)) - } + }, + // TODO (taproot|arik) + _ => todo!() } } @@ -4689,7 +4697,9 @@ impl Channel where max_fee_satoshis: our_max_fee, }), }), signed_tx, shutdown_result)) - } + }, + // TODO (taproot|arik) + _ => todo!() } } } @@ -4801,7 +4811,7 @@ impl Channel where } #[cfg(test)] - pub fn get_signer(&self) -> &ChannelSignerType<::EcdsaSigner> { + pub fn get_signer(&self) -> &ChannelSignerType { &self.context.holder_signer } @@ -5320,7 +5330,9 @@ impl Channel where node_signature: our_node_sig, bitcoin_signature: our_bitcoin_sig, }) - } + }, + // TODO (taproot|arik) + _ => todo!() } } @@ -5347,7 +5359,9 @@ impl Channel where bitcoin_signature_2: if were_node_one { their_bitcoin_sig } else { our_bitcoin_sig }, contents: announcement, }) - } + }, + // TODO (taproot|arik) + _ => todo!() } } else { Err(ChannelError::Ignore("Attempted to sign channel announcement before we'd received announcement_signatures".to_string())) @@ -5720,7 +5734,9 @@ impl Channel where #[cfg(taproot)] partial_signature_with_nonce: None, }, (counterparty_commitment_txid, commitment_stats.htlcs_included))) - } + }, + // TODO (taproot|arik) + _ => todo!() } } diff --git a/lightning/src/sign/taproot.rs b/lightning/src/sign/taproot.rs index 2c9eb697046..0028a0cd12b 100644 --- a/lightning/src/sign/taproot.rs +++ b/lightning/src/sign/taproot.rs @@ -1,5 +1,6 @@ //! Defines a Taproot-specific signer type. +use alloc::vec::Vec; use bitcoin::blockdata::transaction::Transaction; use bitcoin::secp256k1; use bitcoin::secp256k1::{PublicKey, schnorr::Signature, Secp256k1, SecretKey}; diff --git a/lightning/src/sign/type_resolver.rs b/lightning/src/sign/type_resolver.rs index f76650982c2..2a122da3447 100644 --- a/lightning/src/sign/type_resolver.rs +++ b/lightning/src/sign/type_resolver.rs @@ -1,34 +1,43 @@ -use crate::sign::{ChannelSigner, EcdsaChannelSigner}; +use core::ops::Deref; +use crate::sign::{ChannelSigner, SignerProvider}; -pub(crate) enum ChannelSignerType { +pub(crate) enum ChannelSignerType where SP::Target: SignerProvider { // in practice, this will only ever be an EcdsaChannelSigner (specifically, Writeable) - Ecdsa(ECS) + Ecdsa(::EcdsaSigner), + #[cfg(taproot)] + Taproot(::TaprootSigner), } -impl ChannelSignerType{ +impl ChannelSignerType where SP::Target: SignerProvider { pub(crate) fn as_ref(&self) -> &dyn ChannelSigner { match self { - ChannelSignerType::Ecdsa(ecs) => ecs + ChannelSignerType::Ecdsa(ecs) => ecs, + #[cfg(taproot)] + ChannelSignerType::Taproot(tcs) => tcs, } } pub(crate) fn as_mut(&mut self) -> &mut dyn ChannelSigner { match self { - ChannelSignerType::Ecdsa(ecs) => ecs + ChannelSignerType::Ecdsa(ecs) => ecs, + #[cfg(taproot)] + ChannelSignerType::Taproot(tcs) => tcs, } } #[allow(unused)] - pub(crate) fn as_ecdsa(&self) -> Option<&ECS> { + pub(crate) fn as_ecdsa(&self) -> Option<&::EcdsaSigner> { match self { - ChannelSignerType::Ecdsa(ecs) => Some(ecs) + ChannelSignerType::Ecdsa(ecs) => Some(ecs), + _ => None } } #[allow(unused)] - pub(crate) fn as_mut_ecdsa(&mut self) -> Option<&mut ECS> { + pub(crate) fn as_mut_ecdsa(&mut self) -> Option<&mut ::EcdsaSigner> { match self { - ChannelSignerType::Ecdsa(ecs) => Some(ecs) + ChannelSignerType::Ecdsa(ecs) => Some(ecs), + _ => None } } } From 88ce7d6575dd376e98e680d0c0813c7b79151773 Mon Sep 17 00:00:00 2001 From: Arik Sosman Date: Mon, 28 Aug 2023 16:06:41 -0700 Subject: [PATCH 5/5] Move ECDSA-specific signers into ecdsa.rs To separate out the logic in the `sign` module, which will start to be convoluted with multiple signer types, we're splitting out each signer type into its own submodule, following the taproot.rs example from a previous commit. --- lightning/src/chain/chainmonitor.rs | 2 +- lightning/src/chain/channelmonitor.rs | 4 +- lightning/src/chain/mod.rs | 2 +- lightning/src/chain/onchaintx.rs | 2 +- lightning/src/chain/package.rs | 2 +- lightning/src/events/bump_transaction.rs | 12 +- lightning/src/ln/channel.rs | 5 +- lightning/src/ln/channelmanager.rs | 3 +- lightning/src/ln/functional_tests.rs | 2 +- lightning/src/ln/monitor_tests.rs | 2 +- lightning/src/sign/ecdsa.rs | 173 ++++++++++++++++++++++ lightning/src/sign/mod.rs | 157 +------------------- lightning/src/util/persist.rs | 2 +- lightning/src/util/test_channel_signer.rs | 3 +- lightning/src/util/test_utils.rs | 4 +- 15 files changed, 199 insertions(+), 176 deletions(-) create mode 100644 lightning/src/sign/ecdsa.rs diff --git a/lightning/src/chain/chainmonitor.rs b/lightning/src/chain/chainmonitor.rs index 800bee8e3b3..0b7e13f24b0 100644 --- a/lightning/src/chain/chainmonitor.rs +++ b/lightning/src/chain/chainmonitor.rs @@ -31,7 +31,7 @@ use crate::chain::{ChannelMonitorUpdateStatus, Filter, WatchedOutput}; use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator}; use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, Balance, MonitorEvent, TransactionOutputs, LATENCY_GRACE_PERIOD_BLOCKS}; use crate::chain::transaction::{OutPoint, TransactionData}; -use crate::sign::WriteableEcdsaChannelSigner; +use crate::sign::ecdsa::WriteableEcdsaChannelSigner; use crate::events; use crate::events::{Event, EventHandler}; use crate::util::atomic_counter::AtomicCounter; diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index 8d22ab35443..832e60f5dc7 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -43,7 +43,7 @@ use crate::chain; use crate::chain::{BestBlock, WatchedOutput}; use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator}; use crate::chain::transaction::{OutPoint, TransactionData}; -use crate::sign::{ChannelDerivationParameters, HTLCDescriptor, SpendableOutputDescriptor, StaticPaymentOutputDescriptor, DelayedPaymentOutputDescriptor, WriteableEcdsaChannelSigner, SignerProvider, EntropySource}; +use crate::sign::{ChannelDerivationParameters, HTLCDescriptor, SpendableOutputDescriptor, StaticPaymentOutputDescriptor, DelayedPaymentOutputDescriptor, ecdsa::WriteableEcdsaChannelSigner, SignerProvider, EntropySource}; use crate::chain::onchaintx::{ClaimEvent, OnchainTxHandler}; use crate::chain::package::{CounterpartyOfferedHTLCOutput, CounterpartyReceivedHTLCOutput, HolderFundingOutput, HolderHTLCOutput, PackageSolvingData, PackageTemplate, RevokedOutput, RevokedHTLCOutput}; use crate::chain::Filter; @@ -1459,7 +1459,7 @@ impl ChannelMonitor { /// to the commitment transaction being revoked, this will return a signed transaction, but /// the signature will not be valid. /// - /// [`EcdsaChannelSigner::sign_justice_revoked_output`]: crate::sign::EcdsaChannelSigner::sign_justice_revoked_output + /// [`EcdsaChannelSigner::sign_justice_revoked_output`]: crate::sign::ecdsa::EcdsaChannelSigner::sign_justice_revoked_output /// [`Persist`]: crate::chain::chainmonitor::Persist pub fn sign_to_local_justice_tx(&self, justice_tx: Transaction, input_idx: usize, value: u64, commitment_number: u64) -> Result { self.inner.lock().unwrap().sign_to_local_justice_tx(justice_tx, input_idx, value, commitment_number) diff --git a/lightning/src/chain/mod.rs b/lightning/src/chain/mod.rs index a7c3a6d88ba..2a9583f2edf 100644 --- a/lightning/src/chain/mod.rs +++ b/lightning/src/chain/mod.rs @@ -17,7 +17,7 @@ use bitcoin::network::constants::Network; use bitcoin::secp256k1::PublicKey; use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, MonitorEvent}; -use crate::sign::WriteableEcdsaChannelSigner; +use crate::sign::ecdsa::WriteableEcdsaChannelSigner; use crate::chain::transaction::{OutPoint, TransactionData}; use crate::prelude::*; diff --git a/lightning/src/chain/onchaintx.rs b/lightning/src/chain/onchaintx.rs index 30553ed7853..2871abbc223 100644 --- a/lightning/src/chain/onchaintx.rs +++ b/lightning/src/chain/onchaintx.rs @@ -23,7 +23,7 @@ use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature}; use bitcoin::secp256k1; use crate::chain::chaininterface::compute_feerate_sat_per_1000_weight; -use crate::sign::{ChannelDerivationParameters, HTLCDescriptor, ChannelSigner, EntropySource, SignerProvider, WriteableEcdsaChannelSigner}; +use crate::sign::{ChannelDerivationParameters, HTLCDescriptor, ChannelSigner, EntropySource, SignerProvider, ecdsa::WriteableEcdsaChannelSigner}; use crate::ln::msgs::DecodeError; use crate::ln::PaymentPreimage; use crate::ln::chan_utils::{self, ChannelTransactionParameters, HTLCOutputInCommitment, HolderCommitmentTransaction}; diff --git a/lightning/src/chain/package.rs b/lightning/src/chain/package.rs index 0759e80eb63..7c488816048 100644 --- a/lightning/src/chain/package.rs +++ b/lightning/src/chain/package.rs @@ -28,7 +28,7 @@ use crate::ln::features::ChannelTypeFeatures; use crate::ln::channel_keys::{DelayedPaymentBasepoint, HtlcBasepoint}; use crate::ln::msgs::DecodeError; use crate::chain::chaininterface::{FeeEstimator, ConfirmationTarget, MIN_RELAY_FEE_SAT_PER_1000_WEIGHT, compute_feerate_sat_per_1000_weight, FEERATE_FLOOR_SATS_PER_KW}; -use crate::sign::WriteableEcdsaChannelSigner; +use crate::sign::ecdsa::WriteableEcdsaChannelSigner; use crate::chain::onchaintx::{ExternalHTLCClaim, OnchainTxHandler}; use crate::util::logger::Logger; use crate::util::ser::{Readable, Writer, Writeable, RequiredWrapper}; diff --git a/lightning/src/events/bump_transaction.rs b/lightning/src/events/bump_transaction.rs index 2c056401540..8c6390302f1 100644 --- a/lightning/src/events/bump_transaction.rs +++ b/lightning/src/events/bump_transaction.rs @@ -25,9 +25,9 @@ use crate::ln::chan_utils::{ }; use crate::prelude::*; use crate::sign::{ - ChannelDerivationParameters, HTLCDescriptor, EcdsaChannelSigner, SignerProvider, - WriteableEcdsaChannelSigner, P2WPKH_WITNESS_WEIGHT + ChannelDerivationParameters, HTLCDescriptor, SignerProvider, P2WPKH_WITNESS_WEIGHT }; +use crate::sign::ecdsa::{EcdsaChannelSigner, WriteableEcdsaChannelSigner}; use crate::sync::Mutex; use crate::util::logger::Logger; @@ -142,8 +142,8 @@ pub enum BumpTransactionEvent { /// an empty `pending_htlcs`), confirmation of the commitment transaction can be considered to /// be not urgent. /// - /// [`EcdsaChannelSigner`]: crate::sign::EcdsaChannelSigner - /// [`EcdsaChannelSigner::sign_holder_anchor_input`]: crate::sign::EcdsaChannelSigner::sign_holder_anchor_input + /// [`EcdsaChannelSigner`]: crate::sign::ecdsa::EcdsaChannelSigner + /// [`EcdsaChannelSigner::sign_holder_anchor_input`]: crate::sign::ecdsa::EcdsaChannelSigner::sign_holder_anchor_input /// [`build_anchor_input_witness`]: crate::ln::chan_utils::build_anchor_input_witness ChannelClose { /// The unique identifier for the claim of the anchor output in the commitment transaction. @@ -196,8 +196,8 @@ pub enum BumpTransactionEvent { /// longer able to commit external confirmed funds to the HTLC transaction or the fee committed /// to the HTLC transaction is greater in value than the HTLCs being claimed. /// - /// [`EcdsaChannelSigner`]: crate::sign::EcdsaChannelSigner - /// [`EcdsaChannelSigner::sign_holder_htlc_transaction`]: crate::sign::EcdsaChannelSigner::sign_holder_htlc_transaction + /// [`EcdsaChannelSigner`]: crate::sign::ecdsa::EcdsaChannelSigner + /// [`EcdsaChannelSigner::sign_holder_htlc_transaction`]: crate::sign::ecdsa::EcdsaChannelSigner::sign_holder_htlc_transaction HTLCResolution { /// The unique identifier for the claim of the HTLCs in the confirmed commitment /// transaction. diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 38c605515cc..8a50d47cd20 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -37,7 +37,8 @@ use crate::chain::BestBlock; use crate::chain::chaininterface::{FeeEstimator, ConfirmationTarget, LowerBoundedFeeEstimator}; use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, LATENCY_GRACE_PERIOD_BLOCKS, CLOSED_CHANNEL_UPDATE_ID}; use crate::chain::transaction::{OutPoint, TransactionData}; -use crate::sign::{EcdsaChannelSigner, WriteableEcdsaChannelSigner, EntropySource, ChannelSigner, SignerProvider, NodeSigner, Recipient}; +use crate::sign::ecdsa::{EcdsaChannelSigner, WriteableEcdsaChannelSigner}; +use crate::sign::{EntropySource, ChannelSigner, SignerProvider, NodeSigner, Recipient}; use crate::events::ClosureReason; use crate::routing::gossip::NodeId; use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer}; @@ -8361,7 +8362,7 @@ use crate::ln::channelmanager::{self, HTLCSource, PaymentId}; use bitcoin::hashes::hex::FromHex; use bitcoin::hash_types::Txid; use bitcoin::secp256k1::Message; - use crate::sign::{ChannelDerivationParameters, HTLCDescriptor, EcdsaChannelSigner}; + use crate::sign::{ChannelDerivationParameters, HTLCDescriptor, ecdsa::EcdsaChannelSigner}; use crate::ln::PaymentPreimage; use crate::ln::channel::{HTLCOutputInCommitment ,TxCreationKeys}; use crate::ln::channel_keys::{DelayedPaymentBasepoint, HtlcBasepoint}; diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 724c0d77ec6..a7e428c20b0 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -65,7 +65,8 @@ use crate::offers::offer::{DerivedMetadata, Offer, OfferBuilder}; use crate::offers::parse::Bolt12SemanticError; use crate::offers::refund::{Refund, RefundBuilder}; use crate::onion_message::{Destination, OffersMessage, OffersMessageHandler, PendingOnionMessage, new_pending_onion_message}; -use crate::sign::{EntropySource, KeysManager, NodeSigner, Recipient, SignerProvider, WriteableEcdsaChannelSigner}; +use crate::sign::{EntropySource, KeysManager, NodeSigner, Recipient, SignerProvider}; +use crate::sign::ecdsa::WriteableEcdsaChannelSigner; use crate::util::config::{UserConfig, ChannelConfig, ChannelConfigUpdate}; use crate::util::wakers::{Future, Notifier}; use crate::util::scid_utils::fake_scid; diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index b182d17fe82..cc00d93b17a 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -17,7 +17,7 @@ use crate::chain::chaininterface::LowerBoundedFeeEstimator; use crate::chain::channelmonitor; use crate::chain::channelmonitor::{CLOSED_CHANNEL_UPDATE_ID, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY}; use crate::chain::transaction::OutPoint; -use crate::sign::{EcdsaChannelSigner, EntropySource, SignerProvider}; +use crate::sign::{ecdsa::EcdsaChannelSigner, EntropySource, SignerProvider}; use crate::events::{Event, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentPurpose, ClosureReason, HTLCDestination, PaymentFailureReason}; use crate::ln::{ChannelId, PaymentPreimage, PaymentSecret, PaymentHash}; 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, get_holder_selected_channel_reserve_satoshis, OutboundV1Channel, InboundV1Channel, COINBASE_MATURITY, ChannelPhase}; diff --git a/lightning/src/ln/monitor_tests.rs b/lightning/src/ln/monitor_tests.rs index ad5f03a5cf6..80119b55787 100644 --- a/lightning/src/ln/monitor_tests.rs +++ b/lightning/src/ln/monitor_tests.rs @@ -9,7 +9,7 @@ //! Further functional tests which test blockchain reorganizations. -use crate::sign::{EcdsaChannelSigner, SpendableOutputDescriptor}; +use crate::sign::{ecdsa::EcdsaChannelSigner, SpendableOutputDescriptor}; use crate::chain::channelmonitor::{ANTI_REORG_DELAY, LATENCY_GRACE_PERIOD_BLOCKS, Balance}; use crate::chain::transaction::OutPoint; use crate::chain::chaininterface::{LowerBoundedFeeEstimator, compute_feerate_sat_per_1000_weight}; diff --git a/lightning/src/sign/ecdsa.rs b/lightning/src/sign/ecdsa.rs new file mode 100644 index 00000000000..c9677c8ba25 --- /dev/null +++ b/lightning/src/sign/ecdsa.rs @@ -0,0 +1,173 @@ +//! Defines ECDSA-specific signer types. + +use bitcoin::blockdata::transaction::Transaction; + +use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey}; +use bitcoin::secp256k1::ecdsa::Signature; +use bitcoin::secp256k1; + +use crate::util::ser::Writeable; +use crate::ln::PaymentPreimage; +use crate::ln::chan_utils::{HTLCOutputInCommitment, HolderCommitmentTransaction, CommitmentTransaction, ClosingTransaction}; +use crate::ln::msgs::UnsignedChannelAnnouncement; + +use crate::prelude::*; +use crate::sign::{ChannelSigner, HTLCDescriptor}; + +/// A trait to sign Lightning channel transactions as described in +/// [BOLT 3](https://github.com/lightning/bolts/blob/master/03-transactions.md). +/// +/// Signing services could be implemented on a hardware wallet and should implement signing +/// policies in order to be secure. Please refer to the [VLS Policy +/// Controls](https://gitlab.com/lightning-signer/validating-lightning-signer/-/blob/main/docs/policy-controls.md) +/// for an example of such policies. +pub trait EcdsaChannelSigner: ChannelSigner { + /// Create a signature for a counterparty's commitment transaction and associated HTLC transactions. + /// + /// Note that if signing fails or is rejected, the channel will be force-closed. + /// + /// Policy checks should be implemented in this function, including checking the amount + /// sent to us and checking the HTLCs. + /// + /// The preimages of outgoing HTLCs that were fulfilled since the last commitment are provided. + /// A validating signer should ensure that an HTLC output is removed only when the matching + /// preimage is provided, or when the value to holder is restored. + /// + /// Note that all the relevant preimages will be provided, but there may also be additional + /// irrelevant or duplicate preimages. + // + // TODO: Document the things someone using this interface should enforce before signing. + fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction, + preimages: Vec, secp_ctx: &Secp256k1 + ) -> Result<(Signature, Vec), ()>; + /// Validate the counterparty's revocation. + /// + /// This is required in order for the signer to make sure that the state has moved + /// forward and it is safe to sign the next counterparty commitment. + fn validate_counterparty_revocation(&self, idx: u64, secret: &SecretKey) -> Result<(), ()>; + /// Creates a signature for a holder's commitment transaction. + /// + /// This will be called + /// - with a non-revoked `commitment_tx`. + /// - with the latest `commitment_tx` when we initiate a force-close. + /// + /// This may be called multiple times for the same transaction. + /// + /// An external signer implementation should check that the commitment has not been revoked. + // + // TODO: Document the things someone using this interface should enforce before signing. + fn sign_holder_commitment(&self, commitment_tx: &HolderCommitmentTransaction, + secp_ctx: &Secp256k1) -> Result; + /// Same as [`sign_holder_commitment`], but exists only for tests to get access to holder + /// commitment transactions which will be broadcasted later, after the channel has moved on to a + /// newer state. Thus, needs its own method as [`sign_holder_commitment`] may enforce that we + /// only ever get called once. + #[cfg(any(test,feature = "unsafe_revoked_tx_signing"))] + fn unsafe_sign_holder_commitment(&self, commitment_tx: &HolderCommitmentTransaction, + secp_ctx: &Secp256k1) -> Result; + /// Create a signature for the given input in a transaction spending an HTLC transaction output + /// or a commitment transaction `to_local` output when our counterparty broadcasts an old state. + /// + /// A justice transaction may claim multiple outputs at the same time if timelocks are + /// similar, but only a signature for the input at index `input` should be signed for here. + /// It may be called multiple times for same output(s) if a fee-bump is needed with regards + /// to an upcoming timelock expiration. + /// + /// Amount is value of the output spent by this input, committed to in the BIP 143 signature. + /// + /// `per_commitment_key` is revocation secret which was provided by our counterparty when they + /// revoked the state which they eventually broadcast. It's not a _holder_ secret key and does + /// not allow the spending of any funds by itself (you need our holder `revocation_secret` to do + /// so). + fn sign_justice_revoked_output(&self, justice_tx: &Transaction, input: usize, amount: u64, + per_commitment_key: &SecretKey, secp_ctx: &Secp256k1 + ) -> Result; + /// Create a signature for the given input in a transaction spending a commitment transaction + /// HTLC output when our counterparty broadcasts an old state. + /// + /// A justice transaction may claim multiple outputs at the same time if timelocks are + /// similar, but only a signature for the input at index `input` should be signed for here. + /// It may be called multiple times for same output(s) if a fee-bump is needed with regards + /// to an upcoming timelock expiration. + /// + /// `amount` is the value of the output spent by this input, committed to in the BIP 143 + /// signature. + /// + /// `per_commitment_key` is revocation secret which was provided by our counterparty when they + /// revoked the state which they eventually broadcast. It's not a _holder_ secret key and does + /// not allow the spending of any funds by itself (you need our holder revocation_secret to do + /// so). + /// + /// `htlc` holds HTLC elements (hash, timelock), thus changing the format of the witness script + /// (which is committed to in the BIP 143 signatures). + fn sign_justice_revoked_htlc(&self, justice_tx: &Transaction, input: usize, amount: u64, + per_commitment_key: &SecretKey, htlc: &HTLCOutputInCommitment, + secp_ctx: &Secp256k1) -> Result; + /// Computes the signature for a commitment transaction's HTLC output used as an input within + /// `htlc_tx`, which spends the commitment transaction at index `input`. The signature returned + /// must be be computed using [`EcdsaSighashType::All`]. + /// + /// Note that this may be called for HTLCs in the penultimate commitment transaction if a + /// [`ChannelMonitor`] [replica](https://github.com/lightningdevkit/rust-lightning/blob/main/GLOSSARY.md#monitor-replicas) + /// broadcasts it before receiving the update for the latest commitment transaction. + /// + /// [`EcdsaSighashType::All`]: bitcoin::sighash::EcdsaSighashType::All + /// [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor + fn sign_holder_htlc_transaction(&self, htlc_tx: &Transaction, input: usize, + htlc_descriptor: &HTLCDescriptor, secp_ctx: &Secp256k1 + ) -> Result; + /// Create a signature for a claiming transaction for a HTLC output on a counterparty's commitment + /// transaction, either offered or received. + /// + /// Such a transaction may claim multiples offered outputs at same time if we know the + /// preimage for each when we create it, but only the input at index `input` should be + /// signed for here. It may be called multiple times for same output(s) if a fee-bump is + /// needed with regards to an upcoming timelock expiration. + /// + /// `witness_script` is either an offered or received script as defined in BOLT3 for HTLC + /// outputs. + /// + /// `amount` is value of the output spent by this input, committed to in the BIP 143 signature. + /// + /// `per_commitment_point` is the dynamic point corresponding to the channel state + /// detected onchain. It has been generated by our counterparty and is used to derive + /// channel state keys, which are then included in the witness script and committed to in the + /// BIP 143 signature. + fn sign_counterparty_htlc_transaction(&self, htlc_tx: &Transaction, input: usize, amount: u64, + per_commitment_point: &PublicKey, htlc: &HTLCOutputInCommitment, + secp_ctx: &Secp256k1) -> Result; + /// Create a signature for a (proposed) closing transaction. + /// + /// Note that, due to rounding, there may be one "missing" satoshi, and either party may have + /// chosen to forgo their output as dust. + fn sign_closing_transaction(&self, closing_tx: &ClosingTransaction, + secp_ctx: &Secp256k1) -> Result; + /// Computes the signature for a commitment transaction's anchor output used as an + /// input within `anchor_tx`, which spends the commitment transaction, at index `input`. + fn sign_holder_anchor_input( + &self, anchor_tx: &Transaction, input: usize, secp_ctx: &Secp256k1, + ) -> Result; + /// Signs a channel announcement message with our funding key proving it comes from one of the + /// channel participants. + /// + /// Channel announcements also require a signature from each node's network key. Our node + /// signature is computed through [`NodeSigner::sign_gossip_message`]. + /// + /// Note that if this fails or is rejected, the channel will not be publicly announced and + /// our counterparty may (though likely will not) close the channel on us for violating the + /// protocol. + /// + /// [`NodeSigner::sign_gossip_message`]: crate::sign::NodeSigner::sign_gossip_message + fn sign_channel_announcement_with_funding_key( + &self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1 + ) -> Result; +} + +/// A writeable signer. +/// +/// There will always be two instances of a signer per channel, one occupied by the +/// [`ChannelManager`] and another by the channel's [`ChannelMonitor`]. +/// +/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager +/// [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor +pub trait WriteableEcdsaChannelSigner: EcdsaChannelSigner + Writeable {} diff --git a/lightning/src/sign/mod.rs b/lightning/src/sign/mod.rs index a2740bc3558..9de3ed8dc53 100644 --- a/lightning/src/sign/mod.rs +++ b/lightning/src/sign/mod.rs @@ -61,6 +61,7 @@ use musig2::types::{PartialSignature, PublicNonce, SecretNonce}; use crate::io::{self, Error}; use crate::ln::features::ChannelTypeFeatures; use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT}; +use crate::sign::ecdsa::{EcdsaChannelSigner, WriteableEcdsaChannelSigner}; #[cfg(taproot)] use crate::sign::taproot::TaprootChannelSigner; use crate::util::atomic_counter::AtomicCounter; @@ -69,6 +70,7 @@ use crate::util::invoice::construct_invoice_preimage; pub(crate) mod type_resolver; +pub mod ecdsa; #[cfg(taproot)] pub mod taproot; @@ -611,161 +613,6 @@ pub trait ChannelSigner { fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters); } -/// A trait to sign Lightning channel transactions as described in -/// [BOLT 3](https://github.com/lightning/bolts/blob/master/03-transactions.md). -/// -/// Signing services could be implemented on a hardware wallet and should implement signing -/// policies in order to be secure. Please refer to the [VLS Policy -/// Controls](https://gitlab.com/lightning-signer/validating-lightning-signer/-/blob/main/docs/policy-controls.md) -/// for an example of such policies. -pub trait EcdsaChannelSigner: ChannelSigner { - /// Create a signature for a counterparty's commitment transaction and associated HTLC transactions. - /// - /// Note that if signing fails or is rejected, the channel will be force-closed. - /// - /// Policy checks should be implemented in this function, including checking the amount - /// sent to us and checking the HTLCs. - /// - /// The preimages of outgoing HTLCs that were fulfilled since the last commitment are provided. - /// A validating signer should ensure that an HTLC output is removed only when the matching - /// preimage is provided, or when the value to holder is restored. - /// - /// Note that all the relevant preimages will be provided, but there may also be additional - /// irrelevant or duplicate preimages. - // - // TODO: Document the things someone using this interface should enforce before signing. - fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction, - preimages: Vec, secp_ctx: &Secp256k1 - ) -> Result<(Signature, Vec), ()>; - /// Validate the counterparty's revocation. - /// - /// This is required in order for the signer to make sure that the state has moved - /// forward and it is safe to sign the next counterparty commitment. - fn validate_counterparty_revocation(&self, idx: u64, secret: &SecretKey) -> Result<(), ()>; - /// Creates a signature for a holder's commitment transaction. - /// - /// This will be called - /// - with a non-revoked `commitment_tx`. - /// - with the latest `commitment_tx` when we initiate a force-close. - /// - /// This may be called multiple times for the same transaction. - /// - /// An external signer implementation should check that the commitment has not been revoked. - // - // TODO: Document the things someone using this interface should enforce before signing. - fn sign_holder_commitment(&self, commitment_tx: &HolderCommitmentTransaction, - secp_ctx: &Secp256k1) -> Result; - /// Same as [`sign_holder_commitment`], but exists only for tests to get access to holder - /// commitment transactions which will be broadcasted later, after the channel has moved on to a - /// newer state. Thus, needs its own method as [`sign_holder_commitment`] may enforce that we - /// only ever get called once. - #[cfg(any(test,feature = "unsafe_revoked_tx_signing"))] - fn unsafe_sign_holder_commitment(&self, commitment_tx: &HolderCommitmentTransaction, - secp_ctx: &Secp256k1) -> Result; - /// Create a signature for the given input in a transaction spending an HTLC transaction output - /// or a commitment transaction `to_local` output when our counterparty broadcasts an old state. - /// - /// A justice transaction may claim multiple outputs at the same time if timelocks are - /// similar, but only a signature for the input at index `input` should be signed for here. - /// It may be called multiple times for same output(s) if a fee-bump is needed with regards - /// to an upcoming timelock expiration. - /// - /// Amount is value of the output spent by this input, committed to in the BIP 143 signature. - /// - /// `per_commitment_key` is revocation secret which was provided by our counterparty when they - /// revoked the state which they eventually broadcast. It's not a _holder_ secret key and does - /// not allow the spending of any funds by itself (you need our holder `revocation_secret` to do - /// so). - fn sign_justice_revoked_output(&self, justice_tx: &Transaction, input: usize, amount: u64, - per_commitment_key: &SecretKey, secp_ctx: &Secp256k1 - ) -> Result; - /// Create a signature for the given input in a transaction spending a commitment transaction - /// HTLC output when our counterparty broadcasts an old state. - /// - /// A justice transaction may claim multiple outputs at the same time if timelocks are - /// similar, but only a signature for the input at index `input` should be signed for here. - /// It may be called multiple times for same output(s) if a fee-bump is needed with regards - /// to an upcoming timelock expiration. - /// - /// `amount` is the value of the output spent by this input, committed to in the BIP 143 - /// signature. - /// - /// `per_commitment_key` is revocation secret which was provided by our counterparty when they - /// revoked the state which they eventually broadcast. It's not a _holder_ secret key and does - /// not allow the spending of any funds by itself (you need our holder revocation_secret to do - /// so). - /// - /// `htlc` holds HTLC elements (hash, timelock), thus changing the format of the witness script - /// (which is committed to in the BIP 143 signatures). - fn sign_justice_revoked_htlc(&self, justice_tx: &Transaction, input: usize, amount: u64, - per_commitment_key: &SecretKey, htlc: &HTLCOutputInCommitment, - secp_ctx: &Secp256k1) -> Result; - /// Computes the signature for a commitment transaction's HTLC output used as an input within - /// `htlc_tx`, which spends the commitment transaction at index `input`. The signature returned - /// must be be computed using [`EcdsaSighashType::All`]. - /// - /// Note that this may be called for HTLCs in the penultimate commitment transaction if a - /// [`ChannelMonitor`] [replica](https://github.com/lightningdevkit/rust-lightning/blob/main/GLOSSARY.md#monitor-replicas) - /// broadcasts it before receiving the update for the latest commitment transaction. - /// - /// [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor - fn sign_holder_htlc_transaction(&self, htlc_tx: &Transaction, input: usize, - htlc_descriptor: &HTLCDescriptor, secp_ctx: &Secp256k1 - ) -> Result; - /// Create a signature for a claiming transaction for a HTLC output on a counterparty's commitment - /// transaction, either offered or received. - /// - /// Such a transaction may claim multiples offered outputs at same time if we know the - /// preimage for each when we create it, but only the input at index `input` should be - /// signed for here. It may be called multiple times for same output(s) if a fee-bump is - /// needed with regards to an upcoming timelock expiration. - /// - /// `witness_script` is either an offered or received script as defined in BOLT3 for HTLC - /// outputs. - /// - /// `amount` is value of the output spent by this input, committed to in the BIP 143 signature. - /// - /// `per_commitment_point` is the dynamic point corresponding to the channel state - /// detected onchain. It has been generated by our counterparty and is used to derive - /// channel state keys, which are then included in the witness script and committed to in the - /// BIP 143 signature. - fn sign_counterparty_htlc_transaction(&self, htlc_tx: &Transaction, input: usize, amount: u64, - per_commitment_point: &PublicKey, htlc: &HTLCOutputInCommitment, - secp_ctx: &Secp256k1) -> Result; - /// Create a signature for a (proposed) closing transaction. - /// - /// Note that, due to rounding, there may be one "missing" satoshi, and either party may have - /// chosen to forgo their output as dust. - fn sign_closing_transaction(&self, closing_tx: &ClosingTransaction, - secp_ctx: &Secp256k1) -> Result; - /// Computes the signature for a commitment transaction's anchor output used as an - /// input within `anchor_tx`, which spends the commitment transaction, at index `input`. - fn sign_holder_anchor_input( - &self, anchor_tx: &Transaction, input: usize, secp_ctx: &Secp256k1, - ) -> Result; - /// Signs a channel announcement message with our funding key proving it comes from one of the - /// channel participants. - /// - /// Channel announcements also require a signature from each node's network key. Our node - /// signature is computed through [`NodeSigner::sign_gossip_message`]. - /// - /// Note that if this fails or is rejected, the channel will not be publicly announced and - /// our counterparty may (though likely will not) close the channel on us for violating the - /// protocol. - fn sign_channel_announcement_with_funding_key( - &self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1 - ) -> Result; -} - -/// A writeable signer. -/// -/// There will always be two instances of a signer per channel, one occupied by the -/// [`ChannelManager`] and another by the channel's [`ChannelMonitor`]. -/// -/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager -/// [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor -pub trait WriteableEcdsaChannelSigner: EcdsaChannelSigner + Writeable {} - /// Specifies the recipient of an invoice. /// /// This indicates to [`NodeSigner::sign_invoice`] what node secret key should be used to sign diff --git a/lightning/src/util/persist.rs b/lightning/src/util/persist.rs index 823ebc548bf..a9f534ee4d3 100644 --- a/lightning/src/util/persist.rs +++ b/lightning/src/util/persist.rs @@ -21,7 +21,7 @@ use crate::prelude::*; use crate::chain; use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator}; use crate::chain::chainmonitor::{Persist, MonitorUpdateId}; -use crate::sign::{EntropySource, NodeSigner, WriteableEcdsaChannelSigner, SignerProvider}; +use crate::sign::{EntropySource, NodeSigner, ecdsa::WriteableEcdsaChannelSigner, SignerProvider}; use crate::chain::transaction::OutPoint; use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, CLOSED_CHANNEL_UPDATE_ID}; use crate::ln::channelmanager::ChannelManager; diff --git a/lightning/src/util/test_channel_signer.rs b/lightning/src/util/test_channel_signer.rs index 3e0ca970e12..ccdcfdd0934 100644 --- a/lightning/src/util/test_channel_signer.rs +++ b/lightning/src/util/test_channel_signer.rs @@ -11,7 +11,8 @@ use crate::ln::channel::{ANCHOR_OUTPUT_VALUE_SATOSHI, MIN_CHAN_DUST_LIMIT_SATOSH use crate::ln::chan_utils::{HTLCOutputInCommitment, ChannelPublicKeys, HolderCommitmentTransaction, CommitmentTransaction, ChannelTransactionParameters, TrustedCommitmentTransaction, ClosingTransaction}; use crate::ln::channel_keys::{HtlcKey}; use crate::ln::{msgs, PaymentPreimage}; -use crate::sign::{WriteableEcdsaChannelSigner, InMemorySigner, ChannelSigner, EcdsaChannelSigner}; +use crate::sign::{InMemorySigner, ChannelSigner}; +use crate::sign::ecdsa::{EcdsaChannelSigner, WriteableEcdsaChannelSigner}; use crate::prelude::*; use core::cmp; diff --git a/lightning/src/util/test_utils.rs b/lightning/src/util/test_utils.rs index c9563f42f0e..e5c63502354 100644 --- a/lightning/src/util/test_utils.rs +++ b/lightning/src/util/test_utils.rs @@ -336,7 +336,7 @@ impl WatchtowerPersister { } } -impl chainmonitor::Persist for WatchtowerPersister { +impl chainmonitor::Persist for WatchtowerPersister { fn persist_new_channel(&self, funding_txo: OutPoint, data: &channelmonitor::ChannelMonitor, id: MonitorUpdateId ) -> chain::ChannelMonitorUpdateStatus { @@ -416,7 +416,7 @@ impl TestPersister { self.update_rets.lock().unwrap().push_back(next_ret); } } -impl chainmonitor::Persist for TestPersister { +impl chainmonitor::Persist for TestPersister { fn persist_new_channel(&self, _funding_txo: OutPoint, _data: &channelmonitor::ChannelMonitor, _id: MonitorUpdateId) -> chain::ChannelMonitorUpdateStatus { if let Some(update_ret) = self.update_rets.lock().unwrap().pop_front() { return update_ret