Merge pull request #159 from ariard/channel_monitor
[rust-lightning] / src / ln / channelmonitor.rs
index ffc9ed26fdaa60a0f81375ce88588f2f4aa8f18d..cb2aba780a5862ae48ba87bc77db4f07b837e0eb 100644 (file)
@@ -1,5 +1,6 @@
 use bitcoin::blockdata::block::BlockHeader;
 use bitcoin::blockdata::transaction::{TxIn,TxOut,SigHashType,Transaction};
+use bitcoin::blockdata::transaction::OutPoint as BitcoinOutPoint;
 use bitcoin::blockdata::script::Script;
 use bitcoin::network::serialize;
 use bitcoin::util::hash::Sha256dHash;
@@ -9,6 +10,7 @@ use crypto::digest::Digest;
 
 use secp256k1::{Secp256k1,Message,Signature};
 use secp256k1::key::{SecretKey,PublicKey};
+use secp256k1;
 
 use ln::msgs::HandleError;
 use ln::chan_utils;
@@ -44,6 +46,8 @@ pub enum ChannelMonitorUpdateErr {
 /// channel's monitor everywhere (including remote watchtowers) *before* this function returns. If
 /// an update occurs and a remote watchtower is left with old state, it may broadcast transactions
 /// which we have revoked, allowing our counterparty to claim all funds in the channel!
+/// A call to add_update_monitor is needed to register outpoint and its txid with ChainWatchInterface 
+/// after setting funding_txo in a ChannelMonitor
 pub trait ManyChannelMonitor: Send + Sync {
        /// Adds or updates a monitor for the given `funding_txo`.
        fn add_update_monitor(&self, funding_txo: OutPoint, monitor: ChannelMonitor) -> Result<(), ChannelMonitorUpdateErr>;
@@ -67,7 +71,12 @@ impl<Key : Send + cmp::Eq + hash::Hash> ChainListener for SimpleManyChannelMonit
        fn block_connected(&self, _header: &BlockHeader, height: u32, txn_matched: &[&Transaction], _indexes_of_txn_matched: &[u32]) {
                let monitors = self.monitors.lock().unwrap();
                for monitor in monitors.values() {
-                       monitor.block_connected(txn_matched, height, &*self.broadcaster);
+                       let txn_outputs = monitor.block_connected(txn_matched, height, &*self.broadcaster);
+                       for (ref txid, ref outputs) in txn_outputs {
+                               for (idx, output) in outputs.iter().enumerate() {
+                                       self.chain_monitor.install_watch_outpoint((txid.clone(), idx as u32), &output.script_pubkey);
+                               }
+                       }
                }
        }
 
@@ -95,7 +104,7 @@ impl<Key : Send + cmp::Eq + hash::Hash + 'static> SimpleManyChannelMonitor<Key>
                match &monitor.funding_txo {
                        &None => self.chain_monitor.watch_all_txn(),
                        &Some((ref outpoint, ref script)) => {
-                               self.chain_monitor.install_watch_script(script);
+                               self.chain_monitor.install_watch_tx(&outpoint.txid, script);
                                self.chain_monitor.install_watch_outpoint((outpoint.txid, outpoint.index as u32), script);
                        },
                }
@@ -186,7 +195,7 @@ pub struct ChannelMonitor {
        payment_preimages: HashMap<[u8; 32], [u8; 32]>,
 
        destination_script: Script,
-       secp_ctx: Secp256k1, //TODO: dedup this a bit...
+       secp_ctx: Secp256k1<secp256k1::All>, //TODO: dedup this a bit...
 }
 impl Clone for ChannelMonitor {
        fn clone(&self) -> Self {
@@ -462,8 +471,9 @@ impl ChannelMonitor {
        /// optional, without it this monitor cannot be used in an SPV client, but you may wish to
        /// avoid this (or call unset_funding_info) on a monitor you wish to send to a watchtower as it
        /// provides slightly better privacy.
+       /// It's the responsability of the caller to register outpoint and script with passing the former
+       /// value as key to add_update_monitor.
        pub(super) fn set_funding_info(&mut self, funding_info: (OutPoint, Script)) {
-               //TODO: Need to register the given script here with a chain_monitor
                self.funding_txo = Some(funding_info);
        }
 
@@ -906,42 +916,44 @@ impl ChannelMonitor {
        /// height > height + CLTV_SHARED_CLAIM_BUFFER. In any case, will install monitoring for
        /// HTLC-Success/HTLC-Timeout transactions, and claim them using the revocation key (if
        /// applicable) as well.
-       fn check_spend_remote_transaction(&self, tx: &Transaction, height: u32) -> Vec<Transaction> {
+       fn check_spend_remote_transaction(&self, tx: &Transaction, height: u32) -> (Vec<Transaction>, (Sha256dHash, Vec<TxOut>)) {
                // Most secp and related errors trying to create keys means we have no hope of constructing
                // a spend transaction...so we return no transactions to broadcast
                let mut txn_to_broadcast = Vec::new();
+               let mut watch_outputs = Vec::new();
+
+               let commitment_txid = tx.txid(); //TODO: This is gonna be a performance bottleneck for watchtowers!
+               let per_commitment_option = self.remote_claimable_outpoints.get(&commitment_txid);
+
                macro_rules! ignore_error {
                        ( $thing : expr ) => {
                                match $thing {
                                        Ok(a) => a,
-                                       Err(_) => return txn_to_broadcast
+                                       Err(_) => return (txn_to_broadcast, (commitment_txid, watch_outputs))
                                }
                        };
                }
 
-               let commitment_txid = tx.txid(); //TODO: This is gonna be a performance bottleneck for watchtowers!
-               let per_commitment_option = self.remote_claimable_outpoints.get(&commitment_txid);
-
                let commitment_number = 0xffffffffffff - ((((tx.input[0].sequence as u64 & 0xffffff) << 3*8) | (tx.lock_time as u64 & 0xffffff)) ^ self.commitment_transaction_number_obscure_factor);
                if commitment_number >= self.get_min_seen_secret() {
                        let secret = self.get_secret(commitment_number).unwrap();
                        let per_commitment_key = ignore_error!(SecretKey::from_slice(&self.secp_ctx, &secret));
                        let (revocation_pubkey, b_htlc_key) = match self.key_storage {
                                KeyStorage::PrivMode { ref revocation_base_key, ref htlc_base_key } => {
-                                       let per_commitment_point = ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key));
-                                       (ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, &per_commitment_point, &ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &revocation_base_key)))),
-                                       ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &per_commitment_point, &ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &htlc_base_key)))))
+                                       let per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key);
+                                       (ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, &per_commitment_point, &PublicKey::from_secret_key(&self.secp_ctx, &revocation_base_key))),
+                                       ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &per_commitment_point, &PublicKey::from_secret_key(&self.secp_ctx, &htlc_base_key))))
                                },
                                KeyStorage::SigsMode { ref revocation_base_key, ref htlc_base_key, .. } => {
-                                       let per_commitment_point = ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key));
+                                       let per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key);
                                        (ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, &per_commitment_point, &revocation_base_key)),
                                        ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &per_commitment_point, &htlc_base_key)))
                                },
                        };
