From e2f6863eba0ce3c90f40a7ba33a1371997e801f9 Mon Sep 17 00:00:00 2001 From: Renato Dinhani Date: Wed, 31 Jul 2024 05:29:41 -0300 Subject: [PATCH] feat: configure if transactions to non-contracts should be rejected --- src/eth/executor/evm.rs | 23 ++++++++++++++++------- src/eth/executor/executor.rs | 14 ++++++-------- src/eth/executor/executor_config.rs | 6 ++++++ 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/eth/executor/evm.rs b/src/eth/executor/evm.rs index 7390a8334..daf0e4b17 100644 --- a/src/eth/executor/evm.rs +++ b/src/eth/executor/evm.rs @@ -22,10 +22,10 @@ use crate::alias::RevmAddress; use crate::alias::RevmBytecode; use crate::eth::executor::EvmExecutionResult; use crate::eth::executor::EvmInput; +use crate::eth::executor::ExecutorConfig; use crate::eth::primitives::Account; use crate::eth::primitives::Address; use crate::eth::primitives::Bytes; -use crate::eth::primitives::ChainId; use crate::eth::primitives::EvmExecution; use crate::eth::primitives::EvmExecutionMetrics; use crate::eth::primitives::ExecutionAccountChanges; @@ -54,8 +54,8 @@ pub struct Evm { impl Evm { /// Creates a new instance of the Evm. #[allow(clippy::arc_with_non_send_sync)] - pub fn new(storage: Arc, chain_id: ChainId) -> Self { - tracing::info!(%chain_id, "creating revm"); + pub fn new(storage: Arc, config: ExecutorConfig) -> Self { + tracing::info!(?config, "creating revm"); // configure handler let mut handler = Handler::mainnet_with_spec(SpecId::LONDON); @@ -75,15 +75,16 @@ impl Evm { handler.set_instruction_table(instructions); // configure revm + let chain_id = config.chain_id; let mut evm = RevmEvm::builder() .with_external_context(()) - .with_db(RevmSession::new(storage)) + .with_db(RevmSession::new(storage, config)) .with_handler(handler) .build(); // global general config let cfg_env = evm.cfg_mut(); - cfg_env.chain_id = chain_id.into(); + cfg_env.chain_id = chain_id; cfg_env.limit_contract_code_size = Some(usize::MAX); // global block config @@ -188,6 +189,9 @@ impl Evm { /// Contextual data that is read or set durint the execution of a transaction in the EVM. struct RevmSession { + /// Executor configuration. + config: ExecutorConfig, + /// Service to communicate with the storage. storage: Arc, @@ -203,8 +207,9 @@ struct RevmSession { impl RevmSession { /// Creates the base session to be used with REVM. - pub fn new(storage: Arc) -> Self { + pub fn new(storage: Arc, config: ExecutorConfig) -> Self { Self { + config, storage, input: EvmInput::default(), storage_changes: HashMap::default(), @@ -233,7 +238,11 @@ impl Database for RevmSession { // warn if the loaded account is the `to` account and it does not have a bytecode if let Some(ref to_address) = self.input.to { if account.bytecode.is_none() && &address == to_address && self.input.is_contract_call() { - return Err(StratusError::TransactionAccountNotContract { address: *to_address }); + if self.config.reject_not_contract { + return Err(StratusError::TransactionAccountNotContract { address: *to_address }); + } else { + tracing::warn!(%address, "evm to_account is not a contract because does not have bytecode"); + } } } diff --git a/src/eth/executor/executor.rs b/src/eth/executor/executor.rs index 71af50be9..961b51cfd 100644 --- a/src/eth/executor/executor.rs +++ b/src/eth/executor/executor.rs @@ -15,7 +15,6 @@ use crate::eth::executor::ExecutorConfig; use crate::eth::miner::Miner; use crate::eth::primitives::BlockFilter; use crate::eth::primitives::CallInput; -use crate::eth::primitives::ChainId; use crate::eth::primitives::EvmExecution; use crate::eth::primitives::EvmExecutionMetrics; use crate::eth::primitives::ExternalBlock; @@ -82,11 +81,9 @@ struct Evms { impl Evms { /// Spawns EVM tasks in background. fn spawn(storage: Arc, config: &ExecutorConfig) -> Self { - let chain_id: ChainId = config.chain_id.into(); - // function executed by evm threads - fn evm_loop(task_name: &str, storage: Arc, chain_id: ChainId, task_rx: crossbeam_channel::Receiver) { - let mut evm = Evm::new(storage, chain_id); + fn evm_loop(task_name: &str, storage: Arc, config: ExecutorConfig, task_rx: crossbeam_channel::Receiver) { + let mut evm = Evm::new(storage, config); // keep executing transactions until the channel is closed while let Ok(task) = task_rx.recv() { @@ -110,12 +107,13 @@ impl Evms { let (evm_tx, evm_rx) = crossbeam_channel::unbounded::(); for evm_index in 1..=num_evms { + let evm_task_name = format!("{}-{}", task_name, evm_index); let evm_storage = Arc::clone(&storage); + let evm_config = config.clone(); let evm_rx = evm_rx.clone(); - let task_name = format!("{}-{}", task_name, evm_index); - let thread_name = task_name.clone(); + let thread_name = evm_task_name.clone(); spawn_thread(&thread_name, move || { - evm_loop(&task_name, evm_storage, chain_id, evm_rx); + evm_loop(&evm_task_name, evm_storage, evm_config, evm_rx); }); } evm_tx diff --git a/src/eth/executor/executor_config.rs b/src/eth/executor/executor_config.rs index cfc060e2e..be25cba06 100644 --- a/src/eth/executor/executor_config.rs +++ b/src/eth/executor/executor_config.rs @@ -16,12 +16,18 @@ pub struct ExecutorConfig { pub chain_id: u64, /// Number of EVM instances to run. + /// + /// TODO: should be configured for each kind of EvmRoute instead of being a single value. #[arg(long = "evms", env = "EVMS")] pub num_evms: usize, /// EVM execution strategy. #[arg(long = "strategy", env = "STRATEGY", default_value = "serial")] pub strategy: ExecutorStrategy, + + /// Should reject contract transactions and calls to accounts that are not contracts? + #[arg(long = "reject-not-contract", env = "REJECT_NOT_CONTRACT", default_value = "true")] + pub reject_not_contract: bool, } impl ExecutorConfig {