Skip to content
Closed
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
16 changes: 11 additions & 5 deletions core/src/client/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

use crate::consensus::Consensus;
use crate::errors::ClientError;
use crate::execution::evm::Evm;

Check warning on line 11 in core/src/client/node.rs

View workflow job for this annotation

GitHub Actions / check

unused import: `crate::execution::evm::Evm`

Check warning on line 11 in core/src/client/node.rs

View workflow job for this annotation

GitHub Actions / wasm-compatibility

unused import: `crate::execution::evm::Evm`

Check failure on line 11 in core/src/client/node.rs

View workflow job for this annotation

GitHub Actions / clippy

unused import: `crate::execution::evm::Evm`
use crate::execution::rpc::http_rpc::HttpRpc;
use crate::execution::state::State;
use crate::execution::ExecutionClient;
Expand Down Expand Up @@ -46,16 +46,22 @@
) -> Result<Bytes, ClientError> {
self.check_blocktag_age(&block).await?;

let mut evm = Evm::new(self.execution.clone(), self.chain_id(), block);
evm.call(tx).await.map_err(ClientError::EvmError)
N::call(tx, self.execution.clone(), self.chain_id(), block)
.await
.map_err(ClientError::EvmError)
}

pub async fn estimate_gas(&self, tx: &N::TransactionRequest) -> Result<u64, ClientError> {
self.check_head_age().await?;

let mut evm = Evm::new(self.execution.clone(), self.chain_id(), BlockTag::Latest);

evm.estimate_gas(tx).await.map_err(ClientError::EvmError)
N::estimate_gas(
tx,
self.execution.clone(),
self.chain_id(),
BlockTag::Latest,
)
.await
.map_err(ClientError::EvmError)
}

pub async fn get_balance(&self, address: Address, tag: BlockTag) -> Result<U256> {
Expand Down
87 changes: 15 additions & 72 deletions core/src/execution/evm.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{borrow::BorrowMut, collections::HashMap, sync::Arc};
use std::{collections::HashMap, sync::Arc};

use alloy::{
consensus::BlockHeader,
Expand All @@ -8,10 +8,10 @@
use futures::future::join_all;
use revm::{
primitives::{
address, AccessListItem, AccountInfo, Address, Bytecode, Bytes, Env, ExecutionResult,

Check warning on line 11 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / check

unused imports: `Bytes`, `Env`, `ExecutionResult`, and `ResultAndState`

Check warning on line 11 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / wasm-compatibility

unused imports: `Bytes`, `Env`, `ExecutionResult`, and `ResultAndState`

Check failure on line 11 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / clippy

unused imports: `Bytes`, `Env`, `ExecutionResult`, and `ResultAndState`
ResultAndState, B256, U256,
},
Database, Evm as Revm,
Database,
};
use tracing::trace;

Expand All @@ -25,7 +25,7 @@
use crate::types::BlockTag;

pub struct Evm<N: NetworkSpec, R: ExecutionRpc<N>> {
execution: Arc<ExecutionClient<N, R>>,

Check warning on line 28 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / check

fields `execution`, `chain_id`, and `tag` are never read

Check warning on line 28 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / wasm-compatibility

fields `execution`, `chain_id`, and `tag` are never read

Check failure on line 28 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / clippy

fields `execution`, `chain_id`, and `tag` are never read
chain_id: u64,
tag: BlockTag,
}
Expand All @@ -39,80 +39,23 @@
}
}

pub async fn call(&mut self, tx: &N::TransactionRequest) -> Result<Bytes, EvmError> {
let tx = self.call_inner(tx).await?;
// pub fn call(&mut self, tx: &N::TransactionRequest) -> Result<Bytes, EvmError> {
// // N::call(tx, self.execution.clone(), self.chain_id, self.tag)
// }

match tx.result {
ExecutionResult::Success { output, .. } => Ok(output.into_data()),
ExecutionResult::Revert { output, .. } => {
Err(EvmError::Revert(Some(output.to_vec().into())))
}
ExecutionResult::Halt { .. } => Err(EvmError::Revert(None)),
}
}

pub async fn estimate_gas(&mut self, tx: &N::TransactionRequest) -> Result<u64, EvmError> {
let tx = self.call_inner(tx).await?;

match tx.result {
ExecutionResult::Success { gas_used, .. } => Ok(gas_used),
ExecutionResult::Revert { gas_used, .. } => Ok(gas_used),
ExecutionResult::Halt { gas_used, .. } => Ok(gas_used),
}
}

async fn call_inner(&mut self, tx: &N::TransactionRequest) -> Result<ResultAndState, EvmError> {
let mut db = ProofDB::new(self.tag, self.execution.clone());
_ = db.state.prefetch_state(tx).await;

let env = Box::new(self.get_env(tx, self.tag).await);
let evm = Revm::builder().with_db(db).with_env(env).build();
let mut ctx = evm.into_context_with_handler_cfg();

let tx_res = loop {
let db = ctx.context.evm.db.borrow_mut();
if db.state.needs_update() {
db.state.update_state().await.unwrap();
}

let mut evm = Revm::builder().with_context_with_handler_cfg(ctx).build();
let res = evm.transact();
ctx = evm.into_context_with_handler_cfg();
// pub async fn estimate_gas(&mut self, tx: &N::TransactionRequest) -> Result<u64, EvmError> {
// // N::estimate_gas(tx, self.execution.clone(), self.chain_id, self.tag)

let db = ctx.context.evm.db.borrow_mut();
let needs_update = db.state.needs_update();

if res.is_ok() || !needs_update {
break res;
}
};

tx_res.map_err(|_| EvmError::Generic("evm error".to_string()))
}

