From 85b6811e0b5574956b115d93741e7efabfe55fd1 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Tue, 18 Jun 2024 09:25:02 +0200 Subject: [PATCH 1/5] Added EIP-7610 implementation - create collision --- .github/workflows/rust.yml | 1 + runtime/src/handler.rs | 2 ++ src/backend/memory.rs | 7 +++++++ src/backend/mod.rs | 2 ++ src/executor/stack/executor.rs | 28 ++++++++++++++++------------ src/executor/stack/memory.rs | 4 ++++ 6 files changed, 32 insertions(+), 12 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 10d7c3564..4a8cec61e 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -52,6 +52,7 @@ jobs: path: ethtests ref: v13.2 submodules: recursive + fetch-depth: 1 - name: Run Ethereum state tests run: | diff --git a/runtime/src/handler.rs b/runtime/src/handler.rs index c832ccc47..61ac034df 100644 --- a/runtime/src/handler.rs +++ b/runtime/src/handler.rs @@ -35,6 +35,8 @@ pub trait Handler { fn code(&self, address: H160) -> Vec; /// Get storage value of address at index. fn storage(&self, address: H160, index: H256) -> H256; + /// Check is storage of address empty. + fn is_empty_storage(&self, address: H160) -> bool; /// Get original storage value of address at index. fn original_storage(&self, address: H160, index: H256) -> H256; diff --git a/src/backend/memory.rs b/src/backend/memory.rs index 541bada24..6be03cd4e 100644 --- a/src/backend/memory.rs +++ b/src/backend/memory.rs @@ -164,6 +164,13 @@ impl<'vicinity> Backend for MemoryBackend<'vicinity> { .unwrap_or_default() } + fn is_empty_storage(&self, address: H160) -> bool { + self.state + .get(&address) + .map(|v| v.storage.is_empty()) + .unwrap_or(true) + } + fn original_storage(&self, address: H160, index: H256) -> Option { Some(self.storage(address, index)) } diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 56fbdef11..3a0a4482c 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -82,6 +82,8 @@ pub trait Backend { fn code(&self, address: H160) -> Vec; /// Get storage value of address at index. fn storage(&self, address: H160, index: H256) -> H256; + /// Check is storage of address empty. + fn is_empty_storage(&self, address: H160) -> bool; /// Get original storage value of address at index, if available. fn original_storage(&self, address: H160, index: H256) -> Option; /// CANCUN hard fork diff --git a/src/executor/stack/executor.rs b/src/executor/stack/executor.rs index 0066c40fe..a1ccfd6d1 100644 --- a/src/executor/stack/executor.rs +++ b/src/executor/stack/executor.rs @@ -703,6 +703,14 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> self.state.basic(address).nonce } + /// Check is an existing account the "create collision". + /// [EIP-7610](https://eips.ethereum.org/EIPS/eip-7610) + pub fn is_create_collision(&self, address: H160) -> bool { + self.code_size(address) != U256::zero() + || self.nonce(address) > U256::zero() + || !self.state.is_empty_storage(address) + } + /// Get the created address from given scheme. pub fn create_address(&self, scheme: CreateScheme) -> H160 { match scheme { @@ -839,18 +847,10 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> self.enter_substate(gas_limit, false); - { - if self.code_size(address) != U256::zero() { - let _ = self.exit_substate(StackExitKind::Failed); - return Capture::Exit((ExitError::CreateCollision.into(), None, Vec::new())); - } - - if self.nonce(address) > U256::zero() { - let _ = self.exit_substate(StackExitKind::Failed); - return Capture::Exit((ExitError::CreateCollision.into(), None, Vec::new())); - } - - self.state.reset_storage(address); + // Check create collision: EIP-7610 + if self.is_create_collision(address) { + let _ = self.exit_substate(StackExitKind::Failed); + return Capture::Exit((ExitError::CreateCollision.into(), None, Vec::new())); } let context = Context { @@ -1258,6 +1258,10 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> Handler self.state.storage(address, index) } + fn is_empty_storage(&self, address: H160) -> bool { + self.state.is_empty(address) + } + fn original_storage(&self, address: H160, index: H256) -> H256 { self.state .original_storage(address, index) diff --git a/src/executor/stack/memory.rs b/src/executor/stack/memory.rs index 885afed16..828543f3e 100644 --- a/src/executor/stack/memory.rs +++ b/src/executor/stack/memory.rs @@ -511,6 +511,10 @@ impl<'backend, 'config, B: Backend> Backend for MemoryStackState<'backend, 'conf .unwrap_or_else(|| self.backend.storage(address, key)) } + fn is_empty_storage(&self, address: H160) -> bool { + self.backend.is_empty_storage(address) + } + fn original_storage(&self, address: H160, key: H256) -> Option { if let Some(value) = self.substate.known_original_storage(address) { return Some(value); From ad686cc89f084f65ea455faf5a779d99528977a3 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Tue, 18 Jun 2024 10:15:36 +0200 Subject: [PATCH 2/5] Updated Cargo rules --- Cargo.toml | 39 +++++++++++++++++++++++----------- core/Cargo.toml | 16 +++++++------- evm-tests/jsontests/Cargo.toml | 8 +++---- fuzzer/Cargo.toml | 2 +- gasometer/Cargo.toml | 20 ++++++++--------- runtime/Cargo.toml | 20 ++++++++--------- 6 files changed, 60 insertions(+), 45 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 87a41a33b..5bd33ff71 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,16 +1,16 @@ [package] name = "evm" -version = "0.42.0" -license = "Apache-2.0" -authors = ["Wei Tang ", "Parity Technologies "] -description = "SputnikVM - a Portable Blockchain Virtual Machine" -repository = "https://github.com/sorpaas/rust-evm" -keywords = ["no_std", "ethereum"] -edition = "2021" +version.workspace = true +license.workspace = true +authors.workspace = true +description.workspace = true +repository.workspace = true +keywords.workspace = true +edition.workspace = true [dependencies] -auto_impl = "1.0" -ethereum = { version = "0.15", default-features = false } +auto_impl.workspace = true +ethereum.workspace = true log = { version = "0.4", default-features = false } primitive-types = { version = "0.12", default-features = false, features = ["rlp"] } rlp = { version = "0.5", default-features = false } @@ -22,9 +22,9 @@ scale-codec = { package = "parity-scale-codec", version = "3.2", default-feature scale-info = { version = "2.11", default-features = false, features = ["derive"], optional = true } serde = { version = "1.0", default-features = false, features = ["derive"], optional = true } -evm-core = { version = "0.42", path = "core", default-features = false } -evm-gasometer = { version = "0.42", path = "gasometer", default-features = false } -evm-runtime = { version = "0.42", path = "runtime", default-features = false } +evm-core = { version = "0.43", path = "core", default-features = false } +evm-runtime = { version = "0.43", path = "runtime", default-features = false } +evm-gasometer = { version = "0.43", path = "gasometer", default-features = false } [dev-dependencies] criterion = "0.5" @@ -77,7 +77,22 @@ force-debug = [ create-fixed = [] print-debug = ["evm-gasometer/print-debug"] +[workspace.package] +version = "0.43.0" +license = "Apache-2.0" +authors = ["Aurora Labs ", "Wei Tang ", "Parity Technologies "] +description = "Portable Ethereum Virtual Machine implementation written in pure Rust." +repository = "https://github.com/sorpaas/rust-evm" +keywords = ["no_std", "ethereum"] +edition = "2021" + +[workspace.dependencies] +auto_impl = "1.0" +ethereum = { version = "0.15", default-features = false } +primitive-types = { version = "0.12", default-features = false } + [workspace] +resolver = "2" members = [ "core", "gasometer", diff --git a/core/Cargo.toml b/core/Cargo.toml index b762447da..bd31aba51 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -1,16 +1,16 @@ [package] name = "evm-core" -version = "0.42.0" -license = "Apache-2.0" -authors = ["Wei Tang ", "Parity Technologies "] -description = "Portable Ethereum Virtual Machine implementation written in pure Rust." -repository = "https://github.com/sorpaas/rust-evm" -keywords = ["no_std", "ethereum"] -edition = "2021" +version.workspace = true +license.workspace = true +authors.workspace = true +edition.workspace = true +keywords.workspace = true +description.workspace = true +repository.workspace = true [dependencies] log = { version = "0.4", optional = true } -primitive-types = { version = "0.12", default-features = false } +primitive-types.workspace = true scale-codec = { package = "parity-scale-codec", version = "3.2", default-features = false, features = ["derive", "full"], optional = true } scale-info = { version = "2.3", default-features = false, features = ["derive"], optional = true } serde = { version = "1.0", default-features = false, features = ["derive"], optional = true } diff --git a/evm-tests/jsontests/Cargo.toml b/evm-tests/jsontests/Cargo.toml index c74f5aca2..7e035bbc7 100644 --- a/evm-tests/jsontests/Cargo.toml +++ b/evm-tests/jsontests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "evm-jsontests" -version = "0.42.0" +version = "0.43.0" license = "GPL-3.0" authors = ["Aurora Labs ", "Wei Tang ", "Parity Technologies "] description = "SputnikVM - a Portable Blockchain Virtual Machine" @@ -9,9 +9,9 @@ keywords = ["no_std", "ethereum"] edition = "2021" [dependencies] -evm = { path = "../.." } -ethereum = "0.15.0" -primitive-types = "0.12" +evm = { path = "../..", version = "0.43" } +ethereum.workspace = true +primitive-types.workspace = true serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" hex = "0.4" diff --git a/fuzzer/Cargo.toml b/fuzzer/Cargo.toml index 35300b1af..a10a0bf75 100644 --- a/fuzzer/Cargo.toml +++ b/fuzzer/Cargo.toml @@ -9,7 +9,7 @@ license = "Apache-2.0" [dependencies] honggfuzz = "0.5" -evm-core = { version = "0.42", path = "../core" } +evm-core = { version = "0.43", path = "../core" } [[bin]] name = "evm_fuzz" diff --git a/gasometer/Cargo.toml b/gasometer/Cargo.toml index 907d532f7..fd58aa41a 100644 --- a/gasometer/Cargo.toml +++ b/gasometer/Cargo.toml @@ -1,20 +1,20 @@ [package] name = "evm-gasometer" -version = "0.42.0" -license = "Apache-2.0" -authors = ["Wei Tang ", "Parity Technologies "] -description = "Portable Ethereum Virtual Machine implementation written in pure Rust." -repository = "https://github.com/sorpaas/rust-evm" -keywords = ["no_std", "ethereum"] -edition = "2021" +version.workspace = true +license.workspace = true +authors.workspace = true +edition.workspace = true +keywords.workspace = true +description.workspace = true +repository.workspace = true [dependencies] environmental = { version = "1.1.2", default-features = false, optional = true } log = { version = "0.4", optional = true } -primitive-types = { version = "0.12", default-features = false } +primitive-types.workspace = true -evm-core = { version = "0.42", path = "../core", default-features = false } -evm-runtime = { version = "0.42", path = "../runtime", default-features = false } +evm-core = { version = "0.43", path = "../core", default-features = false } +evm-runtime = { version = "0.43", path = "../runtime", default-features = false } [features] default = ["std"] diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index c8f0bf548..4dfd5ed14 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -1,20 +1,20 @@ [package] name = "evm-runtime" -version = "0.42.0" -license = "Apache-2.0" -authors = ["Wei Tang ", "Parity Technologies "] -description = "SputnikVM - a Portable Blockchain Virtual Machine" -repository = "https://github.com/sorpaas/rust-evm" -keywords = ["no_std", "ethereum"] -edition = "2021" +version.workspace = true +license.workspace = true +authors.workspace = true +edition.workspace = true +keywords.workspace = true +description.workspace = true +repository.workspace = true [dependencies] -auto_impl = "1.0" +auto_impl.workspace = true environmental = { version = "1.1", default-features = false, optional = true } -primitive-types = { version = "0.12", default-features = false } +primitive-types.workspace = true sha3 = { version = "0.10", default-features = false } -evm-core = { version = "0.42", path = "../core", default-features = false } +evm-core = { version = "0.43", path = "../core", default-features = false } [features] default = ["std"] From 996aabdd07b7519fcae6d7b1ce79eccc4f3d3d32 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Tue, 18 Jun 2024 10:31:11 +0200 Subject: [PATCH 3/5] Updated cargo rules and dependencies --- Cargo.toml | 9 ++------- core/Cargo.toml | 2 +- evm-tests/jsontests/Cargo.toml | 16 ++++++++-------- gasometer/Cargo.toml | 2 +- runtime/Cargo.toml | 4 ++-- 5 files changed, 14 insertions(+), 19 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5bd33ff71..b035486da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,8 +9,8 @@ keywords.workspace = true edition.workspace = true [dependencies] -auto_impl.workspace = true -ethereum.workspace = true +auto_impl = "1.0" +ethereum = { version = "0.15", default-features = false } log = { version = "0.4", default-features = false } primitive-types = { version = "0.12", default-features = false, features = ["rlp"] } rlp = { version = "0.5", default-features = false } @@ -86,11 +86,6 @@ repository = "https://github.com/sorpaas/rust-evm" keywords = ["no_std", "ethereum"] edition = "2021" -[workspace.dependencies] -auto_impl = "1.0" -ethereum = { version = "0.15", default-features = false } -primitive-types = { version = "0.12", default-features = false } - [workspace] resolver = "2" members = [ diff --git a/core/Cargo.toml b/core/Cargo.toml index bd31aba51..ff424b7de 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -10,7 +10,7 @@ repository.workspace = true [dependencies] log = { version = "0.4", optional = true } -primitive-types.workspace = true +primitive-types = { version = "0.12", default-features = false } scale-codec = { package = "parity-scale-codec", version = "3.2", default-features = false, features = ["derive", "full"], optional = true } scale-info = { version = "2.3", default-features = false, features = ["derive"], optional = true } serde = { version = "1.0", default-features = false, features = ["derive"], optional = true } diff --git a/evm-tests/jsontests/Cargo.toml b/evm-tests/jsontests/Cargo.toml index 7e035bbc7..463cd17f1 100644 --- a/evm-tests/jsontests/Cargo.toml +++ b/evm-tests/jsontests/Cargo.toml @@ -1,17 +1,17 @@ [package] name = "evm-jsontests" -version = "0.43.0" +version.workspace = true license = "GPL-3.0" -authors = ["Aurora Labs ", "Wei Tang ", "Parity Technologies "] -description = "SputnikVM - a Portable Blockchain Virtual Machine" -repository = "https://github.com/sorpaas/rust-evm" -keywords = ["no_std", "ethereum"] -edition = "2021" +authors.workspace = true +description = "EVM jso tests" +repository.workspace = true +keywords.workspace = true +edition.workspace = true [dependencies] evm = { path = "../..", version = "0.43" } -ethereum.workspace = true -primitive-types.workspace = true +ethereum = "0.15.0" +primitive-types = "0.12" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" hex = "0.4" diff --git a/gasometer/Cargo.toml b/gasometer/Cargo.toml index fd58aa41a..859241974 100644 --- a/gasometer/Cargo.toml +++ b/gasometer/Cargo.toml @@ -11,7 +11,7 @@ repository.workspace = true [dependencies] environmental = { version = "1.1.2", default-features = false, optional = true } log = { version = "0.4", optional = true } -primitive-types.workspace = true +primitive-types = { version = "0.12", default-features = false } evm-core = { version = "0.43", path = "../core", default-features = false } evm-runtime = { version = "0.43", path = "../runtime", default-features = false } diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 4dfd5ed14..12937e52e 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -9,9 +9,9 @@ description.workspace = true repository.workspace = true [dependencies] -auto_impl.workspace = true +auto_impl = "1.0" environmental = { version = "1.1", default-features = false, optional = true } -primitive-types.workspace = true +primitive-types = { version = "0.12", default-features = false } sha3 = { version = "0.10", default-features = false } evm-core = { version = "0.43", path = "../core", default-features = false } From 5d11ae75a4ea243db5031c3a8f1c1c5b877a1ccd Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Tue, 18 Jun 2024 10:50:14 +0200 Subject: [PATCH 4/5] Set ethereum/tests to v13.3 --- .github/workflows/rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 4a8cec61e..e5292b3c6 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -50,7 +50,7 @@ jobs: with: repository: ethereum/tests path: ethtests - ref: v13.2 + ref: v13.3 submodules: recursive fetch-depth: 1 From 74af9b66eb9506602602a1fca039bd86fc9480b4 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Wed, 19 Jun 2024 02:23:23 +0200 Subject: [PATCH 5/5] Fixed typos --- evm-tests/jsontests/Cargo.toml | 2 +- runtime/src/handler.rs | 2 +- src/backend/mod.rs | 2 +- src/executor/stack/executor.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/evm-tests/jsontests/Cargo.toml b/evm-tests/jsontests/Cargo.toml index 463cd17f1..924eca292 100644 --- a/evm-tests/jsontests/Cargo.toml +++ b/evm-tests/jsontests/Cargo.toml @@ -3,7 +3,7 @@ name = "evm-jsontests" version.workspace = true license = "GPL-3.0" authors.workspace = true -description = "EVM jso tests" +description = "EVM json tests" repository.workspace = true keywords.workspace = true edition.workspace = true diff --git a/runtime/src/handler.rs b/runtime/src/handler.rs index 61ac034df..648fc888b 100644 --- a/runtime/src/handler.rs +++ b/runtime/src/handler.rs @@ -35,7 +35,7 @@ pub trait Handler { fn code(&self, address: H160) -> Vec; /// Get storage value of address at index. fn storage(&self, address: H160, index: H256) -> H256; - /// Check is storage of address empty. + /// Check if the storage of the address is empty. fn is_empty_storage(&self, address: H160) -> bool; /// Get original storage value of address at index. fn original_storage(&self, address: H160, index: H256) -> H256; diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 3a0a4482c..935d05646 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -82,7 +82,7 @@ pub trait Backend { fn code(&self, address: H160) -> Vec; /// Get storage value of address at index. fn storage(&self, address: H160, index: H256) -> H256; - /// Check is storage of address empty. + /// Check if the storage of the address is empty. fn is_empty_storage(&self, address: H160) -> bool; /// Get original storage value of address at index, if available. fn original_storage(&self, address: H160, index: H256) -> Option; diff --git a/src/executor/stack/executor.rs b/src/executor/stack/executor.rs index a1ccfd6d1..98d287361 100644 --- a/src/executor/stack/executor.rs +++ b/src/executor/stack/executor.rs @@ -703,7 +703,7 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> self.state.basic(address).nonce } - /// Check is an existing account the "create collision". + /// Check if the existing account is "create collision". /// [EIP-7610](https://eips.ethereum.org/EIPS/eip-7610) pub fn is_create_collision(&self, address: H160) -> bool { self.code_size(address) != U256::zero()