Add WithContext and Tests
[rust-lightning] / lightning / src / util / test_utils.rs
index 337dfc063cda3d7254f5625e7390967fde1324ea..0606e36e50e01d88496351e18dc7c019f94aae1e 100644 (file)
@@ -40,16 +40,15 @@ use crate::util::logger::{Logger, Level, Record};
 use crate::util::ser::{Readable, ReadableArgs, Writer, Writeable};
 use crate::util::persist::KVStore;
 
-use bitcoin::EcdsaSighashType;
 use bitcoin::blockdata::constants::ChainHash;
 use bitcoin::blockdata::constants::genesis_block;
 use bitcoin::blockdata::transaction::{Transaction, TxOut};
-use bitcoin::blockdata::script::{Builder, Script};
+use bitcoin::blockdata::script::{Builder, Script, ScriptBuf};
 use bitcoin::blockdata::opcodes;
 use bitcoin::blockdata::block::Block;
 use bitcoin::network::constants::Network;
 use bitcoin::hash_types::{BlockHash, Txid};
-use bitcoin::util::sighash::SighashCache;
+use bitcoin::sighash::{SighashCache, EcdsaSighashType};
 
 use bitcoin::secp256k1::{PublicKey, Scalar, Secp256k1, SecretKey};
 use bitcoin::secp256k1::ecdh::SharedSecret;
@@ -176,13 +175,15 @@ impl EntropySource for OnlyReadsKeysInterface {
        fn get_secure_random_bytes(&self) -> [u8; 32] { [0; 32] }}
 
 impl SignerProvider for OnlyReadsKeysInterface {
-       type Signer = TestChannelSigner;
+       type EcdsaSigner = TestChannelSigner;
+       #[cfg(taproot)]
+       type TaprootSigner = TestChannelSigner;
 
        fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32] { unreachable!(); }
 
-       fn derive_channel_signer(&self, _channel_value_satoshis: u64, _channel_keys_id: [u8; 32]) -> Self::Signer { unreachable!(); }
+       fn derive_channel_signer(&self, _channel_value_satoshis: u64, _channel_keys_id: [u8; 32]) -> Self::EcdsaSigner { unreachable!(); }
 
-       fn read_chan_signer(&self, mut reader: &[u8]) -> Result<Self::Signer, msgs::DecodeError> {
+       fn read_chan_signer(&self, mut reader: &[u8]) -> Result<Self::EcdsaSigner, msgs::DecodeError> {
                let inner: InMemorySigner = ReadableArgs::read(&mut reader, self)?;
                let state = Arc::new(Mutex::new(EnforcementState::new()));
 
@@ -193,7 +194,7 @@ impl SignerProvider for OnlyReadsKeysInterface {
                ))
        }
 
-       fn get_destination_script(&self) -> Result<Script, ()> { Err(()) }
+       fn get_destination_script(&self, _channel_keys_id: [u8; 32]) -> Result<ScriptBuf, ()> { Err(()) }
        fn get_shutdown_scriptpubkey(&self) -> Result<ShutdownScript, ()> { Err(()) }
 }
 
