Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: use impl instead of dyn in GetInspector #1157

Merged
merged 2 commits into from Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 0 additions & 2 deletions crates/interpreter/src/instructions/i256.rs
Expand Up @@ -136,10 +136,8 @@ mod tests {
let one = U256::from(1);
let one_hundred = U256::from(100);
let fifty = U256::from(50);
let _fifty_sign = Sign::Plus;
let two = U256::from(2);
let neg_one_hundred = U256::from(100);
let _neg_one_hundred_sign = Sign::Minus;
let minus_one = U256::from(1);
let max_value = U256::from(2).pow(U256::from(255)) - U256::from(1);
let neg_max_value = U256::from(2).pow(U256::from(255)) - U256::from(1);
Expand Down
4 changes: 1 addition & 3 deletions crates/interpreter/src/interpreter.rs
Expand Up @@ -5,7 +5,7 @@ mod stack;

pub use analysis::BytecodeLocked;
pub use contract::Contract;
pub use shared_memory::{next_multiple_of_32, SharedMemory};
pub use shared_memory::{next_multiple_of_32, SharedMemory, EMPTY_SHARED_MEMORY};
pub use stack::{Stack, STACK_LIMIT};

use crate::{
Expand All @@ -17,8 +17,6 @@ use revm_primitives::U256;
use std::borrow::ToOwned;
use std::boxed::Box;

pub use self::shared_memory::EMPTY_SHARED_MEMORY;

#[derive(Debug)]
pub struct Interpreter {
/// Contract information and invoking data
Expand Down
37 changes: 23 additions & 14 deletions crates/primitives/src/result.rs
Expand Up @@ -52,14 +52,6 @@ impl ExecutionResult {
matches!(self, Self::Halt { .. })
}

/// Return logs, if execution is not successful, function will return empty vec.
pub fn logs(&self) -> Vec<Log> {
match self {
Self::Success { logs, .. } => logs.clone(),
_ => Vec::new(),
}
}

/// Returns the output data of the execution.
///
/// Returns `None` if the execution was halted.
Expand All @@ -82,20 +74,29 @@ impl ExecutionResult {
}
}

/// Consumes the type and returns logs, if execution is not successful, function will return empty vec.
/// Returns the logs if execution is successful, or an empty list otherwise.
pub fn logs(&self) -> &[Log] {
match self {
Self::Success { logs, .. } => logs,
_ => &[],
}
}

/// Consumes `self` and returns the logs if execution is successful, or an empty list otherwise.
pub fn into_logs(self) -> Vec<Log> {
match self {
Self::Success { logs, .. } => logs,
_ => Vec::new(),
}
}

/// Returns the gas used.
pub fn gas_used(&self) -> u64 {
let (Self::Success { gas_used, .. }
| Self::Revert { gas_used, .. }
| Self::Halt { gas_used, .. }) = self;

*gas_used
match *self {
Self::Success { gas_used, .. }
| Self::Revert { gas_used, .. }
| Self::Halt { gas_used, .. } => gas_used,
}
}
}

Expand Down Expand Up @@ -123,6 +124,14 @@ impl Output {
Output::Create(data, _) => data,
}
}

/// Returns the created address, if any.
pub fn address(&self) -> Option<&Address> {
match self {
Output::Call(_) => None,
Output::Create(_, address) => address.as_ref(),
}
}
}

/// Main EVM error.
Expand Down
5 changes: 2 additions & 3 deletions crates/revm/src/builder.rs
Expand Up @@ -497,10 +497,9 @@ mod test {
.build();

let Context {
external,
evm: EvmContext { db, .. },
external: _,
evm: EvmContext { db: _, .. },
} = evm.into_context();
let _ = (external, db);
}

