From 54db33ed8a03101f1e35fcac9a8f2c5766eff7dd Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Sat, 12 Oct 2024 02:41:28 +0200 Subject: [PATCH 1/2] Added smallvec --- Cargo.toml | 1 + src/executor/stack/executor.rs | 33 +++++++++++++++++---------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a06c1717..3ff41865 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ ethereum = { version = "0.15", default-features = false } log = { version = "0.4", default-features = false } primitive-types = { workspace = true, features = ["rlp"] } rlp = { version = "0.5", default-features = false } +smallvec = "1.13 " # Optional dependencies environmental = { version = "1.1.2", default-features = false, optional = true } diff --git a/src/executor/stack/executor.rs b/src/executor/stack/executor.rs index 597e09ae..10092f3b 100644 --- a/src/executor/stack/executor.rs +++ b/src/executor/stack/executor.rs @@ -16,6 +16,7 @@ use evm_core::{ExitFatal, InterpreterHandler, Machine, Trap}; use evm_runtime::Resolve; use primitive_types::{H160, H256, U256}; use sha3::{Digest, Keccak256}; +use smallvec::{smallvec, SmallVec}; macro_rules! emit_exit { ($reason:expr) => {{ @@ -377,11 +378,11 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> /// Execute the runtime until it returns. pub fn execute(&mut self, runtime: &mut Runtime) -> ExitReason { - let mut call_stack = Vec::with_capacity(DEFAULT_CALL_STACK_CAPACITY); - call_stack.push(TaggedRuntime { - kind: RuntimeKind::Execute, - inner: MaybeBorrowed::Borrowed(runtime), - }); + let mut call_stack: SmallVec<[TaggedRuntime; DEFAULT_CALL_STACK_CAPACITY]> = + smallvec!(TaggedRuntime { + kind: RuntimeKind::Execute, + inner: MaybeBorrowed::Borrowed(runtime), + }); let (reason, _, _) = self.execute_with_call_stack(&mut call_stack); reason } @@ -389,7 +390,7 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> /// Execute using Runtimes on the `call_stack` until it returns. fn execute_with_call_stack( &mut self, - call_stack: &mut Vec>, + call_stack: &mut SmallVec<[TaggedRuntime<'_>; DEFAULT_CALL_STACK_CAPACITY]>, ) -> (ExitReason, Option, Vec) { // This `interrupt_runtime` is used to pass the runtime obtained from the // `Capture::Trap` branch in the match below back to the top of the call stack. @@ -544,8 +545,8 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> ) { Capture::Exit((s, _, v)) => emit_exit!(s, v), Capture::Trap(rt) => { - let mut cs = Vec::with_capacity(DEFAULT_CALL_STACK_CAPACITY); - cs.push(rt.0); + let mut cs: SmallVec<[TaggedRuntime<'_>; DEFAULT_CALL_STACK_CAPACITY]> = + smallvec!(rt.0); let (s, _, v) = self.execute_with_call_stack(&mut cs); emit_exit!(s, v) } @@ -590,8 +591,8 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> ) { Capture::Exit((s, _, v)) => emit_exit!(s, v), Capture::Trap(rt) => { - let mut cs = Vec::with_capacity(DEFAULT_CALL_STACK_CAPACITY); - cs.push(rt.0); + let mut cs: SmallVec<[TaggedRuntime<'_>; DEFAULT_CALL_STACK_CAPACITY]> = + smallvec!(rt.0); let (s, _, v) = self.execute_with_call_stack(&mut cs); emit_exit!(s, v) } @@ -651,8 +652,8 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> ) { Capture::Exit((s, _, v)) => emit_exit!(s, v), Capture::Trap(rt) => { - let mut cs = Vec::with_capacity(DEFAULT_CALL_STACK_CAPACITY); - cs.push(rt.0); + let mut cs: SmallVec<[TaggedRuntime<'_>; DEFAULT_CALL_STACK_CAPACITY]> = + smallvec!(rt.0); let (s, _, v) = self.execute_with_call_stack(&mut cs); emit_exit!(s, v) } @@ -722,8 +723,8 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> ) { Capture::Exit((s, v)) => emit_exit!(s, v), Capture::Trap(rt) => { - let mut cs = Vec::with_capacity(DEFAULT_CALL_STACK_CAPACITY); - cs.push(rt.0); + let mut cs: SmallVec<[TaggedRuntime<'_>; DEFAULT_CALL_STACK_CAPACITY]> = + smallvec!(rt.0); let (s, _, v) = self.execute_with_call_stack(&mut cs); emit_exit!(s, v) } @@ -1640,8 +1641,8 @@ impl<'inner, 'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> Pr // not allow it. For now we'll make a recursive call instead of making a breaking // change to the precompile API. But this means a custom precompile could still // potentially cause a stack overflow if you're not careful. - let mut call_stack = Vec::with_capacity(DEFAULT_CALL_STACK_CAPACITY); - call_stack.push(rt.0); + let mut call_stack: SmallVec<[TaggedRuntime; DEFAULT_CALL_STACK_CAPACITY]> = + smallvec![rt.0]; let (reason, _, return_data) = self.executor.execute_with_call_stack(&mut call_stack); emit_exit!(reason, return_data) From 092ac4b345db27b669cb06a51d6a0ef32b3ae5b0 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Tue, 15 Oct 2024 11:40:27 +0200 Subject: [PATCH 2/2] Small fix --- Cargo.toml | 2 +- src/executor/stack/executor.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3ff41865..814ccbeb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ ethereum = { version = "0.15", default-features = false } log = { version = "0.4", default-features = false } primitive-types = { workspace = true, features = ["rlp"] } rlp = { version = "0.5", default-features = false } -smallvec = "1.13 " +smallvec = "1.13" # Optional dependencies environmental = { version = "1.1.2", default-features = false, optional = true } diff --git a/src/executor/stack/executor.rs b/src/executor/stack/executor.rs index 10092f3b..3b815a16 100644 --- a/src/executor/stack/executor.rs +++ b/src/executor/stack/executor.rs @@ -1642,7 +1642,7 @@ impl<'inner, 'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> Pr // change to the precompile API. But this means a custom precompile could still // potentially cause a stack overflow if you're not careful. let mut call_stack: SmallVec<[TaggedRuntime; DEFAULT_CALL_STACK_CAPACITY]> = - smallvec![rt.0]; + smallvec!(rt.0); let (reason, _, return_data) = self.executor.execute_with_call_stack(&mut call_stack); emit_exit!(reason, return_data)