From a86a4b0fe6817f6f37ad13a2f120411a34f24e67 Mon Sep 17 00:00:00 2001 From: Leo Nash Date: Thu, 20 Feb 2025 00:12:37 +0000 Subject: [PATCH] staging --- lightning/src/ln/channel.rs | 20 +++++++++++ lightning/src/sign/mod.rs | 9 +++++ lightning/src/sign/tx_builder.rs | 58 +++++++++++++++++++++++--------- 3 files changed, 71 insertions(+), 16 deletions(-) diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index cb06f4149eb..5065c041e60 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -54,6 +54,7 @@ use crate::chain::BestBlock; use crate::chain::chaininterface::{FeeEstimator, ConfirmationTarget, LowerBoundedFeeEstimator, fee_for_weight}; use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, LATENCY_GRACE_PERIOD_BLOCKS}; use crate::chain::transaction::{OutPoint, TransactionData}; +use crate::sign::tx_builder::ChannelParameters; use crate::sign::ecdsa::EcdsaChannelSigner; use crate::sign::{EntropySource, ChannelSigner, SignerProvider, NodeSigner, Recipient}; use crate::events::{ClosureReason, Event}; @@ -2237,6 +2238,15 @@ impl ChannelContext where SP::Target: SignerProvider { let channel_keys_id = signer_provider.generate_channel_keys_id(true, channel_value_satoshis, user_id); let holder_signer = signer_provider.derive_channel_signer(channel_value_satoshis, channel_keys_id); + let mut tx_builder = holder_signer.derive_tx_builder(); + tx_builder.provide_holder_parameters(&ChannelTransactionParameters { + holder_pubkeys: holder_signer.pubkeys().clone(), + holder_selected_contest_delay: config.channel_handshake_config.our_to_self_delay, + is_outbound_from_holder: false, + counterparty_parameters: None, + funding_outpoint: None, + channel_type_features: channel_type.clone(), + }); let pubkeys = holder_signer.pubkeys().clone(); if config.channel_handshake_config.our_to_self_delay < BREAKDOWN_TIMEOUT { @@ -8568,6 +8578,16 @@ impl OutboundV1Channel where SP::Target: SignerProvider { let channel_keys_id = signer_provider.generate_channel_keys_id(false, channel_value_satoshis, user_id); let holder_signer = signer_provider.derive_channel_signer(channel_value_satoshis, channel_keys_id); let pubkeys = holder_signer.pubkeys().clone(); + let mut tx_builder = holder_signer.derive_tx_builder(); + let channel_type = get_initial_channel_type(&config, their_features); + tx_builder.provide_holder_parameters(&ChannelTransactionParameters { + holder_pubkeys: holder_signer.pubkeys().clone(), + holder_selected_contest_delay: config.channel_handshake_config.our_to_self_delay, + is_outbound_from_holder: true, + counterparty_parameters: None, + funding_outpoint: None, + channel_type_features: channel_type.clone(), + }); let context = ChannelContext::new_for_outbound_channel( fee_estimator, diff --git a/lightning/src/sign/mod.rs b/lightning/src/sign/mod.rs index 701cac14f96..26fbda2fe7a 100644 --- a/lightning/src/sign/mod.rs +++ b/lightning/src/sign/mod.rs @@ -84,6 +84,8 @@ pub mod taproot; #[cfg(custom_tx)] pub mod tx_builder; +use tx_builder::SpecTxBuilder; + /// Information about a spendable output to a P2WSH script. /// /// See [`SpendableOutputDescriptor::DelayedPaymentOutput`] for more details on how to spend this. @@ -818,6 +820,9 @@ pub trait ChannelSigner { /// /// channel_parameters.is_populated() MUST be true. fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters); + + ///Derive a txbuilder + fn derive_tx_builder(&self) -> SpecTxBuilder; } /// Specifies the recipient of an invoice. @@ -1402,6 +1407,10 @@ impl ChannelSigner for InMemorySigner { assert!(channel_parameters.is_populated(), "Channel parameters must be fully populated"); self.channel_parameters = Some(channel_parameters.clone()); } + + fn derive_tx_builder(&self) -> SpecTxBuilder { + SpecTxBuilder::default() + } } const MISSING_PARAMS_ERR: &'static str = diff --git a/lightning/src/sign/tx_builder.rs b/lightning/src/sign/tx_builder.rs index 7c0eea99813..decbd045cc9 100644 --- a/lightning/src/sign/tx_builder.rs +++ b/lightning/src/sign/tx_builder.rs @@ -14,6 +14,10 @@ use crate::prelude::*; /// Defines a trait for types that hold the static channel parameters. pub trait ChannelParameters { + /// Provides the parameters of the channel holder. + fn provide_holder_parameters( + &mut self, channel_parameters: &ChannelTransactionParameters, + ); /// Provides the parameters of the channel counterparty. fn provide_counterparty_parameters( &mut self, channel_parameters: &CounterpartyChannelTransactionParameters, @@ -21,7 +25,7 @@ pub trait ChannelParameters { /// Provides the outpoint of the channel's funding output. fn provide_funding_outpoint(&mut self, funding_outpoint: OutPoint); - /// This may be called at any point. + /// This will be called only after the holder parameters have been provided. fn get_holder_parameters(&self) -> &ChannelTransactionParameters; /// `channel_parameters.counterparty_parameters.is_some()` MUST be true. /// This will be called only after the counterparty parameters have been provided. @@ -61,36 +65,58 @@ pub trait TxBuilder: ChannelParameters { } /// A type that builds commitment transactions according to the Lightning Specification. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct SpecTxBuilder { - channel_parameters: ChannelTransactionParameters, -} - -impl From for SpecTxBuilder { - /// May be called when only the holder channel parameters are known; the counterparty parameters and the funding - /// outpoint will be provided later. - fn from(channel_parameters: ChannelTransactionParameters) -> Self { - SpecTxBuilder { channel_parameters } - } + channel_parameters: Option, } impl ChannelParameters for SpecTxBuilder { + fn provide_holder_parameters(&mut self, channel_parameters: &ChannelTransactionParameters) { + assert!( + self.channel_parameters.is_none() + || self.channel_parameters.as_ref().unwrap() == channel_parameters + ); + if self.channel_parameters.is_some() { + // The channel parameters were already set and they match, return early. + return; + } + self.channel_parameters = Some(channel_parameters.clone()); + } fn provide_counterparty_parameters( &mut self, channel_parameters: &CounterpartyChannelTransactionParameters, ) { - todo!(); + let params = self.channel_parameters.as_mut().unwrap(); + assert!( + params.counterparty_parameters.is_none() + || params.counterparty_parameters.as_ref().unwrap() == channel_parameters + ); + if params.counterparty_parameters.is_some() { + // The channel parameters were already set and they match, return early. + return; + } + params.counterparty_parameters = Some(channel_parameters.clone()); } fn provide_funding_outpoint(&mut self, funding_outpoint: OutPoint) { - todo!(); + let params = self.channel_parameters.as_mut().unwrap(); + assert!(params.counterparty_parameters.is_some()); + assert!( + params.funding_outpoint.is_none() + || params.funding_outpoint.unwrap() == funding_outpoint + ); + if params.funding_outpoint.is_some() { + // The channel parameters were already set and they match, return early. + return; + } + params.funding_outpoint = Some(funding_outpoint); } fn get_holder_parameters(&self) -> &ChannelTransactionParameters { - todo!(); + self.channel_parameters.as_ref().unwrap() } fn get_holder_and_counterparty_parameters(&self) -> &ChannelTransactionParameters { - todo!(); + self.channel_parameters.as_ref().unwrap() } fn get_populated_parameters(&self) -> &ChannelTransactionParameters { - todo!(); + self.channel_parameters.as_ref().unwrap() } }