#[test]
Expand Down
12 changes: 9 additions & 3 deletions crates/revm/src/db/in_memory_db.rs
Expand Up @@ -428,7 +428,9 @@ mod tests {

let (key, value) = (U256::from(123), U256::from(456));
let mut new_state = CacheDB::new(init_state);
let _ = new_state.insert_account_storage(account, key, value);
new_state
.insert_account_storage(account, key, value)
.unwrap();

assert_eq!(new_state.basic(account).unwrap().unwrap().nonce, nonce);
assert_eq!(new_state.storage(account, key), Ok(value));
Expand All @@ -449,10 +451,14 @@ mod tests {

let (key0, value0) = (U256::from(123), U256::from(456));
let (key1, value1) = (U256::from(789), U256::from(999));
let _ = init_state.insert_account_storage(account, key0, value0);
init_state
.insert_account_storage(account, key0, value0)
.unwrap();

let mut new_state = CacheDB::new(init_state);
let _ = new_state.replace_account_storage(account, [(key1, value1)].into());
new_state
.replace_account_storage(account, [(key1, value1)].into())
.unwrap();

assert_eq!(new_state.basic(account).unwrap().unwrap().nonce, nonce);
assert_eq!(new_state.storage(account, key0), Ok(U256::ZERO));
Expand Down
15 changes: 12 additions & 3 deletions crates/revm/src/frame.rs
Expand Up @@ -110,10 +110,9 @@ impl FrameResult {

/// Contains either a frame or a result.
pub enum FrameOrResult {
/// Boxed call frame,
/// Boxed call or create frame.
Frame(Frame),
/// Boxed create frame
/// Interpreter result
/// Call or create result.
Result(FrameResult),
}

Expand Down Expand Up @@ -187,6 +186,16 @@ impl Frame {
Self::Create(create_frame) => &mut create_frame.frame_data,
}
}

/// Returns a reference to the interpreter.
pub fn interpreter(&self) -> &Interpreter {
&self.frame_data().interpreter
}

/// Returns a mutable reference to the interpreter.
pub fn interpreter_mut(&mut self) -> &mut Interpreter {
&mut self.frame_data_mut().interpreter
}
}

impl FrameOrResult {
Expand Down
5 changes: 3 additions & 2 deletions crates/revm/src/handler/mainnet/execution.rs
Expand Up @@ -37,14 +37,15 @@ pub fn frame_return_with_refund_flag<SPEC: Spec>(
}
_ => {}
}

// Calculate gas refund for transaction.
// If config is set to disable gas refund, it will return 0.
// If spec is set to london, it will decrease the maximum refund amount to 5th part of
// gas spend. (Before london it was 2th part of gas spend)
if refund_enabled {
// EIP-3529: Reduction in refunds
gas.set_final_refund::<SPEC>()
};
gas.set_final_refund::<SPEC>();
}
}

