Make test output deterministic
authorJeffrey Czyz <jkczyz@gmail.com>
Wed, 17 Jun 2020 15:29:30 +0000 (08:29 -0700)
committerJeffrey Czyz <jkczyz@gmail.com>
Fri, 19 Jun 2020 02:28:50 +0000 (19:28 -0700)
Tests use sources of randomness to produce seeds, preimages, secrets,
and ephemeral data. However, this makes comparing logs between different
test runs difficult. Remove uses of random number generators and the
current time in favor of fixed values in order to make the test output
deterministic.

lightning/Cargo.toml
lightning/src/lib.rs
lightning/src/ln/channel.rs
lightning/src/ln/channelmonitor.rs
lightning/src/ln/functional_test_utils.rs
lightning/src/ln/functional_tests.rs
lightning/src/ln/peer_handler.rs
lightning/src/util/test_utils.rs

index f89b548184ccfcd76d66a9a1f46f092359fe04d7..3826123a0fbbefc26677d334d9c2a38c7c9c26c2 100644 (file)
@@ -28,4 +28,3 @@ features = ["bitcoinconsensus"]
 
 [dev-dependencies]
 hex = "0.3"
-rand = "0.4"
index 23645ab189aec1c06de223a6a6cad88f1eeceaac..72017e46553b476f3d01f6bda97d7d5c0058d96b 100644 (file)
@@ -19,7 +19,6 @@
 #![allow(ellipsis_inclusive_range_patterns)]
 
 extern crate bitcoin;
-#[cfg(test)] extern crate rand;
 #[cfg(test)] extern crate hex;
 
 #[macro_use]
