Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions src/eth/executor/evm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ use revm_inspectors::tracing::TracingInspector;
use revm_inspectors::tracing::TracingInspectorConfig;
use revm_inspectors::tracing::js::JsInspector;
use session::RevmSession;
pub use types::EvmKind;
pub use types::GeneralRevm;
pub use types::Lane;
use util::default_trace;
use util::enhance_trace_with_decoded_errors;

Expand All @@ -39,32 +39,34 @@ use crate::eth::executor::evm::types::InspectorInput;
use crate::eth::executor::evm::util::EvmExt;
use crate::eth::executor::evm::util::create_evm;
use crate::eth::rpc::BlockFilter;
use crate::eth::storage::ExecutionKind;
use crate::eth::storage::ExecutionContext;
use crate::eth::storage::StorageError;
use crate::eth::storage::StratusStorage;
use crate::eth::types::Job;
use crate::eth::types::MinedData;
use crate::eth::types::StateView;
use crate::eth::types::StratusError;

pub type RevmResultAndState = ExecResultAndState<RevmExecResult>;

/// Implementation of EVM using [`revm`](https://crates.io/crates/revm).
pub struct Evm<Input: EvmInput> {
evm: GeneralRevm<RevmSession>,
kind: EvmKind,
job: Job,
_input_type: PhantomData<Input>,
}

