Bound incoming HTLC witnessScript to min/max limits
[rust-lightning] / lightning / src / ln / channel.rs
index e3edc0e9a98d1b5dfcdcdf24592f01c48fdc0f88..030254fa0db95ce34e53ce6ce0da45e2324ee453 100644 (file)
@@ -4,7 +4,7 @@ use bitcoin::blockdata::transaction::{TxIn, TxOut, Transaction, SigHashType};
 use bitcoin::blockdata::opcodes;
 use bitcoin::util::hash::BitcoinHash;
 use bitcoin::util::bip143;
-use bitcoin::consensus::encode::{self, Encodable, Decodable};
+use bitcoin::consensus::encode;
 
 use bitcoin_hashes::{Hash, HashEngine};
 use bitcoin_hashes::sha256::Hash as Sha256;
@@ -19,13 +19,13 @@ use ln::msgs;
 use ln::msgs::{DecodeError, OptionalField, LocalFeatures, DataLossProtect};
 use ln::channelmonitor::ChannelMonitor;
 use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingForwardHTLCInfo, RAACommitmentOrder, PaymentPreimage, PaymentHash, BREAKDOWN_TIMEOUT, MAX_LOCAL_BREAKDOWN_TIMEOUT};
-use ln::chan_utils::{TxCreationKeys,HTLCOutputInCommitment,HTLC_SUCCESS_TX_WEIGHT,HTLC_TIMEOUT_TX_WEIGHT};
+use ln::chan_utils::{LocalCommitmentTransaction,TxCreationKeys,HTLCOutputInCommitment,HTLC_SUCCESS_TX_WEIGHT,HTLC_TIMEOUT_TX_WEIGHT};
 use ln::chan_utils;
 use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
 use chain::transaction::OutPoint;
 use chain::keysinterface::{ChannelKeys, KeysInterface};
 use util::transaction_utils;
-use util::ser::{Readable, ReadableArgs, Writeable, Writer, WriterWriteAdaptor};
+use util::ser::{Readable, ReadableArgs, Writeable, Writer};
 use util::logger::{Logger, LogHolder};
 use util::errors::APIError;
 use util::config::{UserConfig,ChannelConfig};