/// Handle output of the transaction
Expand Down
7 changes: 2 additions & 5 deletions crates/revm/src/handler/mainnet/post_execution.rs
@@ -1,7 +1,7 @@
use crate::{
interpreter::{Gas, SuccessOrHalt},
primitives::{
db::Database, EVMError, ExecutionResult, Output, ResultAndState, Spec, SpecId::LONDON, U256,
db::Database, EVMError, ExecutionResult, ResultAndState, Spec, SpecId::LONDON, U256,
},
Context, FrameResult,
};
Expand Down Expand Up @@ -94,10 +94,7 @@ pub fn output<EXT, DB: Database>(
},
SuccessOrHalt::Revert => ExecutionResult::Revert {
gas_used: final_gas_used,
output: match output {
Output::Call(return_value) => return_value,
Output::Create(return_value, _) => return_value,
},
output: output.into_data(),
},
SuccessOrHalt::Halt(reason) => ExecutionResult::Halt {
reason,
Expand Down
46 changes: 24 additions & 22 deletions crates/revm/src/inspector/handler_register.rs
Expand Up @@ -11,11 +11,13 @@ use std::{boxed::Box, rc::Rc, sync::Arc, vec::Vec};

/// Provides access to an `Inspector` instance.
pub trait GetInspector<DB: Database> {
fn get_inspector(&mut self) -> &mut dyn Inspector<DB>;
/// Returns the associated `Inspector`.
fn get_inspector(&mut self) -> &mut impl Inspector<DB>;
}

impl<DB: Database, INSP: Inspector<DB>> GetInspector<DB> for INSP {
fn get_inspector(&mut self) -> &mut dyn Inspector<DB> {
#[inline(always)]
fn get_inspector(&mut self) -> &mut impl Inspector<DB> {
self
}
}
Expand All @@ -37,8 +39,7 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector<DB>>(
) {
// Every instruction inside flat table that is going to be wrapped by inspector calls.
let table = handler
.instruction_table
.take()
.take_instruction_table()
.expect("Handler must have instruction table");
let mut table = match table {
InstructionTables::Plain(table) => table
Expand Down Expand Up @@ -123,7 +124,7 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector<DB>>(
}

// cast vector to array.
handler.instruction_table = Some(InstructionTables::Boxed(
handler.set_instruction_table(InstructionTables::Boxed(
table.try_into().unwrap_or_else(|_| unreachable!()),
));

Expand All @@ -146,10 +147,10 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector<DB>>(
create_input_stack_inner.borrow_mut().push(inputs.clone());

let mut frame_or_result = old_handle(ctx, inputs);

let inspector = ctx.external.get_inspector();
if let Ok(FrameOrResult::Frame(frame)) = &mut frame_or_result {
inspector.initialize_interp(&mut frame.frame_data_mut().interpreter, &mut ctx.evm)
ctx.external
.get_inspector()
.initialize_interp(frame.interpreter_mut(), &mut ctx.evm)
}
frame_or_result
},
Expand All @@ -160,20 +161,18 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector<DB>>(
let old_handle = handler.execution.call.clone();
handler.execution.call = Arc::new(
move |ctx, mut inputs| -> Result<FrameOrResult, EVMError<DB::Error>> {
let inspector = ctx.external.get_inspector();
let _mems = inputs.return_memory_offset.clone();
// call inspector callto change input or return outcome.
if let Some(outcome) = inspector.call(&mut ctx.evm, &mut inputs) {
call_input_stack_inner.borrow_mut().push(inputs.clone());
// Call inspector to change input or return outcome.
let outcome = ctx.external.get_inspector().call(&mut ctx.evm, &mut inputs);
call_input_stack_inner.borrow_mut().push(inputs.clone());
if let Some(outcome) = outcome {
return Ok(FrameOrResult::Result(FrameResult::Call(outcome)));
}
call_input_stack_inner.borrow_mut().push(inputs.clone());

let mut frame_or_result = old_handle(ctx, inputs);

let inspector = ctx.external.get_inspector();
if let Ok(FrameOrResult::Frame(frame)) = &mut frame_or_result {
inspector.initialize_interp(&mut frame.frame_data_mut().interpreter, &mut ctx.evm)
ctx.external
.get_inspector()
.initialize_interp(frame.interpreter_mut(), &mut ctx.evm)
}
frame_or_result
},
Expand All @@ -184,19 +183,23 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector<DB>>(
let old_handle = handler.execution.insert_call_outcome.clone();
handler.execution.insert_call_outcome =
Arc::new(move |ctx, frame, shared_memory, mut outcome| {
let inspector = ctx.external.get_inspector();
let call_inputs = call_input_stack_inner.borrow_mut().pop().unwrap();
outcome = inspector.call_end(&mut ctx.evm, &call_inputs, outcome);
outcome = ctx
.external
.get_inspector()
.call_end(&mut ctx.evm, &call_inputs, outcome);
old_handle(ctx, frame, shared_memory, outcome)
});

// create outcome
let create_input_stack_inner = create_input_stack.clone();
let old_handle = handler.execution.insert_create_outcome.clone();
handler.execution.insert_create_outcome = Arc::new(move |ctx, frame, mut outcome| {
let inspector = ctx.external.get_inspector();
let create_inputs = create_input_stack_inner.borrow_mut().pop().unwrap();
outcome = inspector.create_end(&mut ctx.evm, &create_inputs, outcome);
outcome = ctx
.external
.get_inspector()
.create_end(&mut ctx.evm, &create_inputs, outcome);
old_handle(ctx, frame, outcome)
});

Expand All @@ -214,7 +217,6 @@ pub fn inspector_handle_register<'a, DB: Database, EXT: GetInspector<DB>>(
*outcome = inspector.create_end(&mut ctx.evm, &create_inputs, outcome.clone());
}
}
//inspector.last_frame_return(ctx, frame_result);
old_handle(ctx, frame_result)
});
}
Expand Down