diff --git a/chain/tests/chain_test_helper.rs b/chain/tests/chain_test_helper.rs
index 3eb189a48..1d019adb0 100644
--- a/chain/tests/chain_test_helper.rs
+++ b/chain/tests/chain_test_helper.rs
@@ -70,7 +70,7 @@ where
 /// Mine a chain of specified length to assist with automated tests.
 /// Probably a good idea to call clean_output_dir at the beginning and end of each test.
 pub fn mine_chain(dir_name: &str, chain_length: u64) -> Chain {
-	global::set_mining_mode(ChainTypes::AutomatedTesting);
+	global::set_local_chain_type(ChainTypes::AutomatedTesting);
 	let keychain = keychain::ExtKeychain::from_random_seed(false).unwrap();
 	let genesis = genesis_block(&keychain);
 	let mut chain = init_chain(dir_name, genesis.clone());
diff --git a/chain/tests/mine_simple_chain.rs b/chain/tests/mine_simple_chain.rs
index 567f110cd..01a75c29a 100644
--- a/chain/tests/mine_simple_chain.rs
+++ b/chain/tests/mine_simple_chain.rs
@@ -118,7 +118,7 @@ fn process_block(chain: &Chain, block: &Block) {
 fn test_block_a_block_b_block_b_fork_header_c_fork_block_c() {
 	let chain_dir = ".grin.block_a_block_b_block_b_fork_header_c_fork_block_c";
 	clean_output_dir(chain_dir);
-	global::set_mining_mode(ChainTypes::AutomatedTesting);
+	global::set_local_chain_type(ChainTypes::AutomatedTesting);
 	let kc = ExtKeychain::from_random_seed(false).unwrap();
 	let genesis = pow::mine_genesis_block().unwrap();
 	let last_status = RwLock::new(None);
@@ -170,7 +170,7 @@ fn test_block_a_block_b_block_b_fork_header_c_fork_block_c() {
 fn test_block_a_block_b_block_b_fork_header_c_fork_block_c_fork() {
 	let chain_dir = ".grin.block_a_block_b_block_b_fork_header_c_fork_block_c_fork";
 	clean_output_dir(chain_dir);
-	global::set_mining_mode(ChainTypes::AutomatedTesting);
+	global::set_local_chain_type(ChainTypes::AutomatedTesting);
 	let kc = ExtKeychain::from_random_seed(false).unwrap();
 	let genesis = pow::mine_genesis_block().unwrap();
 	let last_status = RwLock::new(None);
@@ -226,7 +226,7 @@ fn test_block_a_block_b_block_b_fork_header_c_fork_block_c_fork() {
 fn test_block_a_header_b_header_b_fork_block_b_fork_block_b_block_c() {
 	let chain_dir = ".grin.test_block_a_header_b_header_b_fork_block_b_fork_block_b_block_c";
 	clean_output_dir(chain_dir);
-	global::set_mining_mode(ChainTypes::AutomatedTesting);
+	global::set_local_chain_type(ChainTypes::AutomatedTesting);
 	let kc = ExtKeychain::from_random_seed(false).unwrap();
 	let genesis = pow::mine_genesis_block().unwrap();
 	let last_status = RwLock::new(None);
@@ -282,7 +282,7 @@ fn test_block_a_header_b_header_b_fork_block_b_fork_block_b_block_c() {
 fn test_block_a_header_b_header_b_fork_block_b_fork_block_b_block_c_fork() {
 	let chain_dir = ".grin.test_block_a_header_b_header_b_fork_block_b_fork_block_b_block_c_fork";
 	clean_output_dir(chain_dir);
-	global::set_mining_mode(ChainTypes::AutomatedTesting);
+	global::set_local_chain_type(ChainTypes::AutomatedTesting);
 	let kc = ExtKeychain::from_random_seed(false).unwrap();
 	let genesis = pow::mine_genesis_block().unwrap();
 	let last_status = RwLock::new(None);
@@ -347,7 +347,7 @@ fn mine_reorg() {
 	const DIR_NAME: &str = ".grin_reorg";
 	clean_output_dir(DIR_NAME);
 
-	global::set_mining_mode(ChainTypes::AutomatedTesting);
+	global::set_local_chain_type(ChainTypes::AutomatedTesting);
 	let kc = ExtKeychain::from_random_seed(false).unwrap();
 
 	let genesis = pow::mine_genesis_block().unwrap();
@@ -399,7 +399,7 @@ fn mine_reorg() {
 #[test]
 fn mine_forks() {
 	clean_output_dir(".grin2");
-	global::set_mining_mode(ChainTypes::AutomatedTesting);
+	global::set_local_chain_type(ChainTypes::AutomatedTesting);
 	{
 		let chain = init_chain(".grin2", pow::mine_genesis_block().unwrap());
 		let kc = ExtKeychain::from_random_seed(false).unwrap();
@@ -447,7 +447,7 @@ fn mine_forks() {
 #[test]
 fn mine_losing_fork() {
 	clean_output_dir(".grin3");
-	global::set_mining_mode(ChainTypes::AutomatedTesting);
+	global::set_local_chain_type(ChainTypes::AutomatedTesting);
 	let kc = ExtKeychain::from_random_seed(false).unwrap();
 	{
 		let chain = init_chain(".grin3", pow::mine_genesis_block().unwrap());
@@ -484,7 +484,7 @@ fn mine_losing_fork() {
 #[test]
 fn longer_fork() {
 	clean_output_dir(".grin4");
-	global::set_mining_mode(ChainTypes::AutomatedTesting);
+	global::set_local_chain_type(ChainTypes::AutomatedTesting);
 	let kc = ExtKeychain::from_random_seed(false).unwrap();
 	// to make it easier to compute the txhashset roots in the test, we
 	// prepare 2 chains, the 2nd will be have the forked blocks we can
@@ -528,7 +528,7 @@ fn longer_fork() {
 
 #[test]
 fn spend_rewind_spend() {
-	global::set_mining_mode(ChainTypes::AutomatedTesting);
+	global::set_local_chain_type(ChainTypes::AutomatedTesting);
 	util::init_test_logger();
 	clean_output_dir(".grin_spend_rewind_spend");
 
@@ -607,7 +607,7 @@ fn spend_rewind_spend() {
 #[test]
 fn spend_in_fork_and_compact() {
 	clean_output_dir(".grin6");
-	global::set_mining_mode(ChainTypes::AutomatedTesting);
+	global::set_local_chain_type(ChainTypes::AutomatedTesting);
 	util::init_test_logger();
 	{
 		let chain = init_chain(".grin6", pow::mine_genesis_block().unwrap());
@@ -746,7 +746,7 @@ fn spend_in_fork_and_compact() {
 /// Test ability to retrieve block headers for a given output
 #[test]
 fn output_header_mappings() {
-	global::set_mining_mode(ChainTypes::AutomatedTesting);
+	global::set_local_chain_type(ChainTypes::AutomatedTesting);
 	{
 		let chain = init_chain(
 			".grin_header_for_output",
@@ -902,7 +902,7 @@ where
 #[test]
 #[ignore]
 fn actual_diff_iter_output() {
-	global::set_mining_mode(ChainTypes::AutomatedTesting);
+	global::set_local_chain_type(ChainTypes::AutomatedTesting);
 	let genesis_block = pow::mine_genesis_block().unwrap();
 	let verifier_cache = Arc::new(RwLock::new(LruVerifierCache::new()));
 	let chain = chain::Chain::init(
diff --git a/chain/tests/test_coinbase_maturity.rs b/chain/tests/test_coinbase_maturity.rs
index 109a51250..4d4831187 100644
--- a/chain/tests/test_coinbase_maturity.rs
+++ b/chain/tests/test_coinbase_maturity.rs
@@ -40,7 +40,7 @@ fn test_coinbase_maturity() {
 	let _ = env_logger::init();
 	let chain_dir = ".grin_coinbase";
 	clean_output_dir(chain_dir);
-	global::set_mining_mode(ChainTypes::AutomatedTesting);
+	global::set_local_chain_type(ChainTypes::AutomatedTesting);
 
 	let genesis_block = pow::mine_genesis_block().unwrap();
 
diff --git a/chain/tests/test_txhashset.rs b/chain/tests/test_txhashset.rs
index 2b35160f2..3210dd341 100644
--- a/chain/tests/test_txhashset.rs
+++ b/chain/tests/test_txhashset.rs
@@ -23,9 +23,10 @@ use std::sync::Arc;
 
 use crate::chain::store::ChainStore;
 use crate::chain::txhashset;
+use crate::core::core::hash::Hashed;
 use crate::core::core::BlockHeader;
+use crate::core::global;
 use crate::util::file;
-use grin_core::core::hash::Hashed;
 
 fn clean_output_dir(dir_name: &str) {
 	let _ = fs::remove_dir_all(dir_name);
@@ -33,6 +34,7 @@ fn clean_output_dir(dir_name: &str) {
 
 #[test]
 fn test_unexpected_zip() {
+	global::set_local_chain_type(global::ChainTypes::AutomatedTesting);
 	let db_root = format!(".grin_txhashset_zip");
 	clean_output_dir(&db_root);
 	{
diff --git a/core/src/consensus.rs b/core/src/consensus.rs
index 94218e4af..5872e30d7 100644
--- a/core/src/consensus.rs
+++ b/core/src/consensus.rs
@@ -142,7 +142,7 @@ pub const TESTING_SECOND_HARD_FORK: u64 = 6;
 /// Compute possible block version at a given height, implements
 /// 6 months interval scheduled hard forks for the first 2 years.
 pub fn header_version(height: u64) -> HeaderVersion {
-	let chain_type = global::CHAIN_TYPE.read().clone();
+	let chain_type = global::get_chain_type();
 	let hf_interval = (1 + height / HARD_FORK_INTERVAL) as u16;
 	match chain_type {
 		global::ChainTypes::Mainnet => HeaderVersion(hf_interval),
@@ -383,6 +383,8 @@ mod test {
 
 	#[test]
 	fn test_graph_weight() {
+		global::set_local_chain_type(global::ChainTypes::Mainnet);
+
 		// initial weights
 		assert_eq!(graph_weight(1, 31), 256 * 31);
 		assert_eq!(graph_weight(1, 32), 512 * 32);
diff --git a/core/src/genesis.rs b/core/src/genesis.rs
index 2dd6cb80a..6cb2eaa7d 100644
--- a/core/src/genesis.rs
+++ b/core/src/genesis.rs
@@ -272,11 +272,13 @@ pub fn genesis_main() -> core::Block {
 mod test {
 	use super::*;
 	use crate::core::hash::Hashed;
+	use crate::global;
 	use crate::ser::{self, ProtocolVersion};
 	use util::ToHex;
 
 	#[test]
 	fn floonet_genesis_hash() {
+		global::set_local_chain_type(global::ChainTypes::Floonet);
 		let gen_hash = genesis_floo().hash();
 		println!("floonet genesis hash: {}", gen_hash.to_hex());
 		let gen_bin = ser::ser_vec(&genesis_floo(), ProtocolVersion(1)).unwrap();
@@ -293,6 +295,7 @@ mod test {
 
 	#[test]
 	fn mainnet_genesis_hash() {
+		global::set_local_chain_type(global::ChainTypes::Mainnet);
 		let gen_hash = genesis_main().hash();
 		println!("mainnet genesis hash: {}", gen_hash.to_hex());
 		let gen_bin = ser::ser_vec(&genesis_main(), ProtocolVersion(1)).unwrap();
diff --git a/core/src/global.rs b/core/src/global.rs
index 339c3f7f4..07a079f5f 100644
--- a/core/src/global.rs
+++ b/core/src/global.rs
@@ -27,7 +27,8 @@ use crate::pow::{
 	self, new_cuckaroo_ctx, new_cuckarood_ctx, new_cuckaroom_ctx, new_cuckatoo_ctx, EdgeType,
 	PoWContext,
 };
-use util::RwLock;
+use std::cell::Cell;
+use util::OneTime;
 
 /// An enum collecting sets of parameters used throughout the
 /// code wherever mining is needed. This should allow for
@@ -104,7 +105,7 @@ pub const TXHASHSET_ARCHIVE_INTERVAL: u64 = 12 * 60;
 
 /// Types of chain a server can run with, dictates the genesis block and
 /// and mining parameters used.
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
 pub enum ChainTypes {
 	/// For CI testing
 	AutomatedTesting,
@@ -134,31 +135,43 @@ impl Default for ChainTypes {
 	}
 }
 
-/// PoW test mining and verifier context
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-pub enum PoWContextTypes {
-	/// Classic Cuckoo
-	Cuckoo,
-	/// ASIC-friendly Cuckatoo
-	Cuckatoo,
-	/// ASIC-resistant Cuckaroo
-	Cuckaroo,
-}
-
 lazy_static! {
-	/// The mining parameter mode
-	pub static ref CHAIN_TYPE: RwLock<ChainTypes> =
-			RwLock::new(ChainTypes::Mainnet);
-
-	/// PoW context type to instantiate
-	pub static ref POW_CONTEXT_TYPE: RwLock<PoWContextTypes> =
-			RwLock::new(PoWContextTypes::Cuckoo);
+	/// Global chain_type that must be initialized once on node startup.
+	/// This is accessed via get_chain_type() which allows the global value
+	/// to be overridden on a per-thread basis (for testing).
+	pub static ref GLOBAL_CHAIN_TYPE: OneTime<ChainTypes> = OneTime::new();
 }
 
-/// Set the mining mode
-pub fn set_mining_mode(mode: ChainTypes) {
-	let mut param_ref = CHAIN_TYPE.write();
-	*param_ref = mode;
+thread_local! {
+	/// Mainnet|Floonet|UserTesting|AutomatedTesting
+	pub static CHAIN_TYPE: Cell<Option<ChainTypes>> = Cell::new(None);
+}
+
+/// Set the chain type on a per-thread basis via thread_local storage.
+pub fn set_local_chain_type(new_type: ChainTypes) {
+	CHAIN_TYPE.with(|chain_type| chain_type.set(Some(new_type)))
+}
+
+/// Get the chain type via thread_local, fallback to global chain_type.
+pub fn get_chain_type() -> ChainTypes {
+	CHAIN_TYPE.with(|chain_type| match chain_type.get() {
+		None => {
+			if GLOBAL_CHAIN_TYPE.is_init() {
+				let chain_type = GLOBAL_CHAIN_TYPE.borrow();
+				set_local_chain_type(chain_type);
+				chain_type
+			} else {
+				panic!("GLOBAL_CHAIN_TYPE and CHAIN_TYPE unset. Consider set_local_chain_type() in tests.");
+			}
+		}
+		Some(chain_type) => chain_type,
+	})
+}
+
+/// One time initialization of the global chain_type.
+/// Will panic if we attempt to re-initialize this (via OneTime).
+pub fn init_global_chain_type(new_type: ChainTypes) {
+	GLOBAL_CHAIN_TYPE.init(new_type)
 }
 
 /// Return either a cuckoo context or a cuckatoo context
@@ -172,7 +185,7 @@ pub fn create_pow_context<T>(
 where
 	T: EdgeType + 'static,
 {
-	let chain_type = CHAIN_TYPE.read().clone();
+	let chain_type = get_chain_type();
 	match chain_type {
 		// Mainnet has Cuckaroo(d)29 for AR and Cuckatoo31+ for AF
 		ChainTypes::Mainnet if edge_bits > 29 => new_cuckatoo_ctx(edge_bits, proof_size, max_sols),
@@ -201,8 +214,7 @@ where
 
 /// The minimum acceptable edge_bits
 pub fn min_edge_bits() -> u8 {
-	let param_ref = CHAIN_TYPE.read();
-	match *param_ref {
+	match get_chain_type() {
 		ChainTypes::AutomatedTesting => AUTOMATED_TESTING_MIN_EDGE_BITS,
 		ChainTypes::UserTesting => USER_TESTING_MIN_EDGE_BITS,
 		_ => DEFAULT_MIN_EDGE_BITS,
@@ -213,8 +225,7 @@ pub fn min_edge_bits() -> u8 {
 /// while the min_edge_bits can be changed on a soft fork, changing
 /// base_edge_bits is a hard fork.
 pub fn base_edge_bits() -> u8 {
-	let param_ref = CHAIN_TYPE.read();
-	match *param_ref {
+	match get_chain_type() {
 		ChainTypes::AutomatedTesting => AUTOMATED_TESTING_MIN_EDGE_BITS,
 		ChainTypes::UserTesting => USER_TESTING_MIN_EDGE_BITS,
 		_ => BASE_EDGE_BITS,
@@ -223,8 +234,7 @@ pub fn base_edge_bits() -> u8 {
 
 /// The proofsize
 pub fn proofsize() -> usize {
-	let param_ref = CHAIN_TYPE.read();
-	match *param_ref {
+	match get_chain_type() {
 		ChainTypes::AutomatedTesting => AUTOMATED_TESTING_PROOF_SIZE,
 		ChainTypes::UserTesting => USER_TESTING_PROOF_SIZE,
 		_ => PROOFSIZE,
@@ -233,8 +243,7 @@ pub fn proofsize() -> usize {
 
 /// Coinbase maturity for coinbases to be spent
 pub fn coinbase_maturity() -> u64 {
-	let param_ref = CHAIN_TYPE.read();
-	match *param_ref {
+	match get_chain_type() {
 		ChainTypes::AutomatedTesting => AUTOMATED_TESTING_COINBASE_MATURITY,
 		ChainTypes::UserTesting => USER_TESTING_COINBASE_MATURITY,
 		_ => COINBASE_MATURITY,
@@ -243,8 +252,7 @@ pub fn coinbase_maturity() -> u64 {
 
 /// Initial mining difficulty
 pub fn initial_block_difficulty() -> u64 {
-	let param_ref = CHAIN_TYPE.read();
-	match *param_ref {
+	match get_chain_type() {
 		ChainTypes::AutomatedTesting => TESTING_INITIAL_DIFFICULTY,
 		ChainTypes::UserTesting => TESTING_INITIAL_DIFFICULTY,
 		ChainTypes::Floonet => INITIAL_DIFFICULTY,
@@ -253,8 +261,7 @@ pub fn initial_block_difficulty() -> u64 {
 }
 /// Initial mining secondary scale
 pub fn initial_graph_weight() -> u32 {
-	let param_ref = CHAIN_TYPE.read();
-	match *param_ref {
+	match get_chain_type() {
 		ChainTypes::AutomatedTesting => TESTING_INITIAL_GRAPH_WEIGHT,
 		ChainTypes::UserTesting => TESTING_INITIAL_GRAPH_WEIGHT,
 		ChainTypes::Floonet => graph_weight(0, SECOND_POW_EDGE_BITS) as u32,
@@ -264,8 +271,7 @@ pub fn initial_graph_weight() -> u32 {
 
 /// Maximum allowed block weight.
 pub fn max_block_weight() -> usize {
-	let param_ref = CHAIN_TYPE.read();
-	match *param_ref {
+	match get_chain_type() {
 		ChainTypes::AutomatedTesting => TESTING_MAX_BLOCK_WEIGHT,
 		ChainTypes::UserTesting => TESTING_MAX_BLOCK_WEIGHT,
 		ChainTypes::Floonet => MAX_BLOCK_WEIGHT,
@@ -275,8 +281,7 @@ pub fn max_block_weight() -> usize {
 
 /// Horizon at which we can cut-through and do full local pruning
 pub fn cut_through_horizon() -> u32 {
-	let param_ref = CHAIN_TYPE.read();
-	match *param_ref {
+	match get_chain_type() {
 		ChainTypes::AutomatedTesting => AUTOMATED_TESTING_CUT_THROUGH_HORIZON,
 		ChainTypes::UserTesting => USER_TESTING_CUT_THROUGH_HORIZON,
 		_ => CUT_THROUGH_HORIZON,
@@ -285,8 +290,7 @@ pub fn cut_through_horizon() -> u32 {
 
 /// Threshold at which we can request a txhashset (and full blocks from)
 pub fn state_sync_threshold() -> u32 {
-	let param_ref = CHAIN_TYPE.read();
-	match *param_ref {
+	match get_chain_type() {
 		ChainTypes::AutomatedTesting => TESTING_STATE_SYNC_THRESHOLD,
 		ChainTypes::UserTesting => TESTING_STATE_SYNC_THRESHOLD,
 		_ => STATE_SYNC_THRESHOLD,
@@ -295,8 +299,7 @@ pub fn state_sync_threshold() -> u32 {
 
 /// Number of blocks to reuse a txhashset zip for.
 pub fn txhashset_archive_interval() -> u64 {
-	let param_ref = CHAIN_TYPE.read();
-	match *param_ref {
+	match get_chain_type() {
 		ChainTypes::AutomatedTesting => TESTING_TXHASHSET_ARCHIVE_INTERVAL,
 		ChainTypes::UserTesting => TESTING_TXHASHSET_ARCHIVE_INTERVAL,
 		_ => TXHASHSET_ARCHIVE_INTERVAL,
@@ -306,8 +309,11 @@ pub fn txhashset_archive_interval() -> u64 {
 /// Are we in production mode?
 /// Production defined as a live public network, testnet[n] or mainnet.
 pub fn is_production_mode() -> bool {
-	let param_ref = CHAIN_TYPE.read();
-	ChainTypes::Floonet == *param_ref || ChainTypes::Mainnet == *param_ref
+	match get_chain_type() {
+		ChainTypes::Floonet => true,
+		ChainTypes::Mainnet => true,
+		_ => false,
+	}
 }
 
 /// Are we in floonet?
@@ -315,8 +321,10 @@ pub fn is_production_mode() -> bool {
 /// as possible to "mainnet" configuration as possible.
 /// We want to avoid missing any mainnet only code paths.
 pub fn is_floonet() -> bool {
-	let param_ref = CHAIN_TYPE.read();
-	ChainTypes::Floonet == *param_ref
+	match get_chain_type() {
+		ChainTypes::Floonet => true,
+		_ => false,
+	}
 }
 
 /// Converts an iterator of block difficulty data to more a more manageable
diff --git a/core/src/libtx/build.rs b/core/src/libtx/build.rs
index 4eb92faa7..02beb197b 100644
--- a/core/src/libtx/build.rs
+++ b/core/src/libtx/build.rs
@@ -252,6 +252,7 @@ mod test {
 	use super::*;
 	use crate::core::transaction::Weighting;
 	use crate::core::verifier_cache::{LruVerifierCache, VerifierCache};
+	use crate::global;
 	use crate::libtx::ProofBuilder;
 	use keychain::{ExtKeychain, ExtKeychainPath};
 
@@ -261,6 +262,7 @@ mod test {
 
 	#[test]
 	fn blind_simple_tx() {
+		global::set_local_chain_type(global::ChainTypes::AutomatedTesting);
 		let keychain = ExtKeychain::from_random_seed(false).unwrap();
 		let builder = ProofBuilder::new(&keychain);
 		let key_id1 = ExtKeychainPath::new(1, 1, 0, 0, 0).to_identifier();
@@ -282,6 +284,7 @@ mod test {
 
 	#[test]
 	fn blind_simple_tx_with_offset() {
+		global::set_local_chain_type(global::ChainTypes::AutomatedTesting);
 		let keychain = ExtKeychain::from_random_seed(false).unwrap();
 		let builder = ProofBuilder::new(&keychain);
 		let key_id1 = ExtKeychainPath::new(1, 1, 0, 0, 0).to_identifier();
@@ -303,6 +306,7 @@ mod test {
 
 	#[test]
 	fn blind_simpler_tx() {
+		global::set_local_chain_type(global::ChainTypes::AutomatedTesting);
 		let keychain = ExtKeychain::from_random_seed(false).unwrap();
 		let builder = ProofBuilder::new(&keychain);
 		let key_id1 = ExtKeychainPath::new(1, 1, 0, 0, 0).to_identifier();
diff --git a/core/src/pow.rs b/core/src/pow.rs
index 2e285e5b8..847e3439b 100644
--- a/core/src/pow.rs
+++ b/core/src/pow.rs
@@ -130,7 +130,7 @@ mod test {
 	/// We'll be generating genesis blocks differently
 	#[test]
 	fn genesis_pow() {
-		global::set_mining_mode(ChainTypes::UserTesting);
+		global::set_local_chain_type(ChainTypes::UserTesting);
 
 		let mut b = genesis::genesis_dev();
 		b.header.pow.nonce = 28106;
diff --git a/core/src/pow/cuckaroo.rs b/core/src/pow/cuckaroo.rs
index 9ce288285..88311dfaf 100644
--- a/core/src/pow/cuckaroo.rs
+++ b/core/src/pow/cuckaroo.rs
@@ -170,6 +170,7 @@ mod test {
 
 	#[test]
 	fn cuckaroo19_vectors() {
+		global::set_local_chain_type(global::ChainTypes::Mainnet);
 		let mut ctx = new_impl::<u64>(19, 42);
 		ctx.params.siphash_keys = V1_19_HASH;
 		assert!(ctx.verify(&Proof::new(V1_19_SOL.to_vec())).is_ok());
diff --git a/core/src/pow/cuckarood.rs b/core/src/pow/cuckarood.rs
index 089f39259..c5fb8c924 100644
--- a/core/src/pow/cuckarood.rs
+++ b/core/src/pow/cuckarood.rs
@@ -172,6 +172,7 @@ mod test {
 
 	#[test]
 	fn cuckarood19_29_vectors() {
+		global::set_local_chain_type(global::ChainTypes::Mainnet);
 		let mut ctx19 = new_impl::<u64>(19, 42);
 		ctx19.params.siphash_keys = V1_19_HASH;
 		assert!(ctx19.verify(&Proof::new(V1_19_SOL.to_vec())).is_ok());
diff --git a/core/src/pow/cuckaroom.rs b/core/src/pow/cuckaroom.rs
index 7590447bb..760025093 100644
--- a/core/src/pow/cuckaroom.rs
+++ b/core/src/pow/cuckaroom.rs
@@ -165,6 +165,7 @@ mod test {
 
 	#[test]
 	fn cuckaroom19_29_vectors() {
+		global::set_local_chain_type(global::ChainTypes::Mainnet);
 		let mut ctx19 = new_impl::<u64>(19, 42);
 		ctx19.params.siphash_keys = V1_19_HASH;
 		assert!(ctx19.verify(&Proof::new(V1_19_SOL.to_vec())).is_ok());
diff --git a/core/src/pow/cuckatoo.rs b/core/src/pow/cuckatoo.rs
index d5611f2b3..d4106ff78 100644
--- a/core/src/pow/cuckatoo.rs
+++ b/core/src/pow/cuckatoo.rs
@@ -367,6 +367,7 @@ mod test {
 
 	#[test]
 	fn cuckatoo() {
+		global::set_local_chain_type(global::ChainTypes::Mainnet);
 		let ret = basic_solve::<u32>();
 		if let Err(r) = ret {
 			panic!("basic_solve u32: Error: {}", r);
diff --git a/core/src/pow/lean.rs b/core/src/pow/lean.rs
index c144dc64a..64310dc5d 100644
--- a/core/src/pow/lean.rs
+++ b/core/src/pow/lean.rs
@@ -88,10 +88,12 @@ impl Lean {
 #[cfg(test)]
 mod test {
 	use super::*;
+	use crate::global;
 	use crate::pow::types::PoWContext;
 
 	#[test]
 	fn lean_miner() {
+		global::set_local_chain_type(global::ChainTypes::Mainnet);
 		let nonce = 15465723;
 		let header = [0u8; 84].to_vec(); // with nonce
 		let edge_bits = 19;
diff --git a/core/src/pow/types.rs b/core/src/pow/types.rs
index c03f3a203..aee995787 100644
--- a/core/src/pow/types.rs
+++ b/core/src/pow/types.rs
@@ -507,6 +507,7 @@ mod tests {
 
 	#[test]
 	fn test_proof_rw() {
+		global::set_local_chain_type(global::ChainTypes::Mainnet);
 		for edge_bits in 10..63 {
 			let mut proof = Proof::new(gen_proof(edge_bits as u32));
 			proof.edge_bits = edge_bits;
diff --git a/core/tests/block.rs b/core/tests/block.rs
index afd9aa66c..ff1193f2b 100644
--- a/core/tests/block.rs
+++ b/core/tests/block.rs
@@ -29,18 +29,22 @@ use crate::core::libtx::ProofBuilder;
 use crate::core::{global, ser};
 use chrono::Duration;
 use grin_core as core;
-use grin_core::global::ChainTypes;
 use keychain::{BlindingFactor, ExtKeychain, Keychain};
 use std::sync::Arc;
 use util::{secp, RwLock, ToHex};
 
+// Setup test with AutomatedTesting chain_type;
+fn test_setup() {
+	global::set_local_chain_type(global::ChainTypes::AutomatedTesting);
+}
+
 fn verifier_cache() -> Arc<RwLock<dyn VerifierCache>> {
 	Arc::new(RwLock::new(LruVerifierCache::new()))
 }
 
 #[test]
 fn too_large_block() {
-	global::set_mining_mode(ChainTypes::AutomatedTesting);
+	test_setup();
 	let keychain = ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let max_out = global::max_block_weight() / BLOCK_OUTPUT_WEIGHT;
@@ -71,6 +75,7 @@ fn too_large_block() {
 // block with no inputs/outputs/kernels
 // no fees, no reward, no coinbase
 fn very_empty_block() {
+	test_setup();
 	let b = Block::with_header(BlockHeader::default());
 
 	assert_eq!(
@@ -82,6 +87,7 @@ fn very_empty_block() {
 #[test]
 // builds a block with a tx spending another and check that cut_through occurred
 fn block_with_cut_through() {
+	test_setup();
 	let keychain = ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let key_id1 = ExtKeychain::derive_key_id(1, 1, 0, 0, 0);
@@ -120,6 +126,7 @@ fn block_with_cut_through() {
 
 #[test]
 fn empty_block_with_coinbase_is_valid() {
+	test_setup();
 	let keychain = ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let prev = BlockHeader::default();
@@ -158,6 +165,7 @@ fn empty_block_with_coinbase_is_valid() {
 // invalidates the block and specifically it causes verify_coinbase to fail
 // additionally verifying the merkle_inputs_outputs also fails
 fn remove_coinbase_output_flag() {
+	test_setup();
 	let keychain = ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let prev = BlockHeader::default();
@@ -181,6 +189,7 @@ fn remove_coinbase_output_flag() {
 // test that flipping the COINBASE flag on the kernel features
 // invalidates the block and specifically it causes verify_coinbase to fail
 fn remove_coinbase_kernel_flag() {
+	test_setup();
 	let keychain = ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let prev = BlockHeader::default();
@@ -223,6 +232,7 @@ fn serialize_deserialize_header_version() {
 
 #[test]
 fn serialize_deserialize_block_header() {
+	test_setup();
 	let keychain = ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let prev = BlockHeader::default();
@@ -240,6 +250,7 @@ fn serialize_deserialize_block_header() {
 
 #[test]
 fn serialize_deserialize_block() {
+	test_setup();
 	let tx1 = tx1i2o();
 	let keychain = ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
@@ -260,7 +271,7 @@ fn serialize_deserialize_block() {
 
 #[test]
 fn empty_block_serialized_size() {
-	global::set_mining_mode(ChainTypes::AutomatedTesting);
+	test_setup();
 	let keychain = ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let prev = BlockHeader::default();
@@ -273,7 +284,7 @@ fn empty_block_serialized_size() {
 
 #[test]
 fn block_single_tx_serialized_size() {
-	global::set_mining_mode(ChainTypes::AutomatedTesting);
+	test_setup();
 	let keychain = ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let tx1 = tx1i2o();
@@ -287,7 +298,7 @@ fn block_single_tx_serialized_size() {
 
 #[test]
 fn empty_compact_block_serialized_size() {
-	global::set_mining_mode(ChainTypes::AutomatedTesting);
+	test_setup();
 	let keychain = ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let prev = BlockHeader::default();
@@ -301,7 +312,7 @@ fn empty_compact_block_serialized_size() {
 
 #[test]
 fn compact_block_single_tx_serialized_size() {
-	global::set_mining_mode(ChainTypes::AutomatedTesting);
+	test_setup();
 	let keychain = ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let tx1 = tx1i2o();
@@ -316,7 +327,7 @@ fn compact_block_single_tx_serialized_size() {
 
 #[test]
 fn block_10_tx_serialized_size() {
-	global::set_mining_mode(global::ChainTypes::AutomatedTesting);
+	test_setup();
 	let keychain = ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 
@@ -353,7 +364,7 @@ fn block_10_tx_serialized_size() {
 
 #[test]
 fn compact_block_10_tx_serialized_size() {
-	global::set_mining_mode(ChainTypes::AutomatedTesting);
+	test_setup();
 	let keychain = ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 
@@ -373,6 +384,7 @@ fn compact_block_10_tx_serialized_size() {
 
 #[test]
 fn compact_block_hash_with_nonce() {
+	test_setup();
 	let keychain = ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let tx = tx1i2o();
@@ -404,6 +416,7 @@ fn compact_block_hash_with_nonce() {
 
 #[test]
 fn convert_block_to_compact_block() {
+	test_setup();
 	let keychain = ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let tx1 = tx1i2o();
@@ -428,6 +441,7 @@ fn convert_block_to_compact_block() {
 
 #[test]
 fn hydrate_empty_compact_block() {
+	test_setup();
 	let keychain = ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let prev = BlockHeader::default();
@@ -442,6 +456,7 @@ fn hydrate_empty_compact_block() {
 
 #[test]
 fn serialize_deserialize_compact_block() {
+	test_setup();
 	let keychain = ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let tx1 = tx1i2o();
@@ -469,6 +484,7 @@ fn serialize_deserialize_compact_block() {
 // Duplicate a range proof from a valid output into another of the same amount
 #[test]
 fn same_amount_outputs_copy_range_proof() {
+	test_setup();
 	let keychain = keychain::ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let key_id1 = keychain::ExtKeychain::derive_key_id(1, 1, 0, 0, 0);
@@ -511,6 +527,7 @@ fn same_amount_outputs_copy_range_proof() {
 // Swap a range proof with the right private key but wrong amount
 #[test]
 fn wrong_amount_range_proof() {
+	test_setup();
 	let keychain = keychain::ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let key_id1 = keychain::ExtKeychain::derive_key_id(1, 1, 0, 0, 0);
@@ -563,6 +580,7 @@ fn wrong_amount_range_proof() {
 
 #[test]
 fn validate_header_proof() {
+	test_setup();
 	let keychain = ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let prev = BlockHeader::default();
diff --git a/core/tests/consensus_automated.rs b/core/tests/consensus_automated.rs
index bd6b51bfc..037c07175 100644
--- a/core/tests/consensus_automated.rs
+++ b/core/tests/consensus_automated.rs
@@ -22,7 +22,7 @@ use grin_core::pow::Difficulty;
 /// Checks different next_target adjustments and difficulty boundaries
 #[test]
 fn next_target_adjustment() {
-	global::set_mining_mode(global::ChainTypes::AutomatedTesting);
+	global::set_local_chain_type(global::ChainTypes::AutomatedTesting);
 	let cur_time = Utc::now().timestamp() as u64;
 	let diff_min = Difficulty::min();
 
diff --git a/core/tests/consensus_floonet.rs b/core/tests/consensus_floonet.rs
index 777b52eff..b793d9b9d 100644
--- a/core/tests/consensus_floonet.rs
+++ b/core/tests/consensus_floonet.rs
@@ -21,7 +21,7 @@ use grin_core::global;
 #[test]
 fn test_secondary_pow_ratio() {
 	// Tests for Floonet chain type (covers pre and post hardfork).
-	global::set_mining_mode(global::ChainTypes::Floonet);
+	global::set_local_chain_type(global::ChainTypes::Floonet);
 	assert_eq!(global::is_floonet(), true);
 
 	assert_eq!(secondary_pow_ratio(1), 90);
@@ -63,7 +63,7 @@ fn test_secondary_pow_ratio() {
 
 #[test]
 fn hard_forks() {
-	global::set_mining_mode(global::ChainTypes::Floonet);
+	global::set_local_chain_type(global::ChainTypes::Floonet);
 	assert_eq!(global::is_floonet(), true);
 	assert!(valid_header_version(0, HeaderVersion(1)));
 	assert!(valid_header_version(10, HeaderVersion(1)));
diff --git a/core/tests/consensus_mainnet.rs b/core/tests/consensus_mainnet.rs
index 9944ca7ce..c9fcacd75 100644
--- a/core/tests/consensus_mainnet.rs
+++ b/core/tests/consensus_mainnet.rs
@@ -245,8 +245,7 @@ fn print_chain_sim(chain_sim: Vec<(HeaderInfo, DiffStats)>) {
 /// Checks different next_target adjustments and difficulty boundaries
 #[test]
 fn adjustment_scenarios() {
-	// Use production parameters for genesis diff
-	global::set_mining_mode(global::ChainTypes::Mainnet);
+	global::set_local_chain_type(global::ChainTypes::Mainnet);
 
 	// Genesis block with initial diff
 	let chain_sim = create_chain_sim(global::initial_block_difficulty());
@@ -318,8 +317,7 @@ fn adjustment_scenarios() {
 
 #[test]
 fn test_secondary_pow_ratio() {
-	global::set_mining_mode(global::ChainTypes::Mainnet);
-	assert_eq!(global::is_floonet(), false);
+	global::set_local_chain_type(global::ChainTypes::Mainnet);
 
 	assert_eq!(secondary_pow_ratio(1), 90);
 	assert_eq!(secondary_pow_ratio(89), 90);
@@ -360,12 +358,11 @@ fn test_secondary_pow_ratio() {
 
 #[test]
 fn test_secondary_pow_scale() {
+	global::set_local_chain_type(global::ChainTypes::Mainnet);
+
 	let window = DIFFICULTY_ADJUST_WINDOW;
 	let mut hi = HeaderInfo::from_diff_scaling(Difficulty::from_num(10), 100);
 
-	global::set_mining_mode(global::ChainTypes::Mainnet);
-	assert_eq!(global::is_floonet(), false);
-
 	// all primary, factor should increase so it becomes easier to find a high
 	// difficulty block
 	hi.is_secondary = false;
@@ -436,8 +433,8 @@ fn test_secondary_pow_scale() {
 
 #[test]
 fn hard_forks() {
-	global::set_mining_mode(global::ChainTypes::Mainnet);
-	assert_eq!(global::is_floonet(), false);
+	global::set_local_chain_type(global::ChainTypes::Mainnet);
+
 	assert!(valid_header_version(0, HeaderVersion(1)));
 	assert!(valid_header_version(10, HeaderVersion(1)));
 	assert!(!valid_header_version(10, HeaderVersion(2)));
diff --git a/core/tests/core.rs b/core/tests/core.rs
index 80f16fcef..b9bc58f8b 100644
--- a/core/tests/core.rs
+++ b/core/tests/core.rs
@@ -25,7 +25,7 @@ use self::core::core::{
 };
 use self::core::libtx::build::{self, initial_tx, input, output, with_excess};
 use self::core::libtx::ProofBuilder;
-use self::core::ser;
+use self::core::{global, ser};
 use crate::common::{new_block, tx1i1o, tx1i2o, tx2i1o};
 use grin_core as core;
 use keychain::{BlindingFactor, ExtKeychain, Keychain};
@@ -33,6 +33,11 @@ use std::sync::Arc;
 use util::static_secp_instance;
 use util::RwLock;
 
+// Setup test with AutomatedTesting chain_type;
+fn test_setup() {
+	global::set_local_chain_type(global::ChainTypes::AutomatedTesting);
+}
+
 #[test]
 fn simple_tx_ser() {
 	let tx = tx2i1o();
@@ -61,6 +66,7 @@ fn simple_tx_ser() {
 
 #[test]
 fn simple_tx_ser_deser() {
+	test_setup();
 	let tx = tx2i1o();
 	let mut vec = Vec::new();
 	ser::serialize_default(&mut vec, &tx).expect("serialization failed");
@@ -73,6 +79,7 @@ fn simple_tx_ser_deser() {
 
 #[test]
 fn tx_double_ser_deser() {
+	test_setup();
 	// checks serializing doesn't mess up the tx and produces consistent results
 	let btx = tx2i1o();
 
@@ -91,6 +98,7 @@ fn tx_double_ser_deser() {
 #[test]
 #[should_panic(expected = "Keychain Error")]
 fn test_zero_commit_fails() {
+	test_setup();
 	let keychain = ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let key_id1 = ExtKeychain::derive_key_id(1, 1, 0, 0, 0);
@@ -111,6 +119,7 @@ fn verifier_cache() -> Arc<RwLock<dyn VerifierCache>> {
 
 #[test]
 fn build_tx_kernel() {
+	test_setup();
 	let keychain = ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let key_id1 = ExtKeychain::derive_key_id(1, 1, 0, 0, 0);
@@ -143,6 +152,7 @@ fn build_tx_kernel() {
 // and check it still validates.
 #[test]
 fn transaction_cut_through() {
+	test_setup();
 	let tx1 = tx1i2o();
 	let tx2 = tx2i1o();
 
@@ -164,6 +174,7 @@ fn transaction_cut_through() {
 // Attempt to deaggregate a multi-kernel transaction in a different way
 #[test]
 fn multi_kernel_transaction_deaggregation() {
+	test_setup();
 	let tx1 = tx1i1o();
 	let tx2 = tx1i1o();
 	let tx3 = tx1i1o();
@@ -202,6 +213,7 @@ fn multi_kernel_transaction_deaggregation() {
 
 #[test]
 fn multi_kernel_transaction_deaggregation_2() {
+	test_setup();
 	let tx1 = tx1i1o();
 	let tx2 = tx1i1o();
 	let tx3 = tx1i1o();
@@ -227,6 +239,7 @@ fn multi_kernel_transaction_deaggregation_2() {
 
 #[test]
 fn multi_kernel_transaction_deaggregation_3() {
+	test_setup();
 	let tx1 = tx1i1o();
 	let tx2 = tx1i1o();
 	let tx3 = tx1i1o();
@@ -253,6 +266,7 @@ fn multi_kernel_transaction_deaggregation_3() {
 
 #[test]
 fn multi_kernel_transaction_deaggregation_4() {
+	test_setup();
 	let tx1 = tx1i1o();
 	let tx2 = tx1i1o();
 	let tx3 = tx1i1o();
@@ -288,6 +302,7 @@ fn multi_kernel_transaction_deaggregation_4() {
 
 #[test]
 fn multi_kernel_transaction_deaggregation_5() {
+	test_setup();
 	let tx1 = tx1i1o();
 	let tx2 = tx1i1o();
 	let tx3 = tx1i1o();
@@ -327,6 +342,7 @@ fn multi_kernel_transaction_deaggregation_5() {
 // Attempt to deaggregate a multi-kernel transaction
 #[test]
 fn basic_transaction_deaggregation() {
+	test_setup();
 	let tx1 = tx1i2o();
 	let tx2 = tx2i1o();
 
@@ -412,6 +428,7 @@ fn tx_hash_diff() {
 /// 2 inputs, 2 outputs transaction.
 #[test]
 fn tx_build_exchange() {
+	test_setup();
 	let keychain = ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let key_id1 = ExtKeychain::derive_key_id(1, 1, 0, 0, 0);
@@ -457,6 +474,7 @@ fn tx_build_exchange() {
 
 #[test]
 fn reward_empty_block() {
+	test_setup();
 	let keychain = keychain::ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let key_id = ExtKeychain::derive_key_id(1, 1, 0, 0, 0);
@@ -473,6 +491,7 @@ fn reward_empty_block() {
 
 #[test]
 fn reward_with_tx_block() {
+	test_setup();
 	let keychain = keychain::ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let key_id = ExtKeychain::derive_key_id(1, 1, 0, 0, 0);
@@ -500,6 +519,7 @@ fn reward_with_tx_block() {
 
 #[test]
 fn simple_block() {
+	test_setup();
 	let keychain = keychain::ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let key_id = ExtKeychain::derive_key_id(1, 1, 0, 0, 0);
@@ -523,6 +543,7 @@ fn simple_block() {
 
 #[test]
 fn test_block_with_timelocked_tx() {
+	test_setup();
 	let keychain = keychain::ExtKeychain::from_random_seed(false).unwrap();
 	let builder = ProofBuilder::new(&keychain);
 	let key_id1 = ExtKeychain::derive_key_id(1, 1, 0, 0, 0);
@@ -581,6 +602,7 @@ fn test_block_with_timelocked_tx() {
 
 #[test]
 pub fn test_verify_1i1o_sig() {
+	test_setup();
 	let tx = tx1i1o();
 	tx.validate(Weighting::AsTransaction, verifier_cache())
 		.unwrap();
@@ -588,6 +610,7 @@ pub fn test_verify_1i1o_sig() {
 
 #[test]
 pub fn test_verify_2i1o_sig() {
+	test_setup();
 	let tx = tx2i1o();
 	tx.validate(Weighting::AsTransaction, verifier_cache())
 		.unwrap();
diff --git a/etc/gen_gen/src/bin/gen_gen.rs b/etc/gen_gen/src/bin/gen_gen.rs
index fdbfd9711..324891166 100644
--- a/etc/gen_gen/src/bin/gen_gen.rs
+++ b/etc/gen_gen/src/bin/gen_gen.rs
@@ -92,7 +92,7 @@ fn main() {
 
 	{
 		// setup a tmp chain to set block header roots
-		core::global::set_mining_mode(core::global::ChainTypes::UserTesting);
+		core::global::set_local_chain_type(core::global::ChainTypes::UserTesting);
 		let tmp_chain = setup_chain(".grin.tmp", core::pow::mine_genesis_block().unwrap());
 		tmp_chain.set_txhashset_roots(&mut gen).unwrap();
 	}
@@ -103,7 +103,7 @@ fn main() {
 	gen.header.prev_root = core::core::hash::Hash::from_hex(&h1).unwrap();
 
 	// mine a Cuckaroo29 block
-	core::global::set_mining_mode(core::global::ChainTypes::Mainnet);
+	core::global::set_local_chain_type(core::global::ChainTypes::Mainnet);
 	let plugin_lib = cuckoo::PluginLibrary::new(PLUGIN_PATH).unwrap();
 	let mut params = plugin_lib.get_default_params();
 	params.mutate_nonce = false;
@@ -216,7 +216,7 @@ fn update_genesis_rs(gen: &core::core::Block) {
 		"excess".to_string(),
 		format!(
 			"Commitment::from_vec(util::from_hex({:x?}.to_string()).unwrap())",
-			gen.kernels()[0].excess.to_hex())
+			gen.kernels()[0].excess.to_hex()
 		),
 	));
 	replacements.push((
diff --git a/p2p/src/msg.rs b/p2p/src/msg.rs
index 0907bf048..d9a5cef8e 100644
--- a/p2p/src/msg.rs
+++ b/p2p/src/msg.rs
@@ -106,7 +106,7 @@ fn max_msg_size(msg_type: Type) -> u64 {
 }
 
 fn magic() -> [u8; 2] {
-	match *global::CHAIN_TYPE.read() {
+	match global::get_chain_type() {
 		global::ChainTypes::Floonet => FLOONET_MAGIC,
 		global::ChainTypes::Mainnet => MAINNET_MAGIC,
 		_ => OTHER_MAGIC,
diff --git a/p2p/tests/peer_handshake.rs b/p2p/tests/peer_handshake.rs
index e313370cc..6c72a89ab 100644
--- a/p2p/tests/peer_handshake.rs
+++ b/p2p/tests/peer_handshake.rs
@@ -23,6 +23,7 @@ use std::sync::Arc;
 use std::{thread, time};
 
 use crate::core::core::hash::Hash;
+use crate::core::global;
 use crate::core::pow::Difficulty;
 use crate::p2p::types::PeerAddr;
 use crate::p2p::Peer;
@@ -35,11 +36,17 @@ fn open_port() -> u16 {
 	listener.local_addr().unwrap().port()
 }
 
+// Setup test with AutomatedTesting chain_type;
+fn test_setup() {
+	global::set_local_chain_type(global::ChainTypes::AutomatedTesting);
+	util::init_test_logger();
+}
+
 // Starts a server and connects a client peer to it to check handshake,
 // followed by a ping/pong exchange to make sure the connection is live.
 #[test]
 fn peer_handshake() {
-	util::init_test_logger();
+	test_setup();
 
 	let p2p_config = p2p::P2PConfig {
 		host: "127.0.0.1".parse().unwrap(),
@@ -62,7 +69,11 @@ fn peer_handshake() {
 	);
 
 	let p2p_inner = server.clone();
-	let _ = thread::spawn(move || p2p_inner.listen());
+	let _ = thread::spawn(move || {
+		// Test setup relies on thread local for chain_type so make sure we setup here.
+		test_setup();
+		p2p_inner.listen()
+	});
 
 	thread::sleep(time::Duration::from_secs(1));
 
diff --git a/pool/src/types.rs b/pool/src/types.rs
index 3d9d08f22..eae0700a2 100644
--- a/pool/src/types.rs
+++ b/pool/src/types.rs
@@ -17,12 +17,12 @@
 
 use chrono::prelude::{DateTime, Utc};
 
+use self::core::consensus;
 use self::core::core::block;
 use self::core::core::committed;
 use self::core::core::hash::Hash;
 use self::core::core::transaction::{self, Transaction};
 use self::core::core::{BlockHeader, BlockSums};
-use self::core::{consensus, global};
 use failure::Fail;
 use grin_core as core;
 use grin_keychain as keychain;
@@ -144,7 +144,7 @@ fn default_max_stempool_size() -> usize {
 	50_000
 }
 fn default_mineable_max_weight() -> usize {
-	global::max_block_weight()
+	consensus::MAX_BLOCK_WEIGHT
 }
 
 /// Represents a single entry in the pool.
diff --git a/pool/tests/block_building.rs b/pool/tests/block_building.rs
index d0feb6e70..0fd144fff 100644
--- a/pool/tests/block_building.rs
+++ b/pool/tests/block_building.rs
@@ -17,8 +17,8 @@ pub mod common;
 use self::core::core::hash::Hashed;
 use self::core::core::verifier_cache::LruVerifierCache;
 use self::core::core::{Block, BlockHeader, Transaction};
-use self::core::libtx;
 use self::core::pow::Difficulty;
+use self::core::{global, libtx};
 use self::keychain::{ExtKeychain, Keychain};
 use self::util::RwLock;
 use crate::common::*;
@@ -30,6 +30,7 @@ use std::sync::Arc;
 #[test]
 fn test_transaction_pool_block_building() {
 	util::init_test_logger();
+	global::set_local_chain_type(global::ChainTypes::AutomatedTesting);
 	let keychain: ExtKeychain = Keychain::from_random_seed(false).unwrap();
 
 	let db_root = ".grin_block_building".to_string();
diff --git a/pool/tests/block_max_weight.rs b/pool/tests/block_max_weight.rs
index 77cf28d07..fec5dcfcc 100644
--- a/pool/tests/block_max_weight.rs
+++ b/pool/tests/block_max_weight.rs
@@ -33,7 +33,7 @@ use std::sync::Arc;
 #[test]
 fn test_block_building_max_weight() {
 	util::init_test_logger();
-	global::set_mining_mode(global::ChainTypes::AutomatedTesting);
+	global::set_local_chain_type(global::ChainTypes::AutomatedTesting);
 
 	let keychain: ExtKeychain = Keychain::from_random_seed(false).unwrap();
 
diff --git a/pool/tests/block_reconciliation.rs b/pool/tests/block_reconciliation.rs
index fe62d6861..804f6a219 100644
--- a/pool/tests/block_reconciliation.rs
+++ b/pool/tests/block_reconciliation.rs
@@ -17,8 +17,8 @@ pub mod common;
 use self::core::core::hash::Hashed;
 use self::core::core::verifier_cache::LruVerifierCache;
 use self::core::core::{Block, BlockHeader};
-use self::core::libtx;
 use self::core::pow::Difficulty;
+use self::core::{global, libtx};
 use self::keychain::{ExtKeychain, Keychain};
 use self::util::RwLock;
 use crate::common::ChainAdapter;
@@ -30,6 +30,7 @@ use std::sync::Arc;
 
 #[test]
 fn test_transaction_pool_block_reconciliation() {
+	global::set_local_chain_type(global::ChainTypes::AutomatedTesting);
 	let keychain: ExtKeychain = Keychain::from_random_seed(false).unwrap();
 
 	let db_root = ".grin_block_reconciliation".to_string();
diff --git a/pool/tests/coinbase_maturity.rs b/pool/tests/coinbase_maturity.rs
index 88eb0e1df..53e9d03d1 100644
--- a/pool/tests/coinbase_maturity.rs
+++ b/pool/tests/coinbase_maturity.rs
@@ -17,6 +17,7 @@ pub mod common;
 use self::core::core::hash::Hash;
 use self::core::core::verifier_cache::LruVerifierCache;
 use self::core::core::{BlockHeader, BlockSums, Transaction};
+use self::core::global;
 use self::keychain::{ExtKeychain, Keychain};
 use self::pool::types::{BlockChain, PoolError};
 use self::util::RwLock;
@@ -67,6 +68,7 @@ impl BlockChain for CoinbaseMaturityErrorChainAdapter {
 /// Test we correctly verify coinbase maturity when adding txs to the pool.
 #[test]
 fn test_coinbase_maturity() {
+	global::set_local_chain_type(global::ChainTypes::AutomatedTesting);
 	let keychain: ExtKeychain = Keychain::from_random_seed(false).unwrap();
 
 	// Mocking this up with an adapter that will raise an error for coinbase
diff --git a/pool/tests/transaction_pool.rs b/pool/tests/transaction_pool.rs
index df41ed3ba..ee9457952 100644
--- a/pool/tests/transaction_pool.rs
+++ b/pool/tests/transaction_pool.rs
@@ -16,8 +16,8 @@ pub mod common;
 
 use self::core::core::verifier_cache::LruVerifierCache;
 use self::core::core::{transaction, Block, BlockHeader, Weighting};
-use self::core::libtx;
 use self::core::pow::Difficulty;
+use self::core::{global, libtx};
 use self::keychain::{ExtKeychain, Keychain};
 use self::pool::TxSource;
 use self::util::RwLock;
@@ -31,6 +31,8 @@ use std::sync::Arc;
 /// Test we can add some txs to the pool (both stempool and txpool).
 #[test]
 fn test_the_transaction_pool() {
+	// Use mainnet config to allow for reasonably large block weights.
+	global::set_local_chain_type(global::ChainTypes::Mainnet);
 	let keychain: ExtKeychain = Keychain::from_random_seed(false).unwrap();
 
 	let db_root = ".grin_transaction_pool".to_string();
diff --git a/src/bin/cmd/server.rs b/src/bin/cmd/server.rs
index 69838afdc..eb17181cc 100644
--- a/src/bin/cmd/server.rs
+++ b/src/bin/cmd/server.rs
@@ -23,7 +23,6 @@ use clap::ArgMatches;
 use ctrlc;
 
 use crate::config::GlobalConfig;
-use crate::core::global;
 use crate::p2p::Seeding;
 use crate::servers;
 use crate::tui::ui;
@@ -86,19 +85,9 @@ fn start_server_tui(config: servers::ServerConfig, logs_rx: Option<mpsc::Receive
 /// configuration.
 pub fn server_command(
 	server_args: Option<&ArgMatches<'_>>,
-	mut global_config: GlobalConfig,
+	global_config: GlobalConfig,
 	logs_rx: Option<mpsc::Receiver<LogEntry>>,
 ) -> i32 {
-	global::set_mining_mode(
-		global_config
-			.members
-			.as_mut()
-			.unwrap()
-			.server
-			.clone()
-			.chain_type,
-	);
-
 	// just get defaults from the global config
 	let mut server_config = global_config.members.as_ref().unwrap().server.clone();
 
diff --git a/src/bin/grin.rs b/src/bin/grin.rs
index 70fdcbd74..c35659c09 100644
--- a/src/bin/grin.rs
+++ b/src/bin/grin.rs
@@ -140,7 +140,8 @@ fn real_main() -> i32 {
 	};
 	init_logger(Some(logging_config), logs_tx);
 
-	global::set_mining_mode(config.members.unwrap().server.chain_type);
+	// One time initialization of the global chain_type.
+	global::init_global_chain_type(config.members.unwrap().server.chain_type);
 
 	if let Some(file_path) = &config.config_file_path {
 		info!(
diff --git a/store/tests/lmdb.rs b/store/tests/lmdb.rs
index 6e63dce7d..cceb4c11e 100644
--- a/store/tests/lmdb.rs
+++ b/store/tests/lmdb.rs
@@ -12,11 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+use grin_core as core;
 use grin_store as store;
 use grin_util as util;
 
-use grin_core::ser::{self, Readable, Reader, Writeable, Writer};
-
+use crate::core::global;
+use crate::core::ser::{self, Readable, Reader, Writeable, Writer};
 use std::fs;
 
 const WRITE_CHUNK_SIZE: usize = 20;
@@ -59,6 +60,7 @@ fn clean_output_dir(test_dir: &str) {
 }
 
 fn setup(test_dir: &str) {
+	global::set_local_chain_type(global::ChainTypes::Mainnet);
 	util::init_test_logger();
 	clean_output_dir(test_dir);
 }
diff --git a/util/src/lib.rs b/util/src/lib.rs
index dd1c4087d..fbe280272 100644
--- a/util/src/lib.rs
+++ b/util/src/lib.rs
@@ -100,6 +100,11 @@ where
 			.clone()
 			.expect("Cannot borrow one_time before initialization.")
 	}
+
+	/// Has this OneTime been initialized?
+	pub fn is_init(&self) -> bool {
+		self.inner.read().is_some()
+	}
 }
 
 /// Encode an utf8 string to a base64 string