@@ -302,12 +303,12 @@ pub(crate) struct WatchtowerPersister {
        /// After receiving a revoke_and_ack for a commitment number, we'll form and store the justice
        /// tx which would be used to provide a watchtower with the data it needs.
        watchtower_state: Mutex<HashMap<OutPoint, HashMap<Txid, Transaction>>>,
-       destination_script: Script,
+       destination_script: ScriptBuf,
 }
 
 impl WatchtowerPersister {
        #[cfg(test)]
-       pub(crate) fn new(destination_script: Script) -> Self {
+       pub(crate) fn new(destination_script: ScriptBuf) -> Self {
                WatchtowerPersister {
                        persister: TestPersister::new(),
                        unsigned_justice_tx_data: Mutex::new(HashMap::new()),
@@ -335,7 +336,7 @@ impl WatchtowerPersister {
        }
 }
 
-impl<Signer: sign::WriteableEcdsaChannelSigner> chainmonitor::Persist<Signer> for WatchtowerPersister {
+impl<Signer: sign::ecdsa::WriteableEcdsaChannelSigner> chainmonitor::Persist<Signer> for WatchtowerPersister {
        fn persist_new_channel(&self, funding_txo: OutPoint,
                data: &channelmonitor::ChannelMonitor<Signer>, id: MonitorUpdateId
        ) -> chain::ChannelMonitorUpdateStatus {
@@ -415,7 +416,7 @@ impl TestPersister {
                self.update_rets.lock().unwrap().push_back(next_ret);
        }
 }
-impl<Signer: sign::WriteableEcdsaChannelSigner> chainmonitor::Persist<Signer> for TestPersister {
+impl<Signer: sign::ecdsa::WriteableEcdsaChannelSigner> chainmonitor::Persist<Signer> for TestPersister {
        fn persist_new_channel(&self, _funding_txo: OutPoint, _data: &channelmonitor::ChannelMonitor<Signer>, _id: MonitorUpdateId) -> chain::ChannelMonitorUpdateStatus {
                if let Some(update_ret) = self.update_rets.lock().unwrap().pop_front() {
                        return update_ret
@@ -561,9 +562,9 @@ impl TestBroadcaster {
 impl chaininterface::BroadcasterInterface for TestBroadcaster {
        fn broadcast_transactions(&self, txs: &[&Transaction]) {
                for tx in txs {
-                       let lock_time = tx.lock_time.0;
+                       let lock_time = tx.lock_time.to_consensus_u32();
                        assert!(lock_time < 1_500_000_000);
-                       if bitcoin::LockTime::from(tx.lock_time).is_block_height() && lock_time > self.blocks.lock().unwrap().last().unwrap().1 {
+                       if tx.lock_time.is_block_height() && lock_time > self.blocks.lock().unwrap().last().unwrap().1 {
                                for inp in tx.input.iter() {
                                        if inp.sequence != Sequence::MAX {
                                                panic!("We should never broadcast a transaction before its locktime ({})!", tx.lock_time);
@@ -646,6 +647,18 @@ impl msgs::ChannelMessageHandler for TestChannelMessageHandler {
        fn handle_closing_signed(&self, _their_node_id: &PublicKey, msg: &msgs::ClosingSigned) {
                self.received_msg(wire::Message::ClosingSigned(msg.clone()));
        }
+       fn handle_stfu(&self, _their_node_id: &PublicKey, msg: &msgs::Stfu) {
+               self.received_msg(wire::Message::Stfu(msg.clone()));
+       }
+       fn handle_splice(&self, _their_node_id: &PublicKey, msg: &msgs::Splice) {
+               self.received_msg(wire::Message::Splice(msg.clone()));
+       }
+       fn handle_splice_ack(&self, _their_node_id: &PublicKey, msg: &msgs::SpliceAck) {
+               self.received_msg(wire::Message::SpliceAck(msg.clone()));
+       }
+       fn handle_splice_locked(&self, _their_node_id: &PublicKey, msg: &msgs::SpliceLocked) {
+               self.received_msg(wire::Message::SpliceLocked(msg.clone()));
+       }
        fn handle_update_add_htlc(&self, _their_node_id: &PublicKey, msg: &msgs::UpdateAddHTLC) {
                self.received_msg(wire::Message::UpdateAddHTLC(msg.clone()));
        }
@@ -918,6 +931,7 @@ pub struct TestLogger {
        level: Level,
        pub(crate) id: String,
        pub lines: Mutex<HashMap<(String, String), usize>>,
+       pub context: Mutex<HashMap<(String, Option<PublicKey>, Option<ChannelId>), usize>>,
 }
 
 impl TestLogger {
@@ -928,7 +942,8 @@ impl TestLogger {
                TestLogger {
                        level: Level::Trace,
                        id,
-                       lines: Mutex::new(HashMap::new())
+                       lines: Mutex::new(HashMap::new()),
+                       context: Mutex::new(HashMap::new()),
                }
        }
        pub fn enable(&mut self, level: Level) {
@@ -963,11 +978,23 @@ impl TestLogger {
                }).map(|(_, c) | { c }).sum();
                assert_eq!(l, count)
        }
+
+       pub fn assert_log_context_contains(
+               &self, module: &str, peer_id: Option<PublicKey>, channel_id: Option<ChannelId>, count: usize
+       ) {
+               let context_entries = self.context.lock().unwrap();
+               let l: usize = context_entries.iter()
+                       .filter(|&(&(ref m, ref p, ref c), _)| m == module && *p == peer_id && *c == channel_id)
+                       .map(|(_, c) | c)
+                       .sum();
+               assert_eq!(l, count)
+       }
 }
 
 impl Logger for TestLogger {
-       fn log(&self, record: &Record) {
+       fn log(&self, record: Record) {
                *self.lines.lock().unwrap().entry((record.module_path.to_string(), format!("{}", record.args))).or_insert(0) += 1;
+               *self.context.lock().unwrap().entry((record.module_path.to_string(), record.peer_id, record.channel_id)).or_insert(0) += 1;
                if record.level >= self.level {
                        #[cfg(all(not(ldk_bench), feature = "std"))] {
                                let pfx = format!("{} {} [{}:{}]", self.id, record.level.to_string(), record.module_path, record.line);
@@ -1085,7 +1112,9 @@ impl NodeSigner for TestKeysInterface {
 }
 
 impl SignerProvider for TestKeysInterface {
-       type Signer = TestChannelSigner;
+       type EcdsaSigner = TestChannelSigner;
+       #[cfg(taproot)]
+       type TaprootSigner = TestChannelSigner;
 
        fn generate_channel_keys_id(&self, inbound: bool, channel_value_satoshis: u64, user_channel_id: u128) -> [u8; 32] {
                self.backing.generate_channel_keys_id(inbound, channel_value_satoshis, user_channel_id)
@@ -1097,7 +1126,7 @@ impl SignerProvider for TestKeysInterface {
                TestChannelSigner::new_with_revoked(keys, state, self.disable_revocation_policy_check)
        }
 
-       fn read_chan_signer(&self, buffer: &[u8]) -> Result<Self::Signer, msgs::DecodeError> {
+       fn read_chan_signer(&self, buffer: &[u8]) -> Result<Self::EcdsaSigner, msgs::DecodeError> {
                let mut reader = io::Cursor::new(buffer);
 
                let inner: InMemorySigner = ReadableArgs::read(&mut reader, self)?;
@@ -1110,7 +1139,7 @@ impl SignerProvider for TestKeysInterface {
                ))
        }
 
-       fn get_destination_script(&self) -> Result<Script, ()> { self.backing.get_destination_script() }
+       fn get_destination_script(&self, channel_keys_id: [u8; 32]) -> Result<ScriptBuf, ()> { self.backing.get_destination_script(channel_keys_id) }
 
        fn get_shutdown_scriptpubkey(&self) -> Result<ShutdownScript, ()> {
                match &mut *self.expectations.lock().unwrap() {
@@ -1200,8 +1229,8 @@ pub struct TestChainSource {
        pub chain_hash: ChainHash,
        pub utxo_ret: Mutex<UtxoResult>,
        pub get_utxo_call_count: AtomicUsize,
-       pub watched_txn: Mutex<HashSet<(Txid, Script)>>,
-       pub watched_outputs: Mutex<HashSet<(OutPoint, Script)>>,
+       pub watched_txn: Mutex<HashSet<(Txid, ScriptBuf)>>,
+       pub watched_outputs: Mutex<HashSet<(OutPoint, ScriptBuf)>>,
 }
 
 impl TestChainSource {
@@ -1230,7 +1259,7 @@ impl UtxoLookup for TestChainSource {
 
 impl chain::Filter for TestChainSource {
        fn register_tx(&self, txid: &Txid, script_pubkey: &Script) {
-               self.watched_txn.lock().unwrap().insert((*txid, script_pubkey.clone()));
+               self.watched_txn.lock().unwrap().insert((*txid, script_pubkey.into()));
        }
 
        fn register_output(&self, output: WatchedOutput) {
@@ -1350,9 +1379,9 @@ impl WalletSource for TestWalletSource {
                Ok(self.utxos.borrow().clone())
        }
 
-       fn get_change_script(&self) -> Result<Script, ()> {
+       fn get_change_script(&self) -> Result<ScriptBuf, ()> {
                let public_key = bitcoin::PublicKey::new(self.secret_key.public_key(&self.secp));
-               Ok(Script::new_p2pkh(&public_key.pubkey_hash()))
+               Ok(ScriptBuf::new_p2pkh(&public_key.pubkey_hash()))
        }
 
        fn sign_tx(&self, mut tx: Transaction) -> Result<Transaction, ()> {
@@ -1362,10 +1391,10 @@ impl WalletSource for TestWalletSource {
                                let sighash = SighashCache::new(&tx)
                                        .legacy_signature_hash(i, &utxo.output.script_pubkey, EcdsaSighashType::All as u32)
                                        .map_err(|_| ())?;
-                               let sig = self.secp.sign_ecdsa(&sighash.as_hash().into(), &self.secret_key);
-                               let bitcoin_sig = bitcoin::EcdsaSig { sig, hash_ty: EcdsaSighashType::All }.to_vec();
+                               let sig = self.secp.sign_ecdsa(&(*sighash.as_raw_hash()).into(), &self.secret_key);
+                               let bitcoin_sig = bitcoin::ecdsa::Signature { sig, hash_ty: EcdsaSighashType::All };
                                tx.input[i].script_sig = Builder::new()
-                                       .push_slice(&bitcoin_sig)
+                                       .push_slice(&bitcoin_sig.serialize())
                                        .push_slice(&self.secret_key.public_key(&self.secp).serialize())
                                        .into_script();
                        }