Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
e35d741
rename main Evm structs, introduce wip external type
rakita Nov 8, 2023
fc03f9b
tests
rakita Nov 8, 2023
90a81f0
Split evm and external context
rakita Nov 16, 2023
fda7f8f
continue previous commit
rakita Nov 16, 2023
99ec673
wip inspector handle register
rakita Nov 21, 2023
ee65aa5
add few more handlers for frame and host
rakita Nov 21, 2023
006a9c2
Add instruction handle
rakita Nov 23, 2023
73f5ebd
add instruction handler registration and Inspector wrap
rakita Nov 24, 2023
42dfcf4
Rm Spec generic, more handlers, start factory
rakita Nov 25, 2023
6252606
move towards the builder, allow EVM modify
rakita Nov 27, 2023
a8eba54
wip on EvmBuilder and modify functionality
rakita Nov 28, 2023
ed188d7
EvmBuilder with stages wip
rakita Nov 29, 2023
85be2c5
Merge remote-tracking branch 'origin/main' into handlers
rakita Nov 29, 2023
64a1bd6
Add wip stages for builer
rakita Nov 29, 2023
45d7209
make handle register simple function, add raw instruction table, spli…
rakita Nov 30, 2023
5ca9580
wip on simple builder functions and handler registry
rakita Dec 1, 2023
aef8257
Examples and cleanup
rakita Dec 1, 2023
bebc79d
fix lifetime and fmt
rakita Dec 1, 2023
580ddf8
Add more handlers, deduct caller, validate tx agains state
rakita Dec 5, 2023
6352f90
All handlers counted, started on docs, some cleanup
rakita Dec 6, 2023
900ff89
renaming and docs
rakita Dec 7, 2023
55f8924
Support all Inspector functionality with Handler
rakita Dec 8, 2023
c930aeb
Handler restructured. Documentation added
rakita Dec 9, 2023
5dc55bd
more docs on registers
rakita Dec 9, 2023
238ea1b
integrate builder, fmt, move optimism l1block
rakita Dec 15, 2023
66b8642
add utility builder stage functions
rakita Dec 15, 2023
697a3e3
add precompiles, fix bugs with journal spec
rakita Dec 18, 2023
9375f35
spec to generic, optimism build
rakita Dec 18, 2023
65997b7
fix optimism test
rakita Dec 18, 2023
bfc5d8b
fuck macros
rakita Dec 26, 2023
8b23136
Merge remote-tracking branch 'origin/main' into handlers
rakita Dec 26, 2023
be3af16
clippy and fmt
rakita Dec 26, 2023
74ae8b0
fix trace block example
rakita Dec 26, 2023
55fc1f7
ci fixes
rakita Dec 26, 2023
b74f7e3
Flatten builder stages to generic and handler stage
rakita Dec 27, 2023
b24c19c
EvmBuilder doc and refactor fn access
rakita Dec 30, 2023
a6feb1a
Merge remote-tracking branch 'origin/main' into handlers
rakita Dec 30, 2023
7024cad
ignore rust code in book
rakita Dec 30, 2023
a704c70
make revme compile, will refactor this in future
rakita Jan 3, 2024
6fdf87a
Rename handles to Pre/Post Execution and ExecutionLoop
rakita Jan 4, 2024
62e9eaa
fix optimism clippy
rakita Jan 4, 2024
c6385be
small rename
rakita Jan 8, 2024
648ba93
FrameData and docs
rakita Jan 9, 2024
055f0f6
check links mdbook
rakita Jan 9, 2024
0b3be0e
comments and cleanup
rakita Jan 10, 2024
8fdcea9
comment
rakita Jan 10, 2024
6cd1414
Merge remote-tracking branch 'origin/main' into handlers
rakita Jan 11, 2024
fa4c712
Add initialize interepreter to first frame
rakita Jan 12, 2024
2133f7f
clippy
rakita Jan 12, 2024
d95dae5
clippy2
rakita Jan 12, 2024
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
Prev Previous commit
Next Next commit
FrameData and docs
  • Loading branch information
rakita committed Jan 9, 2024
commit 648ba938b8a588fe5ae58a7a1db8acd43f7fc752
42 changes: 42 additions & 0 deletions crates/interpreter/src/inner_models.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use revm_primitives::{TransactTo, TxEnv};