-                       let delayed_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key)), &self.delayed_payment_base_key));
+                       let delayed_key = ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key), &self.delayed_payment_base_key));
                        let a_htlc_key = match self.their_htlc_base_key {
-                               None => return txn_to_broadcast,
-                               Some(their_htlc_base_key) => ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key)), &their_htlc_base_key)),
+                               None => return (txn_to_broadcast, (commitment_txid, watch_outputs)),
+                               Some(their_htlc_base_key) => ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, &PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key), &their_htlc_base_key)),
                        };
 
                        let revokeable_redeemscript = chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.our_to_self_delay, &delayed_key);
@@ -955,8 +967,10 @@ impl ChannelMonitor {
                        for (idx, outp) in tx.output.iter().enumerate() {
                                if outp.script_pubkey == revokeable_p2wsh {
                                        inputs.push(TxIn {
-                                               prev_hash: commitment_txid,
-                                               prev_index: idx as u32,
+                                               previous_output: BitcoinOutPoint {
+                                                       txid: commitment_txid,
+                                                       vout: idx as u32,
+                                               },
                                                script_sig: Script::new(),
                                                sequence: 0xfffffffd,
                                                witness: Vec::new(),
@@ -979,7 +993,7 @@ impl ChannelMonitor {
                                                                };
                                                                let sighash = ignore_error!(Message::from_slice(&$sighash_parts.sighash_all(&$input, &redeemscript, $amount)[..]));
                                                                let revocation_key = ignore_error!(chan_utils::derive_private_revocation_key(&self.secp_ctx, &per_commitment_key, &revocation_base_key));
-                                                               (ignore_error!(self.secp_ctx.sign(&sighash, &revocation_key)), redeemscript)
+                                                               (self.secp_ctx.sign(&sighash, &revocation_key), redeemscript)
                                                        },
                                                        KeyStorage::SigsMode { .. } => {
                                                                unimplemented!();
@@ -992,7 +1006,7 @@ impl ChannelMonitor {
                                                } else {
                                                        $input.witness.push(revocation_pubkey.serialize().to_vec());
                                                }
-                                               $input.witness.push(redeemscript.into_vec());
+                                               $input.witness.push(redeemscript.into_bytes());
                                        }
                                }
                        }
@@ -1005,11 +1019,13 @@ impl ChannelMonitor {
                                        if htlc.transaction_output_index as usize >= tx.output.len() ||
                                                        tx.output[htlc.transaction_output_index as usize].value != htlc.amount_msat / 1000 ||
                                                        tx.output[htlc.transaction_output_index as usize].script_pubkey != expected_script.to_v0_p2wsh() {
-                                               return txn_to_broadcast; // Corrupted per_commitment_data, fuck this user
+                                               return (txn_to_broadcast, (commitment_txid, watch_outputs)); // Corrupted per_commitment_data, fuck this user
                                        }
                                        let input = TxIn {
-                                               prev_hash: commitment_txid,
-                                               prev_index: htlc.transaction_output_index,
+                                               previous_output: BitcoinOutPoint {
+                                                       txid: commitment_txid,
+                                                       vout: htlc.transaction_output_index,
+                                               },
                                                script_sig: Script::new(),
                                                sequence: 0xfffffffd,
                                                witness: Vec::new(),
@@ -1038,10 +1054,10 @@ impl ChannelMonitor {
 
                        if !inputs.is_empty() || !txn_to_broadcast.is_empty() { // ie we're confident this is actually ours
                                // We're definitely a remote commitment transaction!
-                               // TODO: Register all outputs in commitment_tx with the ChainWatchInterface!
+                               watch_outputs.append(&mut tx.output.clone());
                                self.remote_commitment_txn_on_chain.lock().unwrap().insert(commitment_txid, commitment_number);
                        }
-                       if inputs.is_empty() { return txn_to_broadcast; } // Nothing to be done...probably a false positive/local tx
+                       if inputs.is_empty() { return (txn_to_broadcast, (commitment_txid, watch_outputs)); } // Nothing to be done...probably a false positive/local tx
 
                        let outputs = vec!(TxOut {
                                script_pubkey: self.destination_script.clone(),
@@ -1071,7 +1087,7 @@ impl ChannelMonitor {
                        // already processed the block, resulting in the remote_commitment_txn_on_chain entry
                        // not being generated by the above conditional. Thus, to be safe, we go ahead and
                        // insert it here.
-                       // TODO: Register all outputs in commitment_tx with the ChainWatchInterface!
+                       watch_outputs.append(&mut tx.output.clone());
                        self.remote_commitment_txn_on_chain.lock().unwrap().insert(commitment_txid, commitment_number);
 
                        if let Some(revocation_points) = self.their_cur_revocation_points {
@@ -1083,8 +1099,8 @@ impl ChannelMonitor {
                                if let Some(revocation_point) = revocation_point_option {
                                        let (revocation_pubkey, b_htlc_key) = match self.key_storage {
                                                KeyStorage::PrivMode { ref revocation_base_key, ref htlc_base_key } => {
-                                                       (ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, revocation_point, &ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &revocation_base_key)))),
-                                                       ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, revocation_point, &ignore_error!(PublicKey::from_secret_key(&self.secp_ctx, &htlc_base_key)))))
+                                                       (ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, revocation_point, &PublicKey::from_secret_key(&self.secp_ctx, &revocation_base_key))),
+                                                       ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, revocation_point, &PublicKey::from_secret_key(&self.secp_ctx, &htlc_base_key))))
                                                },
                                                KeyStorage::SigsMode { ref revocation_base_key, ref htlc_base_key, .. } => {
                                                        (ignore_error!(chan_utils::derive_public_revocation_key(&self.secp_ctx, revocation_point, &revocation_base_key)),
@@ -1092,7 +1108,7 @@ impl ChannelMonitor {
                                                },
                                        };
                                        let a_htlc_key = match self.their_htlc_base_key {
-                                               None => return txn_to_broadcast,
+                                               None => return (txn_to_broadcast, (commitment_txid, watch_outputs)),
                                                Some(their_htlc_base_key) => ignore_error!(chan_utils::derive_public_key(&self.secp_ctx, revocation_point, &their_htlc_base_key)),
                                        };
 
@@ -1109,7 +1125,7 @@ impl ChannelMonitor {
                                                                                let redeemscript = chan_utils::get_htlc_redeemscript_with_explicit_keys(htlc, &a_htlc_key, &b_htlc_key, &revocation_pubkey);
                                                                                let sighash = ignore_error!(Message::from_slice(&$sighash_parts.sighash_all(&$input, &redeemscript, $amount)[..]));
                                                                                let htlc_key = ignore_error!(chan_utils::derive_private_key(&self.secp_ctx, revocation_point, &htlc_base_key));
-                                                                               (ignore_error!(self.secp_ctx.sign(&sighash, &htlc_key)), redeemscript)
+                                                                               (self.secp_ctx.sign(&sighash, &htlc_key), redeemscript)
                                                                        },
                                                                        KeyStorage::SigsMode { .. } => {
                                                                                unimplemented!();
@@ -1118,7 +1134,7 @@ impl ChannelMonitor {
                                                                $input.witness.push(sig.serialize_der(&self.secp_ctx).to_vec());
                                                                $input.witness[0].push(SigHashType::All as u8);
                                                                $input.witness.push($preimage);
-                                                               $input.witness.push(redeemscript.into_vec());
+                                                               $input.witness.push(redeemscript.into_bytes());
                                                        }
                                                }
                                        }
@@ -1126,8 +1142,10 @@ impl ChannelMonitor {
                                        for (idx, htlc) in per_commitment_data.iter().enumerate() {
                                                if let Some(payment_preimage) = self.payment_preimages.get(&htlc.payment_hash) {
                                                        let input = TxIn {
-                                                               prev_hash: commitment_txid,
-                                                               prev_index: htlc.transaction_output_index,
+                                                               previous_output: BitcoinOutPoint {
+                                                                       txid: commitment_txid,
+                                                                       vout: htlc.transaction_output_index,
+                                                               },
                                                                script_sig: Script::new(),
                                                                sequence: idx as u32, // reset to 0xfffffffd in sign_input
                                                                witness: Vec::new(),
@@ -1153,7 +1171,7 @@ impl ChannelMonitor {
                                                }
                                        }
 
-                                       if inputs.is_empty() { return txn_to_broadcast; } // Nothing to be done...probably a false positive/local tx
+                                       if inputs.is_empty() { return (txn_to_broadcast, (commitment_txid, watch_outputs)); } // Nothing to be done...probably a false positive/local tx
 
                                        let outputs = vec!(TxOut {
                                                script_pubkey: self.destination_script.clone(),
@@ -1181,7 +1199,7 @@ impl ChannelMonitor {
                        //TODO: For each input check if its in our remote_commitment_txn_on_chain map!
                }
 
-               txn_to_broadcast
+               (txn_to_broadcast, (commitment_txid, watch_outputs))
        }
 
        fn broadcast_by_local_state(&self, local_tx: &LocalSignedTx) -> Vec<Transaction> {
@@ -1199,7 +1217,7 @@ impl ChannelMonitor {
                                htlc_timeout_tx.input[0].witness[2].push(SigHashType::All as u8);
 
                                htlc_timeout_tx.input[0].witness.push(Vec::new());
-                               htlc_timeout_tx.input[0].witness.push(chan_utils::get_htlc_redeemscript_with_explicit_keys(htlc, &local_tx.a_htlc_key, &local_tx.b_htlc_key, &local_tx.revocation_key).into_vec());
+                               htlc_timeout_tx.input[0].witness.push(chan_utils::get_htlc_redeemscript_with_explicit_keys(htlc, &local_tx.a_htlc_key, &local_tx.b_htlc_key, &local_tx.revocation_key).into_bytes());
 
                                res.push(htlc_timeout_tx);
                        } else {
@@ -1214,7 +1232,7 @@ impl ChannelMonitor {
                                        htlc_success_tx.input[0].witness[2].push(SigHashType::All as u8);
 
                                        htlc_success_tx.input[0].witness.push(payment_preimage.to_vec());
-                                       htlc_success_tx.input[0].witness.push(chan_utils::get_htlc_redeemscript_with_explicit_keys(htlc, &local_tx.a_htlc_key, &local_tx.b_htlc_key, &local_tx.revocation_key).into_vec());
+                                       htlc_success_tx.input[0].witness.push(chan_utils::get_htlc_redeemscript_with_explicit_keys(htlc, &local_tx.a_htlc_key, &local_tx.b_htlc_key, &local_tx.revocation_key).into_bytes());
 
                                        res.push(htlc_success_tx);
                                }
@@ -1242,11 +1260,15 @@ impl ChannelMonitor {
                Vec::new()
        }
 
-       fn block_connected(&self, txn_matched: &[&Transaction], height: u32, broadcaster: &BroadcasterInterface) {
+       fn block_connected(&self, txn_matched: &[&Transaction], height: u32, broadcaster: &BroadcasterInterface)-> Vec<(Sha256dHash, Vec<TxOut>)> {
+               let mut watch_outputs = Vec::new();
                for tx in txn_matched {
                        for txin in tx.input.iter() {
-                               if self.funding_txo.is_none() || (txin.prev_hash == self.funding_txo.as_ref().unwrap().0.txid && txin.prev_index == self.funding_txo.as_ref().unwrap().0.index as u32) {
-                                       let mut txn = self.check_spend_remote_transaction(tx, height);
+                               if self.funding_txo.is_none() || (txin.previous_output.txid == self.funding_txo.as_ref().unwrap().0.txid && txin.previous_output.vout == self.funding_txo.as_ref().unwrap().0.index as u32) {
+                                       let (mut txn, new_outputs) = self.check_spend_remote_transaction(tx, height);
+                                       if !new_outputs.1.is_empty() {
+                                               watch_outputs.push(new_outputs);
+                                       }
                                        if txn.is_empty() {
                                                txn = self.check_spend_local_transaction(tx, height);
                                        }
@@ -1273,6 +1295,7 @@ impl ChannelMonitor {
                                }
                        }
                }
+               watch_outputs
        }
 
        pub fn would_broadcast_at_height(&self, height: u32) -> bool {
@@ -1321,9 +1344,11 @@ mod tests {
                        };
                }
 
+               let delayed_payment_base_key = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap());
+
                {
                        // insert_secret correct sequence
-                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
+                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &delayed_payment_base_key, &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
                        secrets.clear();
 
                        secrets.push([0; 32]);
@@ -1369,7 +1394,7 @@ mod tests {
 
                {
                        // insert_secret #1 incorrect
-                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
+                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &delayed_payment_base_key, &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
                        secrets.clear();
 
                        secrets.push([0; 32]);
@@ -1385,7 +1410,7 @@ mod tests {
 
                {
                        // insert_secret #2 incorrect (#1 derived from incorrect)
-                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
+                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &delayed_payment_base_key, &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
                        secrets.clear();
 
                        secrets.push([0; 32]);
@@ -1411,7 +1436,7 @@ mod tests {
 
                {
                        // insert_secret #3 incorrect
-                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
+                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &delayed_payment_base_key, &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
                        secrets.clear();
 
                        secrets.push([0; 32]);
@@ -1437,7 +1462,7 @@ mod tests {
 
                {
                        // insert_secret #4 incorrect (1,2,3 derived from incorrect)
-                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
+                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &delayed_payment_base_key, &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
                        secrets.clear();
 
                        secrets.push([0; 32]);
@@ -1483,7 +1508,7 @@ mod tests {
 
                {
                        // insert_secret #5 incorrect
-                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
+                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &delayed_payment_base_key, &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
                        secrets.clear();
 
                        secrets.push([0; 32]);
@@ -1519,7 +1544,7 @@ mod tests {
 
                {
                        // insert_secret #6 incorrect (5 derived from incorrect)
-                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
+                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &delayed_payment_base_key, &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
                        secrets.clear();
 
                        secrets.push([0; 32]);
@@ -1565,7 +1590,7 @@ mod tests {
 
                {
                        // insert_secret #7 incorrect
-                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
+                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &delayed_payment_base_key, &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
                        secrets.clear();
 
                        secrets.push([0; 32]);
@@ -1611,7 +1636,7 @@ mod tests {
 
                {
                        // insert_secret #8 incorrect
-                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
+                       monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &delayed_payment_base_key, &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
                        secrets.clear();
 
                        secrets.push([0; 32]);
@@ -1663,13 +1688,16 @@ mod tests {
 
                macro_rules! dummy_keys {
                        () => {
-                               TxCreationKeys {
-                                       per_commitment_point: PublicKey::new(),
-                                       revocation_key: PublicKey::new(),
-                                       a_htlc_key: PublicKey::new(),
-                                       b_htlc_key: PublicKey::new(),
-                                       a_delayed_payment_key: PublicKey::new(),
-                                       b_payment_key: PublicKey::new(),
+                               {
+                                       let dummy_key = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap());
+                                       TxCreationKeys {
+                                               per_commitment_point: dummy_key.clone(),
+                                               revocation_key: dummy_key.clone(),
+                                               a_htlc_key: dummy_key.clone(),
+                                               b_htlc_key: dummy_key.clone(),
+                                               a_delayed_payment_key: dummy_key.clone(),
+                                               b_payment_key: dummy_key.clone(),
+                                       }
                                }
                        }
                }
@@ -1726,7 +1754,8 @@ mod tests {
 
                // Prune with one old state and a local commitment tx holding a few overlaps with the
                // old state.
-               let mut monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &PublicKey::new(), &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
+               let delayed_payment_base_key = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap());
+               let mut monitor = ChannelMonitor::new(&SecretKey::from_slice(&secp_ctx, &[42; 32]).unwrap(), &delayed_payment_base_key, &SecretKey::from_slice(&secp_ctx, &[43; 32]).unwrap(), 0, Script::new());
                monitor.set_their_to_self_delay(10);
 
                monitor.provide_latest_local_commitment_tx_info(dummy_tx.clone(), dummy_keys!(), 0, preimages_to_local_htlcs!(preimages[0..10]));