X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannel.rs;h=76dc15065c05cd298b532247de377b757ce5491f;hb=9e7c02cd125cba991e1b757a5a59c6d4a230280e;hp=dcbaa771f93e1f1798dccb0d7c8eea47a0d80498;hpb=14d2e979651769bfff7acb6fed33b0e7df509d9a;p=rust-lightning diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index dcbaa771..76dc1506 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -27,14 +27,15 @@ use crate::ln::features::{ChannelTypeFeatures, InitFeatures}; use crate::ln::msgs; use crate::ln::msgs::{DecodeError, OptionalField, DataLossProtect}; use crate::ln::script::{self, ShutdownScript}; -use crate::ln::channelmanager::{self, CounterpartyForwardingInfo, PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, MAX_LOCAL_BREAKDOWN_TIMEOUT}; +use crate::ln::channelmanager::{self, CounterpartyForwardingInfo, PendingHTLCStatus, HTLCSource, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, MAX_LOCAL_BREAKDOWN_TIMEOUT}; use crate::ln::chan_utils::{CounterpartyCommitmentSecrets, TxCreationKeys, HTLCOutputInCommitment, htlc_success_tx_weight, htlc_timeout_tx_weight, make_funding_redeemscript, ChannelPublicKeys, CommitmentTransaction, HolderCommitmentTransaction, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, MAX_HTLCS, get_commitment_transaction_number_obscure_factor, ClosingTransaction}; use crate::ln::chan_utils; +use crate::ln::onion_utils::HTLCFailReason; 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, EntropySource, KeysInterface, BaseSign, SignerProvider}; use crate::util::events::ClosureReason; use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer, VecWriter}; use crate::util::logger::Logger; @@ -737,6 +738,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 + /// [`SignerProvider::derive_channel_signer`]. + channel_keys_id: [u8; 32], } #[cfg(any(test, fuzzing))] @@ -909,7 +914,8 @@ impl Channel { let opt_anchors = false; // TODO - should be based on features let holder_selected_contest_delay = config.channel_handshake_config.our_to_self_delay; - let holder_signer = keys_provider.get_channel_signer(false, channel_value_satoshis); + let channel_keys_id = keys_provider.generate_channel_keys_id(false, channel_value_satoshis, user_id); + let holder_signer = keys_provider.derive_channel_signer(channel_value_satoshis, channel_keys_id); let pubkeys = holder_signer.pubkeys().clone(); if !their_features.supports_wumbo() && channel_value_satoshis > MAX_FUNDING_SATOSHIS_NO_WUMBO { @@ -1071,6 +1077,7 @@ impl Channel { historical_inbound_htlc_fulfills: HashSet::new(), channel_type: Self::get_initial_channel_type(&config), + channel_keys_id, }) } @@ -1153,7 +1160,8 @@ impl Channel { return Err(ChannelError::Close("Channel Type was not understood - we require static remote key".to_owned())); } - let holder_signer = keys_provider.get_channel_signer(true, msg.funding_satoshis); + let channel_keys_id = keys_provider.generate_channel_keys_id(true, msg.funding_satoshis, user_id); + let holder_signer = keys_provider.derive_channel_signer(msg.funding_satoshis, channel_keys_id); let pubkeys = holder_signer.pubkeys().clone(); let counterparty_pubkeys = ChannelPublicKeys { funding_pubkey: msg.funding_pubkey, @@ -1417,6 +1425,7 @@ impl Channel { historical_inbound_htlc_fulfills: HashSet::new(), channel_type, + channel_keys_id, }; Ok(chan) @@ -1946,9 +1955,26 @@ impl Channel { /// an HTLC more than once or fulfill once and then attempt to fail after reconnect. We cannot, /// however, fail more than once as we wait for an upstream failure to be irrevocably committed /// before we fail backwards. - /// If we do fail twice, we debug_assert!(false) and return Ok(None). Thus, will always return - /// Ok(_) if debug assertions are turned on or preconditions are met. - pub fn get_update_fail_htlc(&mut self, htlc_id_arg: u64, err_packet: msgs::OnionErrorPacket, logger: &L) -> Result, ChannelError> where L::Target: Logger { + /// + /// If we do fail twice, we `debug_assert!(false)` and return `Ok(None)`. Thus, this will always + /// return `Ok(_)` if preconditions are met. In any case, `Err`s will only be + /// [`ChannelError::Ignore`]. + pub fn queue_fail_htlc(&mut self, htlc_id_arg: u64, err_packet: msgs::OnionErrorPacket, logger: &L) + -> Result<(), ChannelError> where L::Target: Logger { + self.fail_htlc(htlc_id_arg, err_packet, true, logger) + .map(|msg_opt| assert!(msg_opt.is_none(), "We forced holding cell?")) + } + + /// We can only have one resolution per HTLC. In some cases around reconnect, we may fulfill + /// an HTLC more than once or fulfill once and then attempt to fail after reconnect. We cannot, + /// however, fail more than once as we wait for an upstream failure to be irrevocably committed + /// before we fail backwards. + /// + /// If we do fail twice, we `debug_assert!(false)` and return `Ok(None)`. Thus, this will always + /// return `Ok(_)` if preconditions are met. In any case, `Err`s will only be + /// [`ChannelError::Ignore`]. + fn fail_htlc(&mut self, htlc_id_arg: u64, err_packet: msgs::OnionErrorPacket, mut force_holding_cell: bool, logger: &L) + -> Result, ChannelError> where L::Target: Logger { if (self.channel_state & (ChannelState::ChannelReady as u32)) != (ChannelState::ChannelReady as u32) { panic!("Was asked to fail an HTLC when channel was not in an operational state"); } @@ -1986,8 +2012,13 @@ impl Channel { return Ok(None); } - // Now update local state: if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateInProgress as u32)) != 0 { + debug_assert!(force_holding_cell, "!force_holding_cell is only called when emptying the holding cell, so we shouldn't end up back in it!"); + force_holding_cell = true; + } + + // Now update local state: + if force_holding_cell { for pending_update in self.holding_cell_htlc_updates.iter() { match pending_update { &HTLCUpdateAwaitingACK::ClaimHTLC { htlc_id, .. } => { @@ -2190,7 +2221,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())); } @@ -2213,7 +2250,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, @@ -2245,7 +2282,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, @@ -2270,7 +2309,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())); } @@ -2322,7 +2367,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, @@ -3146,8 +3193,8 @@ impl Channel { } else { Ok((None, Vec::new())) } } - /// Used to fulfill holding_cell_htlcs when we get a remote ack (or implicitly get it by them - /// fulfilling or failing the last pending HTLC) + /// Frees any pending commitment updates in the holding cell, generating the relevant messages + /// for our counterparty. fn free_holding_cell_htlcs(&mut self, logger: &L) -> Result<(Option<(msgs::CommitmentUpdate, ChannelMonitorUpdate)>, Vec<(HTLCSource, PaymentHash)>), ChannelError> where L::Target: Logger { assert_eq!(self.channel_state & ChannelState::MonitorUpdateInProgress as u32, 0); if self.holding_cell_htlc_updates.len() != 0 || self.holding_cell_update_fee.is_some() { @@ -3173,7 +3220,7 @@ impl Channel { // to rebalance channels. match &htlc_update { &HTLCUpdateAwaitingACK::AddHTLC {amount_msat, cltv_expiry, ref payment_hash, ref source, ref onion_routing_packet, ..} => { - match self.send_htlc(amount_msat, *payment_hash, cltv_expiry, source.clone(), onion_routing_packet.clone(), logger) { + match self.send_htlc(amount_msat, *payment_hash, cltv_expiry, source.clone(), onion_routing_packet.clone(), false, logger) { Ok(update_add_msg_option) => update_add_htlcs.push(update_add_msg_option.unwrap()), Err(e) => { match e { @@ -3209,13 +3256,13 @@ impl Channel { monitor_update.updates.append(&mut additional_monitor_update.updates); }, &HTLCUpdateAwaitingACK::FailHTLC { htlc_id, ref err_packet } => { - match self.get_update_fail_htlc(htlc_id, err_packet.clone(), logger) { + match self.fail_htlc(htlc_id, err_packet.clone(), false, logger) { Ok(update_fail_msg_option) => { // If an HTLC failure was previously added to the holding cell (via - // `get_update_fail_htlc`) then generating the fail message itself - // must not fail - we should never end up in a state where we - // double-fail an HTLC or fail-then-claim an HTLC as it indicates - // we didn't wait for a full revocation before failing. + // `queue_fail_htlc`) then generating the fail message itself must + // not fail - we should never end up in a state where we double-fail + // an HTLC or fail-then-claim an HTLC as it indicates we didn't wait + // for a full revocation before failing. update_fail_htlcs.push(update_fail_msg_option.unwrap()) }, Err(e) => { @@ -3232,7 +3279,7 @@ impl Channel { return Ok((None, htlcs_to_fail)); } let update_fee = if let Some(feerate) = self.holding_cell_update_fee.take() { - self.send_update_fee(feerate, logger) + self.send_update_fee(feerate, false, logger) } else { None }; @@ -3532,12 +3579,22 @@ impl Channel { } } + /// Queues up an outbound update fee by placing it in the holding cell. You should call + /// [`Self::maybe_free_holding_cell_htlcs`] in order to actually generate and send the + /// commitment update. + pub fn queue_update_fee(&mut self, feerate_per_kw: u32, logger: &L) where L::Target: Logger { + let msg_opt = self.send_update_fee(feerate_per_kw, true, logger); + assert!(msg_opt.is_none(), "We forced holding cell?"); + } + /// Adds a pending update to this channel. See the doc for send_htlc for /// further details on the optionness of the return value. /// If our balance is too low to cover the cost of the next commitment transaction at the /// new feerate, the update is cancelled. - /// You MUST call send_commitment prior to any other calls on this Channel - fn send_update_fee(&mut self, feerate_per_kw: u32, logger: &L) -> Option where L::Target: Logger { + /// + /// You MUST call [`Self::send_commitment_no_state_update`] prior to any other calls on this + /// [`Channel`] if `force_holding_cell` is false. + fn send_update_fee(&mut self, feerate_per_kw: u32, mut force_holding_cell: bool, logger: &L) -> Option where L::Target: Logger { if !self.is_outbound() { panic!("Cannot send fee from inbound channel"); } @@ -3574,6 +3631,10 @@ impl Channel { } if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::MonitorUpdateInProgress as u32)) != 0 { + force_holding_cell = true; + } + + if force_holding_cell { self.holding_cell_update_fee = Some(feerate_per_kw); return None; } @@ -3587,16 +3648,6 @@ impl Channel { }) } - pub fn send_update_fee_and_commit(&mut self, feerate_per_kw: u32, logger: &L) -> Result, ChannelError> where L::Target: Logger { - match self.send_update_fee(feerate_per_kw, logger) { - Some(update_fee) => { - let (commitment_signed, monitor_update) = self.send_commitment_no_status_check(logger)?; - Ok(Some((update_fee, commitment_signed, monitor_update))) - }, - None => Ok(None) - } - } - /// Removes any uncommitted inbound HTLCs and resets the state of uncommitted outbound HTLC /// updates, to be used on peer disconnection. After this, update_*_htlc messages need to be /// resent. @@ -5248,7 +5299,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, @@ -5470,8 +5521,26 @@ impl Channel { // Send stuff to our remote peers: + /// Queues up an outbound HTLC to send by placing it in the holding cell. You should call + /// [`Self::maybe_free_holding_cell_htlcs`] in order to actually generate and send the + /// commitment update. + /// + /// `Err`s will only be [`ChannelError::Ignore`]. + pub fn queue_add_htlc(&mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, + onion_routing_packet: msgs::OnionPacket, logger: &L) + -> Result<(), ChannelError> where L::Target: Logger { + self + .send_htlc(amount_msat, payment_hash, cltv_expiry, source, onion_routing_packet, true, logger) + .map(|msg_opt| assert!(msg_opt.is_none(), "We forced holding cell?")) + .map_err(|err| { + if let ChannelError::Ignore(_) = err { /* fine */ } + else { debug_assert!(false, "Queueing cannot trigger channel failure"); } + err + }) + } + /// Adds a pending outbound HTLC to this channel, note that you probably want - /// send_htlc_and_commit instead cause you'll want both messages at once. + /// [`Self::send_htlc_and_commit`] instead cause you'll want both messages at once. /// /// This returns an optional UpdateAddHTLC as we may be in a state where we cannot add HTLCs on /// the wire: @@ -5482,10 +5551,13 @@ impl Channel { /// we may not yet have sent the previous commitment update messages and will need to /// regenerate them. /// - /// You MUST call send_commitment prior to calling any other methods on this Channel! + /// You MUST call [`Self::send_commitment_no_state_update`] prior to calling any other methods + /// on this [`Channel`] if `force_holding_cell` is false. /// - /// If an Err is returned, it's a ChannelError::Ignore! - pub fn send_htlc(&mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, onion_routing_packet: msgs::OnionPacket, logger: &L) -> Result, ChannelError> where L::Target: Logger { + /// `Err`s will only be [`ChannelError::Ignore`]. + fn send_htlc(&mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, + onion_routing_packet: msgs::OnionPacket, mut force_holding_cell: bool, logger: &L) + -> Result, ChannelError> where L::Target: Logger { if (self.channel_state & (ChannelState::ChannelReady as u32 | BOTH_SIDES_SHUTDOWN_MASK)) != (ChannelState::ChannelReady as u32) { return Err(ChannelError::Ignore("Cannot send HTLC until channel is fully established and we haven't started shutting down".to_owned())); } @@ -5580,8 +5652,12 @@ impl Channel { return Err(ChannelError::Ignore(format!("Cannot send value that would put our balance under counterparty-announced channel reserve value ({})", chan_reserve_msat))); } - // Now update local state: if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::MonitorUpdateInProgress as u32)) != 0 { + force_holding_cell = true; + } + + // Now update local state: + if force_holding_cell { self.holding_cell_htlc_updates.push(HTLCUpdateAwaitingACK::AddHTLC { amount_msat, payment_hash, @@ -5614,41 +5690,6 @@ impl Channel { Ok(Some(res)) } - /// Creates a signed commitment transaction to send to the remote peer. - /// Always returns a ChannelError::Close if an immediately-preceding (read: the - /// last call to this Channel) send_htlc returned Ok(Some(_)) and there is an Err. - /// May panic if called except immediately after a successful, Ok(Some(_))-returning send_htlc. - pub fn send_commitment(&mut self, logger: &L) -> Result<(msgs::CommitmentSigned, ChannelMonitorUpdate), ChannelError> where L::Target: Logger { - if (self.channel_state & (ChannelState::ChannelReady as u32)) != (ChannelState::ChannelReady as u32) { - panic!("Cannot create commitment tx until channel is fully established"); - } - if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) == (ChannelState::AwaitingRemoteRevoke as u32) { - panic!("Cannot create commitment tx until remote revokes their previous commitment"); - } - if (self.channel_state & (ChannelState::PeerDisconnected as u32)) == (ChannelState::PeerDisconnected as u32) { - panic!("Cannot create commitment tx while disconnected, as send_htlc will have returned an Err so a send_commitment precondition has been violated"); - } - if (self.channel_state & (ChannelState::MonitorUpdateInProgress as u32)) == (ChannelState::MonitorUpdateInProgress as u32) { - panic!("Cannot create commitment tx while awaiting monitor update unfreeze, as send_htlc will have returned an Err so a send_commitment precondition has been violated"); - } - let mut have_updates = self.is_outbound() && self.pending_update_fee.is_some(); - for htlc in self.pending_outbound_htlcs.iter() { - if let OutboundHTLCState::LocalAnnounced(_) = htlc.state { - have_updates = true; - } - if have_updates { break; } - } - for htlc in self.pending_inbound_htlcs.iter() { - if let InboundHTLCState::LocalRemoved(_) = htlc.state { - have_updates = true; - } - if have_updates { break; } - } - if !have_updates { - panic!("Cannot create commitment tx until we have some updates to send"); - } - self.send_commitment_no_status_check(logger) - } /// Only fails in case of bad keys fn send_commitment_no_status_check(&mut self, logger: &L) -> Result<(msgs::CommitmentSigned, ChannelMonitorUpdate), ChannelError> where L::Target: Logger { log_trace!(logger, "Updating HTLC state for a newly-sent commitment_signed..."); @@ -5771,10 +5812,11 @@ impl Channel { /// Adds a pending outbound HTLC to this channel, and creates a signed commitment transaction /// to send to the remote peer in one go. - /// Shorthand for calling send_htlc() followed by send_commitment(), see docs on those for - /// more info. + /// + /// Shorthand for calling [`Self::send_htlc`] followed by a commitment update, see docs on + /// [`Self::send_htlc`] and [`Self::send_commitment_no_state_update`] for more info. pub fn send_htlc_and_commit(&mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, onion_routing_packet: msgs::OnionPacket, logger: &L) -> Result, ChannelError> where L::Target: Logger { - match self.send_htlc(amount_msat, payment_hash, cltv_expiry, source, onion_routing_packet, logger)? { + match self.send_htlc(amount_msat, payment_hash, cltv_expiry, source, onion_routing_packet, false, logger)? { Some(update_add_htlc) => { let (commitment_signed, monitor_update) = self.send_commitment_no_status_check(logger)?; Ok(Some((update_add_htlc, commitment_signed, monitor_update))) @@ -5922,19 +5964,20 @@ impl Channel { (monitor_update, dropped_outbound_htlcs) } - pub fn inflight_htlc_sources(&self) -> impl Iterator { + pub fn inflight_htlc_sources(&self) -> impl Iterator { self.holding_cell_htlc_updates.iter() .flat_map(|htlc_update| { match htlc_update { - HTLCUpdateAwaitingACK::AddHTLC { source, .. } => { Some(source) } - _ => None + HTLCUpdateAwaitingACK::AddHTLC { source, payment_hash, .. } + => Some((source, payment_hash)), + _ => None, } }) - .chain(self.pending_outbound_htlcs.iter().map(|htlc| &htlc.source)) + .chain(self.pending_outbound_htlcs.iter().map(|htlc| (&htlc.source, &htlc.payment_hash))) } } -const SERIALIZATION_VERSION: u8 = 2; +const SERIALIZATION_VERSION: u8 = 3; const MIN_SERIALIZATION_VERSION: u8 = 2; impl_writeable_tlv_based_enum!(InboundHTLCRemovalReason,; @@ -5996,7 +6039,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 @@ -6278,6 +6321,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(()) @@ -6285,7 +6329,7 @@ impl Writeable for Channel { } const MAX_ALLOC_SIZE: usize = 64*1024; -impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<::Signer> +impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<::Signer> where K::Target: KeysInterface { fn read(reader: &mut R, args: (&'a K, u32)) -> Result { let (keys_source, serialized_height) = args; @@ -6314,16 +6358,20 @@ impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<::read(reader) { @@ -6541,6 +6589,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), @@ -6560,8 +6609,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() { @@ -6711,6 +6777,7 @@ impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel< [u8; 32] { [0; 32] } + } + + impl NodeSigner for Keys { fn get_node_secret(&self, _recipient: Recipient) -> Result { panic!(); } + + fn get_node_id(&self, recipient: Recipient) -> Result { + let secp_ctx = Secp256k1::signing_only(); + Ok(PublicKey::from_secret_key(&secp_ctx, &self.get_node_secret(recipient)?)) + } + fn ecdh(&self, _recipient: Recipient, _other_key: &PublicKey, _tweak: Option<&Scalar>) -> Result { panic!(); } + fn get_inbound_payment_key_material(&self) -> KeyMaterial { panic!(); } + + fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result { panic!(); } + } + + impl SignerProvider for Keys { + type Signer = 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 { + self.signer.clone() + } + + fn read_chan_signer(&self, _data: &[u8]) -> Result { panic!(); } + fn get_destination_script(&self) -> Script { let secp_ctx = Secp256k1::signing_only(); let channel_monitor_claim_key = SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(); @@ -6802,15 +6896,10 @@ mod tests { let channel_close_key = SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(); ShutdownScript::new_p2wpkh_from_pubkey(PublicKey::from_secret_key(&secp_ctx, &channel_close_key)) } - - fn get_channel_signer(&self, _inbound: bool, _channel_value_satoshis: u64) -> InMemorySigner { - self.signer.clone() - } - fn get_secure_random_bytes(&self) -> [u8; 32] { [0; 32] } - fn read_chan_signer(&self, _data: &[u8]) -> Result { panic!(); } - fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result { panic!(); } } + impl KeysInterface for Keys {} + #[cfg(not(feature = "grind_signatures"))] fn public_from_secret_hex(secp_ctx: &Secp256k1, hex: &str) -> PublicKey { PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&hex::decode(hex).unwrap()[..]).unwrap()) @@ -7018,10 +7107,10 @@ mod tests { }]}; let funding_outpoint = OutPoint{ txid: tx.txid(), index: 0 }; let funding_created_msg = node_a_chan.get_outbound_funding_created(tx.clone(), funding_outpoint, &&logger).unwrap(); - let (funding_signed_msg, _, _) = node_b_chan.funding_created(&funding_created_msg, best_block, &&logger).unwrap(); + let (funding_signed_msg, _, _) = node_b_chan.funding_created(&funding_created_msg, best_block, &&keys_provider, &&logger).unwrap(); // Node B --> 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. @@ -7291,7 +7380,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()[..]);