@@ -228,7 +228,7 @@ enum UpdateStatus {
 // has been completed, and then turn into a Channel to get compiler-time enforcement of things like
 // calling channel_id() before we're set up or things like get_outbound_funding_signed on an
 // inbound channel.
-pub(super) struct Channel {
+pub(super) struct Channel<ChanSigner: ChannelKeys> {
        config: ChannelConfig,
 
        user_id: u64,
@@ -239,7 +239,7 @@ pub(super) struct Channel {
        secp_ctx: Secp256k1<secp256k1::All>,
        channel_value_satoshis: u64,
 
-       local_keys: ChannelKeys,
+       local_keys: ChanSigner,
        shutdown_pubkey: PublicKey,
 
        // Our commitment numbers start at 2^48-1 and count down, whereas the ones used in transaction
@@ -297,13 +297,7 @@ pub(super) struct Channel {
        /// Max to_local and to_remote outputs in a remote-generated commitment transaction
        max_commitment_tx_output_remote: ::std::sync::Mutex<(u64, u64)>,
 
-       #[cfg(test)]
-       // Used in ChannelManager's tests to send a revoked transaction
-       pub last_local_commitment_txn: Vec<Transaction>,
-       #[cfg(not(test))]
-       last_local_commitment_txn: Vec<Transaction>,
-
-       last_sent_closing_fee: Option<(u64, u64)>, // (feerate, fee)
+       last_sent_closing_fee: Option<(u64, u64, Signature)>, // (feerate, fee, our_sig)
 
        /// The hash of the block in which the funding transaction reached our CONF_TARGET. We use this
        /// to detect unconfirmation after a serialize-unserialize roundtrip where we may not see a full
@@ -373,12 +367,6 @@ const B_OUTPUT_PLUS_SPENDING_INPUT_WEIGHT: u64 = 104; // prevout: 40, nSequence:
 /// it's 2^24.
 pub const MAX_FUNDING_SATOSHIS: u64 = (1 << 24);
 
-#[cfg(test)]
-pub const ACCEPTED_HTLC_SCRIPT_WEIGHT: usize = 138; //Here we have a diff due to HTLC CLTV expiry being < 2^15 in test
-#[cfg(not(test))]
-pub const ACCEPTED_HTLC_SCRIPT_WEIGHT: usize = 139;
-pub const OFFERED_HTLC_SCRIPT_WEIGHT: usize = 133;
-
 /// Used to return a simple Error back to ChannelManager. Will get converted to a
 /// msgs::ErrorAction::SendErrorMessage or msgs::ErrorAction::IgnoreError as appropriate with our
 /// channel_id in ChannelManager.
@@ -410,7 +398,7 @@ macro_rules! secp_check {
        };
 }
 
-impl Channel {
+impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
        // Convert constants + channel value to limits:
        fn get_our_max_htlc_value_in_flight_msat(channel_value_satoshis: u64) -> u64 {
                channel_value_satoshis * 1000 / 10 //TODO
@@ -433,7 +421,7 @@ impl Channel {
        }
 
        // Constructors:
-       pub fn new_outbound(fee_estimator: &FeeEstimator, keys_provider: &Arc<KeysInterface>, their_node_id: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_id: u64, logger: Arc<Logger>, config: &UserConfig) -> Result<Channel, APIError> {
+       pub fn new_outbound(fee_estimator: &FeeEstimator, keys_provider: &Arc<KeysInterface<ChanKeySigner = ChanSigner>>, their_node_id: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_id: u64, logger: Arc<Logger>, config: &UserConfig) -> Result<Channel<ChanSigner>, APIError> {
                let chan_keys = keys_provider.get_channel_keys(false);
 
                if channel_value_satoshis >= MAX_FUNDING_SATOSHIS {
@@ -449,15 +437,15 @@ impl Channel {
 
 
                let background_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background);
-               if Channel::get_our_channel_reserve_satoshis(channel_value_satoshis) < Channel::derive_our_dust_limit_satoshis(background_feerate) {
+               if Channel::<ChanSigner>::get_our_channel_reserve_satoshis(channel_value_satoshis) < Channel::<ChanSigner>::derive_our_dust_limit_satoshis(background_feerate) {
                        return Err(APIError::FeeRateTooHigh{err: format!("Not enough reserve above dust limit can be found at current fee rate({})", background_feerate), feerate: background_feerate});
                }
 
                let feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Normal);
 
                let secp_ctx = Secp256k1::new();
-               let channel_monitor = ChannelMonitor::new(&chan_keys.revocation_base_key, &chan_keys.delayed_payment_base_key,
-                                                         &chan_keys.htlc_base_key, &chan_keys.payment_base_key, &keys_provider.get_shutdown_pubkey(), config.own_channel_config.our_to_self_delay,
+               let channel_monitor = ChannelMonitor::new(chan_keys.funding_key(), chan_keys.revocation_base_key(), chan_keys.delayed_payment_base_key(),
+                                                         chan_keys.htlc_base_key(), chan_keys.payment_base_key(), &keys_provider.get_shutdown_pubkey(), config.own_channel_config.our_to_self_delay,
                                                          keys_provider.get_destination_script(), logger.clone());
 
                Ok(Channel {
@@ -498,8 +486,6 @@ impl Channel {
                        #[cfg(debug_assertions)]
                        max_commitment_tx_output_remote: ::std::sync::Mutex::new((channel_value_satoshis * 1000 - push_msat, push_msat)),
 
-                       last_local_commitment_txn: Vec::new(),
-
                        last_sent_closing_fee: None,
 
                        funding_tx_confirmed_in: None,
@@ -509,11 +495,11 @@ impl Channel {
 
                        feerate_per_kw: feerate,
                        their_dust_limit_satoshis: 0,
-                       our_dust_limit_satoshis: Channel::derive_our_dust_limit_satoshis(background_feerate),
+                       our_dust_limit_satoshis: Channel::<ChanSigner>::derive_our_dust_limit_satoshis(background_feerate),
                        their_max_htlc_value_in_flight_msat: 0,
                        their_channel_reserve_satoshis: 0,
                        their_htlc_minimum_msat: 0,
-                       our_htlc_minimum_msat: Channel::derive_our_htlc_minimum_msat(feerate),
+                       our_htlc_minimum_msat: Channel::<ChanSigner>::derive_our_htlc_minimum_msat(feerate),
                        their_to_self_delay: 0,
                        our_to_self_delay: config.own_channel_config.our_to_self_delay,
                        their_max_accepted_htlcs: 0,
@@ -551,7 +537,7 @@ impl Channel {
 
        /// Creates a new channel from a remote sides' request for one.
        /// Assumes chain_hash has already been checked and corresponds with what we expect!
-       pub fn new_from_req(fee_estimator: &FeeEstimator, keys_provider: &Arc<KeysInterface>, their_node_id: PublicKey, their_local_features: LocalFeatures, msg: &msgs::OpenChannel, user_id: u64, logger: Arc<Logger>, config: &UserConfig) -> Result<Channel, ChannelError> {
+       pub fn new_from_req(fee_estimator: &FeeEstimator, keys_provider: &Arc<KeysInterface<ChanKeySigner = ChanSigner>>, their_node_id: PublicKey, their_local_features: LocalFeatures, msg: &msgs::OpenChannel, user_id: u64, logger: Arc<Logger>, config: &UserConfig) -> Result<Channel<ChanSigner>, ChannelError> {
                let chan_keys = keys_provider.get_channel_keys(true);
                let mut local_config = (*config).channel_options.clone();
 
@@ -578,7 +564,7 @@ impl Channel {
                if msg.htlc_minimum_msat >= (msg.funding_satoshis - msg.channel_reserve_satoshis) * 1000 {
                        return Err(ChannelError::Close("Minimum htlc value is full channel value"));
                }
-               Channel::check_remote_fee(fee_estimator, msg.feerate_per_kw)?;
+               Channel::<ChanSigner>::check_remote_fee(fee_estimator, msg.feerate_per_kw)?;
 
                if msg.to_self_delay > config.peer_channel_config_limits.their_to_self_delay || msg.to_self_delay > MAX_LOCAL_BREAKDOWN_TIMEOUT {
                        return Err(ChannelError::Close("They wanted our payments to be delayed by a needlessly long period"));
@@ -626,8 +612,8 @@ impl Channel {
 
                let background_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background);
 
-               let our_dust_limit_satoshis = Channel::derive_our_dust_limit_satoshis(background_feerate);
-               let our_channel_reserve_satoshis = Channel::get_our_channel_reserve_satoshis(msg.funding_satoshis);
+               let our_dust_limit_satoshis = Channel::<ChanSigner>::derive_our_dust_limit_satoshis(background_feerate);
+               let our_channel_reserve_satoshis = Channel::<ChanSigner>::get_our_channel_reserve_satoshis(msg.funding_satoshis);
                if our_channel_reserve_satoshis < our_dust_limit_satoshis {
                        return Err(ChannelError::Close("Suitable channel reserve not found. aborting"));
                }
@@ -652,11 +638,9 @@ impl Channel {
                }
 
                let secp_ctx = Secp256k1::new();
-               let mut channel_monitor = ChannelMonitor::new(&chan_keys.revocation_base_key, &chan_keys.delayed_payment_base_key,
-                                                             &chan_keys.htlc_base_key, &chan_keys.payment_base_key, &keys_provider.get_shutdown_pubkey(), config.own_channel_config.our_to_self_delay,
-                                                             keys_provider.get_destination_script(), logger.clone());
-               channel_monitor.set_their_base_keys(&msg.htlc_basepoint, &msg.delayed_payment_basepoint);
-               channel_monitor.set_their_to_self_delay(msg.to_self_delay);
+               let channel_monitor = ChannelMonitor::new(chan_keys.funding_key(), chan_keys.revocation_base_key(), chan_keys.delayed_payment_base_key(),
+                                                         chan_keys.htlc_base_key(), chan_keys.payment_base_key(), &keys_provider.get_shutdown_pubkey(), config.own_channel_config.our_to_self_delay,
+                                                         keys_provider.get_destination_script(), logger.clone());
 
                let their_shutdown_scriptpubkey = if their_local_features.supports_upfront_shutdown_script() {
                        match &msg.shutdown_scriptpubkey {
@@ -716,8 +700,6 @@ impl Channel {
                        #[cfg(debug_assertions)]
                        max_commitment_tx_output_remote: ::std::sync::Mutex::new((msg.push_msat, msg.funding_satoshis * 1000 - msg.push_msat)),
 
-                       last_local_commitment_txn: Vec::new(),
-
                        last_sent_closing_fee: None,
 
                        funding_tx_confirmed_in: None,
@@ -732,7 +714,7 @@ impl Channel {
                        their_max_htlc_value_in_flight_msat: cmp::min(msg.max_htlc_value_in_flight_msat, msg.funding_satoshis * 1000),
                        their_channel_reserve_satoshis: msg.channel_reserve_satoshis,
                        their_htlc_minimum_msat: msg.htlc_minimum_msat,
-                       our_htlc_minimum_msat: Channel::derive_our_htlc_minimum_msat(msg.feerate_per_kw as u64),
+                       our_htlc_minimum_msat: Channel::<ChanSigner>::derive_our_htlc_minimum_msat(msg.feerate_per_kw as u64),
                        their_to_self_delay: msg.to_self_delay,
                        our_to_self_delay: config.own_channel_config.our_to_self_delay,
                        their_max_accepted_htlcs: msg.max_accepted_htlcs,
@@ -758,7 +740,8 @@ impl Channel {
                };
 
                let obscure_factor = chan.get_commitment_transaction_number_obscure_factor();
-               chan.channel_monitor.set_commitment_obscure_factor(obscure_factor);
+               let funding_redeemscript = chan.get_funding_redeemscript();
+               chan.channel_monitor.set_basic_channel_info(&msg.htlc_basepoint, &msg.delayed_payment_basepoint, msg.to_self_delay, funding_redeemscript, msg.funding_satoshis, obscure_factor);
 
                Ok(chan)
        }
@@ -766,7 +749,7 @@ impl Channel {
        // Utilities to derive keys:
 
        fn build_local_commitment_secret(&self, idx: u64) -> SecretKey {
-               let res = chan_utils::build_commitment_secret(self.local_keys.commitment_seed, idx);
+               let res = chan_utils::build_commitment_secret(self.local_keys.commitment_seed(), idx);
                SecretKey::from_slice(&res).unwrap()
        }
 
@@ -774,7 +757,7 @@ impl Channel {
 
        fn get_commitment_transaction_number_obscure_factor(&self) -> u64 {
                let mut sha = Sha256::engine();
-               let our_payment_basepoint = PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.payment_base_key);
+               let our_payment_basepoint = PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.payment_base_key());
 
                if self.channel_outbound {
                        sha.input(&our_payment_basepoint.serialize());
@@ -833,7 +816,7 @@ impl Channel {
                let mut local_htlc_total_msat = 0;
                let mut value_to_self_msat_offset = 0;
 
-               log_trace!(self, "Building commitment transaction number {} for {}, generated by {} with fee {}...", commitment_number, if local { "us" } else { "remote" }, if generated_by_local { "us" } else { "remote" }, feerate_per_kw);
+               log_trace!(self, "Building commitment transaction number {} (really {} xor {}) for {}, generated by {} with fee {}...", commitment_number, (INITIAL_COMMITMENT_NUMBER - commitment_number), self.get_commitment_transaction_number_obscure_factor(), if local { "us" } else { "remote" }, if generated_by_local { "us" } else { "remote" }, feerate_per_kw);
 
                macro_rules! get_htlc_in_commitment {
                        ($htlc: expr, $offered: expr) => {
@@ -952,7 +935,7 @@ impl Channel {
                        };
                        debug_assert!(max_commitment_tx_output.0 <= value_to_self_msat as u64 || value_to_self_msat / 1000 >= self.their_channel_reserve_satoshis as i64);
                        max_commitment_tx_output.0 = cmp::max(max_commitment_tx_output.0, value_to_self_msat as u64);
-                       debug_assert!(max_commitment_tx_output.1 <= value_to_remote_msat as u64 || value_to_remote_msat / 1000 >= Channel::get_our_channel_reserve_satoshis(self.channel_value_satoshis) as i64);
+                       debug_assert!(max_commitment_tx_output.1 <= value_to_remote_msat as u64 || value_to_remote_msat / 1000 >= Channel::<ChanSigner>::get_our_channel_reserve_satoshis(self.channel_value_satoshis) as i64);
                        max_commitment_tx_output.1 = cmp::max(max_commitment_tx_output.1, value_to_remote_msat as u64);
                }
 
@@ -1097,8 +1080,8 @@ impl Channel {
        /// TODO Some magic rust shit to compile-time check this?
        fn build_local_transaction_keys(&self, commitment_number: u64) -> Result<TxCreationKeys, ChannelError> {
                let per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(commitment_number));
-               let delayed_payment_base = PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.delayed_payment_base_key);
-               let htlc_basepoint = PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.htlc_base_key);
+               let delayed_payment_base = PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.delayed_payment_base_key());
+               let htlc_basepoint = PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.htlc_base_key());
 
                Ok(secp_check!(TxCreationKeys::new(&self.secp_ctx, &per_commitment_point, &delayed_payment_base, &htlc_basepoint, &self.their_revocation_basepoint.unwrap(), &self.their_payment_basepoint.unwrap(), &self.their_htlc_basepoint.unwrap()), "Local tx keys generation got bogus keys"))
        }
@@ -1110,9 +1093,9 @@ impl Channel {
        fn build_remote_transaction_keys(&self) -> Result<TxCreationKeys, ChannelError> {
                //TODO: Ensure that the payment_key derived here ends up in the library users' wallet as we
                //may see payments to it!
-               let payment_basepoint = PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.payment_base_key);
-               let revocation_basepoint = PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.revocation_base_key);
-               let htlc_basepoint = PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.htlc_base_key);
+               let payment_basepoint = PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.payment_base_key());
+               let revocation_basepoint = PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.revocation_base_key());
+               let htlc_basepoint = PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.htlc_base_key());
 
                Ok(secp_check!(TxCreationKeys::new(&self.secp_ctx, &self.their_cur_commitment_point.unwrap(), &self.their_delayed_payment_basepoint.unwrap(), &self.their_htlc_basepoint.unwrap(), &revocation_basepoint, &payment_basepoint, &htlc_basepoint), "Remote tx keys generation got bogus keys"))
        }
@@ -1122,7 +1105,7 @@ impl Channel {
        /// Panics if called before accept_channel/new_from_req
        pub fn get_funding_redeemscript(&self) -> Script {
                let builder = Builder::new().push_opcode(opcodes::all::OP_PUSHNUM_2);
-               let our_funding_key = PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.funding_key).serialize();
+               let our_funding_key = PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key()).serialize();
                let their_funding_key = self.their_funding_pubkey.expect("get_funding_redeemscript only allowed after accept_channel").serialize();
                if our_funding_key[..] < their_funding_key[..] {
                        builder.push_slice(&our_funding_key)
@@ -1133,38 +1116,6 @@ impl Channel {
                }.push_opcode(opcodes::all::OP_PUSHNUM_2).push_opcode(opcodes::all::OP_CHECKMULTISIG).into_script()
        }
 
-       fn sign_commitment_transaction(&self, tx: &mut Transaction, their_sig: &Signature) -> Signature {
-               if tx.input.len() != 1 {
-                       panic!("Tried to sign commitment transaction that had input count != 1!");
-               }
-               if tx.input[0].witness.len() != 0 {
-                       panic!("Tried to re-sign commitment transaction");
-               }
-
-               let funding_redeemscript = self.get_funding_redeemscript();
-
-               let sighash = hash_to_message!(&bip143::SighashComponents::new(&tx).sighash_all(&tx.input[0], &funding_redeemscript, self.channel_value_satoshis)[..]);
-               let our_sig = self.secp_ctx.sign(&sighash, &self.local_keys.funding_key);
-
-               tx.input[0].witness.push(Vec::new()); // First is the multisig dummy
-
-               let our_funding_key = PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.funding_key).serialize();
-               let their_funding_key = self.their_funding_pubkey.unwrap().serialize();
-               if our_funding_key[..] < their_funding_key[..] {
-                       tx.input[0].witness.push(our_sig.serialize_der().to_vec());
-                       tx.input[0].witness.push(their_sig.serialize_der().to_vec());
-               } else {
-                       tx.input[0].witness.push(their_sig.serialize_der().to_vec());
-                       tx.input[0].witness.push(our_sig.serialize_der().to_vec());
-               }
-               tx.input[0].witness[1].push(SigHashType::All as u8);
-               tx.input[0].witness[2].push(SigHashType::All as u8);
-
-               tx.input[0].witness.push(funding_redeemscript.into_bytes());
-
-               our_sig
-       }
-
        /// Builds the htlc-success or htlc-timeout transaction which spends a given HTLC output
        /// @local is used only to convert relevant internal structures which refer to remote vs local
        /// to decide value of outputs and direction of HTLCs.
@@ -1172,54 +1123,6 @@ impl Channel {
                chan_utils::build_htlc_transaction(prev_hash, feerate_per_kw, if local { self.their_to_self_delay } else { self.our_to_self_delay }, htlc, &keys.a_delayed_payment_key, &keys.revocation_key)
        }
 
-       fn create_htlc_tx_signature(&self, tx: &Transaction, htlc: &HTLCOutputInCommitment, keys: &TxCreationKeys) -> Result<(Script, Signature, bool), ChannelError> {
-               if tx.input.len() != 1 {
-                       panic!("Tried to sign HTLC transaction that had input count != 1!");
-               }
-
-               let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &keys);
-
-               let our_htlc_key = secp_check!(chan_utils::derive_private_key(&self.secp_ctx, &keys.per_commitment_point, &self.local_keys.htlc_base_key), "Derived invalid key, peer is maliciously selecting parameters");
-               let sighash = hash_to_message!(&bip143::SighashComponents::new(&tx).sighash_all(&tx.input[0], &htlc_redeemscript, htlc.amount_msat / 1000)[..]);
-               let is_local_tx = PublicKey::from_secret_key(&self.secp_ctx, &our_htlc_key) == keys.a_htlc_key;
-               Ok((htlc_redeemscript, self.secp_ctx.sign(&sighash, &our_htlc_key), is_local_tx))
-       }
-
-       /// Signs a transaction created by build_htlc_transaction. If the transaction is an
-       /// HTLC-Success transaction (ie htlc.offered is false), preimage must be set!
-       fn sign_htlc_transaction(&self, tx: &mut Transaction, their_sig: &Signature, preimage: &Option<PaymentPreimage>, htlc: &HTLCOutputInCommitment, keys: &TxCreationKeys) -> Result<Signature, ChannelError> {
-               if tx.input.len() != 1 {
-                       panic!("Tried to sign HTLC transaction that had input count != 1!");
-               }
-               if tx.input[0].witness.len() != 0 {
-                       panic!("Tried to re-sign HTLC transaction");
-               }
-
-               let (htlc_redeemscript, our_sig, local_tx) = self.create_htlc_tx_signature(tx, htlc, keys)?;
-
-               tx.input[0].witness.push(Vec::new()); // First is the multisig dummy
-
-               if local_tx { // b, then a
-                       tx.input[0].witness.push(their_sig.serialize_der().to_vec());
-                       tx.input[0].witness.push(our_sig.serialize_der().to_vec());
-               } else {
-                       tx.input[0].witness.push(our_sig.serialize_der().to_vec());
-                       tx.input[0].witness.push(their_sig.serialize_der().to_vec());
-               }
-               tx.input[0].witness[1].push(SigHashType::All as u8);
-               tx.input[0].witness[2].push(SigHashType::All as u8);
-
-               if htlc.offered {
-                       tx.input[0].witness.push(Vec::new());
-               } else {
-                       tx.input[0].witness.push(preimage.unwrap().0.to_vec());
-               }
-
-               tx.input[0].witness.push(htlc_redeemscript.into_bytes());
-
-               Ok(our_sig)
-       }
-
        /// Per HTLC, only one get_update_fail_htlc or get_update_fulfill_htlc call may be made.
        /// In such cases we debug_assert!(false) and return an IgnoreError. Thus, will always return
        /// Ok(_) if debug assertions are turned on and preconditions are met.
@@ -1417,7 +1320,7 @@ impl Channel {
                if msg.channel_reserve_satoshis < self.our_dust_limit_satoshis {
                        return Err(ChannelError::Close("Peer never wants payout outputs?"));
                }
-               if msg.dust_limit_satoshis > Channel::get_our_channel_reserve_satoshis(self.channel_value_satoshis) {
+               if msg.dust_limit_satoshis > Channel::<ChanSigner>::get_our_channel_reserve_satoshis(self.channel_value_satoshis) {
                        return Err(ChannelError::Close("Dust limit is bigger than our channel reverse"));
                }
                if msg.htlc_minimum_msat >= (self.channel_value_satoshis - msg.channel_reserve_satoshis) * 1000 {
@@ -1477,8 +1380,6 @@ impl Channel {
                        }
                } else { None };
 
-               self.channel_monitor.set_their_base_keys(&msg.htlc_basepoint, &msg.delayed_payment_basepoint);
-
                self.their_dust_limit_satoshis = msg.dust_limit_satoshis;
                self.their_max_htlc_value_in_flight_msat = cmp::min(msg.max_htlc_value_in_flight_msat, self.channel_value_satoshis * 1000);
                self.their_channel_reserve_satoshis = msg.channel_reserve_satoshis;
@@ -1495,33 +1396,33 @@ impl Channel {
                self.their_shutdown_scriptpubkey = their_shutdown_scriptpubkey;
 
                let obscure_factor = self.get_commitment_transaction_number_obscure_factor();
-               self.channel_monitor.set_commitment_obscure_factor(obscure_factor);
-               self.channel_monitor.set_their_to_self_delay(msg.to_self_delay);
+               let funding_redeemscript = self.get_funding_redeemscript();
+               self.channel_monitor.set_basic_channel_info(&msg.htlc_basepoint, &msg.delayed_payment_basepoint, msg.to_self_delay, funding_redeemscript, self.channel_value_satoshis, obscure_factor);
 
                self.channel_state = ChannelState::OurInitSent as u32 | ChannelState::TheirInitSent as u32;
 
                Ok(())
        }
 
-       fn funding_created_signature(&mut self, sig: &Signature) -> Result<(Transaction, Transaction, Signature, TxCreationKeys), ChannelError> {
+       fn funding_created_signature(&mut self, sig: &Signature) -> Result<(Transaction, LocalCommitmentTransaction, Signature, TxCreationKeys), ChannelError> {
                let funding_script = self.get_funding_redeemscript();
 
                let local_keys = self.build_local_transaction_keys(self.cur_local_commitment_transaction_number)?;
-               let mut local_initial_commitment_tx = self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false, self.feerate_per_kw).0;
+               let local_initial_commitment_tx = self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false, self.feerate_per_kw).0;
                let local_sighash = hash_to_message!(&bip143::SighashComponents::new(&local_initial_commitment_tx).sighash_all(&local_initial_commitment_tx.input[0], &funding_script, self.channel_value_satoshis)[..]);
 
                // They sign the "local" commitment transaction...
                secp_check!(self.secp_ctx.verify(&local_sighash, &sig, &self.their_funding_pubkey.unwrap()), "Invalid funding_created signature from peer");
 
-               // ...and we sign it, allowing us to broadcast the tx if we wish
-               self.sign_commitment_transaction(&mut local_initial_commitment_tx, sig);
+               let localtx = LocalCommitmentTransaction::new_missing_local_sig(local_initial_commitment_tx, sig, &PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key()), self.their_funding_pubkey.as_ref().unwrap());
 
                let remote_keys = self.build_remote_transaction_keys()?;
                let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw).0;
-               let remote_sighash = hash_to_message!(&bip143::SighashComponents::new(&remote_initial_commitment_tx).sighash_all(&remote_initial_commitment_tx.input[0], &funding_script, self.channel_value_satoshis)[..]);
+               let remote_signature = self.local_keys.sign_remote_commitment(self.channel_value_satoshis, &self.get_funding_redeemscript(), self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), self.our_to_self_delay, &self.secp_ctx)
+                               .map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed"))?.0;
 
                // We sign the "remote" commitment transaction, allowing them to broadcast the tx if they wish.
-               Ok((remote_initial_commitment_tx, local_initial_commitment_tx, self.secp_ctx.sign(&remote_sighash, &self.local_keys.funding_key), local_keys))
+               Ok((remote_initial_commitment_tx, localtx, remote_signature, local_keys))
        }
 
        pub fn funding_created(&mut self, msg: &msgs::FundingCreated) -> Result<(msgs::FundingSigned, ChannelMonitor), ChannelError> {
@@ -1555,7 +1456,6 @@ impl Channel {
                // Now that we're past error-generating stuff, update our local state:
 
                self.channel_monitor.provide_latest_remote_commitment_tx_info(&remote_initial_commitment_tx, Vec::new(), self.cur_remote_commitment_transaction_number, self.their_cur_commitment_point.unwrap());
-               self.last_local_commitment_txn = vec![local_initial_commitment_tx.clone()];
                self.channel_monitor.provide_latest_local_commitment_tx_info(local_initial_commitment_tx, local_keys, self.feerate_per_kw, Vec::new());
                self.channel_state = ChannelState::FundingSent as u32;
                self.channel_id = funding_txo.to_channel_id();
@@ -1586,15 +1486,15 @@ impl Channel {
                let funding_script = self.get_funding_redeemscript();
 
                let local_keys = self.build_local_transaction_keys(self.cur_local_commitment_transaction_number)?;
-               let mut local_initial_commitment_tx = self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false, self.feerate_per_kw).0;
+               let local_initial_commitment_tx = self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false, self.feerate_per_kw).0;
                let local_sighash = hash_to_message!(&bip143::SighashComponents::new(&local_initial_commitment_tx).sighash_all(&local_initial_commitment_tx.input[0], &funding_script, self.channel_value_satoshis)[..]);
 
                // They sign the "local" commitment transaction, allowing us to broadcast the tx if we wish.
                secp_check!(self.secp_ctx.verify(&local_sighash, &msg.signature, &self.their_funding_pubkey.unwrap()), "Invalid funding_signed signature from peer");
 
-               self.sign_commitment_transaction(&mut local_initial_commitment_tx, &msg.signature);
-               self.channel_monitor.provide_latest_local_commitment_tx_info(local_initial_commitment_tx.clone(), local_keys, self.feerate_per_kw, Vec::new());
-               self.last_local_commitment_txn = vec![local_initial_commitment_tx];
+               self.channel_monitor.provide_latest_local_commitment_tx_info(
+                       LocalCommitmentTransaction::new_missing_local_sig(local_initial_commitment_tx, &msg.signature, &PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key()), self.their_funding_pubkey.as_ref().unwrap()),
+                       local_keys, self.feerate_per_kw, Vec::new());
                self.channel_state = ChannelState::FundingSent as u32 | (self.channel_state & (ChannelState::MonitorUpdateFailed as u32));
                self.cur_local_commitment_transaction_number -= 1;
 
@@ -1695,7 +1595,7 @@ impl Channel {
                        return Err(ChannelError::Close("Remote tried to push more than our max accepted HTLCs"));
                }
                // Check our_max_htlc_value_in_flight_msat
-               if htlc_inbound_value_msat + msg.amount_msat > Channel::get_our_max_htlc_value_in_flight_msat(self.channel_value_satoshis) {
+               if htlc_inbound_value_msat + msg.amount_msat > Channel::<ChanSigner>::get_our_max_htlc_value_in_flight_msat(self.channel_value_satoshis) {
                        return Err(ChannelError::Close("Remote HTLC add would put them over our max HTLC value"));
                }
                // Check our_channel_reserve_satoshis (we're getting paid, so they have to at least meet
@@ -1718,7 +1618,7 @@ impl Channel {
                                removed_outbound_total_msat += htlc.amount_msat;
                        }
                }
-               if htlc_inbound_value_msat + msg.amount_msat + self.value_to_self_msat > (self.channel_value_satoshis - Channel::get_our_channel_reserve_satoshis(self.channel_value_satoshis)) * 1000 + removed_outbound_total_msat {
+               if htlc_inbound_value_msat + msg.amount_msat + self.value_to_self_msat > (self.channel_value_satoshis - Channel::<ChanSigner>::get_our_channel_reserve_satoshis(self.channel_value_satoshis)) * 1000 + removed_outbound_total_msat {
                        return Err(ChannelError::Close("Remote HTLC add would put them over their reserve value"));
                }
                if self.next_remote_htlc_id != msg.htlc_id {
@@ -1858,33 +1758,22 @@ impl Channel {
                        return Err(ChannelError::Close("Got wrong number of HTLC signatures from remote"));
                }
 
-               let mut new_local_commitment_txn = Vec::with_capacity(local_commitment_tx.1 + 1);
-               self.sign_commitment_transaction(&mut local_commitment_tx.0, &msg.signature);
-               new_local_commitment_txn.push(local_commitment_tx.0.clone());
-
                let mut htlcs_and_sigs = Vec::with_capacity(local_commitment_tx.2.len());
                for (idx, (htlc, source)) in local_commitment_tx.2.drain(..).enumerate() {
                        if let Some(_) = htlc.transaction_output_index {
-                               let mut htlc_tx = self.build_htlc_transaction(&local_commitment_txid, &htlc, true, &local_keys, feerate_per_kw);
+                               let htlc_tx = self.build_htlc_transaction(&local_commitment_txid, &htlc, true, &local_keys, feerate_per_kw);
                                let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &local_keys);
                                log_trace!(self, "Checking HTLC tx signature {} by key {} against tx {} with redeemscript {}", log_bytes!(msg.htlc_signatures[idx].serialize_compact()[..]), log_bytes!(local_keys.b_htlc_key.serialize()), encode::serialize_hex(&htlc_tx), encode::serialize_hex(&htlc_redeemscript));
                                let htlc_sighash = hash_to_message!(&bip143::SighashComponents::new(&htlc_tx).sighash_all(&htlc_tx.input[0], &htlc_redeemscript, htlc.amount_msat / 1000)[..]);
                                secp_check!(self.secp_ctx.verify(&htlc_sighash, &msg.htlc_signatures[idx], &local_keys.b_htlc_key), "Invalid HTLC tx signature from peer");
-                               let htlc_sig = if htlc.offered {
-                                       let htlc_sig = self.sign_htlc_transaction(&mut htlc_tx, &msg.htlc_signatures[idx], &None, &htlc, &local_keys)?;
-                                       new_local_commitment_txn.push(htlc_tx);
-                                       htlc_sig
-                               } else {
-                                       self.create_htlc_tx_signature(&htlc_tx, &htlc, &local_keys)?.1
-                               };
-                               htlcs_and_sigs.push((htlc, Some((msg.htlc_signatures[idx], htlc_sig)), source));
+                               htlcs_and_sigs.push((htlc, Some(msg.htlc_signatures[idx]), source));
                        } else {
                                htlcs_and_sigs.push((htlc, None, source));
                        }
                }
 
                let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number - 1));
-               let per_commitment_secret = chan_utils::build_commitment_secret(self.local_keys.commitment_seed, self.cur_local_commitment_transaction_number + 1);
+               let per_commitment_secret = chan_utils::build_commitment_secret(self.local_keys.commitment_seed(), self.cur_local_commitment_transaction_number + 1);
 
                // Update state now that we've passed all the can-fail calls...
                let mut need_our_commitment = false;
@@ -1901,7 +1790,10 @@ impl Channel {
                        }
                }
 
-               self.channel_monitor.provide_latest_local_commitment_tx_info(local_commitment_tx.0, local_keys, self.feerate_per_kw, htlcs_and_sigs);
+
+               self.channel_monitor.provide_latest_local_commitment_tx_info(
+                       LocalCommitmentTransaction::new_missing_local_sig(local_commitment_tx.0, &msg.signature, &PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key()), self.their_funding_pubkey.as_ref().unwrap()),
+                       local_keys, self.feerate_per_kw, htlcs_and_sigs);
 
                for htlc in self.pending_inbound_htlcs.iter_mut() {
                        let new_forward = if let &InboundHTLCState::RemoteAnnounced(ref forward_info) = &htlc.state {
@@ -1922,7 +1814,6 @@ impl Channel {
                }
 
                self.cur_local_commitment_transaction_number -= 1;
-               self.last_local_commitment_txn = new_local_commitment_txn;
                // Note that if we need_our_commitment & !AwaitingRemoteRevoke we'll call
                // send_commitment_no_status_check() next which will reset this to RAAFirst.
                self.resend_order = RAACommitmentOrder::CommitmentFirst;
@@ -2444,7 +2335,7 @@ impl Channel {
                if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 {
                        return Err(ChannelError::Close("Peer sent update_fee when we needed a channel_reestablish"));
                }
-               Channel::check_remote_fee(fee_estimator, msg.feerate_per_kw)?;
+               Channel::<ChanSigner>::check_remote_fee(fee_estimator, msg.feerate_per_kw)?;
                self.pending_update_fee = Some(msg.feerate_per_kw as u64);
                self.channel_update_count += 1;
                Ok(())
@@ -2452,7 +2343,7 @@ impl Channel {
 
        fn get_last_revoke_and_ack(&self) -> msgs::RevokeAndACK {
                let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number));
-               let per_commitment_secret = chan_utils::build_commitment_secret(self.local_keys.commitment_seed, self.cur_local_commitment_transaction_number + 2);
+               let per_commitment_secret = chan_utils::build_commitment_secret(self.local_keys.commitment_seed(), self.cur_local_commitment_transaction_number + 2);
                msgs::RevokeAndACK {
                        channel_id: self.channel_id,
                        per_commitment_secret,
@@ -2535,7 +2426,7 @@ impl Channel {
                if msg.next_remote_commitment_number > 0 {
                        match msg.data_loss_protect {
                                OptionalField::Present(ref data_loss) => {
-                                       if chan_utils::build_commitment_secret(self.local_keys.commitment_seed, INITIAL_COMMITMENT_NUMBER - msg.next_remote_commitment_number + 1) != data_loss.your_last_per_commitment_secret {
+                                       if chan_utils::build_commitment_secret(self.local_keys.commitment_seed(), INITIAL_COMMITMENT_NUMBER - msg.next_remote_commitment_number + 1) != data_loss.your_last_per_commitment_secret {
                                                return Err(ChannelError::Close("Peer sent a garbage channel_reestablish with secret key not matching the commitment height provided"));
                                        }
                                        if msg.next_remote_commitment_number > INITIAL_COMMITMENT_NUMBER - self.cur_local_commitment_transaction_number {
@@ -2664,14 +2555,16 @@ impl Channel {
                let proposed_total_fee_satoshis = proposed_feerate * tx_weight / 1000;
 
                let (closing_tx, total_fee_satoshis) = self.build_closing_transaction(proposed_total_fee_satoshis, false);
-               let funding_redeemscript = self.get_funding_redeemscript();
-               let sighash = hash_to_message!(&bip143::SighashComponents::new(&closing_tx).sighash_all(&closing_tx.input[0], &funding_redeemscript, self.channel_value_satoshis)[..]);
+               let our_sig = self.local_keys
+                       .sign_closing_transaction(self.channel_value_satoshis, &self.get_funding_redeemscript(), &closing_tx, &self.secp_ctx)
+                       .ok();
+               if our_sig.is_none() { return None; }
 
-               self.last_sent_closing_fee = Some((proposed_feerate, total_fee_satoshis));
+               self.last_sent_closing_fee = Some((proposed_feerate, total_fee_satoshis, our_sig.clone().unwrap()));
                Some(msgs::ClosingSigned {
                        channel_id: self.channel_id,
                        fee_satoshis: total_fee_satoshis,
-                       signature: self.secp_ctx.sign(&sighash, &self.local_keys.funding_key),
+                       signature: our_sig.unwrap(),
                })
        }
 
@@ -2748,6 +2641,28 @@ impl Channel {
                Ok((our_shutdown, self.maybe_propose_first_closing_signed(fee_estimator), dropped_outbound_htlcs))
        }
 
+       fn build_signed_closing_transaction(&self, tx: &mut Transaction, their_sig: &Signature, our_sig: &Signature) {
+               if tx.input.len() != 1 { panic!("Tried to sign closing transaction that had input count != 1!"); }
+               if tx.input[0].witness.len() != 0 { panic!("Tried to re-sign closing transaction"); }
+               if tx.output.len() > 2 { panic!("Tried to sign bogus closing transaction"); }
+
+               tx.input[0].witness.push(Vec::new()); // First is the multisig dummy
+
+               let our_funding_key = PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key()).serialize();
+               let their_funding_key = self.their_funding_pubkey.unwrap().serialize();
+               if our_funding_key[..] < their_funding_key[..] {
+                       tx.input[0].witness.push(our_sig.serialize_der().to_vec());
+                       tx.input[0].witness.push(their_sig.serialize_der().to_vec());
+               } else {
+                       tx.input[0].witness.push(their_sig.serialize_der().to_vec());
+                       tx.input[0].witness.push(our_sig.serialize_der().to_vec());
+               }
+               tx.input[0].witness[1].push(SigHashType::All as u8);
+               tx.input[0].witness[2].push(SigHashType::All as u8);
+
+               tx.input[0].witness.push(self.get_funding_redeemscript().into_bytes());
+       }
+
        pub fn closing_signed(&mut self, fee_estimator: &FeeEstimator, msg: &msgs::ClosingSigned) -> Result<(Option<msgs::ClosingSigned>, Option<Transaction>), ChannelError> {
                if self.channel_state & BOTH_SIDES_SHUTDOWN_MASK != BOTH_SIDES_SHUTDOWN_MASK {
                        return Err(ChannelError::Close("Remote end sent us a closing_signed before both sides provided a shutdown"));
@@ -2780,9 +2695,9 @@ impl Channel {
                        },
                };
 
-               if let Some((_, last_fee)) = self.last_sent_closing_fee {
+               if let Some((_, last_fee, our_sig)) = self.last_sent_closing_fee {
                        if last_fee == msg.fee_satoshis {
-                               self.sign_commitment_transaction(&mut closing_tx, &msg.signature);
+                               self.build_signed_closing_transaction(&mut closing_tx, &msg.signature, &our_sig);
                                self.channel_state = ChannelState::ShutdownComplete as u32;
                                self.channel_update_count += 1;
                                return Ok((None, Some(closing_tx)));
@@ -2793,9 +2708,10 @@ impl Channel {
                        ($new_feerate: expr) => {
                                let closing_tx_max_weight = Self::get_closing_transaction_weight(&self.get_closing_scriptpubkey(), self.their_shutdown_scriptpubkey.as_ref().unwrap());
                                let (closing_tx, used_total_fee) = self.build_closing_transaction($new_feerate * closing_tx_max_weight / 1000, false);
-                               sighash = hash_to_message!(&bip143::SighashComponents::new(&closing_tx).sighash_all(&closing_tx.input[0], &funding_redeemscript, self.channel_value_satoshis)[..]);
-                               let our_sig = self.secp_ctx.sign(&sighash, &self.local_keys.funding_key);
-                               self.last_sent_closing_fee = Some(($new_feerate, used_total_fee));
+                               let our_sig = self.local_keys
+                                       .sign_closing_transaction(self.channel_value_satoshis, &funding_redeemscript, &closing_tx, &self.secp_ctx)
+                                       .map_err(|_| ChannelError::Close("External signer refused to sign closing transaction"))?;
+                               self.last_sent_closing_fee = Some(($new_feerate, used_total_fee, our_sig.clone()));
                                return Ok((Some(msgs::ClosingSigned {
                                        channel_id: self.channel_id,
                                        fee_satoshis: used_total_fee,
@@ -2808,7 +2724,7 @@ impl Channel {
                if self.channel_outbound {
                        let our_max_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Normal);
                        if proposed_sat_per_kw > our_max_feerate {
-                               if let Some((last_feerate, _)) = self.last_sent_closing_fee {
+                               if let Some((last_feerate, _, _)) = self.last_sent_closing_fee {
                                        if our_max_feerate <= last_feerate {
                                                return Err(ChannelError::Close("Unable to come to consensus about closing feerate, remote wanted something higher than our Normal feerate"));
                                        }
@@ -2818,7 +2734,7 @@ impl Channel {
                } else {
                        let our_min_feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background);
                        if proposed_sat_per_kw < our_min_feerate {
-                               if let Some((last_feerate, _)) = self.last_sent_closing_fee {
+                               if let Some((last_feerate, _, _)) = self.last_sent_closing_fee {
                                        if our_min_feerate >= last_feerate {
                                                return Err(ChannelError::Close("Unable to come to consensus about closing feerate, remote wanted something lower than our Background feerate"));
                                        }
@@ -2827,7 +2743,11 @@ impl Channel {
                        }
                }
 
-               let our_sig = self.sign_commitment_transaction(&mut closing_tx, &msg.signature);
+               let our_sig = self.local_keys
+                       .sign_closing_transaction(self.channel_value_satoshis, &funding_redeemscript, &closing_tx, &self.secp_ctx)
+                       .map_err(|_| ChannelError::Close("External signer refused to sign closing transaction"))?;
+               self.build_signed_closing_transaction(&mut closing_tx, &msg.signature, &our_sig);
+
                self.channel_state = ChannelState::ShutdownComplete as u32;
                self.channel_update_count += 1;
 
@@ -2851,11 +2771,11 @@ impl Channel {
        }
 
        /// May only be called after funding has been initiated (ie is_funding_initiated() is true)
-       pub fn channel_monitor(&self) -> ChannelMonitor {
+       pub fn channel_monitor(&mut self) -> &mut ChannelMonitor {
                if self.channel_state < ChannelState::FundingCreated as u32 {
                        panic!("Can't get a channel monitor until funding has been created");
                }
-               self.channel_monitor.clone()
+               &mut self.channel_monitor
        }
 
        /// Guaranteed to be Some after both FundingLocked messages have been exchanged (and, thus,
@@ -2912,7 +2832,7 @@ impl Channel {
        }
 
        #[cfg(test)]
-       pub fn get_local_keys(&self) -> &ChannelKeys {
+       pub fn get_local_keys(&self) -> &ChanSigner {
                &self.local_keys
        }
 
@@ -3171,17 +3091,17 @@ impl Channel {
                        funding_satoshis: self.channel_value_satoshis,
                        push_msat: self.channel_value_satoshis * 1000 - self.value_to_self_msat,
                        dust_limit_satoshis: self.our_dust_limit_satoshis,
-                       max_htlc_value_in_flight_msat: Channel::get_our_max_htlc_value_in_flight_msat(self.channel_value_satoshis),
-                       channel_reserve_satoshis: Channel::get_our_channel_reserve_satoshis(self.channel_value_satoshis),
+                       max_htlc_value_in_flight_msat: Channel::<ChanSigner>::get_our_max_htlc_value_in_flight_msat(self.channel_value_satoshis),
+                       channel_reserve_satoshis: Channel::<ChanSigner>::get_our_channel_reserve_satoshis(self.channel_value_satoshis),
                        htlc_minimum_msat: self.our_htlc_minimum_msat,
                        feerate_per_kw: fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Background) as u32,
                        to_self_delay: self.our_to_self_delay,
                        max_accepted_htlcs: OUR_MAX_HTLCS,
-                       funding_pubkey: PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.funding_key),
-                       revocation_basepoint: PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.revocation_base_key),
-                       payment_basepoint: PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.payment_base_key),
-                       delayed_payment_basepoint: PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.delayed_payment_base_key),
-                       htlc_basepoint: PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.htlc_base_key),
+                       funding_pubkey: PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key()),
+                       revocation_basepoint: PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.revocation_base_key()),
+                       payment_basepoint: PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.payment_base_key()),
+                       delayed_payment_basepoint: PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.delayed_payment_base_key()),
+                       htlc_basepoint: PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.htlc_base_key()),
                        first_per_commitment_point: PublicKey::from_secret_key(&self.secp_ctx, &local_commitment_secret),
                        channel_flags: if self.config.announced_channel {1} else {0},
                        shutdown_scriptpubkey: OptionalField::Present(if self.config.commit_upfront_shutdown_pubkey { self.get_closing_scriptpubkey() } else { Builder::new().into_script() })
@@ -3204,17 +3124,17 @@ impl Channel {
                msgs::AcceptChannel {
                        temporary_channel_id: self.channel_id,
                        dust_limit_satoshis: self.our_dust_limit_satoshis,
-                       max_htlc_value_in_flight_msat: Channel::get_our_max_htlc_value_in_flight_msat(self.channel_value_satoshis),
-                       channel_reserve_satoshis: Channel::get_our_channel_reserve_satoshis(self.channel_value_satoshis),
+                       max_htlc_value_in_flight_msat: Channel::<ChanSigner>::get_our_max_htlc_value_in_flight_msat(self.channel_value_satoshis),
+                       channel_reserve_satoshis: Channel::<ChanSigner>::get_our_channel_reserve_satoshis(self.channel_value_satoshis),
                        htlc_minimum_msat: self.our_htlc_minimum_msat,
                        minimum_depth: self.minimum_depth,
                        to_self_delay: self.our_to_self_delay,
                        max_accepted_htlcs: OUR_MAX_HTLCS,
-                       funding_pubkey: PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.funding_key),
-                       revocation_basepoint: PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.revocation_base_key),
-                       payment_basepoint: PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.payment_base_key),
-                       delayed_payment_basepoint: PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.delayed_payment_base_key),
-                       htlc_basepoint: PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.htlc_base_key),
+                       funding_pubkey: PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key()),
+                       revocation_basepoint: PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.revocation_base_key()),
+                       payment_basepoint: PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.payment_base_key()),
+                       delayed_payment_basepoint: PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.delayed_payment_base_key()),
+                       htlc_basepoint: PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.htlc_base_key()),
                        first_per_commitment_point: PublicKey::from_secret_key(&self.secp_ctx, &local_commitment_secret),
                        shutdown_scriptpubkey: OptionalField::Present(if self.config.commit_upfront_shutdown_pubkey { self.get_closing_scriptpubkey() } else { Builder::new().into_script() })
                }
@@ -3222,14 +3142,10 @@ 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) -> Result<(Signature, Transaction), ChannelError> {
-               let funding_script = self.get_funding_redeemscript();
-
                let remote_keys = self.build_remote_transaction_keys()?;
                let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw).0;
-               let remote_sighash = hash_to_message!(&bip143::SighashComponents::new(&remote_initial_commitment_tx).sighash_all(&remote_initial_commitment_tx.input[0], &funding_script, self.channel_value_satoshis)[..]);
-
-               // We sign the "remote" commitment transaction, allowing them to broadcast the tx if they wish.
-               Ok((self.secp_ctx.sign(&remote_sighash, &self.local_keys.funding_key), remote_initial_commitment_tx))
+               Ok((self.local_keys.sign_remote_commitment(self.channel_value_satoshis, &self.get_funding_redeemscript(), self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), self.our_to_self_delay, &self.secp_ctx)
+                               .map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed"))?.0, remote_initial_commitment_tx))
        }
 
        /// Updates channel state with knowledge of the funding transaction's txid/index, and generates
@@ -3300,7 +3216,7 @@ impl Channel {
                }
 
                let were_node_one = our_node_id.serialize()[..] < self.their_node_id.serialize()[..];
-               let our_bitcoin_key = PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.funding_key);
+               let our_bitcoin_key = PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key());
 
                let msg = msgs::UnsignedChannelAnnouncement {
                        features: msgs::GlobalFeatures::new(),
@@ -3313,8 +3229,8 @@ impl Channel {
                        excess_data: Vec::new(),
                };
 
-               let msghash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]);
-               let sig = self.secp_ctx.sign(&msghash, &self.local_keys.funding_key);
+               let sig = self.local_keys.sign_channel_announcement(&msg, &self.secp_ctx)
+                       .map_err(|_| ChannelError::Ignore("Signer rejected channel_announcement"))?;
 
                Ok((msg, sig))
        }
@@ -3519,8 +3435,6 @@ 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) -> Result<(msgs::CommitmentSigned, (Transaction, Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)>)), ChannelError> {
-               let funding_script = self.get_funding_redeemscript();
-
                let mut feerate_per_kw = self.feerate_per_kw;
                if let Some(feerate) = self.pending_update_fee {
                        if self.channel_outbound {
@@ -3530,27 +3444,37 @@ impl Channel {
 
                let remote_keys = self.build_remote_transaction_keys()?;
                let remote_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, true, feerate_per_kw);
-               let remote_commitment_txid = remote_commitment_tx.0.txid();
-               let remote_sighash = hash_to_message!(&bip143::SighashComponents::new(&remote_commitment_tx.0).sighash_all(&remote_commitment_tx.0.input[0], &funding_script, self.channel_value_satoshis)[..]);
-               let our_sig = self.secp_ctx.sign(&remote_sighash, &self.local_keys.funding_key);
-               log_trace!(self, "Signing remote commitment tx {} with redeemscript {} with pubkey {} -> {}", encode::serialize_hex(&remote_commitment_tx.0), encode::serialize_hex(&funding_script), log_bytes!(PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.funding_key).serialize()), log_bytes!(our_sig.serialize_compact()[..]));
+               let (signature, htlc_signatures);
 
-               let mut htlc_sigs = Vec::with_capacity(remote_commitment_tx.1);
-               for &(ref htlc, _) in remote_commitment_tx.2.iter() {
-                       if let Some(_) = htlc.transaction_output_index {
-                               let htlc_tx = self.build_htlc_transaction(&remote_commitment_txid, htlc, false, &remote_keys, feerate_per_kw);
-                               let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &remote_keys);
-                               let htlc_sighash = hash_to_message!(&bip143::SighashComponents::new(&htlc_tx).sighash_all(&htlc_tx.input[0], &htlc_redeemscript, htlc.amount_msat / 1000)[..]);
-                               let our_htlc_key = secp_check!(chan_utils::derive_private_key(&self.secp_ctx, &remote_keys.per_commitment_point, &self.local_keys.htlc_base_key), "Derived invalid key, peer is maliciously selecting parameters");
-                               htlc_sigs.push(self.secp_ctx.sign(&htlc_sighash, &our_htlc_key));
-                               log_trace!(self, "Signing remote HTLC tx {} with redeemscript {} with pubkey {} -> {}", encode::serialize_hex(&htlc_tx), encode::serialize_hex(&htlc_redeemscript), log_bytes!(PublicKey::from_secret_key(&self.secp_ctx, &our_htlc_key).serialize()), log_bytes!(htlc_sigs.last().unwrap().serialize_compact()[..]));
+               {
+                       let mut htlcs = Vec::with_capacity(remote_commitment_tx.2.len());
+                       for &(ref htlc, _) in remote_commitment_tx.2.iter() {
+                               htlcs.push(htlc);
+                       }
+
+                       let res = self.local_keys.sign_remote_commitment(self.channel_value_satoshis, &self.get_funding_redeemscript(), feerate_per_kw, &remote_commitment_tx.0, &remote_keys, &htlcs, self.our_to_self_delay, &self.secp_ctx)
+                               .map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed"))?;
+                       signature = res.0;
+                       htlc_signatures = res.1;
+
+                       log_trace!(self, "Signed remote commitment tx {} with redeemscript {} -> {}",
+                               encode::serialize_hex(&remote_commitment_tx.0),
+                               encode::serialize_hex(&self.get_funding_redeemscript()),
+                               log_bytes!(signature.serialize_compact()[..]));
+
+                       for (ref htlc_sig, ref htlc) in htlc_signatures.iter().zip(htlcs) {
+                               log_trace!(self, "Signed remote HTLC tx {} with redeemscript {} with pubkey {} -> {}",
+                                       encode::serialize_hex(&chan_utils::build_htlc_transaction(&remote_commitment_tx.0.txid(), feerate_per_kw, self.our_to_self_delay, htlc, &remote_keys.a_delayed_payment_key, &remote_keys.revocation_key)),
+                                       encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, &remote_keys)),
+                                       log_bytes!(remote_keys.a_htlc_key.serialize()),
+                                       log_bytes!(htlc_sig.serialize_compact()[..]));
                        }
                }
 
                Ok((msgs::CommitmentSigned {
                        channel_id: self.channel_id,
-                       signature: our_sig,
-                       htlc_signatures: htlc_sigs,
+                       signature,
+                       htlc_signatures,
                }, (remote_commitment_tx.0, remote_commitment_tx.2)))
        }
 
@@ -3647,9 +3571,7 @@ impl Channel {
 
                self.channel_state = ChannelState::ShutdownComplete as u32;
                self.channel_update_count += 1;
-               let mut res = Vec::new();
-               mem::swap(&mut res, &mut self.last_local_commitment_txn);
-               (res, dropped_outbound_htlcs)
+               (self.channel_monitor.get_latest_local_commitment_txn(), dropped_outbound_htlcs)
        }
 }
 
@@ -3688,7 +3610,7 @@ impl<R: ::std::io::Read> Readable<R> for InboundHTLCRemovalReason {
        }
 }
 
-impl Writeable for Channel {
+impl<ChanSigner: ChannelKeys + Writeable> Writeable for Channel<ChanSigner> {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
                // Note that we write out as if remove_uncommitted_htlcs_and_mark_paused had just been
                // called but include holding cell updates (and obviously we don't modify self).
@@ -3839,21 +3761,12 @@ impl Writeable for Channel {
                self.channel_update_count.write(writer)?;
                self.feerate_per_kw.write(writer)?;
 
-               (self.last_local_commitment_txn.len() as u64).write(writer)?;
-               for tx in self.last_local_commitment_txn.iter() {
-                       if let Err(e) = tx.consensus_encode(&mut WriterWriteAdaptor(writer)) {
-                               match e {
-                                       encode::Error::Io(e) => return Err(e),
-                                       _ => panic!("last_local_commitment_txn must have been well-formed!"),
-                               }
-                       }
-               }
-
                match self.last_sent_closing_fee {
-                       Some((feerate, fee)) => {
+                       Some((feerate, fee, sig)) => {
                                1u8.write(writer)?;
                                feerate.write(writer)?;
                                fee.write(writer)?;
+                               sig.write(writer)?;
                        },
                        None => 0u8.write(writer)?,
                }
@@ -3892,7 +3805,7 @@ impl Writeable for Channel {
        }
 }
 
-impl<R : ::std::io::Read> ReadableArgs<R, Arc<Logger>> for Channel {
+impl<R : ::std::io::Read, ChanSigner: ChannelKeys + Readable<R>> ReadableArgs<R, Arc<Logger>> for Channel<ChanSigner> {
        fn read(reader: &mut R, logger: Arc<Logger>) -> Result<Self, DecodeError> {
                let _ver: u8 = Readable::read(reader)?;
                let min_ver: u8 = Readable::read(reader)?;
@@ -4006,18 +3919,9 @@ impl<R : ::std::io::Read> ReadableArgs<R, Arc<Logger>> for Channel {
                let channel_update_count = Readable::read(reader)?;
                let feerate_per_kw = Readable::read(reader)?;
 
-               let last_local_commitment_txn_count: u64 = Readable::read(reader)?;
-               let mut last_local_commitment_txn = Vec::with_capacity(cmp::min(last_local_commitment_txn_count as usize, OUR_MAX_HTLCS as usize*2 + 1));
-               for _ in 0..last_local_commitment_txn_count {
-                       last_local_commitment_txn.push(match Transaction::consensus_decode(reader.by_ref()) {
-                               Ok(tx) => tx,
-                               Err(_) => return Err(DecodeError::InvalidValue),
-                       });
-               }
-
                let last_sent_closing_fee = match <u8 as Readable<R>>::read(reader)? {
                        0 => None,
-                       1 => Some((Readable::read(reader)?, Readable::read(reader)?)),
+                       1 => Some((Readable::read(reader)?, Readable::read(reader)?, Readable::read(reader)?)),
                        _ => return Err(DecodeError::InvalidValue),
                };
 
@@ -4097,8 +4001,6 @@ impl<R : ::std::io::Read> ReadableArgs<R, Arc<Logger>> for Channel {
                        #[cfg(debug_assertions)]
                        max_commitment_tx_output_remote: ::std::sync::Mutex::new((0, 0)),
 
-                       last_local_commitment_txn,
-
                        last_sent_closing_fee,
 
                        funding_tx_confirmed_in,
@@ -4151,8 +4053,9 @@ mod tests {
        use ln::channel::{Channel,ChannelKeys,InboundHTLCOutput,OutboundHTLCOutput,InboundHTLCState,OutboundHTLCState,HTLCOutputInCommitment,TxCreationKeys};
        use ln::channel::MAX_FUNDING_SATOSHIS;
        use ln::chan_utils;
+       use ln::chan_utils::LocalCommitmentTransaction;
        use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
-       use chain::keysinterface::KeysInterface;
+       use chain::keysinterface::{InMemoryChannelKeys, KeysInterface};
        use chain::transaction::OutPoint;
        use util::config::UserConfig;
        use util::test_utils;
@@ -4181,9 +4084,11 @@ mod tests {
        }
 
        struct Keys {
-               chan_keys: ChannelKeys,
+               chan_keys: InMemoryChannelKeys,
        }
        impl KeysInterface for Keys {
+               type ChanKeySigner = InMemoryChannelKeys;
+
                fn get_node_secret(&self) -> SecretKey { panic!(); }
                fn get_destination_script(&self) -> Script {
                        let secp_ctx = Secp256k1::signing_only();
@@ -4198,7 +4103,7 @@ mod tests {
                        PublicKey::from_secret_key(&secp_ctx, &channel_close_key)
                }
 
-               fn get_channel_keys(&self, _inbound: bool) -> ChannelKeys { self.chan_keys.clone() }
+               fn get_channel_keys(&self, _inbound: bool) -> InMemoryChannelKeys { self.chan_keys.clone() }
                fn get_onion_rand(&self) -> (SecretKey, [u8; 32]) { panic!(); }
                fn get_channel_id(&self) -> [u8; 32] { [0; 32] }
        }
@@ -4210,7 +4115,7 @@ mod tests {
                let logger : Arc<Logger> = Arc::new(test_utils::TestLogger::new());
                let secp_ctx = Secp256k1::new();
 
-               let chan_keys = ChannelKeys {
+               let chan_keys = InMemoryChannelKeys {
                        funding_key: SecretKey::from_slice(&hex::decode("30ff4956bbdd3222d44cc5e8a1261dab1e07957bdac5ae88fe3261ef321f3749").unwrap()[..]).unwrap(),
                        payment_base_key: SecretKey::from_slice(&hex::decode("1111111111111111111111111111111111111111111111111111111111111111").unwrap()[..]).unwrap(),
                        delayed_payment_base_key: SecretKey::from_slice(&hex::decode("3333333333333333333333333333333333333333333333333333333333333333").unwrap()[..]).unwrap(),
@@ -4220,14 +4125,14 @@ mod tests {
                        revocation_base_key: SecretKey::from_slice(&hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(),
                        commitment_seed: [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
                };
-               assert_eq!(PublicKey::from_secret_key(&secp_ctx, &chan_keys.funding_key).serialize()[..],
+               assert_eq!(PublicKey::from_secret_key(&secp_ctx, chan_keys.funding_key()).serialize()[..],
                                hex::decode("023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb").unwrap()[..]);
-               let keys_provider: Arc<KeysInterface> = Arc::new(Keys { chan_keys });
+               let keys_provider: Arc<KeysInterface<ChanKeySigner = InMemoryChannelKeys>> = Arc::new(Keys { chan_keys });
 
                let their_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
                let mut config = UserConfig::default();
                config.channel_options.announced_channel = false;
-               let mut chan = Channel::new_outbound(&feeest, &keys_provider, their_node_id, 10000000, 100000, 42, Arc::clone(&logger), &config).unwrap(); // Nothing uses their network key in this test
+               let mut chan = Channel::<InMemoryChannelKeys>::new_outbound(&feeest, &keys_provider, their_node_id, 10000000, 100000, 42, Arc::clone(&logger), &config).unwrap(); // Nothing uses their network key in this test
                chan.their_to_self_delay = 144;
                chan.our_dust_limit_satoshis = 546;
 
@@ -4251,10 +4156,10 @@ mod tests {
                // We can't just use build_local_transaction_keys here as the per_commitment_secret is not
                // derived from a commitment_seed, so instead we copy it here and call
                // build_commitment_transaction.
-               let delayed_payment_base = PublicKey::from_secret_key(&secp_ctx, &chan.local_keys.delayed_payment_base_key);
+               let delayed_payment_base = PublicKey::from_secret_key(&secp_ctx, chan.local_keys.delayed_payment_base_key());
                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 = PublicKey::from_secret_key(&secp_ctx, &chan.local_keys.htlc_base_key);
+               let htlc_basepoint = PublicKey::from_secret_key(&secp_ctx, chan.local_keys.htlc_base_key());
                let keys = TxCreationKeys::new(&secp_ctx, &per_commitment_point, &delayed_payment_base, &htlc_basepoint, &chan.their_revocation_basepoint.unwrap(), &chan.their_payment_basepoint.unwrap(), &chan.their_htlc_basepoint.unwrap()).unwrap();
 
                let mut unsigned_tx: (Transaction, Vec<HTLCOutputInCommitment>);
@@ -4268,13 +4173,15 @@ mod tests {
                                                .collect();
                                        (res.0, htlcs)
                                };
+                               let redeemscript = chan.get_funding_redeemscript();
                                let their_signature = Signature::from_der(&hex::decode($their_sig_hex).unwrap()[..]).unwrap();
-                               let sighash = Message::from_slice(&bip143::SighashComponents::new(&unsigned_tx.0).sighash_all(&unsigned_tx.0.input[0], &chan.get_funding_redeemscript(), chan.channel_value_satoshis)[..]).unwrap();
+                               let sighash = Message::from_slice(&bip143::SighashComponents::new(&unsigned_tx.0).sighash_all(&unsigned_tx.0.input[0], &redeemscript, chan.channel_value_satoshis)[..]).unwrap();
                                secp_ctx.verify(&sighash, &their_signature, &chan.their_funding_pubkey.unwrap()).unwrap();
 
-                               chan.sign_commitment_transaction(&mut unsigned_tx.0, &their_signature);
+                               let mut localtx = LocalCommitmentTransaction::new_missing_local_sig(unsigned_tx.0.clone(), &their_signature, &PublicKey::from_secret_key(&secp_ctx, chan.local_keys.funding_key()), chan.their_funding_pubkey.as_ref().unwrap());
+                               localtx.add_local_sig(chan.local_keys.funding_key(), &redeemscript, chan.channel_value_satoshis, &chan.secp_ctx);
 
-                               assert_eq!(serialize(&unsigned_tx.0)[..],
+                               assert_eq!(serialize(localtx.with_valid_witness())[..],
                                                hex::decode($tx_hex).unwrap()[..]);
                        };
                }
@@ -4301,7 +4208,7 @@ mod tests {
                                        assert!(preimage.is_some());
                                }
 
-                               chan.sign_htlc_transaction(&mut htlc_tx, &remote_signature, &preimage, &htlc, &keys).unwrap();
+                               chan_utils::sign_htlc_transaction(&mut htlc_tx, &remote_signature, &preimage, &htlc, &keys.a_htlc_key, &keys.b_htlc_key, &keys.revocation_key, &keys.per_commitment_point, chan.local_keys.htlc_base_key(), &chan.secp_ctx).unwrap();
                                assert_eq!(serialize(&htlc_tx)[..],
                                                hex::decode($tx_hex).unwrap()[..]);
                        };
@@ -4699,21 +4606,21 @@ mod tests {
 
                let mut seed = [0; 32];
                seed[0..32].clone_from_slice(&hex::decode("0000000000000000000000000000000000000000000000000000000000000000").unwrap());
-               assert_eq!(chan_utils::build_commitment_secret(seed, 281474976710655),
+               assert_eq!(chan_utils::build_commitment_secret(&seed, 281474976710655),
                           hex::decode("02a40c85b6f28da08dfdbe0926c53fab2de6d28c10301f8f7c4073d5e42e3148").unwrap()[..]);
 
                seed[0..32].clone_from_slice(&hex::decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF").unwrap());
-               assert_eq!(chan_utils::build_commitment_secret(seed, 281474976710655),
+               assert_eq!(chan_utils::build_commitment_secret(&seed, 281474976710655),
                           hex::decode("7cc854b54e3e0dcdb010d7a3fee464a9687be6e8db3be6854c475621e007a5dc").unwrap()[..]);
 
-               assert_eq!(chan_utils::build_commitment_secret(seed, 0xaaaaaaaaaaa),
+               assert_eq!(chan_utils::build_commitment_secret(&seed, 0xaaaaaaaaaaa),
                           hex::decode("56f4008fb007ca9acf0e15b054d5c9fd12ee06cea347914ddbaed70d1c13a528").unwrap()[..]);
 
-               assert_eq!(chan_utils::build_commitment_secret(seed, 0x555555555555),
+               assert_eq!(chan_utils::build_commitment_secret(&seed, 0x555555555555),
                           hex::decode("9015daaeb06dba4ccc05b91b2f73bd54405f2be9f217fbacd3c5ac2e62327d31").unwrap()[..]);
 
                seed[0..32].clone_from_slice(&hex::decode("0101010101010101010101010101010101010101010101010101010101010101").unwrap());
-               assert_eq!(chan_utils::build_commitment_secret(seed, 1),
+               assert_eq!(chan_utils::build_commitment_secret(&seed, 1),
                           hex::decode("915c75942a26bb3a433a8ce2cb0427c29ec6c1775cfc78328b57f6ba7bfeaa9c").unwrap()[..]);
        }