impl<Input: EvmInput> Evm<Input> {
/// Creates a new instance of the Evm.
pub fn new(storage: Arc<StratusStorage>, config: &ExecutorConfig, kind: EvmKind) -> Self {
pub fn new(storage: Arc<StratusStorage>, config: &ExecutorConfig, job: Job) -> Self {
tracing::info!(?config, "creating revm");

// configure revm
let chain_id = config.executor_chain_id;

Self {
evm: create_evm(chain_id, config.executor_evm_spec, RevmSession::new(storage), kind),
kind,
evm: create_evm(chain_id, config.executor_evm_spec, RevmSession::new(storage), job),
job,
_input_type: PhantomData,
}
}
Expand All @@ -74,7 +76,7 @@ impl<Input: EvmInput> Evm<Input> {
let metrics_context = input.metrics_context();

// configure session
self.evm.journaled_state.database.reset(input.kind());
self.evm.journaled_state.database.reset(input.context());
input.fill_env(&mut self.evm);

let tx = std::mem::take(&mut self.evm.tx);
Expand Down Expand Up @@ -144,12 +146,12 @@ impl Evm<TransactionExecutionInput> {
};
let inspect_input: TransactionExecutionInput = tx.input;
let target = inspect_input.block_number.prev().unwrap_or_default();
self.evm.journaled_state.database.reset(ExecutionKind::CallPast(target));
self.evm.journaled_state.database.reset(ExecutionContext::call(StateView::Past(target)));

let spec = self.evm.cfg.spec;

let mut cache_db = CacheDB::new(&self.evm.journaled_state.database);
let mut evm = create_evm(inspect_input.chain_id.unwrap_or_default().into(), spec, &mut cache_db, self.kind);
let mut evm = create_evm(inspect_input.chain_id.unwrap_or_default().into(), spec, &mut cache_db, self.job);

// Execute all transactions before target tx_hash
for tx in block.transactions.into_iter() {
Expand Down
16 changes: 8 additions & 8 deletions src/eth/executor/evm/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use revm::state::AccountInfo;
use crate::alias::RevmAddress;
use crate::alias::RevmBytecode;
use crate::eth::executor::evm::types::StorageMetrics;
use crate::eth::storage::ExecutionKind;
use crate::eth::storage::ExecutionContext;
use crate::eth::storage::FoundAt;
use crate::eth::storage::StorageError;
use crate::eth::storage::StratusStorage;
Expand All @@ -25,8 +25,8 @@ pub struct RevmSession {
/// Service to communicate with the storage.
pub storage: Arc<StratusStorage>,

/// Input passed to EVM to execute the transaction.
pub kind: ExecutionKind,
/// Execution context that determines how storage reads resolve during EVM execution.
pub context: ExecutionContext,

/// Metrics collected during EVM execution.
pub metrics: StorageMetrics,
Expand All @@ -37,14 +37,14 @@ impl RevmSession {
pub fn new(storage: Arc<StratusStorage>) -> Self {
Self {
storage,
kind: ExecutionKind::default(),
context: ExecutionContext::default(),
metrics: StorageMetrics::default(),
}
}

/// Resets the session to be used with a new transaction.
pub fn reset(&mut self, kind: ExecutionKind) {
self.kind = kind;
pub fn reset(&mut self, context: ExecutionContext) {
self.context = context;
self.metrics = StorageMetrics::default();
}
}
Expand Down Expand Up @@ -103,7 +103,7 @@ impl RevmSession {
return Ok((None, FoundAt::Temp));
}

let (account, found_at) = self.storage.read_account(address, self.kind)?;
let (account, found_at) = self.storage.read_account(address, self.context)?;
Ok((Some(account.into()), found_at))
}

Expand All @@ -117,7 +117,7 @@ impl RevmSession {
let index: SlotIndex = index.into();

// load slot from storage
let (slot, found_at) = self.storage.read_slot(address, index, self.kind)?;
let (slot, found_at) = self.storage.read_slot(address, index, self.context)?;

Ok((slot.value.into(), found_at))
}
Expand Down
19 changes: 12 additions & 7 deletions src/eth/executor/evm/types/execution_metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::eth::codegen::SoliditySignature;
use crate::eth::storage::FoundAt;
use crate::eth::types::Address;
use crate::eth::types::Bytes;
use crate::eth::types::ExecutionKind;
use crate::eth::types::ExecutionContext;
use crate::eth::types::Gas;

#[derive(Debug, Default, Clone, Copy)]
Expand Down Expand Up @@ -58,26 +58,26 @@ pub struct StorageMetrics {
#[derive(Debug, Clone, Copy)]
pub struct ExecutionMetricsContext {
#[cfg(feature = "metrics")]
kind: ExecutionKind,
execution_context: ExecutionContext,
#[cfg(feature = "metrics")]
contract: ContractName,
#[cfg(feature = "metrics")]
function: SoliditySignature,
}

impl ExecutionMetricsContext {
pub fn new(kind: ExecutionKind, to: &Option<Address>, input: &Bytes) -> Self {
pub fn new(context: ExecutionContext, to: &Option<Address>, input: &Bytes) -> Self {
#[cfg(feature = "metrics")]
{
Self {
kind,
execution_context: context,
contract: codegen::contract_name(to),
function: codegen::function_sig(input),
}
}
#[cfg(not(feature = "metrics"))]
{
let _ = (kind, to, input);
let _ = (context, to, input);
Self {}
}
}
Expand All @@ -104,7 +104,12 @@ impl ExecutionMetrics {
fn publish(&self) {
let context = &self.context;
self.storage_metrics.publish(context);
metrics::inc_evm_execution_gas(self.gas_used.as_u64() as usize, context.kind.as_ref(), context.contract, context.function);
metrics::inc_evm_execution_gas(
self.gas_used.as_u64() as usize,
context.execution_context.metrics_label(),
context.contract,
context.function,
);
}
}

Expand All @@ -118,7 +123,7 @@ impl Drop for ExecutionMetrics {
impl StorageMetrics {
#[cfg(feature = "metrics")]
fn publish(&self, context: &ExecutionMetricsContext) {
let execution_kind = context.kind.as_ref();
let execution_kind = context.execution_context.metrics_label();
for (found_at, stats) in self.account_reads.iter() {
if stats.count > 0 {
metrics::inc_n_evm_execution_account_reads(stats.count as u64, execution_kind, found_at.as_str(), context.contract, context.function);
Expand Down
14 changes: 7 additions & 7 deletions src/eth/executor/evm/types/input/call_execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::eth::executor::evm::types::EvmInput;
use crate::eth::executor::evm::types::ExecutionMetricsContext;
use crate::eth::executor::evm::types::GAS_MAX_LIMIT;
use crate::eth::executor::evm::types::GeneralRevm;
use crate::eth::storage::ExecutionKind;
use crate::eth::storage::ExecutionContext;
use crate::eth::types::Address;
use crate::eth::types::BlockInfo;
use crate::eth::types::BlockNumber;
Expand Down Expand Up @@ -56,19 +56,19 @@ pub struct CallExecutionInput {
/// Timestamp of the block where the transaction will be or was included.
pub block_timestamp: UnixTime,

pub kind: ExecutionKind,
pub context: ExecutionContext,
}

impl CallExecutionInput {
pub fn create(input: CallInput, block_info: BlockInfo, kind: ExecutionKind) -> Self {
pub fn create(input: CallInput, block_info: BlockInfo, context: ExecutionContext) -> Self {
Self {
from: input.from.unwrap_or(Address::ZERO),
to: input.to.map_into(),
value: input.value,
data: input.data,
block_number: block_info.number,
block_timestamp: *block_info.timestamp,
kind,
context,
}
}
}
Expand All @@ -95,11 +95,11 @@ impl EvmInput for CallExecutionInput {
evm.tx.gas_priority_fee = None;
}

fn kind(&self) -> ExecutionKind {
self.kind
fn context(&self) -> ExecutionContext {
self.context
}

fn metrics_context(&self) -> ExecutionMetricsContext {
ExecutionMetricsContext::new(self.kind, &self.to, &self.data)
ExecutionMetricsContext::new(self.context, &self.to, &self.data)
}
}
4 changes: 2 additions & 2 deletions src/eth/executor/evm/types/input/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ use revm::Database;

use crate::eth::executor::evm::GeneralRevm;
use crate::eth::executor::evm::types::ExecutionMetricsContext;
use crate::eth::types::ExecutionKind;
use crate::eth::types::ExecutionContext;

pub mod call_execution;
pub mod inspector;
pub mod transaction_execution;

pub trait EvmInput: Default + Clone {
fn kind(&self) -> ExecutionKind;
fn context(&self) -> ExecutionContext;

fn metrics_context(&self) -> ExecutionMetricsContext;

Expand Down
12 changes: 6 additions & 6 deletions src/eth/executor/evm/types/input/transaction_execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::eth::executor::evm::types::EvmInput;
use crate::eth::executor::evm::types::ExecutionMetricsContext;
use crate::eth::executor::evm::types::GAS_MAX_LIMIT;
use crate::eth::executor::evm::types::GeneralRevm;
use crate::eth::storage::ExecutionKind;
use crate::eth::storage::ExecutionContext;
use crate::eth::types::Address;
use crate::eth::types::BlockInfo;
use crate::eth::types::BlockNumber;
Expand Down Expand Up @@ -77,7 +77,7 @@ pub struct TransactionExecutionInput {
/// If not specified, it will not be validated.
pub chain_id: Option<ChainId>,

pub kind: ExecutionKind,
pub context: ExecutionContext,
}

impl TransactionExecutionInput {
Expand All @@ -94,7 +94,7 @@ impl TransactionExecutionInput {
block_number: block_info.number,
block_timestamp: *block_info.timestamp,
chain_id: input.execution_info.chain_id,
kind: ExecutionKind::Transaction,
context: ExecutionContext::transaction(),
}
}
}
Expand Down Expand Up @@ -127,11 +127,11 @@ impl EvmInput for TransactionExecutionInput {
evm.tx.gas_priority_fee = None;
}

fn kind(&self) -> ExecutionKind {
self.kind
fn context(&self) -> ExecutionContext {
self.context
}

fn metrics_context(&self) -> ExecutionMetricsContext {
ExecutionMetricsContext::new(self.kind, &self.to, &self.data)
ExecutionMetricsContext::new(self.context, &self.to, &self.data)
}
}
23 changes: 5 additions & 18 deletions src/eth/executor/evm/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,25 +34,12 @@ pub const GAS_MAX_LIMIT: u64 = 100_000_000;
pub type ContextWithDB<DB> = Context<BlockEnv, TxEnv, CfgEnv, DB, Journal<DB>>;
pub type GeneralRevm<DB, I = ()> = RevmEvm<ContextWithDB<DB>, I, EthInstructions<EthInterpreter, ContextWithDB<DB>>, EthPrecompiles, EthFrame>;

/// Classification of an EVM by the kind of execution it performs. Used to route
/// work to the right EVM worker pool and as a metrics label.
/// Executor worker pool lane. Determines which pool executes the task and
/// labels the `executor_workers_busy` gauge.
#[derive(Clone, Copy)]
pub enum EvmKind {
pub enum Lane {
Transaction,
CallPast,
CallPresent,
Inspect,
}

impl EvmKind {
pub fn is_call(&self) -> bool {
match self {
EvmKind::Transaction => false,
EvmKind::CallPast | EvmKind::CallPresent | EvmKind::Inspect => true,
}
}

pub fn is_transaction(&self) -> bool {
!self.is_call()
}
CallPast,
Inspector,
}
10 changes: 5 additions & 5 deletions src/eth/executor/evm/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ use revm::handler::instructions::EthInstructions;
use revm::primitives::hardfork::SpecId;

use crate::eth::codegen;
use crate::eth::executor::EvmKind;
use crate::eth::executor::TransactionExecution;
use crate::eth::executor::TransactionExecutionInput;
use crate::eth::executor::evm::GeneralRevm;
use crate::eth::executor::evm::types::GAS_MAX_LIMIT;
use crate::eth::types::Address;
use crate::eth::types::Job;
use crate::ext::OptionExt;

pub fn default_trace(tracer_type: GethDebugTracerType, tx: TransactionExecution) -> GethTrace {
Expand Down Expand Up @@ -119,18 +119,18 @@ impl BlockEnvExt for BlockEnv {
}
}

pub fn create_evm<DB: Database>(chain_id: u64, spec: SpecId, db: DB, kind: EvmKind) -> GeneralRevm<DB> {
pub fn create_evm<DB: Database>(chain_id: u64, spec: SpecId, db: DB, job: Job) -> GeneralRevm<DB> {
let ctx = Context::new(db, spec)
.modify_cfg_chained(|cfg_env| {
cfg_env.chain_id = chain_id;
cfg_env.spec = spec;
cfg_env.tx_chain_id_check = kind.is_transaction();
cfg_env.tx_chain_id_check = job.is_transaction();
cfg_env.limit_contract_initcode_size = None;
cfg_env.disable_nonce_check = kind.is_call();
cfg_env.disable_nonce_check = !job.is_transaction();
cfg_env.max_blobs_per_tx = None;
cfg_env.tx_gas_limit_cap = None;
cfg_env.blob_base_fee_update_fraction = None;
cfg_env.disable_eip3607 = kind.is_call();
cfg_env.disable_eip3607 = !job.is_transaction();
cfg_env.limit_contract_code_size = Some(usize::MAX);
cfg_env.memory_limit = (1 << 32) - 1;
cfg_env.disable_balance_check = false;
Expand Down
Loading
Loading