async fn get_env(&self, tx: &N::TransactionRequest, tag: BlockTag) -> Env {
let mut env = Env::default();
env.tx = N::tx_env(tx);

let block = self
.execution
.get_block(tag, false)
.await
.ok_or(ExecutionError::BlockNotFound(tag))
.unwrap();
env.block = N::block_env(&block);

env.cfg.chain_id = self.chain_id;
env.cfg.disable_block_gas_limit = true;
env.cfg.disable_eip3607 = true;
env.cfg.disable_base_fee = true;

env
}
// // match tx.result {
// // ExecutionResult::Success { gas_used, .. } => Ok(gas_used),
// // ExecutionResult::Revert { gas_used, .. } => Ok(gas_used),
// // ExecutionResult::Halt { gas_used, .. } => Ok(gas_used),
// // }
// }
}

struct ProofDB<N: NetworkSpec, R: ExecutionRpc<N>> {
state: EvmState<N, R>,
pub struct ProofDB<N: NetworkSpec, R: ExecutionRpc<N>> {
pub state: EvmState<N, R>,

Check warning on line 58 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / check

type `EvmState<N, R>` is more private than the item `ProofDB::state`

Check warning on line 58 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / wasm-compatibility

type `EvmState<N, R>` is more private than the item `ProofDB::state`

Check failure on line 58 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / clippy

type `execution::evm::EvmState<N, R>` is more private than the item `execution::evm::ProofDB::state`
}

impl<N: NetworkSpec, R: ExecutionRpc<N>> ProofDB<N, R> {
Expand All @@ -123,16 +66,16 @@
}

enum StateAccess {
Basic(Address),

Check warning on line 69 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / check

field `0` is never read

Check warning on line 69 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / wasm-compatibility

field `0` is never read

Check failure on line 69 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / clippy

field `0` is never read
BlockHash(u64),

Check warning on line 70 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / check

field `0` is never read

Check warning on line 70 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / wasm-compatibility

field `0` is never read

Check failure on line 70 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / clippy

field `0` is never read
Storage(Address, U256),

Check warning on line 71 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / check

fields `0` and `1` are never read

Check warning on line 71 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / wasm-compatibility

fields `0` and `1` are never read

Check failure on line 71 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / clippy

fields `0` and `1` are never read
}

struct EvmState<N: NetworkSpec, R: ExecutionRpc<N>> {
basic: HashMap<Address, AccountInfo>,
block_hash: HashMap<u64, B256>,
storage: HashMap<Address, HashMap<U256, U256>>,
block: BlockTag,

Check warning on line 78 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / check

fields `block` and `execution` are never read

Check warning on line 78 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / wasm-compatibility

fields `block` and `execution` are never read

Check failure on line 78 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / clippy

fields `block` and `execution` are never read
access: Option<StateAccess>,
execution: Arc<ExecutionClient<N, R>>,
}
Expand All @@ -149,7 +92,7 @@
}
}

pub async fn update_state(&mut self) -> Result<()> {

Check warning on line 95 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / check

methods `update_state`, `needs_update`, and `prefetch_state` are never used

Check warning on line 95 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / wasm-compatibility

methods `update_state`, `needs_update`, and `prefetch_state` are never used

Check failure on line 95 in core/src/execution/evm.rs

View workflow job for this annotation

GitHub Actions / clippy

methods `update_state`, `needs_update`, and `prefetch_state` are never used
if let Some(access) = &self.access.take() {
match access {
StateAccess::Basic(address) => {
Expand Down
25 changes: 21 additions & 4 deletions core/src/network_spec.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
use alloy::{network::Network, rpc::types::Log};
use revm::primitives::{BlockEnv, TxEnv};
use std::{future::Future, sync::Arc};

use alloy::{network::Network, primitives::Bytes, rpc::types::Log};

use crate::{
execution::{errors::EvmError, rpc::http_rpc::HttpRpc, ExecutionClient},
types::BlockTag,
};

pub trait NetworkSpec: Network {
fn call(
tx: &Self::TransactionRequest,
execution: Arc<ExecutionClient<Self, HttpRpc<Self>>>,
chain_id: u64,
tag: BlockTag,
) -> impl Future<Output = Result<Bytes, EvmError>> + Send;
fn estimate_gas(
tx: &Self::TransactionRequest,
execution: Arc<ExecutionClient<Self, HttpRpc<Self>>>,
chain_id: u64,
tag: BlockTag,
) -> impl Future<Output = Result<u64, EvmError>> + Send;

fn encode_receipt(receipt: &Self::ReceiptResponse) -> Vec<u8>;
fn is_hash_valid(block: &Self::BlockResponse) -> bool;
fn receipt_contains(list: &[Self::ReceiptResponse], elem: &Self::ReceiptResponse) -> bool;
fn receipt_logs(receipt: &Self::ReceiptResponse) -> Vec<Log>;
fn tx_env(request: &Self::TransactionRequest) -> TxEnv;
fn block_env(block: &Self::BlockResponse) -> BlockEnv;
}
Loading
Loading