diff --git a/core/executor/src/lib.rs b/core/executor/src/lib.rs index 82197e5a0..176a3beb4 100644 --- a/core/executor/src/lib.rs +++ b/core/executor/src/lib.rs @@ -10,7 +10,10 @@ mod utils; pub use crate::adapter::{ AxonExecutorApplyAdapter, AxonExecutorReadOnlyAdapter, MPTTrie, RocksTrieDB, }; -pub use crate::system_contract::{metadata::MetadataHandle, DataProvider}; +pub use crate::system_contract::{ + metadata::{MetadataHandle, HARDFORK_INFO}, + DataProvider, +}; pub use crate::utils::{code_address, decode_revert_msg, DefaultFeeAllocator, FeeInlet}; use std::cell::RefCell; @@ -18,6 +21,7 @@ use std::collections::BTreeMap; use std::iter::FromIterator; use arc_swap::ArcSwap; +use common_config_parser::types::spec::HardforkName; use evm::executor::stack::{MemoryStackState, PrecompileFn, StackExecutor, StackSubstateMetadata}; use evm::CreateScheme; @@ -69,7 +73,7 @@ impl Executor for AxonExecutor { value: U256, data: Vec, ) -> TxResp { - let config = Config::london(); + let config = self.config(); let metadata = StackSubstateMetadata::new(gas_limit, &config); let state = MemoryStackState::new(metadata, backend); let precompiles = build_precompile_set(); @@ -134,7 +138,7 @@ impl Executor for AxonExecutor { let mut hashes = Vec::with_capacity(txs_len); let (mut gas, mut fee) = (0u64, U256::zero()); let precompiles = build_precompile_set(); - let config = Config::london(); + let config = self.config(); self.init_local_system_contract_roots(adapter); @@ -316,6 +320,23 @@ impl AxonExecutor { }); } + fn config(&self) -> Config { + let mut config = Config::london(); + let create_contract_limit = { + let latest_hardfork_info = &**HARDFORK_INFO.load(); + let enable_contract_limit_flag = H256::from_low_u64_be(HardforkName::Andromeda as u64); + if latest_hardfork_info & &enable_contract_limit_flag == enable_contract_limit_flag { + let handle = MetadataHandle::new(CURRENT_METADATA_ROOT.with(|r| *r.borrow())); + let config = handle.get_consensus_config().unwrap(); + Some(config.max_contract_limit as usize) + } else { + None + } + }; + config.create_contract_limit = create_contract_limit; + config + } + #[cfg(test)] fn test_exec( &self, diff --git a/core/executor/src/system_contract/metadata/handle.rs b/core/executor/src/system_contract/metadata/handle.rs index 3765f704a..edd3de3f2 100644 --- a/core/executor/src/system_contract/metadata/handle.rs +++ b/core/executor/src/system_contract/metadata/handle.rs @@ -1,4 +1,4 @@ -use protocol::types::{CkbRelatedInfo, HardforkInfo, Metadata, H160, H256}; +use protocol::types::{CkbRelatedInfo, ConsensusConfig, HardforkInfo, Metadata, H160, H256}; use protocol::ProtocolResult; use std::sync::Arc; @@ -62,4 +62,8 @@ impl MetadataHandle { HARDFORK_INFO.swap(Arc::new(hardfork)); Ok(()) } + + pub fn get_consensus_config(&self) -> ProtocolResult { + MetadataStore::new(self.root)?.get_consensus_config() + } } diff --git a/core/executor/src/system_contract/metadata/mod.rs b/core/executor/src/system_contract/metadata/mod.rs index b2fec8e79..20324ed1d 100644 --- a/core/executor/src/system_contract/metadata/mod.rs +++ b/core/executor/src/system_contract/metadata/mod.rs @@ -34,7 +34,7 @@ lazy_static::lazy_static! { static ref CKB_RELATED_INFO_KEY: H256 = Hasher::digest("ckb_related_info"); static ref CONSENSUS_CONFIG: H256 = Hasher::digest("consensus_config"); static ref HARDFORK_KEY: H256 = Hasher::digest("hardfork"); - static ref HARDFORK_INFO: ArcSwap = ArcSwap::new(Arc::new(H256::zero())); + pub static ref HARDFORK_INFO: ArcSwap = ArcSwap::new(Arc::new(H256::zero())); static ref METADATA_CACHE: RwLock> = RwLock::new(LruCache::new(METADATA_CACHE_SIZE)); } diff --git a/core/executor/src/system_contract/metadata/store.rs b/core/executor/src/system_contract/metadata/store.rs index 743f60511..8fc123e09 100644 --- a/core/executor/src/system_contract/metadata/store.rs +++ b/core/executor/src/system_contract/metadata/store.rs @@ -152,7 +152,7 @@ impl MetadataStore { MetadataInner::decode(raw) } - fn get_consensus_config(&self) -> ProtocolResult { + pub fn get_consensus_config(&self) -> ProtocolResult { let raw = self .trie .get(CONSENSUS_CONFIG.as_bytes())?