index e9651532650334037ea03a377c07616144dfbe5a..b4a24833919b96fa26b9037ecea1844d253d0e0e 100644 (file)
@@ -4478,7 +4478,6 @@ mod tests {
        use bitcoin::hashes::Hash;
        use bitcoin::hash_types::{Txid, WPubkeyHash};
        use std::sync::Arc;
-       use rand::{thread_rng,Rng};
 
        struct TestFeeEstimator {
                fee_est: u32
@@ -4533,9 +4532,7 @@ mod tests {
                let original_fee = 253;
                let mut fee_est = TestFeeEstimator{fee_est: original_fee };
                let secp_ctx = Secp256k1::new();
-               let mut seed = [0; 32];
-               let mut rng = thread_rng();
-               rng.fill_bytes(&mut seed);
+               let seed = [42; 32];
                let network = Network::Testnet;
                let keys_provider = test_utils::TestKeysInterface::new(&seed, network);
 
@@ -4555,9 +4552,7 @@ mod tests {
                let feeest = TestFeeEstimator{fee_est: 15000};
                let logger = test_utils::TestLogger::new();
                let secp_ctx = Secp256k1::new();
-               let mut seed = [0; 32];
-               let mut rng = thread_rng();
-               rng.fill_bytes(&mut seed);
+               let seed = [42; 32];
                let network = Network::Testnet;
                let keys_provider = test_utils::TestKeysInterface::new(&seed, network);
 
index 0b8f8c07862eeb8514bbea78e254059fc1b73a72..d8689faeb60460988c69ad267d50cd52bcb6a4a2 100644 (file)
@@ -2544,7 +2544,6 @@ mod tests {
        use util::test_utils::TestLogger;
        use bitcoin::secp256k1::key::{SecretKey,PublicKey};
        use bitcoin::secp256k1::Secp256k1;
-       use rand::{thread_rng,Rng};
        use std::sync::Arc;
        use chain::keysinterface::InMemoryChannelKeys;
 
@@ -2558,10 +2557,8 @@ mod tests {
 
                let mut preimages = Vec::new();
                {
-                       let mut rng  = thread_rng();
-                       for _ in 0..20 {
-                               let mut preimage = PaymentPreimage([0; 32]);
-                               rng.fill_bytes(&mut preimage.0[..]);
+                       for i in 0..20 {
+                               let preimage = PaymentPreimage([i; 32]);
                                let hash = PaymentHash(Sha256::hash(&preimage.0[..]).into_inner());
                                preimages.push((preimage, hash));
                        }
index bed83a925cb3e893df9b507b3906c6b608614454..547e58bc287ccbbc6d2fab745706eaa80fcca0e5 100644 (file)
@@ -29,8 +29,6 @@ use bitcoin::hash_types::BlockHash;
 
 use bitcoin::secp256k1::key::PublicKey;
 
-use rand::{thread_rng,Rng};
-
 use std::cell::RefCell;
 use std::rc::Rc;
 use std::sync::{Mutex, RwLock};
@@ -1071,11 +1069,9 @@ pub fn create_chanmon_cfgs(node_count: usize) -> Vec<TestChanMonCfg> {
 
 pub fn create_node_cfgs<'a>(node_count: usize, chanmon_cfgs: &'a Vec<TestChanMonCfg>) -> Vec<NodeCfg<'a>> {
        let mut nodes = Vec::new();
-       let mut rng = thread_rng();
 
        for i in 0..node_count {
-               let mut seed = [0; 32];
-               rng.fill_bytes(&mut seed);
+               let seed = [i as u8; 32];
                let keys_manager = test_utils::TestKeysInterface::new(&seed, Network::Testnet);
                let chan_monitor = test_utils::TestChannelMonitor::new(&chanmon_cfgs[i].chain_monitor, &chanmon_cfgs[i].tx_broadcaster, &chanmon_cfgs[i].logger, &chanmon_cfgs[i].fee_estimator);
                nodes.push(NodeCfg { chain_monitor: &chanmon_cfgs[i].chain_monitor, logger: &chanmon_cfgs[i].logger, tx_broadcaster: &chanmon_cfgs[i].tx_broadcaster, fee_estimator: &chanmon_cfgs[i].fee_estimator, chan_monitor, keys_manager, node_seed: seed });
index 7047de4daf93e40d233ec665b47b48b573f05285..e7d793b7dfd3e2d61c9e0ec6ec4e9a0d0e5a57da 100644 (file)
@@ -48,8 +48,6 @@ use std::sync::{Arc, Mutex};
 use std::sync::atomic::Ordering;
 use std::{mem, io};
 
-use rand::{thread_rng, Rng};
-
 use ln::functional_test_utils::*;
 
 #[test]
@@ -1613,15 +1611,8 @@ fn test_chan_reserve_violation_inbound_htlc_outbound_channel() {
        let (route, payment_hash, _) = get_route_and_payment_hash!(1000);
        // Need to manually create the update_add_htlc message to go around the channel reserve check in send_htlc()
        let secp_ctx = Secp256k1::new();
-       let session_priv = SecretKey::from_slice(&{
-               let mut session_key = [0; 32];
-               let mut rng = thread_rng();
-               rng.fill_bytes(&mut session_key);
-               session_key
-       }).expect("RNG is bad!");
-
+       let session_priv = SecretKey::from_slice(&[42; 32]).unwrap();
        let cur_height = nodes[1].node.latest_block_height.load(Ordering::Acquire) as u32 + 1;
-
        let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route.paths[0], &session_priv).unwrap();
        let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0], 1000, &None, cur_height).unwrap();
        let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &payment_hash);
@@ -1692,15 +1683,8 @@ fn test_chan_reserve_violation_inbound_htlc_inbound_chan() {
 
        // Need to manually create the update_add_htlc message to go around the channel reserve check in send_htlc()
        let secp_ctx = Secp256k1::new();
-       let session_priv = SecretKey::from_slice(&{
-               let mut session_key = [0; 32];
-               let mut rng = thread_rng();
-               rng.fill_bytes(&mut session_key);
-               session_key
-       }).expect("RNG is bad!");
-
+       let session_priv = SecretKey::from_slice(&[42; 32]).unwrap();
        let cur_height = nodes[0].node.latest_block_height.load(Ordering::Acquire) as u32 + 1;
-
        let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route_2.paths[0], &session_priv).unwrap();
        let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(&route_2.paths[0], recv_value_2, &None, cur_height).unwrap();
        let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &our_payment_hash_1);
@@ -3176,13 +3160,7 @@ fn fail_backward_pending_htlc_upon_channel_failure() {
                let (_, payment_hash) = get_payment_preimage_hash!(nodes[1]);
 
                let secp_ctx = Secp256k1::new();
-               let session_priv = {
-                       let mut session_key = [0; 32];
-                       let mut rng = thread_rng();
-                       rng.fill_bytes(&mut session_key);
-                       SecretKey::from_slice(&session_key).expect("RNG is bad!")
-               };
-
+               let session_priv = SecretKey::from_slice(&[42; 32]).unwrap();
                let current_height = nodes[1].node.latest_block_height.load(Ordering::Acquire) as u32 + 1;
                let net_graph_msg_handler = &nodes[1].net_graph_msg_handler;
                let route = get_route(&nodes[1].node.get_our_node_id(), net_graph_msg_handler, &nodes[0].node.get_our_node_id(), None, &Vec::new(), 50_000, TEST_FINAL_CLTV, &logger).unwrap();
@@ -5480,9 +5458,7 @@ fn test_key_derivation_params() {
        let chanmon_cfgs = create_chanmon_cfgs(3);
 
        // We manually create the node configuration to backup the seed.
-       let mut rng = thread_rng();
-       let mut seed = [0; 32];
-       rng.fill_bytes(&mut seed);
+       let seed = [42; 32];
        let keys_manager = test_utils::TestKeysInterface::new(&seed, Network::Testnet);
        let chan_monitor = test_utils::TestChannelMonitor::new(&chanmon_cfgs[0].chain_monitor, &chanmon_cfgs[0].tx_broadcaster, &chanmon_cfgs[0].logger, &chanmon_cfgs[0].fee_estimator);
        let node = NodeCfg { chain_monitor: &chanmon_cfgs[0].chain_monitor, logger: &chanmon_cfgs[0].logger, tx_broadcaster: &chanmon_cfgs[0].tx_broadcaster, fee_estimator: &chanmon_cfgs[0].fee_estimator, chan_monitor, keys_manager, node_seed: seed };
@@ -6475,13 +6451,7 @@ fn test_update_add_htlc_bolt2_receiver_check_max_htlc_limit() {
        let logger = test_utils::TestLogger::new();
 
        let (_, our_payment_hash) = get_payment_preimage_hash!(nodes[0]);
-
-       let session_priv = SecretKey::from_slice(&{
-               let mut session_key = [0; 32];
-               let mut rng = thread_rng();
-               rng.fill_bytes(&mut session_key);
-               session_key
-       }).expect("RNG is bad!");
+       let session_priv = SecretKey::from_slice(&[42; 32]).unwrap();
 
        let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
        let route = get_route(&nodes[0].node.get_our_node_id(), net_graph_msg_handler, &nodes[1].node.get_our_node_id(), None, &[], 3999999, TEST_FINAL_CLTV, &logger).unwrap();
index e5a973bca36c52626134fc33d74c76371f9fb4e2..2902ece769405ffa14e83ed62cfa4e38e784e7c8 100644 (file)
@@ -1216,8 +1216,6 @@ mod tests {
        use bitcoin::secp256k1::Secp256k1;
        use bitcoin::secp256k1::key::{SecretKey, PublicKey};
 
-       use rand::{thread_rng, Rng};
-
        use std;
        use std::sync::{Arc, Mutex};
        use std::sync::atomic::Ordering;
@@ -1271,18 +1269,11 @@ mod tests {
 
        fn create_network<'a>(peer_count: usize, cfgs: &'a Vec<PeerManagerCfg>) -> Vec<PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, &'a test_utils::TestLogger>> {
                let mut peers = Vec::new();
-               let mut rng = thread_rng();
-               let mut ephemeral_bytes = [0; 32];
-               rng.fill_bytes(&mut ephemeral_bytes);
-
                for i in 0..peer_count {
-                       let node_id = {
-                               let mut key_slice = [0;32];
-                               rng.fill_bytes(&mut key_slice);
-                               SecretKey::from_slice(&key_slice).unwrap()
-                       };
+                       let node_secret = SecretKey::from_slice(&[42 + i as u8; 32]).unwrap();
+                       let ephemeral_bytes = [i as u8; 32];
                        let msg_handler = MessageHandler { chan_handler: &cfgs[i].chan_handler, route_handler: &cfgs[i].routing_handler };
-                       let peer = PeerManager::new(msg_handler, node_id, &ephemeral_bytes, &cfgs[i].logger);
+                       let peer = PeerManager::new(msg_handler, node_secret, &ephemeral_bytes, &cfgs[i].logger);
                        peers.push(peer);
                }
 
index a79b86175a6c17df066256b2d51656d1011766d8..c6302b9062d8525bf2d1b7b974e8f45415676ba8 100644 (file)
@@ -22,7 +22,7 @@ use bitcoin::hash_types::{Txid, BlockHash};
 
 use bitcoin::secp256k1::{SecretKey, PublicKey, Secp256k1, Signature};
 
-use std::time::{SystemTime, UNIX_EPOCH};
+use std::time::Duration;
 use std::sync::Mutex;
 use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
 use std::{cmp, mem};
@@ -344,7 +344,7 @@ impl keysinterface::KeysInterface for TestKeysInterface {
 
 impl TestKeysInterface {
        pub fn new(seed: &[u8; 32], network: Network) -> Self {
-               let now = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards");
+               let now = Duration::from_secs(genesis_block(network).header.time as u64);
                Self {
                        backing: keysinterface::KeysManager::new(seed, network, now.as_secs(), now.subsec_nanos()),
                        override_session_priv: Mutex::new(None),