diff --git a/Cargo.lock b/Cargo.lock index 17dbaddaf45..8597a6ff0d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3422,12 +3422,12 @@ dependencies = [ "easy-ext", "hex", "jemallocator", - "lazy_static", "near-crypto", "near-primitives-core", "near-rpc-error-macro", "near-vm-errors", "num-rational", + "once_cell", "primitive-types", "rand 0.7.3", "reed-solomon-erasure", diff --git a/core/primitives/Cargo.toml b/core/primitives/Cargo.toml index 2ae8f879af9..9ca4398a2f2 100644 --- a/core/primitives/Cargo.toml +++ b/core/primitives/Cargo.toml @@ -19,11 +19,11 @@ chrono = { version = "0.4.4", features = ["serde"] } derive_more = "0.99.3" easy-ext = "0.2" sha2 = "0.9" -lazy_static = "1.4" serde = { version = "1", features = ["derive"] } serde_json = "1" smart-default = "0.6" validator = "0.12" +once_cell = "1" rand = "0.7" reed-solomon-erasure = "4" jemallocator = { version = "0.3", optional = true } diff --git a/core/primitives/src/runtime/config.rs b/core/primitives/src/runtime/config.rs index 052650eca3a..37ffd7e2c74 100644 --- a/core/primitives/src/runtime/config.rs +++ b/core/primitives/src/runtime/config.rs @@ -1,4 +1,5 @@ //! Settings of the parameters of the runtime. +use once_cell::sync::OnceCell; use serde::{Deserialize, Serialize}; use crate::checked_feature; @@ -7,7 +8,7 @@ use crate::runtime::fees::RuntimeFeesConfig; use crate::serialize::u128_dec_format; use crate::types::{AccountId, Balance}; use crate::version::ProtocolVersion; -use std::sync::{Arc, Mutex}; +use std::sync::Arc; /// The structure that holds the parameters of the runtime, mostly economics. #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] @@ -26,6 +27,34 @@ pub struct RuntimeConfig { pub account_creation_config: AccountCreationConfig, } +/// We start with a specific runtime config at the genesis, but we might want to +/// do slight adjustments to it, depending on the protocol version. +/// +/// This struct takes care of returning a config appropriate for particular +/// protocol version. +pub struct CurrentRuntimeConfig { + genesis_runtime_config: Arc, + with_lower_storage_cost: OnceCell>, +} + +impl CurrentRuntimeConfig { + pub fn new(genesis_runtime_config: RuntimeConfig) -> Self { + Self { + genesis_runtime_config: Arc::new(genesis_runtime_config), + with_lower_storage_cost: OnceCell::new(), + } + } + + pub fn for_protocol_version(&self, protocol_version: ProtocolVersion) -> &Arc { + if checked_feature!("stable", LowerStorageCost, protocol_version) { + self.with_lower_storage_cost + .get_or_init(|| Arc::new(self.genesis_runtime_config.decrease_storage_cost())) + } else { + &self.genesis_runtime_config + } + } +} + impl Default for RuntimeConfig { fn default() -> Self { RuntimeConfig { @@ -38,10 +67,6 @@ impl Default for RuntimeConfig { } } -lazy_static::lazy_static! { - static ref LOWER_STORAGE_COST_CONFIG: Mutex>> = Mutex::new(None); -} - impl RuntimeConfig { pub fn free() -> Self { Self { @@ -52,23 +77,6 @@ impl RuntimeConfig { } } - /// Returns a `RuntimeConfig` for the corresponding protocol version. - /// It uses `genesis_runtime_config` to identify the original - /// config and `protocol_version` for the current protocol version. - pub fn from_protocol_version( - genesis_runtime_config: &Arc, - protocol_version: ProtocolVersion, - ) -> Arc { - if checked_feature!("stable", LowerStorageCost, protocol_version) { - let mut config = LOWER_STORAGE_COST_CONFIG.lock().unwrap(); - config - .get_or_insert_with(|| Arc::new(genesis_runtime_config.decrease_storage_cost())) - .clone() - } else { - genesis_runtime_config.clone() - } - } - /// Returns a new config with decreased storage cost. fn decrease_storage_cost(&self) -> Self { let mut config = self.clone(); @@ -113,15 +121,16 @@ mod tests { #[test] fn test_lower_cost() { - let config = Arc::new(RuntimeConfig::default()); - let config_same = RuntimeConfig::from_protocol_version(&config, 0); + let genesis_config = RuntimeConfig::default(); + let current_config = CurrentRuntimeConfig::new(genesis_config.clone()); + let config_same = current_config.for_protocol_version(0); assert_eq!( config_same.as_ref().storage_amount_per_byte, - config.as_ref().storage_amount_per_byte + genesis_config.storage_amount_per_byte ); - let config_lower = RuntimeConfig::from_protocol_version(&config, ProtocolVersion::MAX); + let config_lower = current_config.for_protocol_version(ProtocolVersion::MAX); assert!( - config_lower.as_ref().storage_amount_per_byte < config.as_ref().storage_amount_per_byte + config_lower.as_ref().storage_amount_per_byte < genesis_config.storage_amount_per_byte ); } } diff --git a/neard/src/lib.rs b/neard/src/lib.rs index 2327507c778..6b92706aa28 100644 --- a/neard/src/lib.rs +++ b/neard/src/lib.rs @@ -39,6 +39,9 @@ mod migrations; mod runtime; mod shard_tracker; +#[cfg(test)] +mod tests; + const STORE_PATH: &str = "data"; pub fn store_path_exists>(path: P) -> bool { diff --git a/neard/src/runtime/mod.rs b/neard/src/runtime/mod.rs index d4ff279365d..f25fe43eeae 100644 --- a/neard/src/runtime/mod.rs +++ b/neard/src/runtime/mod.rs @@ -30,6 +30,7 @@ use near_primitives::epoch_manager::EpochConfig; use near_primitives::errors::{EpochError, InvalidTxError, RuntimeError}; use near_primitives::hash::{hash, CryptoHash}; use near_primitives::receipt::Receipt; +use near_primitives::runtime::config::CurrentRuntimeConfig; use near_primitives::sharding::ChunkHash; use near_primitives::state_record::StateRecord; use near_primitives::transaction::SignedTransaction; @@ -56,7 +57,6 @@ use node_runtime::{ }; use crate::shard_tracker::{account_id_to_shard_id, ShardTracker}; -use near_primitives::runtime::config::RuntimeConfig; use errors::FromStateViewerErrors; @@ -121,7 +121,7 @@ impl EpochInfoProvider for SafeEpochManager { /// TODO: this possibly should be merged with the runtime cargo or at least reconciled on the interfaces. pub struct NightshadeRuntime { genesis_config: GenesisConfig, - genesis_runtime_config: Arc, + current_runtime_config: CurrentRuntimeConfig, store: Arc, tries: ShardTries, @@ -144,7 +144,8 @@ impl NightshadeRuntime { let runtime = Runtime::new(); let trie_viewer = TrieViewer::new_with_state_size_limit(trie_viewer_state_size_limit); let genesis_config = genesis.config.clone(); - let genesis_runtime_config = Arc::new(genesis_config.runtime_config.clone()); + let current_runtime_config = + CurrentRuntimeConfig::new(genesis_config.runtime_config.clone()); let num_shards = genesis.config.num_block_producer_seats_per_shard.len() as NumShards; let initial_epoch_config = EpochConfig::from(&genesis_config); let reward_calculator = RewardCalculator::new(&genesis_config); @@ -173,7 +174,7 @@ impl NightshadeRuntime { ); NightshadeRuntime { genesis_config, - genesis_runtime_config, + current_runtime_config, store, tries, runtime, @@ -408,10 +409,10 @@ impl NightshadeRuntime { gas_limit: Some(gas_limit), random_seed, current_protocol_version, - config: RuntimeConfig::from_protocol_version( - &self.genesis_runtime_config, - current_protocol_version, - ), + config: self + .current_runtime_config + .for_protocol_version(current_protocol_version) + .clone(), cache: Some(Arc::new(StoreCompiledContractCache { store: self.store.clone() })), is_new_chunk, #[cfg(feature = "protocol_feature_evm")] @@ -544,10 +545,8 @@ impl RuntimeAdapter for NightshadeRuntime { verify_signature: bool, current_protocol_version: ProtocolVersion, ) -> Result, Error> { - let runtime_config = RuntimeConfig::from_protocol_version( - &self.genesis_runtime_config, - current_protocol_version, - ); + let runtime_config = + self.current_runtime_config.for_protocol_version(current_protocol_version); if let Some(state_root) = state_root { let shard_id = self.account_id_to_shard_id(&transaction.transaction.signer_id); @@ -616,10 +615,8 @@ impl RuntimeAdapter for NightshadeRuntime { let mut transactions = vec![]; let mut num_checked_transactions = 0; - let runtime_config = RuntimeConfig::from_protocol_version( - &self.genesis_runtime_config, - current_protocol_version, - ); + let runtime_config = + self.current_runtime_config.for_protocol_version(current_protocol_version); while total_gas_burnt < transactions_gas_limit { if let Some(iter) = pool_iterator.next() { @@ -1491,9 +1488,8 @@ impl RuntimeAdapter for NightshadeRuntime { let mut config = self.genesis_config.clone(); config.protocol_version = protocol_version; // Currently only runtime config is changed through protocol upgrades. - let runtime_config = - RuntimeConfig::from_protocol_version(&self.genesis_runtime_config, protocol_version); - config.runtime_config = (*runtime_config).clone(); + let runtime_config = self.current_runtime_config.for_protocol_version(protocol_version); + config.runtime_config = (**runtime_config).clone(); Ok(config) } } diff --git a/neard/tests/node_cluster.rs b/neard/src/tests.rs similarity index 95% rename from neard/tests/node_cluster.rs rename to neard/src/tests.rs index 7b11cc7eac2..d51a4be25fe 100644 --- a/neard/tests/node_cluster.rs +++ b/neard/src/tests.rs @@ -1,3 +1,12 @@ +mod economics; +mod load_genesis; +mod rpc_nodes; +mod run_nodes; +mod stake_nodes; +mod sync_nodes; +mod sync_state_nodes; +mod track_shards; + use futures::future; use near_actix_test_utils::{run_actix_until_stop, spawn_interruptible}; diff --git a/neard/tests/economics.rs b/neard/src/tests/economics.rs similarity index 97% rename from neard/tests/economics.rs rename to neard/src/tests/economics.rs index 1fbdd6d7648..0b82a21e5b0 100644 --- a/neard/tests/economics.rs +++ b/neard/src/tests/economics.rs @@ -4,6 +4,7 @@ use std::sync::Arc; use num_rational::Rational; +use crate::config::GenesisExt; use near_chain::{ChainGenesis, RuntimeAdapter}; use near_chain_configs::Genesis; use near_client::test_utils::TestEnv; @@ -11,7 +12,6 @@ use near_crypto::{InMemorySigner, KeyType}; use near_logger_utils::init_integration_logger; use near_primitives::transaction::SignedTransaction; use near_store::test_utils::create_test_store; -use neard::config::GenesisExt; use testlib::fees_utils::FeeHelper; use primitive_types::U256; @@ -25,7 +25,7 @@ fn setup_env(f: &mut dyn FnMut(&mut Genesis) -> ()) -> (TestEnv, FeeHelper) { genesis.config.runtime_config.transaction_costs.clone(), genesis.config.min_gas_price, ); - let runtimes: Vec> = vec![Arc::new(neard::NightshadeRuntime::new( + let runtimes: Vec> = vec![Arc::new(crate::NightshadeRuntime::new( Path::new("."), store1, &genesis, diff --git a/neard/tests/load_genesis.rs b/neard/src/tests/load_genesis.rs similarity index 100% rename from neard/tests/load_genesis.rs rename to neard/src/tests/load_genesis.rs diff --git a/neard/tests/rpc_nodes.rs b/neard/src/tests/rpc_nodes.rs similarity index 99% rename from neard/tests/rpc_nodes.rs rename to neard/src/tests/rpc_nodes.rs index a58f4ec3096..aa33e026958 100644 --- a/neard/tests/rpc_nodes.rs +++ b/neard/src/tests/rpc_nodes.rs @@ -23,11 +23,10 @@ use near_primitives::types::{BlockId, BlockReference, Finality, TransactionOrRec use near_primitives::views::{ ExecutionOutcomeView, ExecutionStatusView, FinalExecutionOutcomeViewEnum, FinalExecutionStatus, }; -use neard::config::TESTING_INIT_BALANCE; use testlib::genesis_block; -mod node_cluster; -use node_cluster::NodeCluster; +use crate::config::TESTING_INIT_BALANCE; +use crate::tests::NodeCluster; macro_rules! panic_on_rpc_error { ($e:expr) => { diff --git a/neard/tests/run_nodes.rs b/neard/src/tests/run_nodes.rs similarity index 98% rename from neard/tests/run_nodes.rs rename to neard/src/tests/run_nodes.rs index d2ea43f2a0c..66cccd984da 100644 --- a/neard/tests/run_nodes.rs +++ b/neard/src/tests/run_nodes.rs @@ -7,8 +7,7 @@ use near_network::test_utils::WaitOrTimeout; use near_primitives::types::{BlockHeightDelta, NumSeats, NumShards}; use rand::{thread_rng, Rng}; -mod node_cluster; -use node_cluster::NodeCluster; +use crate::tests::NodeCluster; fn run_heavy_nodes( num_shards: NumShards, diff --git a/neard/tests/stake_nodes.rs b/neard/src/tests/stake_nodes.rs similarity index 99% rename from neard/tests/stake_nodes.rs rename to neard/src/tests/stake_nodes.rs index 947f291d42f..95c44bb8000 100644 --- a/neard/tests/stake_nodes.rs +++ b/neard/src/tests/stake_nodes.rs @@ -19,12 +19,13 @@ use near_primitives::hash::CryptoHash; use near_primitives::transaction::SignedTransaction; use near_primitives::types::{AccountId, BlockHeightDelta, BlockReference, NumSeats}; use near_primitives::views::{QueryRequest, QueryResponseKind, ValidatorInfo}; -use neard::config::{GenesisExt, TESTING_INIT_BALANCE, TESTING_INIT_STAKE}; -use neard::{load_test_config, start_with_config, NearConfig, NEAR_BASE}; use testlib::{genesis_hash, test_helpers::heavy_test}; use {near_primitives::types::BlockId, primitive_types::U256}; +use crate::config::{GenesisExt, TESTING_INIT_BALANCE, TESTING_INIT_STAKE}; +use crate::{load_test_config, start_with_config, NearConfig, NEAR_BASE}; + #[derive(Clone)] struct TestNode { account_id: AccountId, diff --git a/neard/tests/sync_nodes.rs b/neard/src/tests/sync_nodes.rs similarity index 99% rename from neard/tests/sync_nodes.rs rename to neard/src/tests/sync_nodes.rs index 8549b211218..54092a89d87 100644 --- a/neard/tests/sync_nodes.rs +++ b/neard/src/tests/sync_nodes.rs @@ -21,10 +21,11 @@ use near_primitives::types::validator_stake::ValidatorStake; use near_primitives::types::{BlockHeightDelta, EpochId}; use near_primitives::validator_signer::{InMemoryValidatorSigner, ValidatorSigner}; use near_primitives::version::PROTOCOL_VERSION; -use neard::config::{GenesisExt, TESTING_INIT_STAKE}; -use neard::{load_test_config, start_with_config, NearConfig}; use testlib::{genesis_block, test_helpers::heavy_test}; +use crate::config::{GenesisExt, TESTING_INIT_STAKE}; +use crate::{load_test_config, start_with_config, NearConfig}; + // This assumes that there is no height skipped. Otherwise epoch hash calculation will be wrong. fn add_blocks( mut blocks: Vec, diff --git a/neard/tests/sync_state_nodes.rs b/neard/src/tests/sync_state_nodes.rs similarity index 99% rename from neard/tests/sync_state_nodes.rs rename to neard/src/tests/sync_state_nodes.rs index cb462978c38..627734e8b5b 100644 --- a/neard/tests/sync_state_nodes.rs +++ b/neard/src/tests/sync_state_nodes.rs @@ -9,9 +9,10 @@ use near_chain_configs::Genesis; use near_client::GetBlock; use near_logger_utils::init_integration_logger; use near_network::test_utils::{convert_boot_nodes, open_port, WaitOrTimeout}; -use neard::{config::GenesisExt, load_test_config, start_with_config}; use testlib::test_helpers::heavy_test; +use crate::{config::GenesisExt, load_test_config, start_with_config}; + /// One client is in front, another must sync to it using state (fast) sync. #[test] fn sync_state_nodes() { diff --git a/neard/tests/track_shards.rs b/neard/src/tests/track_shards.rs similarity index 97% rename from neard/tests/track_shards.rs rename to neard/src/tests/track_shards.rs index ab286f10ccf..b7a015e347a 100644 --- a/neard/tests/track_shards.rs +++ b/neard/src/tests/track_shards.rs @@ -9,8 +9,7 @@ use near_logger_utils::init_integration_logger; use near_network::test_utils::WaitOrTimeout; use near_primitives::hash::CryptoHash; -mod node_cluster; -use node_cluster::NodeCluster; +use crate::tests::NodeCluster; #[test] fn track_shards() {