Skip to content
Merged
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
4 changes: 2 additions & 2 deletions bins/revme/src/cmd/bench/analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ pub fn run() {
let mut evm = context.build_mainnet();

let time = Instant::now();
let _ = evm.transact_previous();
let _ = evm.replay();
println!("First init: {:?}", time.elapsed());

let time = Instant::now();
let _ = evm.transact_previous();
let _ = evm.replay();
println!("Run: {:?}", time.elapsed());
}
2 changes: 1 addition & 1 deletion bins/revme/src/cmd/bench/burntpix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub fn run() {
.build_mainnet();

let started = Instant::now();
let tx_result = evm.transact_previous().unwrap().result;
let tx_result = evm.replay().unwrap().result;
let return_data = match tx_result {
ExecutionResult::Success {
output, gas_used, ..
Expand Down
2 changes: 1 addition & 1 deletion bins/revme/src/cmd/bench/snailtracer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub fn simple_example(bytecode: Bytecode) {
tx.gas_limit = 1_000_000_000;
})
.build_mainnet();
let _ = evm.transact_previous().unwrap();
let _ = evm.replay().unwrap();
}

pub fn run() {
Expand Down
4 changes: 2 additions & 2 deletions bins/revme/src/cmd/bench/transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ pub fn run() {
println!("Init: {:?}", time.elapsed());

let time = Instant::now();
let _ = evm.transact_previous();
let _ = evm.replay();
println!("First run: {:?}", time.elapsed());

let time = Instant::now();
let _ = evm.transact_previous();
let _ = evm.replay();
println!("Second run: {:?}", time.elapsed());
}
4 changes: 2 additions & 2 deletions bins/revme/src/cmd/evmrunner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ impl Cmd {
let bench_options = microbench::Options::default().time(Duration::from_secs(3));

microbench::bench(&bench_options, "Run bytecode", || {
let _ = evm.transact_previous().unwrap();
let _ = evm.replay().unwrap();
});

return Ok(());
Expand All @@ -106,7 +106,7 @@ impl Cmd {
let out = if self.trace {
evm.inspect_previous().map_err(|_| Errors::EVMError)?
} else {
let out = evm.transact_previous().map_err(|_| Errors::EVMError)?;
let out = evm.replay().map_err(|_| Errors::EVMError)?;
println!("Result: {:#?}", out.result);
out
};
Expand Down
2 changes: 1 addition & 1 deletion bins/revme/src/cmd/statetest/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ pub fn execute_test_suite(
(e, res)
} else {
let timer = Instant::now();
let res = evm.transact_commit_previous();
let res = evm.replay_commit();
*elapsed.lock().unwrap() += timer.elapsed();

let spec = cfg.spec();
Expand Down
6 changes: 6 additions & 0 deletions crates/context/src/setters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@ use crate::Context;
use auto_impl::auto_impl;
use context_interface::{Block, Cfg, Database, Journal, Transaction};

/// Setters for the context.
#[auto_impl(&mut, Box)]
pub trait ContextSetters {
/// Transaction type.
type Tx: Transaction;
/// Block type.
type Block: Block;

/// Set the transaction.
fn set_tx(&mut self, tx: Self::Tx);

/// Set the block.
fn set_block(&mut self, block: Self::Block);
}

Expand Down
111 changes: 99 additions & 12 deletions crates/handler/src/evm.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,124 @@
use crate::{instructions::EthInstructions, EthFrame, Handler, MainnetHandler, PrecompileProvider};
use crate::{
instructions::{EthInstructions, InstructionProvider},
EthFrame, Handler, MainnetHandler, PrecompileProvider,
};
use auto_impl::auto_impl;
use context::{
result::{EVMError, ExecutionResult, HaltReason, InvalidTransaction, ResultAndState},
setters::ContextSetters,
ContextTr, Database, Evm, Journal,
};
use database_interface::DatabaseCommit;
use interpreter::{interpreter::EthInterpreter, InterpreterResult};
use interpreter::{
interpreter::EthInterpreter, Interpreter, InterpreterAction, InterpreterResult,
InterpreterTypes,
};
use primitives::Log;
use state::EvmState;
use std::vec::Vec;

/// Execute EVM transactions.
/// Main trait that combines the context, instructions and precompiles and allows execution of interpreter.
#[auto_impl(&mut, Box)]
pub trait EvmTr {
type Context: ContextTr;
type Instructions: InstructionProvider;
type Precompiles;

/// Run the interpreter loop and returns the output that can be a return or a next action.
fn run_interpreter(
&mut self,
interpreter: &mut Interpreter<
<Self::Instructions as InstructionProvider>::InterpreterTypes,
>,
) -> <<Self::Instructions as InstructionProvider>::InterpreterTypes as InterpreterTypes>::Output;

/// Get the context.
fn ctx(&mut self) -> &mut Self::Context;

/// Get the context reference.
fn ctx_ref(&self) -> &Self::Context;

/// Get the context and instructions.
fn ctx_instructions(&mut self) -> (&mut Self::Context, &mut Self::Instructions);

/// Get the context and precompiles.
fn ctx_precompiles(&mut self) -> (&mut Self::Context, &mut Self::Precompiles);
}

/// Execute EVM transactions. Main trait for transaction execution.
pub trait ExecuteEvm: ContextSetters {
/// Output of transaction execution.
type Output;

fn transact_previous(&mut self) -> Self::Output;
/// Transact the transaction that is set in the context.
fn replay(&mut self) -> Self::Output;

/// Transact the given transaction.
///
/// Internally sets transaction in context and use `replay` to execute the transaction.
fn transact(&mut self, tx: Self::Tx) -> Self::Output {
self.set_tx(tx);
self.transact_previous()
self.replay()
}
}

/// Execute EVM transactions and commit to the state.
/// TODO this trait can be implemented for all ExecuteEvm for specific Output/CommitOutput
/// Extension of the [`ExecuteEvm`] trait that adds a method that commits the state after execution.
pub trait ExecuteCommitEvm: ExecuteEvm {
/// Commit output of transaction execution.
type CommitOutput;

fn transact_commit_previous(&mut self) -> Self::CommitOutput;
/// Transact the transaction and commit to the state.
fn replay_commit(&mut self) -> Self::CommitOutput;

/// Transact the transaction and commit to the state.
fn transact_commit(&mut self, tx: Self::Tx) -> Self::CommitOutput {
self.set_tx(tx);
self.transact_commit_previous()
self.replay_commit()
}
}

impl<CTX, INSP, I, P> EvmTr for Evm<CTX, INSP, I, P>
where
CTX: ContextTr,
I: InstructionProvider<
Context = CTX,
InterpreterTypes: InterpreterTypes<Output = InterpreterAction>,
>,
{
type Context = CTX;
type Instructions = I;
type Precompiles = P;

#[inline]
fn run_interpreter(
&mut self,
interpreter: &mut Interpreter<
<Self::Instructions as InstructionProvider>::InterpreterTypes,
>,
) -> <<Self::Instructions as InstructionProvider>::InterpreterTypes as InterpreterTypes>::Output
{
let context = &mut self.data.ctx;
let instructions = &mut self.instruction;
interpreter.run_plain(instructions.instruction_table(), context)
}
#[inline]
fn ctx(&mut self) -> &mut Self::Context {
&mut self.data.ctx
}

#[inline]
fn ctx_ref(&self) -> &Self::Context {
&self.data.ctx
}

#[inline]
fn ctx_instructions(&mut self) -> (&mut Self::Context, &mut Self::Instructions) {
(&mut self.data.ctx, &mut self.instruction)
}

#[inline]
fn ctx_precompiles(&mut self) -> (&mut Self::Context, &mut Self::Precompiles) {
(&mut self.data.ctx, &mut self.precompiles)
}
}

Expand All @@ -46,7 +133,7 @@ where
EVMError<<CTX::Db as Database>::Error, InvalidTransaction>,
>;

fn transact_previous(&mut self) -> Self::Output {
fn replay(&mut self) -> Self::Output {
let mut t = MainnetHandler::<_, _, EthFrame<_, _, _>>::default();
t.run(self)
}
Expand All @@ -64,8 +151,8 @@ where
EVMError<<CTX::Db as Database>::Error, InvalidTransaction>,
>;

fn transact_commit_previous(&mut self) -> Self::CommitOutput {
self.transact_previous().map(|r| {
fn replay_commit(&mut self) -> Self::CommitOutput {
self.replay().map(|r| {
self.db().commit(r.state);
r.result
})
Expand Down
25 changes: 2 additions & 23 deletions crates/handler/src/execution.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
use super::frame_data::FrameResult;
use bytecode::EOF_MAGIC_BYTES;
use context_interface::ContextTr;
use context_interface::Transaction;
use interpreter::{
CallInputs, CallScheme, CallValue, CreateInputs, CreateScheme, EOFCreateInputs, EOFCreateKind,
FrameInput, Gas,
FrameInput,
};
use primitives::TxKind;
use specification::hardfork::SpecId;
use std::boxed::Box;

/// Creates the first [`FrameInput`] from the transaction, spec and gas limit.
pub fn create_init_frame(tx: &impl Transaction, spec: SpecId, gas_limit: u64) -> FrameInput {
// Make new frame action.
let input = tx.input().clone();

match tx.kind() {
Expand Down Expand Up @@ -48,22 +46,3 @@ pub fn create_init_frame(tx: &impl Transaction, spec: SpecId, gas_limit: u64) ->
}
}
}

/// TODO : Frame result should be a generic trait with needed functions.
pub fn last_frame_result<CTX: ContextTr>(context: CTX, frame_result: &mut FrameResult) {
let instruction_result = frame_result.interpreter_result().result;
let gas = frame_result.gas_mut();
let remaining = gas.remaining();
let refunded = gas.refunded();

// Spend the gas limit. Gas is reimbursed when the tx returns successfully.
*gas = Gas::new_spent(context.tx().gas_limit());

if instruction_result.is_ok_or_revert() {
gas.erase_cost(remaining);
}

if instruction_result.is_ok() {
gas.record_refund(refunded);
}
}
2 changes: 1 addition & 1 deletion crates/handler/src/frame.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::frame_data::*;
use crate::{
handler::EvmTr, instructions::InstructionProvider, precompile_provider::PrecompileProvider,
instructions::InstructionProvider, precompile_provider::PrecompileProvider, EvmTr,
FrameInitOrResult, FrameOrResult, ItemOrResult,
};
use bytecode::{Eof, EOF_MAGIC_BYTES};
Expand Down
Loading
Loading