X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannel.rs;h=81372ee3da862cb35908da437e2a2fe578ef75f2;hb=607cd6f523179d49452b7c9a525a75f350b2a63a;hp=cd6448d088cdec223c3927dafbfcde2eff270e06;hpb=b04d1b868fe28bea2e4c711e6e6d2470d2b98d77;p=rust-lightning diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index cd6448d0..81372ee3 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -34,7 +34,7 @@ use crate::chain::BestBlock; use crate::chain::chaininterface::{FeeEstimator, ConfirmationTarget, LowerBoundedFeeEstimator}; use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, LATENCY_GRACE_PERIOD_BLOCKS}; use crate::chain::transaction::{OutPoint, TransactionData}; -use crate::chain::keysinterface::{Sign, KeysInterface}; +use crate::chain::keysinterface::{Sign, KeysInterface, BaseSign}; use crate::util::events::ClosureReason; use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer, VecWriter}; use crate::util::logger::Logger; @@ -737,6 +737,10 @@ pub(super) struct Channel { // We track whether we already emitted a `ChannelReady` event. channel_ready_event_emitted: bool, + + /// The unique identifier used to re-derive the private key material for the channel through + /// [`KeysInterface::derive_channel_signer`]. + channel_keys_id: [u8; 32], } #[cfg(any(test, fuzzing))] @@ -1072,6 +1076,7 @@ impl Channel { historical_inbound_htlc_fulfills: HashSet::new(), channel_type: Self::get_initial_channel_type(&config), + channel_keys_id, }) } @@ -1419,6 +1424,7 @@ impl Channel { historical_inbound_htlc_fulfills: HashSet::new(), channel_type, + channel_keys_id, }; Ok(chan) @@ -2192,7 +2198,13 @@ impl Channel { &self.get_counterparty_pubkeys().funding_pubkey } - pub fn funding_created(&mut self, msg: &msgs::FundingCreated, best_block: BestBlock, logger: &L) -> Result<(msgs::FundingSigned, ChannelMonitor, Option), ChannelError> where L::Target: Logger { + pub fn funding_created( + &mut self, msg: &msgs::FundingCreated, best_block: BestBlock, keys_source: &K, logger: &L + ) -> Result<(msgs::FundingSigned, ChannelMonitor<::Signer>, Option), ChannelError> + where + K::Target: KeysInterface, + L::Target: Logger + { if self.is_outbound() { return Err(ChannelError::Close("Received funding_created for an outbound channel?".to_owned())); } @@ -2215,7 +2227,7 @@ impl Channel { self.channel_transaction_parameters.funding_outpoint = Some(funding_txo); // This is an externally observable change before we finish all our checks. In particular // funding_created_signature may fail. - self.holder_signer.ready_channel(&self.channel_transaction_parameters); + self.holder_signer.provide_channel_parameters(&self.channel_transaction_parameters); let (counterparty_initial_commitment_txid, initial_commitment_tx, signature) = match self.funding_created_signature(&msg.signature, logger) { Ok(res) => res, @@ -2247,7 +2259,9 @@ impl Channel { let funding_txo_script = funding_redeemscript.to_v0_p2wsh(); let obscure_factor = get_commitment_transaction_number_obscure_factor(&self.get_holder_pubkeys().payment_point, &self.get_counterparty_pubkeys().payment_point, self.is_outbound()); let shutdown_script = self.shutdown_scriptpubkey.clone().map(|script| script.into_inner()); - let channel_monitor = ChannelMonitor::new(self.secp_ctx.clone(), self.holder_signer.clone(), + let mut monitor_signer = keys_source.derive_channel_signer(self.channel_value_satoshis, self.channel_keys_id); + monitor_signer.provide_channel_parameters(&self.channel_transaction_parameters); + let channel_monitor = ChannelMonitor::new(self.secp_ctx.clone(), monitor_signer, shutdown_script, self.get_holder_selected_contest_delay(), &self.destination_script, (funding_txo, funding_txo_script.clone()), &self.channel_transaction_parameters, @@ -2272,7 +2286,13 @@ impl Channel { /// Handles a funding_signed message from the remote end. /// If this call is successful, broadcast the funding transaction (and not before!) - pub fn funding_signed(&mut self, msg: &msgs::FundingSigned, best_block: BestBlock, logger: &L) -> Result<(ChannelMonitor, Transaction, Option), ChannelError> where L::Target: Logger { + pub fn funding_signed( + &mut self, msg: &msgs::FundingSigned, best_block: BestBlock, keys_source: &K, logger: &L + ) -> Result<(ChannelMonitor<::Signer>, Transaction, Option), ChannelError> + where + K::Target: KeysInterface, + L::Target: Logger + { if !self.is_outbound() { return Err(ChannelError::Close("Received funding_signed for an inbound channel?".to_owned())); } @@ -2324,7 +2344,9 @@ impl Channel { let funding_txo_script = funding_redeemscript.to_v0_p2wsh(); let obscure_factor = get_commitment_transaction_number_obscure_factor(&self.get_holder_pubkeys().payment_point, &self.get_counterparty_pubkeys().payment_point, self.is_outbound()); let shutdown_script = self.shutdown_scriptpubkey.clone().map(|script| script.into_inner()); - let channel_monitor = ChannelMonitor::new(self.secp_ctx.clone(), self.holder_signer.clone(), + let mut monitor_signer = keys_source.derive_channel_signer(self.channel_value_satoshis, self.channel_keys_id); + monitor_signer.provide_channel_parameters(&self.channel_transaction_parameters); + let channel_monitor = ChannelMonitor::new(self.secp_ctx.clone(), monitor_signer, shutdown_script, self.get_holder_selected_contest_delay(), &self.destination_script, (funding_txo, funding_txo_script), &self.channel_transaction_parameters, @@ -5250,7 +5272,7 @@ impl Channel { } self.channel_transaction_parameters.funding_outpoint = Some(funding_txo); - self.holder_signer.ready_channel(&self.channel_transaction_parameters); + self.holder_signer.provide_channel_parameters(&self.channel_transaction_parameters); let signature = match self.get_outbound_funding_created_signature(logger) { Ok(res) => res, @@ -5936,7 +5958,7 @@ impl Channel { } } -const SERIALIZATION_VERSION: u8 = 2; +const SERIALIZATION_VERSION: u8 = 3; const MIN_SERIALIZATION_VERSION: u8 = 2; impl_writeable_tlv_based_enum!(InboundHTLCRemovalReason,; @@ -5998,7 +6020,7 @@ impl Writeable for Channel { // Note that we write out as if remove_uncommitted_htlcs_and_mark_paused had just been // called. - write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION); + write_ver_prefix!(writer, MIN_SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION); // `user_id` used to be a single u64 value. In order to remain backwards compatible with // versions prior to 0.0.113, the u128 is serialized as two separate u64 values. We write @@ -6280,6 +6302,7 @@ impl Writeable for Channel { (21, self.outbound_scid_alias, required), (23, channel_ready_event_emitted, option), (25, user_id_high_opt, option), + (27, self.channel_keys_id, required), }); Ok(()) @@ -6316,16 +6339,20 @@ impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<::read(reader) { @@ -6543,6 +6570,7 @@ impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel< = None; + let mut channel_keys_id: Option<[u8; 32]> = None; read_tlv_fields!(reader, { (0, announcement_sigs, option), @@ -6562,8 +6590,25 @@ impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<= (ChannelState::FundingCreated as u32) { + holder_signer.provide_channel_parameters(&channel_parameters); + } + (channel_keys_id, holder_signer) + } else { + // `keys_data` can be `None` if we had corrupted data. + let keys_data = keys_data.ok_or(DecodeError::InvalidValue)?; + let holder_signer = keys_source.read_chan_signer(&keys_data)?; + (holder_signer.channel_keys_id(), holder_signer) + }; + if let Some(preimages) = preimages_opt { let mut iter = preimages.into_iter(); for htlc in pending_outbound_htlcs.iter_mut() { @@ -6713,6 +6758,7 @@ impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel< Node A: funding signed - let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&logger); + let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, &&logger); // Now disconnect the two nodes and check that the commitment point in // Node B's channel_reestablish message is sane. @@ -7296,7 +7342,7 @@ mod tests { selected_contest_delay: 144 }); chan.channel_transaction_parameters.funding_outpoint = Some(funding_info); - signer.ready_channel(&chan.channel_transaction_parameters); + signer.provide_channel_parameters(&chan.channel_transaction_parameters); assert_eq!(counterparty_pubkeys.payment_point.serialize()[..], hex::decode("032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991").unwrap()[..]);