Generate shutdown script at channel close
[rust-lightning] / lightning / src / util / test_utils.rs
index a1438f3c6ea92a88213c5dff9c8656d431f69ec1..15157e50e556554a38988d67e2a38043d23a938f 100644 (file)
@@ -19,6 +19,7 @@ use chain::keysinterface;
 use ln::features::{ChannelFeatures, InitFeatures};
 use ln::msgs;
 use ln::msgs::OptionalField;
+use ln::script::ShutdownScript;
 use util::enforcing_trait_impls::{EnforcingSigner, INITIAL_REVOKED_COMMITMENT_NUMBER};
 use util::events;
 use util::logger::{Logger, Level, Record};
@@ -37,17 +38,17 @@ use bitcoin::secp256k1::recovery::RecoverableSignature;
 
 use regex;
 
+use io;
 use prelude::*;
 use core::time::Duration;
-use std::sync::{Mutex, Arc};
+use sync::{Mutex, Arc};
 use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
 use core::{cmp, mem};
-use std::collections::{HashMap, HashSet, VecDeque};
 use chain::keysinterface::InMemorySigner;
 
 pub struct TestVecWriter(pub Vec<u8>);
 impl Writer for TestVecWriter {
-       fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
+       fn write_all(&mut self, buf: &[u8]) -> Result<(), io::Error> {
                self.0.extend_from_slice(buf);
                Ok(())
        }
@@ -57,11 +58,11 @@ impl Writer for TestVecWriter {
 }
 
 pub struct TestFeeEstimator {
-       pub sat_per_kw: u32,
+       pub sat_per_kw: Mutex<u32>,
 }
 impl chaininterface::FeeEstimator for TestFeeEstimator {
        fn get_est_sat_per_1000_weight(&self, _confirmation_target: ConfirmationTarget) -> u32 {
-               self.sat_per_kw
+               *self.sat_per_kw.lock().unwrap()
        }
 }
 
@@ -71,12 +72,12 @@ impl keysinterface::KeysInterface for OnlyReadsKeysInterface {
 
        fn get_node_secret(&self) -> SecretKey { unreachable!(); }
        fn get_destination_script(&self) -> Script { unreachable!(); }
-       fn get_shutdown_pubkey(&self) -> PublicKey { unreachable!(); }
+       fn get_shutdown_scriptpubkey(&self) -> ShutdownScript { unreachable!(); }
        fn get_channel_signer(&self, _inbound: bool, _channel_value_satoshis: u64) -> EnforcingSigner { unreachable!(); }
        fn get_secure_random_bytes(&self) -> [u8; 32] { [0; 32] }
 
        fn read_chan_signer(&self, reader: &[u8]) -> Result<Self::Signer, msgs::DecodeError> {
-               EnforcingSigner::read(&mut std::io::Cursor::new(reader))
+               EnforcingSigner::read(&mut io::Cursor::new(reader))
        }
        fn sign_invoice(&self, _invoice_preimage: Vec<u8>) -> Result<RecoverableSignature, ()> { unreachable!(); }
 }
@@ -115,7 +116,7 @@ impl<'a> chain::Watch<EnforcingSigner> for TestChainMonitor<'a> {
                let mut w = TestVecWriter(Vec::new());
                monitor.write(&mut w).unwrap();
                let new_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(
-                       &mut ::std::io::Cursor::new(&w.0), self.keys_manager).unwrap().1;
+                       &mut io::Cursor::new(&w.0), self.keys_manager).unwrap().1;
                assert!(new_monitor == monitor);
                self.latest_monitor_update_id.lock().unwrap().insert(funding_txo.to_channel_id(), (funding_txo, monitor.get_latest_update_id()));
                self.added_monitors.lock().unwrap().push((funding_txo, monitor));
@@ -137,7 +138,7 @@ impl<'a> chain::Watch<EnforcingSigner> for TestChainMonitor<'a> {
                let mut w = TestVecWriter(Vec::new());
                update.write(&mut w).unwrap();
                assert!(channelmonitor::ChannelMonitorUpdate::read(
-                               &mut ::std::io::Cursor::new(&w.0)).unwrap() == update);
+                               &mut io::Cursor::new(&w.0)).unwrap() == update);
 
                if let Some(exp) = self.expect_channel_force_closed.lock().unwrap().take() {
                        assert_eq!(funding_txo.to_channel_id(), exp.0);
@@ -156,7 +157,7 @@ impl<'a> chain::Watch<EnforcingSigner> for TestChainMonitor<'a> {
                w.0.clear();
                monitor.write(&mut w).unwrap();
                let new_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(
-                       &mut ::std::io::Cursor::new(&w.0), self.keys_manager).unwrap().1;
+                       &mut io::Cursor::new(&w.0), self.keys_manager).unwrap().1;
                assert!(new_monitor == *monitor);
                self.added_monitors.lock().unwrap().push((funding_txo, new_monitor));
 
@@ -206,6 +207,14 @@ pub struct TestBroadcaster {
 }
 impl chaininterface::BroadcasterInterface for TestBroadcaster {
        fn broadcast_transaction(&self, tx: &Transaction) {
+               assert!(tx.lock_time < 1_500_000_000);
+               if tx.lock_time > self.blocks.lock().unwrap().len() as u32 + 1 && tx.lock_time < 500_000_000 {
+                       for inp in tx.input.iter() {
+                               if inp.sequence != 0xffffffff {
+                                       panic!("We should never broadcast a transaction before its locktime ({})!", tx.lock_time);
+                               }
+                       }
+               }
                self.txn_broadcasted.lock().unwrap().push(tx.clone());
        }
 }
@@ -432,7 +441,7 @@ impl TestLogger {
 impl Logger for TestLogger {
        fn log(&self, record: &Record) {
                *self.lines.lock().unwrap().entry((record.module_path.to_string(), format!("{}", record.args))).or_insert(0) += 1;
-               if self.level >= record.level {
+               if record.level >= self.level {
                        println!("{:<5} {} [{} : {}, {}] {}", record.level.to_string(), self.id, record.module_path, record.file, record.line, record.args);
                }
        }
@@ -444,6 +453,7 @@ pub struct TestKeysInterface {
        pub override_channel_id_priv: Mutex<Option<[u8; 32]>>,
        pub disable_revocation_policy_check: bool,
        revoked_commitments: Mutex<HashMap<[u8;32], Arc<Mutex<u64>>>>,
+       expectations: Mutex<Option<VecDeque<OnGetShutdownScriptpubkey>>>,
 }
 
 impl keysinterface::KeysInterface for TestKeysInterface {
@@ -451,7 +461,17 @@ impl keysinterface::KeysInterface for TestKeysInterface {
 
        fn get_node_secret(&self) -> SecretKey { self.backing.get_node_secret() }
        fn get_destination_script(&self) -> Script { self.backing.get_destination_script() }
-       fn get_shutdown_pubkey(&self) -> PublicKey { self.backing.get_shutdown_pubkey() }
+
+       fn get_shutdown_scriptpubkey(&self) -> ShutdownScript {
+               match &mut *self.expectations.lock().unwrap() {
+                       None => self.backing.get_shutdown_scriptpubkey(),
+                       Some(expectations) => match expectations.pop_front() {
+                               None => panic!("Unexpected get_shutdown_scriptpubkey"),
+                               Some(expectation) => expectation.returns,
+                       },
+               }
+       }
+
        fn get_channel_signer(&self, inbound: bool, channel_value_satoshis: u64) -> EnforcingSigner {
                let keys = self.backing.get_channel_signer(inbound, channel_value_satoshis);
                let revoked_commitment = self.make_revoked_commitment_cell(keys.commitment_seed);
@@ -474,7 +494,7 @@ impl keysinterface::KeysInterface for TestKeysInterface {
        }
 
        fn read_chan_signer(&self, buffer: &[u8]) -> Result<Self::Signer, msgs::DecodeError> {
-               let mut reader = std::io::Cursor::new(buffer);
+               let mut reader = io::Cursor::new(buffer);
 
                let inner: InMemorySigner = Readable::read(&mut reader)?;
                let revoked_commitment = self.make_revoked_commitment_cell(inner.commitment_seed);
@@ -494,7 +514,6 @@ impl keysinterface::KeysInterface for TestKeysInterface {
        }
 }
 
-
 impl TestKeysInterface {
        pub fn new(seed: &[u8; 32], network: Network) -> Self {
                let now = Duration::from_secs(genesis_block(network).header.time as u64);
@@ -504,8 +523,19 @@ impl TestKeysInterface {
                        override_channel_id_priv: Mutex::new(None),
                        disable_revocation_policy_check: false,
                        revoked_commitments: Mutex::new(HashMap::new()),
+                       expectations: Mutex::new(None),
                }
        }
+
+       /// Sets an expectation that [`keysinterface::KeysInterface::get_shutdown_scriptpubkey`] is
+       /// called.
+       pub fn expect(&self, expectation: OnGetShutdownScriptpubkey) -> &Self {
+               self.expectations.lock().unwrap()
+                       .get_or_insert_with(|| VecDeque::new())
+                       .push_back(expectation);
+               self
+       }
+
        pub fn derive_channel_keys(&self, channel_value_satoshis: u64, id: &[u8; 32]) -> EnforcingSigner {
                let keys = self.backing.derive_channel_keys(channel_value_satoshis, id);
                let revoked_commitment = self.make_revoked_commitment_cell(keys.commitment_seed);
@@ -522,6 +552,33 @@ impl TestKeysInterface {
        }
 }
 
+impl Drop for TestKeysInterface {
+       fn drop(&mut self) {
+               if std::thread::panicking() {
+                       return;
+               }
+
+               if let Some(expectations) = &*self.expectations.lock().unwrap() {
+                       if !expectations.is_empty() {
+                               panic!("Unsatisfied expectations: {:?}", expectations);
+                       }
+               }
+       }
+}
+
+/// An expectation that [`keysinterface::KeysInterface::get_shutdown_scriptpubkey`] was called and
+/// returns a [`ShutdownScript`].
+pub struct OnGetShutdownScriptpubkey {
+       /// A shutdown script used to close a channel.
+       pub returns: ShutdownScript,
+}
+
+impl core::fmt::Debug for OnGetShutdownScriptpubkey {
+       fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+               f.debug_struct("OnGetShutdownScriptpubkey").finish()
+       }
+}
+
 pub struct TestChainSource {
        pub genesis_hash: BlockHash,
        pub utxo_ret: Mutex<Result<TxOut, chain::AccessError>>,