X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannel.rs;h=f7ea1ba552bb2c5b4979d30d5b8390bff602a149;hb=2390dbcb2236888f1a06f8b5666486eb54ace4b1;hp=5cc4f4a364bf3fe80ab15b896b51557a58acc5d1;hpb=5e577cb94afe8838a4456f4c81acb073a35e3463;p=rust-lightning diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 5cc4f4a3..f7ea1ba5 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, KeysInterface, BaseSign}; 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 + /// [`KeysInterface::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) @@ -1749,27 +1758,27 @@ impl Channel { /// our counterparty!) /// The result is a transaction which we can revoke broadcastership of (ie a "local" transaction) /// TODO Some magic rust shit to compile-time check this? - fn build_holder_transaction_keys(&self, commitment_number: u64) -> Result { + fn build_holder_transaction_keys(&self, commitment_number: u64) -> TxCreationKeys { let per_commitment_point = self.holder_signer.get_per_commitment_point(commitment_number, &self.secp_ctx); let delayed_payment_base = &self.get_holder_pubkeys().delayed_payment_basepoint; let htlc_basepoint = &self.get_holder_pubkeys().htlc_basepoint; let counterparty_pubkeys = self.get_counterparty_pubkeys(); - Ok(secp_check!(TxCreationKeys::derive_new(&self.secp_ctx, &per_commitment_point, delayed_payment_base, htlc_basepoint, &counterparty_pubkeys.revocation_basepoint, &counterparty_pubkeys.htlc_basepoint), "Local tx keys generation got bogus keys".to_owned())) + TxCreationKeys::derive_new(&self.secp_ctx, &per_commitment_point, delayed_payment_base, htlc_basepoint, &counterparty_pubkeys.revocation_basepoint, &counterparty_pubkeys.htlc_basepoint) } #[inline] /// Creates a set of keys for build_commitment_transaction to generate a transaction which we /// will sign and send to our counterparty. /// If an Err is returned, it is a ChannelError::Close (for get_outbound_funding_created) - fn build_remote_transaction_keys(&self) -> Result { + fn build_remote_transaction_keys(&self) -> TxCreationKeys { //TODO: Ensure that the payment_key derived here ends up in the library users' wallet as we //may see payments to it! let revocation_basepoint = &self.get_holder_pubkeys().revocation_basepoint; let htlc_basepoint = &self.get_holder_pubkeys().htlc_basepoint; let counterparty_pubkeys = self.get_counterparty_pubkeys(); - Ok(secp_check!(TxCreationKeys::derive_new(&self.secp_ctx, &self.counterparty_cur_commitment_point.unwrap(), &counterparty_pubkeys.delayed_payment_basepoint, &counterparty_pubkeys.htlc_basepoint, revocation_basepoint, htlc_basepoint), "Remote tx keys generation got bogus keys".to_owned())) + TxCreationKeys::derive_new(&self.secp_ctx, &self.counterparty_cur_commitment_point.unwrap(), &counterparty_pubkeys.delayed_payment_basepoint, &counterparty_pubkeys.htlc_basepoint, revocation_basepoint, htlc_basepoint) } /// Gets the redeemscript for the funding transaction output (ie the funding transaction output @@ -2157,7 +2166,7 @@ impl Channel { fn funding_created_signature(&mut self, sig: &Signature, logger: &L) -> Result<(Txid, CommitmentTransaction, Signature), ChannelError> where L::Target: Logger { let funding_script = self.get_funding_redeemscript(); - let keys = self.build_holder_transaction_keys(self.cur_holder_commitment_transaction_number)?; + let keys = self.build_holder_transaction_keys(self.cur_holder_commitment_transaction_number); let initial_commitment_tx = self.build_commitment_transaction(self.cur_holder_commitment_transaction_number, &keys, true, false, logger).tx; { let trusted_tx = initial_commitment_tx.trust(); @@ -2171,7 +2180,7 @@ impl Channel { secp_check!(self.secp_ctx.verify_ecdsa(&sighash, &sig, self.counterparty_funding_pubkey()), "Invalid funding_created signature from peer".to_owned()); } - let counterparty_keys = self.build_remote_transaction_keys()?; + let counterparty_keys = self.build_remote_transaction_keys(); let counterparty_initial_commitment_tx = self.build_commitment_transaction(self.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, false, logger).tx; let counterparty_trusted_tx = counterparty_initial_commitment_tx.trust(); @@ -2190,7 +2199,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 +2228,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 +2260,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 +2287,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())); } @@ -2285,7 +2308,7 @@ impl Channel { let funding_script = self.get_funding_redeemscript(); - let counterparty_keys = self.build_remote_transaction_keys()?; + let counterparty_keys = self.build_remote_transaction_keys(); let counterparty_initial_commitment_tx = self.build_commitment_transaction(self.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, false, logger).tx; let counterparty_trusted_tx = counterparty_initial_commitment_tx.trust(); let counterparty_initial_bitcoin_tx = counterparty_trusted_tx.built_transaction(); @@ -2293,7 +2316,7 @@ impl Channel { log_trace!(logger, "Initial counterparty tx for channel {} is: txid {} tx {}", log_bytes!(self.channel_id()), counterparty_initial_bitcoin_tx.txid, encode::serialize_hex(&counterparty_initial_bitcoin_tx.transaction)); - let holder_signer = self.build_holder_transaction_keys(self.cur_holder_commitment_transaction_number)?; + let holder_signer = self.build_holder_transaction_keys(self.cur_holder_commitment_transaction_number); let initial_commitment_tx = self.build_commitment_transaction(self.cur_holder_commitment_transaction_number, &holder_signer, true, false, logger).tx; { let trusted_tx = initial_commitment_tx.trust(); @@ -2322,7 +2345,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, @@ -2959,7 +2984,7 @@ impl Channel { let funding_script = self.get_funding_redeemscript(); - let keys = self.build_holder_transaction_keys(self.cur_holder_commitment_transaction_number).map_err(|e| (None, e))?; + let keys = self.build_holder_transaction_keys(self.cur_holder_commitment_transaction_number); let commitment_stats = self.build_commitment_transaction(self.cur_holder_commitment_transaction_number, &keys, true, false, logger); let commitment_txid = { @@ -3551,7 +3576,7 @@ impl Channel { // Before proposing a feerate update, check that we can actually afford the new fee. let inbound_stats = self.get_inbound_pending_htlc_stats(Some(feerate_per_kw)); let outbound_stats = self.get_outbound_pending_htlc_stats(Some(feerate_per_kw)); - let keys = if let Ok(keys) = self.build_holder_transaction_keys(self.cur_holder_commitment_transaction_number) { keys } else { return None; }; + let keys = self.build_holder_transaction_keys(self.cur_holder_commitment_transaction_number); let commitment_stats = self.build_commitment_transaction(self.cur_holder_commitment_transaction_number, &keys, true, true, logger); let buffer_fee_msat = Channel::::commit_tx_fee_sat(feerate_per_kw, commitment_stats.num_nondust_htlcs + outbound_stats.on_holder_tx_holding_cell_htlcs_count as usize + CONCURRENT_INBOUND_HTLC_FEE_BUFFER as usize, self.opt_anchors()) * 1000; let holder_balance_msat = commitment_stats.local_balance_msat - outbound_stats.holding_cell_msat; @@ -5221,7 +5246,7 @@ impl Channel { /// If an Err is returned, it is a ChannelError::Close (for get_outbound_funding_created) fn get_outbound_funding_created_signature(&mut self, logger: &L) -> Result where L::Target: Logger { - let counterparty_keys = self.build_remote_transaction_keys()?; + let counterparty_keys = self.build_remote_transaction_keys(); let counterparty_initial_commitment_tx = self.build_commitment_transaction(self.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, false, logger).tx; Ok(self.holder_signer.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), &self.secp_ctx) .map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0) @@ -5248,7 +5273,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, @@ -5522,7 +5547,7 @@ impl Channel { return Err(ChannelError::Ignore(format!("Cannot send value that would put us over the max HTLC value in flight our peer will accept ({})", self.counterparty_max_htlc_value_in_flight_msat))); } - let keys = self.build_holder_transaction_keys(self.cur_holder_commitment_transaction_number)?; + let keys = self.build_holder_transaction_keys(self.cur_holder_commitment_transaction_number); let commitment_stats = self.build_commitment_transaction(self.cur_holder_commitment_transaction_number, &keys, true, true, logger); if !self.is_outbound() { // Check that we won't violate the remote channel reserve by adding this HTLC. @@ -5714,7 +5739,7 @@ impl Channel { /// Only fails in case of bad keys. Used for channel_reestablish commitment_signed generation /// when we shouldn't change HTLC/channel state. fn send_commitment_no_state_update(&self, logger: &L) -> Result<(msgs::CommitmentSigned, (Txid, Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)>)), ChannelError> where L::Target: Logger { - let counterparty_keys = self.build_remote_transaction_keys()?; + let counterparty_keys = self.build_remote_transaction_keys(); let commitment_stats = self.build_commitment_transaction(self.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, true, logger); let counterparty_commitment_txid = commitment_stats.tx.trust().txid(); let (signature, htlc_signatures); @@ -5922,19 +5947,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 +6022,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 +6304,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(()) @@ -6314,16 +6341,20 @@ impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<::read(reader) { @@ -6541,6 +6572,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 +6592,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 +6760,7 @@ impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel< 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 get_secure_random_bytes(&self) -> [u8; 32] { [0; 32] } @@ -7018,10 +7071,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 +7344,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()[..]); @@ -7309,7 +7362,7 @@ mod tests { let per_commitment_secret = SecretKey::from_slice(&hex::decode("1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100").unwrap()[..]).unwrap(); let per_commitment_point = PublicKey::from_secret_key(&secp_ctx, &per_commitment_secret); let htlc_basepoint = &chan.holder_signer.pubkeys().htlc_basepoint; - let keys = TxCreationKeys::derive_new(&secp_ctx, &per_commitment_point, delayed_payment_base, htlc_basepoint, &counterparty_pubkeys.revocation_basepoint, &counterparty_pubkeys.htlc_basepoint).unwrap(); + let keys = TxCreationKeys::derive_new(&secp_ctx, &per_commitment_point, delayed_payment_base, htlc_basepoint, &counterparty_pubkeys.revocation_basepoint, &counterparty_pubkeys.htlc_basepoint); macro_rules! test_commitment { ( $counterparty_sig_hex: expr, $sig_hex: expr, $tx_hex: expr, $($remain:tt)* ) => { @@ -7962,16 +8015,16 @@ mod tests { let per_commitment_point = PublicKey::from_secret_key(&secp_ctx, &per_commitment_secret); assert_eq!(per_commitment_point.serialize()[..], hex::decode("025f7117a78150fe2ef97db7cfc83bd57b2e2c0d0dd25eaf467a4a1c2a45ce1486").unwrap()[..]); - assert_eq!(chan_utils::derive_public_key(&secp_ctx, &per_commitment_point, &base_point).unwrap().serialize()[..], + assert_eq!(chan_utils::derive_public_key(&secp_ctx, &per_commitment_point, &base_point).serialize()[..], hex::decode("0235f2dbfaa89b57ec7b055afe29849ef7ddfeb1cefdb9ebdc43f5494984db29e5").unwrap()[..]); - assert_eq!(chan_utils::derive_private_key(&secp_ctx, &per_commitment_point, &base_secret).unwrap(), + assert_eq!(chan_utils::derive_private_key(&secp_ctx, &per_commitment_point, &base_secret), SecretKey::from_slice(&hex::decode("cbced912d3b21bf196a766651e436aff192362621ce317704ea2f75d87e7be0f").unwrap()[..]).unwrap()); - assert_eq!(chan_utils::derive_public_revocation_key(&secp_ctx, &per_commitment_point, &base_point).unwrap().serialize()[..], + assert_eq!(chan_utils::derive_public_revocation_key(&secp_ctx, &per_commitment_point, &base_point).serialize()[..], hex::decode("02916e326636d19c33f13e8c0c3a03dd157f332f3e99c317c141dd865eb01f8ff0").unwrap()[..]); - assert_eq!(chan_utils::derive_private_revocation_key(&secp_ctx, &per_commitment_secret, &base_secret).unwrap(), + assert_eq!(chan_utils::derive_private_revocation_key(&secp_ctx, &per_commitment_secret, &base_secret), SecretKey::from_slice(&hex::decode("d09ffff62ddb2297ab000cc85bcb4283fdeb6aa052affbc9dddcf33b61078110").unwrap()[..]).unwrap()); }