Skip to content

Commit

Permalink
Feat: EIP-7610 - non-empty storage create collision and upgrade evm…
Browse files Browse the repository at this point in the history
…-tests (#46)

* Added EIP-7610 implementation - create collision

* Updated Cargo rules

* Updated cargo rules and dependencies

* Set ethereum/tests to v13.3

* Fixed typos
  • Loading branch information
mrLSD authored Jun 19, 2024
1 parent 58f7b84 commit 91ea85d
Show file tree
Hide file tree
Showing 12 changed files with 85 additions and 55 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ jobs:
with:
repository: ethereum/tests
path: ethtests
ref: v13.2
ref: v13.3
submodules: recursive
fetch-depth: 1

- name: Run Ethereum state tests
run: |
Expand Down
30 changes: 20 additions & 10 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[package]
name = "evm"
version = "0.42.0"
license = "Apache-2.0"
authors = ["Wei Tang <hi@that.world>", "Parity Technologies <admin@parity.io>"]
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"
Expand All @@ -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"
Expand Down Expand Up @@ -77,7 +77,17 @@ force-debug = [
create-fixed = []
print-debug = ["evm-gasometer/print-debug"]

[workspace.package]
version = "0.43.0"
license = "Apache-2.0"
authors = ["Aurora Labs <hello@aurora.dev>", "Wei Tang <hi@that.world>", "Parity Technologies <admin@parity.io>"]
description = "Portable Ethereum Virtual Machine implementation written in pure Rust."
repository = "https://github.com/sorpaas/rust-evm"
keywords = ["no_std", "ethereum"]
edition = "2021"

[workspace]
resolver = "2"
members = [
"core",
"gasometer",
Expand Down
14 changes: 7 additions & 7 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[package]
name = "evm-core"
version = "0.42.0"
license = "Apache-2.0"
authors = ["Wei Tang <hi@that.world>", "Parity Technologies <admin@parity.io>"]
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 }
Expand Down
14 changes: 7 additions & 7 deletions evm-tests/jsontests/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
[package]
name = "evm-jsontests"
version = "0.42.0"
version.workspace = true
license = "GPL-3.0"
authors = ["Aurora Labs <hello@aurora.dev>", "Wei Tang <hi@that.world>", "Parity Technologies <admin@parity.io>"]
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 json tests"
repository.workspace = true
keywords.workspace = true
edition.workspace = true

[dependencies]
evm = { path = "../.." }
evm = { path = "../..", version = "0.43" }
ethereum = "0.15.0"
primitive-types = "0.12"
serde = { version = "1.0", features = ["derive"] }
Expand Down
2 changes: 1 addition & 1 deletion fuzzer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
18 changes: 9 additions & 9 deletions gasometer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
[package]
name = "evm-gasometer"
version = "0.42.0"
license = "Apache-2.0"
authors = ["Wei Tang <hi@that.world>", "Parity Technologies <admin@parity.io>"]
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 }

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"]
Expand Down
16 changes: 8 additions & 8 deletions runtime/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
[package]
name = "evm-runtime"
version = "0.42.0"
license = "Apache-2.0"
authors = ["Wei Tang <hi@that.world>", "Parity Technologies <admin@parity.io>"]
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"
environmental = { version = "1.1", default-features = false, optional = true }
primitive-types = { version = "0.12", default-features = false }
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"]
Expand Down
2 changes: 2 additions & 0 deletions runtime/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ pub trait Handler {
fn code(&self, address: H160) -> Vec<u8>;
/// Get storage value of address at index.
fn storage(&self, address: H160, index: H256) -> H256;
/// 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;

Expand Down
7 changes: 7 additions & 0 deletions src/backend/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<H256> {
Some(self.storage(address, index))
}
Expand Down
2 changes: 2 additions & 0 deletions src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ pub trait Backend {
fn code(&self, address: H160) -> Vec<u8>;
/// Get storage value of address at index.
fn storage(&self, address: H160, index: H256) -> H256;
/// 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<H256>;
/// CANCUN hard fork
Expand Down
28 changes: 16 additions & 12 deletions src/executor/stack/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,14 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet>
self.state.basic(address).nonce
}

/// 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()
|| 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 {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions src/executor/stack/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<H256> {
if let Some(value) = self.substate.known_original_storage(address) {
return Some(value);
Expand Down

0 comments on commit 91ea85d

Please sign in to comment.