pub use crate::primitives::CreateScheme;
use crate::primitives::{Address, Bytes, B256, U256};

Expand Down Expand Up @@ -35,7 +37,47 @@ pub struct CreateInputs {
pub gas_limit: u64,
}

impl CallInputs {
pub fn new(tx_env: &TxEnv, gas_limit: u64) -> Option<Self> {
let TransactTo::Call(address) = tx_env.transact_to else {
return None;
};

Some(CallInputs {
contract: address,
transfer: Transfer {
source: tx_env.caller,
target: address,
value: tx_env.value,
},
input: tx_env.data.clone(),
gas_limit,
context: CallContext {
caller: tx_env.caller,
address,
code_address: address,
apparent_value: tx_env.value,
scheme: CallScheme::Call,
},
is_static: false,
})
}
}

impl CreateInputs {
pub fn new(tx_env: &TxEnv, gas_limit: u64) -> Option<Self> {
let TransactTo::Create(scheme) = tx_env.transact_to else {
return None;
};

Some(CreateInputs {
caller: tx_env.caller,
scheme,
value: tx_env.value,
init_code: tx_env.data.clone(),
gas_limit,
})
}
/// Returns the address that this create call will create.
pub fn created_address(&self, nonce: u64) -> Address {
match self.scheme {
Expand Down
2 changes: 0 additions & 2 deletions crates/revm/src/builder.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//! Evm Builder.

use crate::{
db::{Database, DatabaseRef, EmptyDB, WrapDatabaseRef},
handler::register,
Expand Down
53 changes: 28 additions & 25 deletions crates/revm/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
keccak256, Address, AnalysisKind, Bytecode, Bytes, EVMError, Env, HashSet, Spec, SpecId,
SpecId::*, B256, U256,
},
CallStackFrame, FrameOrResult, CALL_STACK_LIMIT,
CallStackFrame, FrameData, FrameOrResult, JournalCheckpoint, CALL_STACK_LIMIT,
};
use alloc::boxed::Box;
use core::ops::Range;
Expand Down Expand Up @@ -280,10 +280,8 @@ impl<DB: Database> EvmContext<DB> {
));

FrameOrResult::new_frame(CallStackFrame {
is_create: true,
checkpoint,
created_address: Some(created_address),
subcall_return_memory_range: 0..0,
frame_data: FrameData::Create { created_address },
interpreter: Interpreter::new(contract, gas.limit(), false),
})
}
Expand All @@ -292,7 +290,7 @@ impl<DB: Database> EvmContext<DB> {
pub fn make_call_frame(
&mut self,
inputs: &CallInputs,
return_memory_offset: Range<usize>,
return_memory_range: Range<usize>,
) -> FrameOrResult {
let gas = Gas::new(inputs.gas_limit);

Expand Down Expand Up @@ -359,10 +357,10 @@ impl<DB: Database> EvmContext<DB> {
));
// Create interpreter and execute subcall and push new CallStackFrame.
FrameOrResult::new_frame(CallStackFrame {
is_create: false,
checkpoint,
created_address: None,
subcall_return_memory_range: return_memory_offset,
frame_data: FrameData::Call {
return_memory_range,
},
interpreter: Interpreter::new(contract, gas.limit(), inputs.is_static),
})
} else {
Expand Down Expand Up @@ -416,13 +414,13 @@ impl<DB: Database> EvmContext<DB> {
pub fn call_return(
&mut self,
interpreter_result: InterpreterResult,
frame: Box<CallStackFrame>,
journal_checkpoint: JournalCheckpoint,
) -> InterpreterResult {
// revert changes or not.
if matches!(interpreter_result.result, return_ok!()) {
self.journaled_state.checkpoint_commit();
} else {
self.journaled_state.checkpoint_revert(frame.checkpoint);
self.journaled_state.checkpoint_revert(journal_checkpoint);
}
interpreter_result
}
Expand All @@ -432,13 +430,14 @@ impl<DB: Database> EvmContext<DB> {
pub fn create_return<SPEC: Spec>(
&mut self,
mut interpreter_result: InterpreterResult,
frame: Box<CallStackFrame>,
) -> (InterpreterResult, Address) {
let address = frame.created_address.unwrap();
address: Address,
journal_checkpoint: JournalCheckpoint,
) -> InterpreterResult {
//let address = frame.created_address.unwrap();
// if return is not ok revert and return.
if !matches!(interpreter_result.result, return_ok!()) {
self.journaled_state.checkpoint_revert(frame.checkpoint);
return (interpreter_result, address);
self.journaled_state.checkpoint_revert(journal_checkpoint);
return interpreter_result;
}
// Host error if present on execution
// if ok, check contract creation limit and calculate gas deduction on output len.
Expand All @@ -448,9 +447,9 @@ impl<DB: Database> EvmContext<DB> {
&& !interpreter_result.output.is_empty()
&& interpreter_result.output.first() == Some(&0xEF)
{
self.journaled_state.checkpoint_revert(frame.checkpoint);
self.journaled_state.checkpoint_revert(journal_checkpoint);
interpreter_result.result = InstructionResult::CreateContractStartingWithEF;
return (interpreter_result, address);
return interpreter_result;
}

// EIP-170: Contract code size limit
Expand All @@ -463,9 +462,9 @@ impl<DB: Database> EvmContext<DB> {
.limit_contract_code_size
.unwrap_or(MAX_CODE_SIZE)
{
self.journaled_state.checkpoint_revert(frame.checkpoint);
self.journaled_state.checkpoint_revert(journal_checkpoint);
interpreter_result.result = InstructionResult::CreateContractSizeLimit;
return (interpreter_result, frame.created_address.unwrap());
return interpreter_result;
}
let gas_for_code = interpreter_result.output.len() as u64 * gas::CODEDEPOSIT;
if !interpreter_result.gas.record_cost(gas_for_code) {
Expand All @@ -474,9 +473,9 @@ impl<DB: Database> EvmContext<DB> {
// final gas fee for adding the contract code to the state, the contract
// creation fails (i.e. goes out-of-gas) rather than leaving an empty contract.
if SPEC::enabled(HOMESTEAD) {
self.journaled_state.checkpoint_revert(frame.checkpoint);
self.journaled_state.checkpoint_revert(journal_checkpoint);
interpreter_result.result = InstructionResult::OutOfGas;
return (interpreter_result, address);
return interpreter_result;
} else {
interpreter_result.output = Bytes::new();
}
Expand All @@ -499,7 +498,7 @@ impl<DB: Database> EvmContext<DB> {
self.journaled_state.set_code(address, bytecode);

interpreter_result.result = InstructionResult::Return;
(interpreter_result, address)
interpreter_result
}
}
/// Test utilities for the [`EvmContext`].
Expand Down Expand Up @@ -669,8 +668,12 @@ mod tests {
let FrameOrResult::Frame(frame) = res else {
panic!("Expected FrameOrResult::Frame");
};
assert!(!frame.is_create);
assert_eq!(frame.created_address, None);
assert_eq!(frame.subcall_return_memory_range, 0..0);
assert!(!frame.is_create());
assert_eq!(
frame.frame_data,
FrameData::Call {
return_memory_range: 0..0
}
);
}
}
2 changes: 1 addition & 1 deletion crates/revm/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ impl<EXT, DB: Database> Evm<'_, EXT, DB> {
// start main loop if CallStackFrame is created correctly
let result = match first_stack_frame {
FrameOrResult::Frame(first_stack_frame) => {
created_address = first_stack_frame.created_address;
created_address = first_stack_frame.created_address();
// take instruction talbe
let table = self
.handler
Expand Down
37 changes: 31 additions & 6 deletions crates/revm/src/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,21 @@ use core::ops::Range;
/// Call CallStackFrame.
#[derive(Debug)]
pub struct CallStackFrame {
/// True if it is create false if it is call.
pub is_create: bool,
/// Journal checkpoint
pub checkpoint: JournalCheckpoint,
/// temporary. If it is create it should have address.
pub created_address: Option<Address>,
/// temporary. Call range
pub subcall_return_memory_range: Range<usize>,
/// Interpreter
pub interpreter: Interpreter,
/// Frame data
pub frame_data: FrameData,
}

/// Specific data for call or create frame.
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum FrameData {
/// Call frame has return memory range where output will be stored.
Call { return_memory_range: Range<usize> },
/// Create frame has a created address.
Create { created_address: Address },
}

/// Contains either a frame or a result.
Expand All @@ -29,6 +34,26 @@ pub enum FrameOrResult {
Result(InterpreterResult),
}

impl CallStackFrame {
/// Returns true if frame is call frame.
pub fn is_call(&self) -> bool {
matches!(self.frame_data, FrameData::Call { .. })
}

/// Returns true if frame is create frame.
pub fn is_create(&self) -> bool {
matches!(self.frame_data, FrameData::Create { .. })
}

/// Returns created address if frame is create otherwise returns None.
pub fn created_address(&self) -> Option<Address> {
match self.frame_data {
FrameData::Create { created_address } => Some(created_address),
_ => None,
}
}
}

impl FrameOrResult {
/// Returns new frame.
pub fn new_frame(frame: CallStackFrame) -> Self {
Expand Down
4 changes: 0 additions & 4 deletions crates/revm/src/handler.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
//! Handler contains all the logic that is specific to the Evm.
//! It is used to define different behavior depending on the chain (Optimism,Mainnet) or
//! hardfork (Berlin, London, ..).

// Modules.
mod handle_types;
pub mod mainnet;
Expand Down
8 changes: 4 additions & 4 deletions crates/revm/src/handler/handle_types/execution_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ impl<'a, EXT: 'a, DB: Database + 'a> ExecutionLoopHandler<'a, EXT, DB> {
pub fn new<SPEC: Spec + 'a>() -> Self {
Self {
create_first_frame: Arc::new(mainnet::create_first_frame::<SPEC, EXT, DB>),
first_frame_return: Arc::new(mainnet::main_frame_return::<SPEC>),
frame_return: Arc::new(mainnet::handle_frame_return::<SPEC, EXT, DB>),
sub_call: Arc::new(mainnet::handle_frame_sub_call::<SPEC, EXT, DB>),
sub_create: Arc::new(mainnet::handle_frame_sub_create::<SPEC, EXT, DB>),
first_frame_return: Arc::new(mainnet::first_frame_return::<SPEC>),
frame_return: Arc::new(mainnet::frame_return::<SPEC, EXT, DB>),
sub_call: Arc::new(mainnet::sub_call::<SPEC, EXT, DB>),
sub_create: Arc::new(mainnet::sub_create::<SPEC, EXT, DB>),
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions crates/revm/src/handler/handle_types/pre_execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ impl<'a, EXT: 'a, DB: Database + 'a> PreExecutionHandler<'a, EXT, DB> {
/// Creates mainnet MainHandles.
pub fn new<SPEC: Spec + 'a>() -> Self {
Self {
load_precompiles: Arc::new(mainnet::main_load_precompiles::<SPEC>),
load_accounts: Arc::new(mainnet::main_load::<SPEC, EXT, DB>),
deduct_caller: Arc::new(mainnet::main_deduct_caller::<SPEC, EXT, DB>),
load_precompiles: Arc::new(mainnet::load_precompiles::<SPEC>),
load_accounts: Arc::new(mainnet::load::<SPEC, EXT, DB>),
deduct_caller: Arc::new(mainnet::deduct_caller::<SPEC, EXT, DB>),
}
}
}
Expand Down
12 changes: 5 additions & 7 deletions crates/revm/src/handler/mainnet.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
//! Mainnet related handlers.

mod frame;
mod execution_loop;
mod post_execution;
mod pre_execution;
mod validation;

pub use frame::{
create_first_frame, frame_return_with_refund_flag, handle_frame_return, handle_frame_sub_call,
handle_frame_sub_create, main_frame_return,
pub use execution_loop::{
create_first_frame, first_frame_return, frame_return, frame_return_with_refund_flag, sub_call,
sub_create,
};
pub use post_execution::{end, output, reimburse_caller, reward_beneficiary};
pub use pre_execution::{
deduct_caller_inner, main_deduct_caller, main_load, main_load_precompiles,
};
pub use pre_execution::{deduct_caller, deduct_caller_inner, load, load_precompiles};
pub use validation::{validate_env, validate_initial_tx_gas, validate_tx_against_state};
Loading