From af59cf4252510007920f2e7d44bed86e7790d06a Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 26 Jun 2024 18:21:58 -0300 Subject: [PATCH 01/41] Draft --- Cargo.toml | 1 + crates/core/Cargo.toml | 2 +- crates/evm/Cargo.toml | 2 ++ crates/evm/src/lib.rs | 16 ++++++++++++++-- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 155db8f84..cfed78799 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,3 +23,4 @@ tracing-subscriber = "0.3.0" serde = "1.0.203" serde_json = "1.0.117" libmdbx = { version = "0.5.0", features = ["orm"] } +bytes = "1.6.0" diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 07846c98d..fff4cebad 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bytes = { version = "1.6.0", features = ["serde"] } +bytes = { workspace = true, features = ["serde"] } tinyvec = "1.6.0" ethereum-types = "0.14.1" serde.workspace = true diff --git a/crates/evm/Cargo.toml b/crates/evm/Cargo.toml index b2b8c45de..85e1fdeb8 100644 --- a/crates/evm/Cargo.toml +++ b/crates/evm/Cargo.toml @@ -6,3 +6,5 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +revm = "10.0.0" +bytes.workspace = true diff --git a/crates/evm/src/lib.rs b/crates/evm/src/lib.rs index 7d12d9af8..71775b503 100644 --- a/crates/evm/src/lib.rs +++ b/crates/evm/src/lib.rs @@ -1,5 +1,17 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right +use bytes::Bytes; +use revm::{primitives::{Address, ExecutionResult, Output, TxEnv, TxKind, U256}, Evm}; + +fn run_evm() { + let caller = Address([0;20].into()); + let to = Address([0;20].into()); + let code = Bytes::new(); + let mut evm = Evm::builder().modify_tx_env(|tx| { + tx.caller = caller; + tx.transact_to = TxKind::Call(to); + tx.data = code.into(); + tx.value = U256::from(0); + }).build(); + let tx_result = evm.transact().unwrap(); } #[cfg(test)] From f568b4cae9d4e4c3e4dbcca26b20764143ba4777 Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 27 Jun 2024 13:55:18 -0300 Subject: [PATCH 02/41] Add state cache --- crates/core/src/types/block.rs | 34 ++++++++++++++--- crates/evm/src/lib.rs | 67 ++++++++++++++++++++++++---------- 2 files changed, 76 insertions(+), 25 deletions(-) diff --git a/crates/core/src/types/block.rs b/crates/core/src/types/block.rs index 0b54b461c..c67547ce0 100644 --- a/crates/core/src/types/block.rs +++ b/crates/core/src/types/block.rs @@ -163,16 +163,38 @@ impl RLPEncode for EIP1559Transaction { } impl Transaction { - // pub fn nonce(&self) -> u64 { - // match self { - // Transaction::LegacyTransaction(tx) => tx.nonce, - // Transaction::EIP1559Transaction(tx) => tx.signer_nonce, - // } - // } + pub fn sender(&self) -> Address { + match self { + Transaction::LegacyTransaction(_tx) => todo!(), + Transaction::EIP1559Transaction(_tx) => todo!(), + } + } + + pub fn gas_limit(&self) -> u64 { + match self { + Transaction::LegacyTransaction(_tx) => todo!(), + Transaction::EIP1559Transaction(tx) => tx.gas_limit, + } + } + + pub fn gas_price(&self) -> u64 { + match self { + Transaction::LegacyTransaction(tx) => tx.gas_price, + Transaction::EIP1559Transaction(_tx) => todo!(), + } + } + pub fn to(&self) -> Address { match self { Transaction::LegacyTransaction(tx) => tx.to, Transaction::EIP1559Transaction(tx) => tx.destination, } } + + pub fn value(&self) -> U256 { + match self { + Transaction::LegacyTransaction(tx) => tx.value, + Transaction::EIP1559Transaction(_tx) => todo!(), + } + } } diff --git a/crates/evm/src/lib.rs b/crates/evm/src/lib.rs index a594faf0e..a40ef43fb 100644 --- a/crates/evm/src/lib.rs +++ b/crates/evm/src/lib.rs @@ -1,31 +1,60 @@ -use bytes::Bytes; -use core::types::{BlockHeader, Transaction}; +use core::{ + types::{Account, BlockHeader, Transaction}, + Address, +}; use revm::{ - primitives::{ruint::Uint, Address, BlockEnv, ExecutionResult, Output, TxEnv, TxKind, U256}, - Evm, + primitives::{BlockEnv, Bytecode, TxEnv, TxKind, U256}, + CacheState, Evm, }; +use std::collections::HashMap; +// Rename imported types for clarity +use revm::primitives::AccountInfo as RevmAccountInfo; +use revm::primitives::Address as RevmAddress; -fn run_evm(tx: &Transaction, header: &BlockHeader) { - let caller = Address([0; 20].into()); - let to = Address([0; 20].into()); - let code = Bytes::new(); +fn execute_tx(tx: &Transaction, header: &BlockHeader, pre: HashMap) { let block_env = block_env(header); let tx_env = tx_env(tx); + let cache_state = cache_state(pre); + let mut state = revm::db::State::builder() + .with_cached_prestate(cache_state) + .with_bundle_update() + .build(); let mut evm = Evm::builder() + .with_db(&mut state) .with_block_env(block_env) .with_tx_env(tx_env) .build(); let _tx_result = evm.transact().unwrap(); } +fn cache_state(pre: HashMap) -> CacheState { + let mut cache_state = revm::CacheState::new(false); + for (address, account) in pre { + let acc_info = RevmAccountInfo { + balance: U256::from_limbs(account.info.balance.0), + code_hash: account.info.code_hash.0.into(), + code: Some(Bytecode::new_raw(account.code.into())), + nonce: account.info.nonce, + }; + + let mut storage = HashMap::new(); + for (k, v) in account.storage { + storage.insert(U256::from_be_bytes(k.0), U256::from_be_bytes(v.0.into())); + } + + cache_state.insert_account_with_storage(address.to_fixed_bytes().into(), acc_info, storage); + } + cache_state +} + fn block_env(header: &BlockHeader) -> BlockEnv { BlockEnv { - number: Uint::<256, 4>::from(header.number), - coinbase: Address(header.coinbase.0.into()), - timestamp: Uint::<256, 4>::from(header.timestamp), - gas_limit: Uint::<256, 4>::from(header.gas_limit), - basefee: Uint::<256, 4>::from(header.base_fee_per_gas), - difficulty: Uint::<256, 4>::from_limbs(header.difficulty.0), + number: U256::from(header.number), + coinbase: RevmAddress(header.coinbase.0.into()), + timestamp: U256::from(header.timestamp), + gas_limit: U256::from(header.gas_limit), + basefee: U256::from(header.base_fee_per_gas), + difficulty: U256::from_limbs(header.difficulty.0), prevrandao: Some(header.prev_randao.as_fixed_bytes().into()), ..Default::default() } @@ -33,11 +62,11 @@ fn block_env(header: &BlockHeader) -> BlockEnv { fn tx_env(tx: &Transaction) -> TxEnv { TxEnv { - caller: todo!(), - gas_limit: todo!(), - gas_price: todo!(), - transact_to: todo!(), - value: todo!(), + caller: RevmAddress(tx.sender().0.into()), + gas_limit: tx.gas_limit(), + gas_price: U256::from(tx.gas_price()), + transact_to: TxKind::Call(RevmAddress(tx.to().0.into())), // Todo: handle case where this is Create + value: U256::from_limbs(tx.value().0), data: todo!(), nonce: todo!(), chain_id: todo!(), From 4d82b04642364413861f83063bab7a89a0ced1f5 Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 27 Jun 2024 14:06:52 -0300 Subject: [PATCH 03/41] Fill more tx env fields --- crates/core/src/types/block.rs | 14 ++++++++++++++ crates/evm/src/lib.rs | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/crates/core/src/types/block.rs b/crates/core/src/types/block.rs index c67547ce0..b40a9451c 100644 --- a/crates/core/src/types/block.rs +++ b/crates/core/src/types/block.rs @@ -197,4 +197,18 @@ impl Transaction { Transaction::EIP1559Transaction(_tx) => todo!(), } } + + pub fn max_priority_fee(&self) -> Option { + match self { + Transaction::LegacyTransaction(_tx) => None, + Transaction::EIP1559Transaction(tx) => Some(tx.max_priority_fee_per_gas), + } + } + + pub fn chain_id(&self) -> Option { + match self { + Transaction::LegacyTransaction(_tx) => None, + Transaction::EIP1559Transaction(tx) => Some(tx.chain_id), + } + } } diff --git a/crates/evm/src/lib.rs b/crates/evm/src/lib.rs index a40ef43fb..93e768dd4 100644 --- a/crates/evm/src/lib.rs +++ b/crates/evm/src/lib.rs @@ -69,9 +69,9 @@ fn tx_env(tx: &Transaction) -> TxEnv { value: U256::from_limbs(tx.value().0), data: todo!(), nonce: todo!(), - chain_id: todo!(), + chain_id: tx.chain_id(), access_list: todo!(), - gas_priority_fee: todo!(), + gas_priority_fee: tx.max_priority_fee(), blob_hashes: todo!(), max_fee_per_blob_gas: todo!(), } From 9c8f150c3a451513c4d69218a1ecd231b30199fb Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 27 Jun 2024 14:12:13 -0300 Subject: [PATCH 04/41] Move `Transaction` to its own module --- crates/core/src/types/block.rs | 126 --------------------------- crates/core/src/types/mod.rs | 2 + crates/core/src/types/transaction.rs | 125 ++++++++++++++++++++++++++ 3 files changed, 127 insertions(+), 126 deletions(-) create mode 100644 crates/core/src/types/transaction.rs diff --git a/crates/core/src/types/block.rs b/crates/core/src/types/block.rs index b40a9451c..b17de7ea7 100644 --- a/crates/core/src/types/block.rs +++ b/crates/core/src/types/block.rs @@ -86,129 +86,3 @@ impl RLPEncode for Withdrawal { self.amount.encode(buf); } } - -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum Transaction { - LegacyTransaction(LegacyTransaction), - EIP1559Transaction(EIP1559Transaction), -} - -impl RLPEncode for Transaction { - fn encode(&self, buf: &mut dyn bytes::BufMut) { - match self { - Transaction::LegacyTransaction(t) => t.encode(buf), - Transaction::EIP1559Transaction(t) => t.encode(buf), - }; - } -} - -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct LegacyTransaction { - nonce: U256, - gas_price: u64, - gas: u64, - to: Address, - value: U256, - data: Bytes, - v: U256, - r: U256, - s: U256, -} - -impl RLPEncode for LegacyTransaction { - fn encode(&self, buf: &mut dyn bytes::BufMut) { - self.nonce.encode(buf); - self.gas_price.encode(buf); - self.gas.encode(buf); - self.to.encode(buf); - self.value.encode(buf); - self.data.encode(buf); - self.v.encode(buf); - self.r.encode(buf); - self.s.encode(buf); - } -} - -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct EIP1559Transaction { - chain_id: u64, - signer_nonce: U256, - max_priority_fee_per_gas: u64, - max_fee_per_gas: u64, - gas_limit: u64, - destination: Address, - amount: u64, - payload: Bytes, - access_list: Vec<(Address, Vec)>, - signature_y_parity: bool, - signature_r: U256, - signature_s: U256, -} - -impl RLPEncode for EIP1559Transaction { - fn encode(&self, buf: &mut dyn bytes::BufMut) { - self.chain_id.encode(buf); - self.signer_nonce.encode(buf); - self.max_priority_fee_per_gas.encode(buf); - self.max_fee_per_gas.encode(buf); - self.gas_limit.encode(buf); - self.destination.encode(buf); - self.amount.encode(buf); - self.payload.encode(buf); - self.access_list.encode(buf); - self.signature_y_parity.encode(buf); - self.signature_r.encode(buf); - self.signature_s.encode(buf); - } -} - -impl Transaction { - pub fn sender(&self) -> Address { - match self { - Transaction::LegacyTransaction(_tx) => todo!(), - Transaction::EIP1559Transaction(_tx) => todo!(), - } - } - - pub fn gas_limit(&self) -> u64 { - match self { - Transaction::LegacyTransaction(_tx) => todo!(), - Transaction::EIP1559Transaction(tx) => tx.gas_limit, - } - } - - pub fn gas_price(&self) -> u64 { - match self { - Transaction::LegacyTransaction(tx) => tx.gas_price, - Transaction::EIP1559Transaction(_tx) => todo!(), - } - } - - pub fn to(&self) -> Address { - match self { - Transaction::LegacyTransaction(tx) => tx.to, - Transaction::EIP1559Transaction(tx) => tx.destination, - } - } - - pub fn value(&self) -> U256 { - match self { - Transaction::LegacyTransaction(tx) => tx.value, - Transaction::EIP1559Transaction(_tx) => todo!(), - } - } - - pub fn max_priority_fee(&self) -> Option { - match self { - Transaction::LegacyTransaction(_tx) => None, - Transaction::EIP1559Transaction(tx) => Some(tx.max_priority_fee_per_gas), - } - } - - pub fn chain_id(&self) -> Option { - match self { - Transaction::LegacyTransaction(_tx) => None, - Transaction::EIP1559Transaction(tx) => Some(tx.chain_id), - } - } -} diff --git a/crates/core/src/types/mod.rs b/crates/core/src/types/mod.rs index 8690cf36e..b4585fe6b 100644 --- a/crates/core/src/types/mod.rs +++ b/crates/core/src/types/mod.rs @@ -1,7 +1,9 @@ mod account; mod block; mod genesis; +mod transaction; pub use account::*; pub use block::*; pub use genesis::*; +pub use transaction::*; diff --git a/crates/core/src/types/transaction.rs b/crates/core/src/types/transaction.rs new file mode 100644 index 000000000..b52ae9c52 --- /dev/null +++ b/crates/core/src/types/transaction.rs @@ -0,0 +1,125 @@ +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum Transaction { + LegacyTransaction(LegacyTransaction), + EIP1559Transaction(EIP1559Transaction), +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct LegacyTransaction { + nonce: U256, + gas_price: u64, + gas: u64, + to: Address, + value: U256, + data: Bytes, + v: U256, + r: U256, + s: U256, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct EIP1559Transaction { + chain_id: u64, + signer_nonce: U256, + max_priority_fee_per_gas: u64, + max_fee_per_gas: u64, + gas_limit: u64, + destination: Address, + amount: u64, + payload: Bytes, + access_list: Vec<(Address, Vec)>, + signature_y_parity: bool, + signature_r: U256, + signature_s: U256, +} + +impl RLPEncode for Transaction { + fn encode(&self, buf: &mut dyn bytes::BufMut) { + match self { + Transaction::LegacyTransaction(t) => t.encode(buf), + Transaction::EIP1559Transaction(t) => t.encode(buf), + }; + } +} + +impl RLPEncode for LegacyTransaction { + fn encode(&self, buf: &mut dyn bytes::BufMut) { + self.nonce.encode(buf); + self.gas_price.encode(buf); + self.gas.encode(buf); + self.to.encode(buf); + self.value.encode(buf); + self.data.encode(buf); + self.v.encode(buf); + self.r.encode(buf); + self.s.encode(buf); + } +} + +impl RLPEncode for EIP1559Transaction { + fn encode(&self, buf: &mut dyn bytes::BufMut) { + self.chain_id.encode(buf); + self.signer_nonce.encode(buf); + self.max_priority_fee_per_gas.encode(buf); + self.max_fee_per_gas.encode(buf); + self.gas_limit.encode(buf); + self.destination.encode(buf); + self.amount.encode(buf); + self.payload.encode(buf); + self.access_list.encode(buf); + self.signature_y_parity.encode(buf); + self.signature_r.encode(buf); + self.signature_s.encode(buf); + } +} + +impl Transaction { + pub fn sender(&self) -> Address { + match self { + Transaction::LegacyTransaction(_tx) => todo!(), + Transaction::EIP1559Transaction(_tx) => todo!(), + } + } + + pub fn gas_limit(&self) -> u64 { + match self { + Transaction::LegacyTransaction(_tx) => todo!(), + Transaction::EIP1559Transaction(tx) => tx.gas_limit, + } + } + + pub fn gas_price(&self) -> u64 { + match self { + Transaction::LegacyTransaction(tx) => tx.gas_price, + Transaction::EIP1559Transaction(_tx) => todo!(), + } + } + + pub fn to(&self) -> Address { + match self { + Transaction::LegacyTransaction(tx) => tx.to, + Transaction::EIP1559Transaction(tx) => tx.destination, + } + } + + pub fn value(&self) -> U256 { + match self { + Transaction::LegacyTransaction(tx) => tx.value, + Transaction::EIP1559Transaction(_tx) => todo!(), + } + } + + pub fn max_priority_fee(&self) -> Option { + match self { + Transaction::LegacyTransaction(_tx) => None, + Transaction::EIP1559Transaction(tx) => Some(tx.max_priority_fee_per_gas), + } + } + + pub fn chain_id(&self) -> Option { + match self { + Transaction::LegacyTransaction(_tx) => None, + Transaction::EIP1559Transaction(tx) => Some(tx.chain_id), + } + } +} From d48b3f65547b78527e629c636b4f1f174aa48c70 Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 27 Jun 2024 14:35:32 -0300 Subject: [PATCH 05/41] Update crate name + add access list --- crates/core/src/types/block.rs | 2 ++ crates/core/src/types/transaction.rs | 12 ++++++++++++ crates/evm/Cargo.toml | 2 +- crates/evm/src/lib.rs | 15 ++++++++++++--- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/crates/core/src/types/block.rs b/crates/core/src/types/block.rs index b17de7ea7..9d4d1a85e 100644 --- a/crates/core/src/types/block.rs +++ b/crates/core/src/types/block.rs @@ -1,6 +1,8 @@ use crate::{rlp::encode::RLPEncode, Address, H256, U256}; use bytes::Bytes; +use super::Transaction; + pub type BlockNumber = u64; pub type Bloom = [u8; 256]; diff --git a/crates/core/src/types/transaction.rs b/crates/core/src/types/transaction.rs index b52ae9c52..e5dd66dad 100644 --- a/crates/core/src/types/transaction.rs +++ b/crates/core/src/types/transaction.rs @@ -1,3 +1,8 @@ +use bytes::Bytes; +use ethereum_types::{Address, H256, U256}; + +use crate::rlp::encode::RLPEncode; + #[derive(Clone, Debug, PartialEq, Eq)] pub enum Transaction { LegacyTransaction(LegacyTransaction), @@ -122,4 +127,11 @@ impl Transaction { Transaction::EIP1559Transaction(tx) => Some(tx.chain_id), } } + + pub fn access_list(&self) -> Vec<(Address, Vec)> { + match self { + Transaction::LegacyTransaction(_tx) => Vec::new(), + Transaction::EIP1559Transaction(tx) => tx.access_list.clone(), + } + } } diff --git a/crates/evm/Cargo.toml b/crates/evm/Cargo.toml index d60d14f96..137068e3d 100644 --- a/crates/evm/Cargo.toml +++ b/crates/evm/Cargo.toml @@ -8,4 +8,4 @@ edition = "2021" [dependencies] revm = "10.0.0" bytes.workspace = true -core.workspace = true +ethrex-core.workspace = true diff --git a/crates/evm/src/lib.rs b/crates/evm/src/lib.rs index 93e768dd4..093593b5c 100644 --- a/crates/evm/src/lib.rs +++ b/crates/evm/src/lib.rs @@ -1,4 +1,4 @@ -use core::{ +use ethrex_core::{ types::{Account, BlockHeader, Transaction}, Address, }; @@ -70,8 +70,17 @@ fn tx_env(tx: &Transaction) -> TxEnv { data: todo!(), nonce: todo!(), chain_id: tx.chain_id(), - access_list: todo!(), - gas_priority_fee: tx.max_priority_fee(), + access_list: tx + .access_list() + .into_iter() + .map(|(addr, list)| { + ( + RevmAddress(addr.0.into()), + list.into_iter().map(|a| U256::from_be_bytes(a.0)).collect(), + ) + }) + .collect(), + gas_priority_fee: tx.max_priority_fee().map(U256::from), blob_hashes: todo!(), max_fee_per_blob_gas: todo!(), } From 0423796924507efb149789b4e1bca50cad3ce69f Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 27 Jun 2024 15:09:22 -0300 Subject: [PATCH 06/41] Add nonce and external handler --- crates/core/src/types/transaction.rs | 11 +++++++++-- crates/evm/Cargo.toml | 2 +- crates/evm/src/lib.rs | 20 +++++++++++++++----- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/crates/core/src/types/transaction.rs b/crates/core/src/types/transaction.rs index e5dd66dad..a8d1d2372 100644 --- a/crates/core/src/types/transaction.rs +++ b/crates/core/src/types/transaction.rs @@ -11,7 +11,7 @@ pub enum Transaction { #[derive(Clone, Debug, PartialEq, Eq)] pub struct LegacyTransaction { - nonce: U256, + nonce: u64, gas_price: u64, gas: u64, to: Address, @@ -25,7 +25,7 @@ pub struct LegacyTransaction { #[derive(Clone, Debug, PartialEq, Eq)] pub struct EIP1559Transaction { chain_id: u64, - signer_nonce: U256, + signer_nonce: u64, max_priority_fee_per_gas: u64, max_fee_per_gas: u64, gas_limit: u64, @@ -134,4 +134,11 @@ impl Transaction { Transaction::EIP1559Transaction(tx) => tx.access_list.clone(), } } + + pub fn nonce(&self) -> u64 { + match self { + Transaction::LegacyTransaction(tx) => tx.nonce, + Transaction::EIP1559Transaction(tx) => tx.signer_nonce, + } + } } diff --git a/crates/evm/Cargo.toml b/crates/evm/Cargo.toml index 137068e3d..d7f0ed390 100644 --- a/crates/evm/Cargo.toml +++ b/crates/evm/Cargo.toml @@ -6,6 +6,6 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -revm = "10.0.0" +revm = { version = "10.0.0", features = ["serde", "std", "serde-json"] } bytes.workspace = true ethrex-core.workspace = true diff --git a/crates/evm/src/lib.rs b/crates/evm/src/lib.rs index 093593b5c..141d37bf6 100644 --- a/crates/evm/src/lib.rs +++ b/crates/evm/src/lib.rs @@ -3,7 +3,9 @@ use ethrex_core::{ Address, }; use revm::{ - primitives::{BlockEnv, Bytecode, TxEnv, TxKind, U256}, + inspector_handle_register, + inspectors::TracerEip3155, + primitives::{BlockEnv, Bytecode, SpecId, TxEnv, TxKind, U256}, CacheState, Evm, }; use std::collections::HashMap; @@ -11,7 +13,12 @@ use std::collections::HashMap; use revm::primitives::AccountInfo as RevmAccountInfo; use revm::primitives::Address as RevmAddress; -fn execute_tx(tx: &Transaction, header: &BlockHeader, pre: HashMap) { +fn execute_tx( + tx: &Transaction, + header: &BlockHeader, + pre: HashMap, + spec_id: SpecId, +) { let block_env = block_env(header); let tx_env = tx_env(tx); let cache_state = cache_state(pre); @@ -23,6 +30,10 @@ fn execute_tx(tx: &Transaction, header: &BlockHeader, pre: HashMap TxEnv { transact_to: TxKind::Call(RevmAddress(tx.to().0.into())), // Todo: handle case where this is Create value: U256::from_limbs(tx.value().0), data: todo!(), - nonce: todo!(), + nonce: Some(tx.nonce()), chain_id: tx.chain_id(), access_list: tx .access_list() @@ -81,8 +92,7 @@ fn tx_env(tx: &Transaction) -> TxEnv { }) .collect(), gas_priority_fee: tx.max_priority_fee().map(U256::from), - blob_hashes: todo!(), - max_fee_per_blob_gas: todo!(), + ..Default::default() } } From 0e7739e2b3debd9ffdc29beb36e88b3aa0b4a460 Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 27 Jun 2024 15:46:44 -0300 Subject: [PATCH 07/41] Fill some todos --- crates/core/src/types/transaction.rs | 15 +++++++++++---- crates/evm/src/lib.rs | 9 ++------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/crates/core/src/types/transaction.rs b/crates/core/src/types/transaction.rs index a8d1d2372..3664a86d2 100644 --- a/crates/core/src/types/transaction.rs +++ b/crates/core/src/types/transaction.rs @@ -30,7 +30,7 @@ pub struct EIP1559Transaction { max_fee_per_gas: u64, gas_limit: u64, destination: Address, - amount: u64, + amount: U256, payload: Bytes, access_list: Vec<(Address, Vec)>, signature_y_parity: bool, @@ -88,7 +88,7 @@ impl Transaction { pub fn gas_limit(&self) -> u64 { match self { - Transaction::LegacyTransaction(_tx) => todo!(), + Transaction::LegacyTransaction(tx) => tx.gas_price, Transaction::EIP1559Transaction(tx) => tx.gas_limit, } } @@ -96,7 +96,7 @@ impl Transaction { pub fn gas_price(&self) -> u64 { match self { Transaction::LegacyTransaction(tx) => tx.gas_price, - Transaction::EIP1559Transaction(_tx) => todo!(), + Transaction::EIP1559Transaction(tx) => tx.max_fee_per_gas, } } @@ -110,7 +110,7 @@ impl Transaction { pub fn value(&self) -> U256 { match self { Transaction::LegacyTransaction(tx) => tx.value, - Transaction::EIP1559Transaction(_tx) => todo!(), + Transaction::EIP1559Transaction(tx) => tx.amount, } } @@ -141,4 +141,11 @@ impl Transaction { Transaction::EIP1559Transaction(tx) => tx.signer_nonce, } } + + pub fn data(&self) -> &Bytes { + match self { + Transaction::LegacyTransaction(tx) => &tx.data, + Transaction::EIP1559Transaction(tx) => &tx.payload, + } + } } diff --git a/crates/evm/src/lib.rs b/crates/evm/src/lib.rs index 141d37bf6..cf53f81a8 100644 --- a/crates/evm/src/lib.rs +++ b/crates/evm/src/lib.rs @@ -13,7 +13,7 @@ use std::collections::HashMap; use revm::primitives::AccountInfo as RevmAccountInfo; use revm::primitives::Address as RevmAddress; -fn execute_tx( +pub fn execute_tx( tx: &Transaction, header: &BlockHeader, pre: HashMap, @@ -78,7 +78,7 @@ fn tx_env(tx: &Transaction) -> TxEnv { gas_price: U256::from(tx.gas_price()), transact_to: TxKind::Call(RevmAddress(tx.to().0.into())), // Todo: handle case where this is Create value: U256::from_limbs(tx.value().0), - data: todo!(), + data: tx.data().clone().into(), nonce: Some(tx.nonce()), chain_id: tx.chain_id(), access_list: tx @@ -95,8 +95,3 @@ fn tx_env(tx: &Transaction) -> TxEnv { ..Default::default() } } - -#[cfg(test)] -mod tests { - use super::*; -} From e854ae5a7cdbf92b2a5dc5aa86f78c0f79e651a4 Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 27 Jun 2024 16:02:17 -0300 Subject: [PATCH 08/41] Convert eftests header to ethrex block header --- crates/core/src/types/block.rs | 2 +- ef_tests/src/types.rs | 31 ++++++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/crates/core/src/types/block.rs b/crates/core/src/types/block.rs index 9d4d1a85e..0bc77573f 100644 --- a/crates/core/src/types/block.rs +++ b/crates/core/src/types/block.rs @@ -10,7 +10,7 @@ pub type Bloom = [u8; 256]; #[derive(Clone, Debug, PartialEq, Eq)] pub struct BlockHeader { pub parent_hash: H256, - pub ommers_hash: H256, + pub ommers_hash: H256, // ommer = uncle pub coinbase: Address, pub state_root: H256, pub transactions_root: H256, diff --git a/ef_tests/src/types.rs b/ef_tests/src/types.rs index 4f7ca078a..ef85d4eb6 100644 --- a/ef_tests/src/types.rs +++ b/ef_tests/src/types.rs @@ -1,4 +1,4 @@ -use ethrex_core::{Address, Bloom, H256, U256, U64}; +use ethrex_core::{types::BlockHeader, Address, Bloom, H256, U256, U64}; use revm::primitives::Bytes; use serde::{Deserialize, Serialize}; @@ -112,3 +112,32 @@ pub struct Transaction { pub sender: Address, pub to: Address, } + +// Conversions between EFtests & Ethrex types + +impl Into for Header { + fn into(self) -> BlockHeader { + BlockHeader { + parent_hash: self.parent_hash, + ommers_hash: self.uncle_hash, + coinbase: self.coinbase, + state_root: self.state_root, + transactions_root: self.transactions_trie, + receipt_root: self.receipt_trie, + logs_bloom: self.bloom.into(), + difficulty: self.difficulty, + number: self.number.as_u64(), + gas_limit: self.gas_limit.as_u64(), + gas_used: self.gas_used.as_u64(), + timestamp: self.timestamp.as_u64(), + extra_data: self.extra_data.0, + prev_randao: self.mix_hash, + nonce: self.nonce.as_u64(), + base_fee_per_gas: self.base_fee_per_gas.unwrap().as_u64(), + withdrawals_root: self.withdrawals_root.unwrap(), + blob_gas_used: self.blob_gas_used.unwrap().as_u64(), + excess_blob_gas: self.excess_blob_gas.unwrap().as_u64(), + parent_beacon_block_root: self.parent_beacon_block_root.unwrap(), + } + } +} From 639b74e16ac0d6673d74100f9c8a2feb7cdaa237 Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 27 Jun 2024 16:16:58 -0300 Subject: [PATCH 09/41] Convert eftests tx to ethrex tx --- crates/core/src/types/transaction.rs | 42 ++++++++++++++-------------- ef_tests/src/types.rs | 23 +++++++++++++++ 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/crates/core/src/types/transaction.rs b/crates/core/src/types/transaction.rs index 3664a86d2..9abf1e232 100644 --- a/crates/core/src/types/transaction.rs +++ b/crates/core/src/types/transaction.rs @@ -11,31 +11,31 @@ pub enum Transaction { #[derive(Clone, Debug, PartialEq, Eq)] pub struct LegacyTransaction { - nonce: u64, - gas_price: u64, - gas: u64, - to: Address, - value: U256, - data: Bytes, - v: U256, - r: U256, - s: U256, + pub nonce: u64, + pub gas_price: u64, + pub gas: u64, + pub to: Address, + pub value: U256, + pub data: Bytes, + pub v: U256, + pub r: U256, + pub s: U256, } #[derive(Clone, Debug, PartialEq, Eq)] pub struct EIP1559Transaction { - chain_id: u64, - signer_nonce: u64, - max_priority_fee_per_gas: u64, - max_fee_per_gas: u64, - gas_limit: u64, - destination: Address, - amount: U256, - payload: Bytes, - access_list: Vec<(Address, Vec)>, - signature_y_parity: bool, - signature_r: U256, - signature_s: U256, + pub chain_id: u64, + pub signer_nonce: u64, + pub max_priority_fee_per_gas: u64, + pub max_fee_per_gas: u64, + pub gas_limit: u64, + pub destination: Address, + pub amount: U256, + pub payload: Bytes, + pub access_list: Vec<(Address, Vec)>, + pub signature_y_parity: bool, + pub signature_r: U256, + pub signature_s: U256, } impl RLPEncode for Transaction { diff --git a/ef_tests/src/types.rs b/ef_tests/src/types.rs index ef85d4eb6..84b8b4000 100644 --- a/ef_tests/src/types.rs +++ b/ef_tests/src/types.rs @@ -1,3 +1,4 @@ +use ethrex_core::types::{EIP1559Transaction, Transaction as EthrexTransacion}; use ethrex_core::{types::BlockHeader, Address, Bloom, H256, U256, U64}; use revm::primitives::Bytes; @@ -141,3 +142,25 @@ impl Into for Header { } } } + +impl Into for Transaction { + fn into(self) -> EthrexTransacion { + EthrexTransacion::EIP1559Transaction(EIP1559Transaction { + // Note: gas_price is not used in this conversion as it is not part of EIP1559Transaction, this could be a problem + chain_id: self.chain_id.unwrap().as_u64(), + signer_nonce: self.nonce.as_u64(), + max_priority_fee_per_gas: self.max_priority_fee_per_gas.unwrap().as_u64(), + max_fee_per_gas: self.max_fee_per_gas.unwrap().as_u64(), + gas_limit: self.gas_limit.as_u64(), + destination: self.to, + amount: self.value, + payload: self.data.0, + access_list: self.access_list.unwrap().into_iter().map(|item| { + (item.address, item.storage_keys) + }).collect(), + signature_y_parity: self.v.as_u64() != 0, // TODO: check this + signature_r: self.r, + signature_s: self.s, + }) + } +} From ff7297f5601d0bf0d2ee91f4f03012faddfa8c1b Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 27 Jun 2024 16:26:39 -0300 Subject: [PATCH 10/41] Convert eftests account to ethrex account --- crates/core/src/types/account.rs | 2 +- ef_tests/src/types.rs | 22 +++++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/crates/core/src/types/account.rs b/crates/core/src/types/account.rs index 46f0e165d..a4df3e2df 100644 --- a/crates/core/src/types/account.rs +++ b/crates/core/src/types/account.rs @@ -36,7 +36,7 @@ impl From for Account { } } -fn code_hash(code: &Bytes) -> H256 { +pub fn code_hash(code: &Bytes) -> H256 { keccak_hash::keccak(code.as_ref()) } diff --git a/ef_tests/src/types.rs b/ef_tests/src/types.rs index 84b8b4000..0d9176fc0 100644 --- a/ef_tests/src/types.rs +++ b/ef_tests/src/types.rs @@ -1,4 +1,4 @@ -use ethrex_core::types::{EIP1559Transaction, Transaction as EthrexTransacion}; +use ethrex_core::types::{code_hash, Account as EthrexAccount, AccountInfo, EIP1559Transaction, Transaction as EthrexTransacion}; use ethrex_core::{types::BlockHeader, Address, Bloom, H256, U256, U64}; use revm::primitives::Bytes; @@ -164,3 +164,23 @@ impl Into for Transaction { }) } } + +impl Into for Account { + fn into(self) -> EthrexAccount { + EthrexAccount { + info: AccountInfo { + code_hash: code_hash(&self.code), + balance: self.balance, + nonce: self.nonce.as_u64(), + }, + code: self.code.0, + storage: self.storage.into_iter().map(|(k, v)| { + let mut k_bytes = [0;32]; + let mut v_bytes = [0;32]; + k.to_big_endian(&mut k_bytes); + v.to_big_endian(&mut v_bytes); + (H256(k_bytes), H256(v_bytes)) + }).collect(), + } + } +} From 5e1d06bfafd5820e5eb869825d9d639c634e05ef Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 27 Jun 2024 16:44:48 -0300 Subject: [PATCH 11/41] Replace evm code in eftests with ethrex-evm import --- crates/evm/src/lib.rs | 12 +++--- ef_tests/Cargo.toml | 3 +- ef_tests/src/evm.rs | 94 ----------------------------------------- ef_tests/src/lib.rs | 1 - ef_tests/src/types.rs | 47 ++++++++++++--------- ef_tests/tests/tests.rs | 11 ++++- 6 files changed, 46 insertions(+), 122 deletions(-) delete mode 100644 ef_tests/src/evm.rs diff --git a/crates/evm/src/lib.rs b/crates/evm/src/lib.rs index cf53f81a8..0ef414af0 100644 --- a/crates/evm/src/lib.rs +++ b/crates/evm/src/lib.rs @@ -5,18 +5,20 @@ use ethrex_core::{ use revm::{ inspector_handle_register, inspectors::TracerEip3155, - primitives::{BlockEnv, Bytecode, SpecId, TxEnv, TxKind, U256}, + primitives::{BlockEnv, Bytecode, TxEnv, TxKind, U256}, CacheState, Evm, }; use std::collections::HashMap; // Rename imported types for clarity use revm::primitives::AccountInfo as RevmAccountInfo; use revm::primitives::Address as RevmAddress; +// Export needed types +pub use revm::primitives::SpecId; pub fn execute_tx( tx: &Transaction, header: &BlockHeader, - pre: HashMap, + pre: &HashMap, // TODO: Modify this type when we have a defined State structure spec_id: SpecId, ) { let block_env = block_env(header); @@ -38,18 +40,18 @@ pub fn execute_tx( let _tx_result = evm.transact().unwrap(); } -fn cache_state(pre: HashMap) -> CacheState { +fn cache_state(pre: &HashMap) -> CacheState { let mut cache_state = revm::CacheState::new(false); for (address, account) in pre { let acc_info = RevmAccountInfo { balance: U256::from_limbs(account.info.balance.0), code_hash: account.info.code_hash.0.into(), - code: Some(Bytecode::new_raw(account.code.into())), + code: Some(Bytecode::new_raw(account.code.clone().into())), nonce: account.info.nonce, }; let mut storage = HashMap::new(); - for (k, v) in account.storage { + for (k, v) in &account.storage { storage.insert(U256::from_be_bytes(k.0), U256::from_be_bytes(v.0.into())); } diff --git a/ef_tests/Cargo.toml b/ef_tests/Cargo.toml index 4f7db70e0..4f5845a93 100644 --- a/ef_tests/Cargo.toml +++ b/ef_tests/Cargo.toml @@ -4,7 +4,8 @@ version.workspace = true edition.workspace = true [dependencies] -revm = { version = "9.0.0", features = ["serde", "std", "serde-json"] } ethrex-core.workspace = true +ethrex-evm.workspace = true serde.workspace = true serde_json.workspace = true +bytes.workspace = true diff --git a/ef_tests/src/evm.rs b/ef_tests/src/evm.rs deleted file mode 100644 index 5c5f29c21..000000000 --- a/ef_tests/src/evm.rs +++ /dev/null @@ -1,94 +0,0 @@ -use std::{collections::HashMap, io::stderr}; - -use ethrex_core::{Address, U256}; -use revm::{ - inspector_handle_register, - inspectors::TracerEip3155, - primitives::{ - keccak256, AccountInfo, Bytecode, Env, ExecutionResult, FixedBytes, SpecId, TransactTo, - U256 as AlloyU256, - }, - Evm, -}; - -use crate::types::{Account, Header, Transaction}; - -pub fn execute_transaction( - block: &Header, - transaction: &Transaction, - pre: HashMap, -) -> ExecutionResult { - let mut env = Box::::default(); - - env.block.number = to_alloy_bytes(block.number); - env.block.coinbase = block.coinbase.to_fixed_bytes().into(); - env.block.timestamp = to_alloy_bytes(block.timestamp); - env.block.gas_limit = to_alloy_bytes(block.gas_limit); - env.block.basefee = AlloyU256::ZERO; - env.block.difficulty = AlloyU256::ZERO; - env.block.prevrandao = Some(block.mix_hash.as_fixed_bytes().into()); - - env.tx.caller = transaction.sender.to_fixed_bytes().into(); - - env.tx.gas_price = to_alloy_bytes( - transaction - .gas_price - .or(transaction.max_fee_per_gas) - .unwrap_or_default(), - ); - env.tx.gas_priority_fee = transaction.max_priority_fee_per_gas.map(to_alloy_bytes); - - let spec_id = SpecId::CANCUN; - - env.tx.gas_limit = transaction.gas_limit.as_u64(); - - env.tx.data = transaction.data.clone(); - env.tx.value = to_alloy_bytes(transaction.value); - - env.tx.transact_to = TransactTo::Call(transaction.to.to_fixed_bytes().into()); - - let mut cache_state = revm::CacheState::new(false); - for (address, info) in pre { - let acc_info = AccountInfo { - balance: to_alloy_bytes(info.balance), - code_hash: keccak256(&info.code), - code: Some(Bytecode::new_raw(info.code)), - nonce: info.nonce.as_u64(), - }; - - let mut storage = HashMap::new(); - for (k, v) in info.storage { - storage.insert(to_alloy_bytes(k), to_alloy_bytes(v)); - } - - cache_state.insert_account_with_storage(address.to_fixed_bytes().into(), acc_info, storage); - } - - let cache = cache_state.clone(); - let mut state = revm::db::State::builder() - .with_cached_prestate(cache) - .with_bundle_update() - .build(); - let evm = Evm::builder() - .with_db(&mut state) - .modify_env(|e| e.clone_from(&env)) - .with_spec_id(spec_id) - .build(); - - let mut evm = evm - .modify() - .reset_handler_with_external_context( - TracerEip3155::new(Box::new(stderr())).without_summary(), - ) - .append_handler_register(inspector_handle_register) - .build(); - - evm.transact_commit().unwrap() -} - -fn to_alloy_bytes(eth_byte: U256) -> AlloyU256 { - let mut bytes = [0u8; 32]; - eth_byte.to_big_endian(&mut bytes); - let fixed_bytes: FixedBytes<32> = bytes.into(); - fixed_bytes.into() -} diff --git a/ef_tests/src/lib.rs b/ef_tests/src/lib.rs index 1dc5a8894..cd408564e 100644 --- a/ef_tests/src/lib.rs +++ b/ef_tests/src/lib.rs @@ -1,2 +1 @@ -pub mod evm; pub mod types; diff --git a/ef_tests/src/types.rs b/ef_tests/src/types.rs index 0d9176fc0..571c82307 100644 --- a/ef_tests/src/types.rs +++ b/ef_tests/src/types.rs @@ -1,7 +1,9 @@ -use ethrex_core::types::{code_hash, Account as EthrexAccount, AccountInfo, EIP1559Transaction, Transaction as EthrexTransacion}; +use bytes::Bytes; +use ethrex_core::types::{ + code_hash, Account as EthrexAccount, AccountInfo, EIP1559Transaction, + Transaction as EthrexTransacion, +}; use ethrex_core::{types::BlockHeader, Address, Bloom, H256, U256, U64}; - -use revm::primitives::Bytes; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -131,7 +133,7 @@ impl Into for Header { gas_limit: self.gas_limit.as_u64(), gas_used: self.gas_used.as_u64(), timestamp: self.timestamp.as_u64(), - extra_data: self.extra_data.0, + extra_data: self.extra_data, prev_randao: self.mix_hash, nonce: self.nonce.as_u64(), base_fee_per_gas: self.base_fee_per_gas.unwrap().as_u64(), @@ -147,17 +149,20 @@ impl Into for Transaction { fn into(self) -> EthrexTransacion { EthrexTransacion::EIP1559Transaction(EIP1559Transaction { // Note: gas_price is not used in this conversion as it is not part of EIP1559Transaction, this could be a problem - chain_id: self.chain_id.unwrap().as_u64(), + chain_id: self.chain_id.unwrap_or_default().as_u64(), // TODO: Consider converting this into Option signer_nonce: self.nonce.as_u64(), - max_priority_fee_per_gas: self.max_priority_fee_per_gas.unwrap().as_u64(), - max_fee_per_gas: self.max_fee_per_gas.unwrap().as_u64(), + max_priority_fee_per_gas: self.max_priority_fee_per_gas.unwrap_or_default().as_u64(), // TODO: Consider converting this into Option + max_fee_per_gas: self.max_fee_per_gas.unwrap_or_default().as_u64(), // TODO: Consider converting this into Option gas_limit: self.gas_limit.as_u64(), destination: self.to, amount: self.value, - payload: self.data.0, - access_list: self.access_list.unwrap().into_iter().map(|item| { - (item.address, item.storage_keys) - }).collect(), + payload: self.data, + access_list: self + .access_list + .unwrap_or_default() + .into_iter() + .map(|item| (item.address, item.storage_keys)) + .collect(), signature_y_parity: self.v.as_u64() != 0, // TODO: check this signature_r: self.r, signature_s: self.s, @@ -173,14 +178,18 @@ impl Into for Account { balance: self.balance, nonce: self.nonce.as_u64(), }, - code: self.code.0, - storage: self.storage.into_iter().map(|(k, v)| { - let mut k_bytes = [0;32]; - let mut v_bytes = [0;32]; - k.to_big_endian(&mut k_bytes); - v.to_big_endian(&mut v_bytes); - (H256(k_bytes), H256(v_bytes)) - }).collect(), + code: self.code, + storage: self + .storage + .into_iter() + .map(|(k, v)| { + let mut k_bytes = [0; 32]; + let mut v_bytes = [0; 32]; + k.to_big_endian(&mut k_bytes); + v.to_big_endian(&mut v_bytes); + (H256(k_bytes), H256(v_bytes)) + }) + .collect(), } } } diff --git a/ef_tests/tests/tests.rs b/ef_tests/tests/tests.rs index ed9c64e74..56e6cf7a0 100644 --- a/ef_tests/tests/tests.rs +++ b/ef_tests/tests/tests.rs @@ -1,4 +1,5 @@ -use ::ef_tests::{evm::execute_transaction, types::TestUnit}; +use ::ef_tests::types::TestUnit; +use ethrex_evm::{execute_tx, SpecId}; fn execute_test(test: TestUnit) { // TODO: Add support for multiple blocks and multiple transactions per block. @@ -11,7 +12,13 @@ fn execute_test(test: TestUnit) { .unwrap() .first() .unwrap(); - execute_transaction(&test.genesis_block_header, transaction, test.pre); + let pre = test.pre.into_iter().map(|(k, v)| (k, v.into())).collect(); + execute_tx( + &transaction.clone().into(), + &test.genesis_block_header.into(), + &pre, + SpecId::CANCUN, + ); } #[cfg(test)] From c1f7f538d0413095dfa1772b48e58e21b55c02e4 Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 27 Jun 2024 19:01:51 -0300 Subject: [PATCH 12/41] WIP: add address recovery --- Cargo.toml | 1 + crates/core/Cargo.toml | 2 ++ crates/core/src/types/transaction.rs | 31 ++++++++++++++++++++++++++-- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0e456e3e4..98bdc8b82 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,3 +31,4 @@ serde_json = "1.0.117" libmdbx = { version = "0.5.0", features = ["orm"] } bytes = "1.6.0" tokio = { version = "1.38.0", features = ["full"] } +k256 = "0.13.3" diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 3c7803970..1c9d9f24b 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -12,6 +12,8 @@ ethereum-types = "0.14.1" serde.workspace = true serde_json.workspace = true keccak-hash = "0.10.0" +k256 = { workspace = true, features = ["ecdsa"]} +sha3 = "0.10.8" [dev-dependencies] hex-literal = "0.4.1" diff --git a/crates/core/src/types/transaction.rs b/crates/core/src/types/transaction.rs index 9abf1e232..ef7fa9e3b 100644 --- a/crates/core/src/types/transaction.rs +++ b/crates/core/src/types/transaction.rs @@ -1,5 +1,7 @@ use bytes::Bytes; use ethereum_types::{Address, H256, U256}; +use k256::ecdsa::{RecoveryId, Signature, VerifyingKey}; +use sha3::{Digest, Keccak256}; use crate::rlp::encode::RLPEncode; @@ -81,8 +83,14 @@ impl RLPEncode for EIP1559Transaction { impl Transaction { pub fn sender(&self) -> Address { match self { - Transaction::LegacyTransaction(_tx) => todo!(), - Transaction::EIP1559Transaction(_tx) => todo!(), + Transaction::LegacyTransaction(tx) => recover_address(&tx.r, &tx.s, &tx.data), + Transaction::EIP1559Transaction(tx) => { + dbg!(recover_address( + &tx.signature_r, + &tx.signature_s, + &tx.payload + )) + } } } @@ -149,3 +157,22 @@ impl Transaction { } } } + +// TODO: Fix +fn recover_address(signature_r: &U256, signature_s: &U256, message: &Bytes) -> Address { + let mut r_bytes = [0; 32]; + let mut s_bytes = [0; 32]; + signature_r.to_big_endian(&mut r_bytes); + signature_s.to_big_endian(&mut s_bytes); + let signature = Signature::from_scalars(r_bytes, s_bytes).unwrap(); + let recid = RecoveryId::try_from(1u8).unwrap(); + let recovered_key = VerifyingKey::recover_from_digest( + Keccak256::new_with_prefix(message.as_ref()), + &signature, + recid, + ) + .unwrap(); + let state = &mut recovered_key.to_sec1_bytes()[1..]; + keccak_hash::keccak256(state); + Address::from_slice(&state[12..]) +} From f29a030e60c6b701dd1cdaf5733947b15d7bbd26 Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 28 Jun 2024 10:49:28 -0300 Subject: [PATCH 13/41] Make ef tests run: Set chain id to mainnet + use current block instead of genesis block --- ef_tests/src/types.rs | 6 ++++-- ef_tests/tests/tests.rs | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ef_tests/src/types.rs b/ef_tests/src/types.rs index 571c82307..7bdb7d9a6 100644 --- a/ef_tests/src/types.rs +++ b/ef_tests/src/types.rs @@ -147,12 +147,14 @@ impl Into for Header { impl Into for Transaction { fn into(self) -> EthrexTransacion { + dbg!(self.sender); + dbg!(&self); EthrexTransacion::EIP1559Transaction(EIP1559Transaction { // Note: gas_price is not used in this conversion as it is not part of EIP1559Transaction, this could be a problem - chain_id: self.chain_id.unwrap_or_default().as_u64(), // TODO: Consider converting this into Option + chain_id: self.chain_id.map(|id| id.as_u64()).unwrap_or(1 /*mainnet*/), // TODO: Consider converting this into Option signer_nonce: self.nonce.as_u64(), max_priority_fee_per_gas: self.max_priority_fee_per_gas.unwrap_or_default().as_u64(), // TODO: Consider converting this into Option - max_fee_per_gas: self.max_fee_per_gas.unwrap_or_default().as_u64(), // TODO: Consider converting this into Option + max_fee_per_gas: self.max_fee_per_gas.unwrap_or(self.gas_price.unwrap_or_default()).as_u64(), // TODO: Consider converting this into Option gas_limit: self.gas_limit.as_u64(), destination: self.to, amount: self.value, diff --git a/ef_tests/tests/tests.rs b/ef_tests/tests/tests.rs index 56e6cf7a0..fd76fc759 100644 --- a/ef_tests/tests/tests.rs +++ b/ef_tests/tests/tests.rs @@ -15,7 +15,7 @@ fn execute_test(test: TestUnit) { let pre = test.pre.into_iter().map(|(k, v)| (k, v.into())).collect(); execute_tx( &transaction.clone().into(), - &test.genesis_block_header.into(), + &test.blocks.first().as_ref().clone().unwrap().block_header.clone().unwrap().into(), &pre, SpecId::CANCUN, ); From 98b9eddab2097444703e63289c964525d26564e9 Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 28 Jun 2024 13:13:57 -0300 Subject: [PATCH 14/41] Update address calculation --- crates/core/Cargo.toml | 5 +++- crates/core/src/types/transaction.rs | 35 ++++++++++++++++------------ ef_tests/src/types.rs | 5 +++- ef_tests/tests/tests.rs | 11 ++++++++- 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 1c9d9f24b..7818edb5f 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -12,8 +12,11 @@ ethereum-types = "0.14.1" serde.workspace = true serde_json.workspace = true keccak-hash = "0.10.0" -k256 = { workspace = true, features = ["ecdsa"]} sha3 = "0.10.8" +secp256k1 = { version = "0.29", default-features = false, features = [ + "global-context", + "recovery", +] } [dev-dependencies] hex-literal = "0.4.1" diff --git a/crates/core/src/types/transaction.rs b/crates/core/src/types/transaction.rs index ef7fa9e3b..b7f572d2e 100644 --- a/crates/core/src/types/transaction.rs +++ b/crates/core/src/types/transaction.rs @@ -1,6 +1,6 @@ use bytes::Bytes; use ethereum_types::{Address, H256, U256}; -use k256::ecdsa::{RecoveryId, Signature, VerifyingKey}; +use secp256k1::{ecdsa::RecoveryId, Message, SECP256K1}; use sha3::{Digest, Keccak256}; use crate::rlp::encode::RLPEncode; @@ -158,21 +158,26 @@ impl Transaction { } } -// TODO: Fix fn recover_address(signature_r: &U256, signature_s: &U256, message: &Bytes) -> Address { - let mut r_bytes = [0; 32]; - let mut s_bytes = [0; 32]; - signature_r.to_big_endian(&mut r_bytes); - signature_s.to_big_endian(&mut s_bytes); - let signature = Signature::from_scalars(r_bytes, s_bytes).unwrap(); - let recid = RecoveryId::try_from(1u8).unwrap(); - let recovered_key = VerifyingKey::recover_from_digest( - Keccak256::new_with_prefix(message.as_ref()), - &signature, - recid, + // Create signature + let mut signature_bytes = [0; 64]; + signature_r.to_big_endian(&mut signature_bytes[0..32]); + signature_s.to_big_endian(&mut signature_bytes[32..]); + let signature = secp256k1::ecdsa::RecoverableSignature::from_compact( + &signature_bytes, + RecoveryId::from_i32(0).unwrap(), // TODO: use y_parrity for this ) .unwrap(); - let state = &mut recovered_key.to_sec1_bytes()[1..]; - keccak_hash::keccak256(state); - Address::from_slice(&state[12..]) + // Hash message + let message = Bytes::new(); // TODO: Fix parsing so "0x" is empty bytes + let msg_digest: [u8; 32] = Keccak256::new_with_prefix(message.as_ref()) + .finalize() + .into(); + // Recover public key + let public = SECP256K1 + .recover_ecdsa(&Message::from_digest(msg_digest), &signature) + .unwrap(); + // Hash public key to obtain address + let hash = Keccak256::new_with_prefix(&public.serialize_uncompressed()[1..]).finalize(); + Address::from_slice(&hash[12..]) } diff --git a/ef_tests/src/types.rs b/ef_tests/src/types.rs index 7bdb7d9a6..4d4777f0c 100644 --- a/ef_tests/src/types.rs +++ b/ef_tests/src/types.rs @@ -154,7 +154,10 @@ impl Into for Transaction { chain_id: self.chain_id.map(|id| id.as_u64()).unwrap_or(1 /*mainnet*/), // TODO: Consider converting this into Option signer_nonce: self.nonce.as_u64(), max_priority_fee_per_gas: self.max_priority_fee_per_gas.unwrap_or_default().as_u64(), // TODO: Consider converting this into Option - max_fee_per_gas: self.max_fee_per_gas.unwrap_or(self.gas_price.unwrap_or_default()).as_u64(), // TODO: Consider converting this into Option + max_fee_per_gas: self + .max_fee_per_gas + .unwrap_or(self.gas_price.unwrap_or_default()) + .as_u64(), // TODO: Consider converting this into Option gas_limit: self.gas_limit.as_u64(), destination: self.to, amount: self.value, diff --git a/ef_tests/tests/tests.rs b/ef_tests/tests/tests.rs index fd76fc759..42cd399be 100644 --- a/ef_tests/tests/tests.rs +++ b/ef_tests/tests/tests.rs @@ -15,7 +15,16 @@ fn execute_test(test: TestUnit) { let pre = test.pre.into_iter().map(|(k, v)| (k, v.into())).collect(); execute_tx( &transaction.clone().into(), - &test.blocks.first().as_ref().clone().unwrap().block_header.clone().unwrap().into(), + &test + .blocks + .first() + .as_ref() + .clone() + .unwrap() + .block_header + .clone() + .unwrap() + .into(), &pre, SpecId::CANCUN, ); From 2d27e43f2f2628bc0734d4d221039f91c7b60ce6 Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 28 Jun 2024 13:20:21 -0300 Subject: [PATCH 15/41] Use y parity --- crates/core/src/types/transaction.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/crates/core/src/types/transaction.rs b/crates/core/src/types/transaction.rs index b7f572d2e..7df5066ec 100644 --- a/crates/core/src/types/transaction.rs +++ b/crates/core/src/types/transaction.rs @@ -83,11 +83,12 @@ impl RLPEncode for EIP1559Transaction { impl Transaction { pub fn sender(&self) -> Address { match self { - Transaction::LegacyTransaction(tx) => recover_address(&tx.r, &tx.s, &tx.data), + Transaction::LegacyTransaction(tx) => recover_address(&tx.r, &tx.s, false, &tx.data), Transaction::EIP1559Transaction(tx) => { dbg!(recover_address( &tx.signature_r, &tx.signature_s, + tx.signature_y_parity, &tx.payload )) } @@ -158,14 +159,19 @@ impl Transaction { } } -fn recover_address(signature_r: &U256, signature_s: &U256, message: &Bytes) -> Address { +fn recover_address( + signature_r: &U256, + signature_s: &U256, + signature_y_parity: bool, + message: &Bytes, +) -> Address { // Create signature let mut signature_bytes = [0; 64]; signature_r.to_big_endian(&mut signature_bytes[0..32]); signature_s.to_big_endian(&mut signature_bytes[32..]); let signature = secp256k1::ecdsa::RecoverableSignature::from_compact( &signature_bytes, - RecoveryId::from_i32(0).unwrap(), // TODO: use y_parrity for this + RecoveryId::from_i32(signature_y_parity as i32).unwrap(), // cannot fail ) .unwrap(); // Hash message From f25208f408b81ba8cee2d13ba001809c6b751482 Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 28 Jun 2024 13:30:19 -0300 Subject: [PATCH 16/41] Fix parity calc --- ef_tests/src/types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ef_tests/src/types.rs b/ef_tests/src/types.rs index 4d4777f0c..9f2368d99 100644 --- a/ef_tests/src/types.rs +++ b/ef_tests/src/types.rs @@ -168,7 +168,7 @@ impl Into for Transaction { .into_iter() .map(|item| (item.address, item.storage_keys)) .collect(), - signature_y_parity: self.v.as_u64() != 0, // TODO: check this + signature_y_parity: self.v.as_u64().saturating_sub(27) != 0, signature_r: self.r, signature_s: self.s, }) From 890cff8c152ae6954ad6320fb0ba2cb136ba1e82 Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 28 Jun 2024 13:31:09 -0300 Subject: [PATCH 17/41] Fix parity calc --- crates/core/src/types/transaction.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/crates/core/src/types/transaction.rs b/crates/core/src/types/transaction.rs index 7df5066ec..69a177493 100644 --- a/crates/core/src/types/transaction.rs +++ b/crates/core/src/types/transaction.rs @@ -83,7 +83,12 @@ impl RLPEncode for EIP1559Transaction { impl Transaction { pub fn sender(&self) -> Address { match self { - Transaction::LegacyTransaction(tx) => recover_address(&tx.r, &tx.s, false, &tx.data), + Transaction::LegacyTransaction(tx) => recover_address( + &tx.r, + &tx.s, + tx.v.as_u64().saturating_sub(27) != 0, + &tx.data, + ), Transaction::EIP1559Transaction(tx) => { dbg!(recover_address( &tx.signature_r, From 937e1a9bd444d23ef56f3419766bea5f9f42bee5 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 1 Jul 2024 11:57:16 -0300 Subject: [PATCH 18/41] Add another ef test example --- ef_tests/tests/tests.rs | 12 ++ ef_tests/vectors/solidityExample.json | 158 ++++++++++++++++++++++++++ 2 files changed, 170 insertions(+) create mode 100644 ef_tests/vectors/solidityExample.json diff --git a/ef_tests/tests/tests.rs b/ef_tests/tests/tests.rs index 42cd399be..7d98cdfce 100644 --- a/ef_tests/tests/tests.rs +++ b/ef_tests/tests/tests.rs @@ -49,4 +49,16 @@ mod ef_tests { execute_test(test) } } + + #[test] + fn solidity_example_test() { + let s: String = + std::fs::read_to_string("./vectors/solidityExample.json").expect("Unable to read file"); + let tests: HashMap = + serde_json::from_str(&s).expect("Unable to parse JSON"); + + for (_k, test) in tests { + execute_test(test) + } + } } diff --git a/ef_tests/vectors/solidityExample.json b/ef_tests/vectors/solidityExample.json new file mode 100644 index 000000000..cb5aa16cb --- /dev/null +++ b/ef_tests/vectors/solidityExample.json @@ -0,0 +1,158 @@ +{ + "solidityExample_d0g0v0_Cancun" : { + "_info" : { + "comment" : "An example test for using solidity contracts in the test", + "filling-rpc-server" : "evm version 1.14.4-unstable-3d8028a6-20240513", + "filling-tool-version" : "retesteth-0.3.2-cancun+commit.cae6bc33.Linux.g++", + "generatedTestHash" : "b1ef657f83adfccd30474ca07cbb852fe5de9016ca3d92f8171bcc8203dc86ef", + "lllcversion" : "Version: 0.5.14-develop.2023.7.11+commit.c58ab2c6.mod.Linux.g++", + "solidity" : "Version: 0.8.21+commit.d9974bed.Linux.g++", + "source" : "src/GeneralStateTestsFiller/stExample/solidityExampleFiller.yml", + "sourceHash" : "183aba76ca652aca9dba9268833bc330bb2c52d0d83d0f00d5d1bd167f983b5d" + }, + "blocks" : [ + { + "blockHeader" : { + "baseFeePerGas" : "0x0a", + "blobGasUsed" : "0x00", + "bloom" : "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "difficulty" : "0x00", + "excessBlobGas" : "0x00", + "extraData" : "0x00", + "gasLimit" : "0x05f5e100", + "gasUsed" : "0x029e1f", + "hash" : "0x004932044123a9c656fa761728cb4cbced856df14aaec79b17819f7ff92110b1", + "mixHash" : "0x0000000000000000000000000000000000000000000000000000000000020000", + "nonce" : "0x0000000000000000", + "number" : "0x01", + "parentBeaconBlockRoot" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash" : "0x7f968420a06afa4d25513f22f68e1ed9708c5cab62493403a59e9972d6304b99", + "receiptTrie" : "0x8560690af929551571bc1385f70c39c932a89e08b43355d540a38125ebd87490", + "stateRoot" : "0x3cd24ae5e4ae9cf56a73a3f4e764cc50b63e8b1aaff75b7cbd3a840c8a449cca", + "timestamp" : "0x03e8", + "transactionsTrie" : "0xb8466b5b437cf6d45ed3dfa2058e2b6709f1a86145215e8a59694dc559a4526f", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "withdrawalsRoot" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" + }, + "rlp" : "0xf902eaf9023ba07f968420a06afa4d25513f22f68e1ed9708c5cab62493403a59e9972d6304b99a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa03cd24ae5e4ae9cf56a73a3f4e764cc50b63e8b1aaff75b7cbd3a840c8a449ccaa0b8466b5b437cf6d45ed3dfa2058e2b6709f1a86145215e8a59694dc559a4526fa08560690af929551571bc1385f70c39c932a89e08b43355d540a38125ebd87490b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080018405f5e10083029e1f8203e800a000000000000000000000000000000000000000000000000000000000000200008800000000000000000aa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000f8a8f8a6800a8404c4b40094095e7baea6a6c7c4c2dfeb977efac326af552d8780b844b66176a7000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000451ca0557b882a6f4c398e1dc30731cc0490f9743d2df3a13b9e465a87198920d34877a071659dc2b9ff195215e075315734b937a7773e470d47d33cdca183b1bc4093a7c0c0", + "transactions" : [ + { + "data" : "0xb66176a700000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000045", + "gasLimit" : "0x04c4b400", + "gasPrice" : "0x0a", + "nonce" : "0x00", + "r" : "0x557b882a6f4c398e1dc30731cc0490f9743d2df3a13b9e465a87198920d34877", + "s" : "0x71659dc2b9ff195215e075315734b937a7773e470d47d33cdca183b1bc4093a7", + "sender" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "to" : "0x095e7baea6a6c7c4c2dfeb977efac326af552d87", + "v" : "0x1c", + "value" : "0x00" + } + ], + "uncleHeaders" : [ + ], + "withdrawals" : [ + ] + } + ], + "genesisBlockHeader" : { + "baseFeePerGas" : "0x0b", + "blobGasUsed" : "0x00", + "bloom" : "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "difficulty" : "0x00", + "excessBlobGas" : "0x060000", + "extraData" : "0x00", + "gasLimit" : "0x05f5e100", + "gasUsed" : "0x00", + "hash" : "0x7f968420a06afa4d25513f22f68e1ed9708c5cab62493403a59e9972d6304b99", + "mixHash" : "0x0000000000000000000000000000000000000000000000000000000000020000", + "nonce" : "0x0000000000000000", + "number" : "0x00", + "parentBeaconBlockRoot" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0x8dd822dbb200af06a3faa988d8fead75e3af89e24c1d74ba377c7e4ec7cebf56", + "timestamp" : "0x00", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "withdrawalsRoot" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" + }, + "genesisRLP" : "0xf9023ff90239a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2697ff9baa08dd822dbb200af06a3faa988d8fead75e3af89e24c1d74ba377c7e4ec7cebf56a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080808405f5e100808000a000000000000000000000000000000000000000000000000000000000000200008800000000000000000ba056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218083060000a00000000000000000000000000000000000000000000000000000000000000000c0c0c0", + "lastblockhash" : "0x004932044123a9c656fa761728cb4cbced856df14aaec79b17819f7ff92110b1", + "network" : "Cancun", + "postState" : { + "0x000f3df6d732807ef1319fb7b8bb8522d0beac02" : { + "balance" : "0x00", + "code" : "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500", + "nonce" : "0x01", + "storage" : { + "0x03e8" : "0x03e8" + } + }, + "0x095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x0ba1a9ce0ba1a9ce", + "code" : "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063b66176a714610030575b600080fd5b61004a6004803603810190610045919061018d565b61004c565b005b60405161005890610145565b604051809103906000f080158015610074573d6000803e3d6000fd5b506000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b66176a783836040518363ffffffff1660e01b815260040161010f9291906101dc565b600060405180830381600087803b15801561012957600080fd5b505af115801561013d573d6000803e3d6000fd5b505050505050565b6101238061020683390190565b600080fd5b6000819050919050565b61016a81610157565b811461017557600080fd5b50565b60008135905061018781610161565b92915050565b600080604083850312156101a4576101a3610152565b5b60006101b285828601610178565b92505060206101c385828601610178565b9150509250929050565b6101d681610157565b82525050565b60006040820190506101f160008301856101cd565b6101fe60208301846101cd565b939250505056fe608060405267ff00ff00ff00ff0060005534801561001c57600080fd5b5060f88061002b6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063b66176a714602d575b600080fd5b60436004803603810190603f91906089565b6045565b005b806000819055508082555050565b600080fd5b6000819050919050565b6069816058565b8114607357600080fd5b50565b6000813590506083816062565b92915050565b60008060408385031215609d57609c6053565b5b600060a9858286016076565b925050602060b8858286016076565b915050925092905056fea2646970667358221220bf97a493dcca1030df869e90defab95c4fe213b1465aef60276095472e3250cf64736f6c63430008150033a26469706673582212206eab0a7969fe2c3def96c16981b10296eeffbe3ba077c61e666c576b0573f10f64736f6c63430008150033", + "nonce" : "0x01", + "storage" : { + "0x00" : "0xd2571607e241ecf590ed94b12d87c94babe36db6" + } + }, + "0x195e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x0ba1a9ce0ba1a9ce", + "code" : "0x6080604052348015600e575f80fd5b50600436106026575f3560e01c8063b66176a714602a575b5f80fd5b60406004803603810190603c91906081565b6042565b005b805f819055508082555050565b5f80fd5b5f819050919050565b6063816053565b8114606c575f80fd5b50565b5f81359050607b81605c565b92915050565b5f80604083850312156094576093604f565b5b5f609f85828601606f565b925050602060ae85828601606f565b915050925092905056fea2646970667358221220019739184511327e8fcb2252099d4070e2bac9220fc47dcf6a69c5397c26b63e64736f6c63430008150033", + "nonce" : "0x00", + "storage" : { + } + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0ba1a9ce0b877c98", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + }, + "0xd2571607e241ecf590ed94b12d87c94babe36db6" : { + "balance" : "0x00", + "code" : "0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063b66176a714602d575b600080fd5b60436004803603810190603f91906089565b6045565b005b806000819055508082555050565b600080fd5b6000819050919050565b6069816058565b8114607357600080fd5b50565b6000813590506083816062565b92915050565b60008060408385031215609d57609c6053565b5b600060a9858286016076565b925050602060b8858286016076565b915050925092905056fea2646970667358221220bf97a493dcca1030df869e90defab95c4fe213b1465aef60276095472e3250cf64736f6c63430008150033", + "nonce" : "0x01", + "storage" : { + "0x00" : "0x45", + "0x05" : "0x45" + } + } + }, + "pre" : { + "0x000f3df6d732807ef1319fb7b8bb8522d0beac02" : { + "balance" : "0x00", + "code" : "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500", + "nonce" : "0x01", + "storage" : { + } + }, + "0x095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x0ba1a9ce0ba1a9ce", + "code" : "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063b66176a714610030575b600080fd5b61004a6004803603810190610045919061018d565b61004c565b005b60405161005890610145565b604051809103906000f080158015610074573d6000803e3d6000fd5b506000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b66176a783836040518363ffffffff1660e01b815260040161010f9291906101dc565b600060405180830381600087803b15801561012957600080fd5b505af115801561013d573d6000803e3d6000fd5b505050505050565b6101238061020683390190565b600080fd5b6000819050919050565b61016a81610157565b811461017557600080fd5b50565b60008135905061018781610161565b92915050565b600080604083850312156101a4576101a3610152565b5b60006101b285828601610178565b92505060206101c385828601610178565b9150509250929050565b6101d681610157565b82525050565b60006040820190506101f160008301856101cd565b6101fe60208301846101cd565b939250505056fe608060405267ff00ff00ff00ff0060005534801561001c57600080fd5b5060f88061002b6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063b66176a714602d575b600080fd5b60436004803603810190603f91906089565b6045565b005b806000819055508082555050565b600080fd5b6000819050919050565b6069816058565b8114607357600080fd5b50565b6000813590506083816062565b92915050565b60008060408385031215609d57609c6053565b5b600060a9858286016076565b925050602060b8858286016076565b915050925092905056fea2646970667358221220bf97a493dcca1030df869e90defab95c4fe213b1465aef60276095472e3250cf64736f6c63430008150033a26469706673582212206eab0a7969fe2c3def96c16981b10296eeffbe3ba077c61e666c576b0573f10f64736f6c63430008150033", + "nonce" : "0x00", + "storage" : { + } + }, + "0x195e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x0ba1a9ce0ba1a9ce", + "code" : "0x6080604052348015600e575f80fd5b50600436106026575f3560e01c8063b66176a714602a575b5f80fd5b60406004803603810190603c91906081565b6042565b005b805f819055508082555050565b5f80fd5b5f819050919050565b6063816053565b8114606c575f80fd5b50565b5f81359050607b81605c565b92915050565b5f80604083850312156094576093604f565b5b5f609f85828601606f565b925050602060ae85828601606f565b915050925092905056fea2646970667358221220019739184511327e8fcb2252099d4070e2bac9220fc47dcf6a69c5397c26b63e64736f6c63430008150033", + "nonce" : "0x00", + "storage" : { + } + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0ba1a9ce0ba1a9ce", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "sealEngine" : "NoProof" + } +} \ No newline at end of file From 7c663df0210381d3d8a492a172e1b0224b12dc20 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 1 Jul 2024 11:58:10 -0300 Subject: [PATCH 19/41] Comment quick fix --- crates/core/src/types/transaction.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core/src/types/transaction.rs b/crates/core/src/types/transaction.rs index 69a177493..2c6748473 100644 --- a/crates/core/src/types/transaction.rs +++ b/crates/core/src/types/transaction.rs @@ -180,7 +180,7 @@ fn recover_address( ) .unwrap(); // Hash message - let message = Bytes::new(); // TODO: Fix parsing so "0x" is empty bytes + // let message = Bytes::new(); // TODO: Fix parsing so "0x" is empty bytes (Uncomment this when running add11 ef test) let msg_digest: [u8; 32] = Keccak256::new_with_prefix(message.as_ref()) .finalize() .into(); From 6ca3811b575f8ae26888457102925b810110c192 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 1 Jul 2024 12:29:07 -0300 Subject: [PATCH 20/41] Differentiate between legacy and eip tx when converting from eftests types --- crates/core/src/types/transaction.rs | 2 +- ef_tests/src/types.rs | 33 +++++++++++++++++++++++----- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/crates/core/src/types/transaction.rs b/crates/core/src/types/transaction.rs index 2c6748473..37b4fff29 100644 --- a/crates/core/src/types/transaction.rs +++ b/crates/core/src/types/transaction.rs @@ -102,7 +102,7 @@ impl Transaction { pub fn gas_limit(&self) -> u64 { match self { - Transaction::LegacyTransaction(tx) => tx.gas_price, + Transaction::LegacyTransaction(tx) => tx.gas, Transaction::EIP1559Transaction(tx) => tx.gas_limit, } } diff --git a/ef_tests/src/types.rs b/ef_tests/src/types.rs index 9f2368d99..39199bc94 100644 --- a/ef_tests/src/types.rs +++ b/ef_tests/src/types.rs @@ -1,6 +1,6 @@ use bytes::Bytes; use ethrex_core::types::{ - code_hash, Account as EthrexAccount, AccountInfo, EIP1559Transaction, + code_hash, Account as EthrexAccount, AccountInfo, EIP1559Transaction, LegacyTransaction, Transaction as EthrexTransacion, }; use ethrex_core::{types::BlockHeader, Address, Bloom, H256, U256, U64}; @@ -147,9 +147,16 @@ impl Into for Header { impl Into for Transaction { fn into(self) -> EthrexTransacion { - dbg!(self.sender); - dbg!(&self); - EthrexTransacion::EIP1559Transaction(EIP1559Transaction { + match self.transaction_type { + Some(_) => EthrexTransacion::EIP1559Transaction(self.into()), + None => EthrexTransacion::LegacyTransaction(self.into()), + } + } +} + +impl Into for Transaction { + fn into(self) -> EIP1559Transaction { + EIP1559Transaction { // Note: gas_price is not used in this conversion as it is not part of EIP1559Transaction, this could be a problem chain_id: self.chain_id.map(|id| id.as_u64()).unwrap_or(1 /*mainnet*/), // TODO: Consider converting this into Option signer_nonce: self.nonce.as_u64(), @@ -171,7 +178,23 @@ impl Into for Transaction { signature_y_parity: self.v.as_u64().saturating_sub(27) != 0, signature_r: self.r, signature_s: self.s, - }) + } + } +} + +impl Into for Transaction { + fn into(self) -> LegacyTransaction { + LegacyTransaction { + nonce: self.nonce.as_u64(), + gas_price: self.gas_price.unwrap_or_default().as_u64(), // TODO: Consider converting this into Option + gas: self.gas_limit.as_u64(), + to: self.to, + value: self.value, + data: self.data, + v: self.v, + r: self.r, + s: self.s, + } } } From 9748e863a4ebba0b4d70e61223887b34a9d577bc Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 1 Jul 2024 13:19:52 -0300 Subject: [PATCH 21/41] Filter by tx_type --- ef_tests/src/types.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ef_tests/src/types.rs b/ef_tests/src/types.rs index 39199bc94..dd395909b 100644 --- a/ef_tests/src/types.rs +++ b/ef_tests/src/types.rs @@ -148,7 +148,10 @@ impl Into for Header { impl Into for Transaction { fn into(self) -> EthrexTransacion { match self.transaction_type { - Some(_) => EthrexTransacion::EIP1559Transaction(self.into()), + Some(tx_type) => match tx_type.as_u64() { + 2 => EthrexTransacion::EIP1559Transaction(self.into()), + _ => unimplemented!(), + }, None => EthrexTransacion::LegacyTransaction(self.into()), } } From f0b02a04ef2313648ea7aa4ac691578f48f96f75 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 1 Jul 2024 13:22:08 -0300 Subject: [PATCH 22/41] execute_tx return ExecutionResult --- crates/evm/src/lib.rs | 6 ++++-- ef_tests/tests/tests.rs | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/crates/evm/src/lib.rs b/crates/evm/src/lib.rs index 0ef414af0..225ddd13c 100644 --- a/crates/evm/src/lib.rs +++ b/crates/evm/src/lib.rs @@ -13,6 +13,7 @@ use std::collections::HashMap; use revm::primitives::AccountInfo as RevmAccountInfo; use revm::primitives::Address as RevmAddress; // Export needed types +pub use revm::primitives::ExecutionResult; pub use revm::primitives::SpecId; pub fn execute_tx( @@ -20,7 +21,7 @@ pub fn execute_tx( header: &BlockHeader, pre: &HashMap, // TODO: Modify this type when we have a defined State structure spec_id: SpecId, -) { +) -> ExecutionResult { let block_env = block_env(header); let tx_env = tx_env(tx); let cache_state = cache_state(pre); @@ -37,7 +38,8 @@ pub fn execute_tx( .with_external_context(TracerEip3155::new(Box::new(std::io::stderr())).without_summary()) .append_handler_register(inspector_handle_register) .build(); - let _tx_result = evm.transact().unwrap(); + let tx_result = evm.transact().unwrap(); + tx_result.result } fn cache_state(pre: &HashMap) -> CacheState { diff --git a/ef_tests/tests/tests.rs b/ef_tests/tests/tests.rs index 7d98cdfce..9b58f9a5b 100644 --- a/ef_tests/tests/tests.rs +++ b/ef_tests/tests/tests.rs @@ -13,7 +13,7 @@ fn execute_test(test: TestUnit) { .first() .unwrap(); let pre = test.pre.into_iter().map(|(k, v)| (k, v.into())).collect(); - execute_tx( + assert!(execute_tx( &transaction.clone().into(), &test .blocks @@ -27,7 +27,8 @@ fn execute_test(test: TestUnit) { .into(), &pre, SpecId::CANCUN, - ); + ) + .is_success()); } #[cfg(test)] From fe64b2c2433a9970443d9812657dfa8185b6b477 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 1 Jul 2024 13:38:42 -0300 Subject: [PATCH 23/41] Handle y_parity in protected legacy txs --- crates/core/src/types/transaction.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/crates/core/src/types/transaction.rs b/crates/core/src/types/transaction.rs index 37b4fff29..4e35f213e 100644 --- a/crates/core/src/types/transaction.rs +++ b/crates/core/src/types/transaction.rs @@ -83,12 +83,14 @@ impl RLPEncode for EIP1559Transaction { impl Transaction { pub fn sender(&self) -> Address { match self { - Transaction::LegacyTransaction(tx) => recover_address( - &tx.r, - &tx.s, - tx.v.as_u64().saturating_sub(27) != 0, - &tx.data, - ), + Transaction::LegacyTransaction(tx) => { + let signature_y_parity = match self.chain_id() { + // If there is a chain_id it means the tx is protected (TODO: check if this is true) + Some(chain_id) => tx.v.as_u64().saturating_sub(35 + chain_id * 2) != 0, + None => tx.v.as_u64().saturating_sub(27) != 0, + }; + recover_address(&tx.r, &tx.s, signature_y_parity, &tx.data) + } Transaction::EIP1559Transaction(tx) => { dbg!(recover_address( &tx.signature_r, From 5e52b860fbc4749213c65d1d11122a23fea8809a Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 1 Jul 2024 15:39:40 -0300 Subject: [PATCH 24/41] Move quick fix for empty data --- crates/core/src/types/transaction.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/core/src/types/transaction.rs b/crates/core/src/types/transaction.rs index d6c0bcf1e..f9634817d 100644 --- a/crates/core/src/types/transaction.rs +++ b/crates/core/src/types/transaction.rs @@ -95,7 +95,8 @@ impl Transaction { tx.gas, tx.to, tx.value, - tx.data.clone(), + Bytes::new(), // TODO: Fix parsing so "0x" is empty bytes (Uncomment this when running add11 ef test) + //tx.data.clone(), ); let mut buf = vec![]; data.encode(&mut buf); @@ -197,7 +198,6 @@ fn recover_address( ) .unwrap(); // Hash message - // let message = Bytes::new(); // TODO: Fix parsing so "0x" is empty bytes (Uncomment this when running add11 ef test) let msg_digest: [u8; 32] = Keccak256::new_with_prefix(message.as_ref()) .finalize() .into(); From 184d56b04183ed598d74388ea864cbe542705751 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 1 Jul 2024 15:43:07 -0300 Subject: [PATCH 25/41] Add todo comment --- crates/core/src/types/transaction.rs | 29 +++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/crates/core/src/types/transaction.rs b/crates/core/src/types/transaction.rs index f9634817d..e95ceb7b1 100644 --- a/crates/core/src/types/transaction.rs +++ b/crates/core/src/types/transaction.rs @@ -96,7 +96,7 @@ impl Transaction { tx.to, tx.value, Bytes::new(), // TODO: Fix parsing so "0x" is empty bytes (Uncomment this when running add11 ef test) - //tx.data.clone(), + //tx.data.clone(), ); let mut buf = vec![]; data.encode(&mut buf); @@ -107,14 +107,25 @@ impl Transaction { &Bytes::from(buf) )) } - Transaction::EIP1559Transaction(tx) => { - dbg!(recover_address( - &tx.signature_r, - &tx.signature_s, - tx.signature_y_parity, - &tx.payload - )) - } + Transaction::EIP1559Transaction(tx) => + /*TODO: message = rlp.encode( + tx.nonce, + tx.gas_price, + tx.gas, + tx.to, + tx.value, + tx.data, + chain_id, + Uint(0), + Uint(0), + ) + */ + recover_address( + &tx.signature_r, + &tx.signature_s, + tx.signature_y_parity, + &tx.payload, + ), } } From e8bd271a6bf1f6cbda280fdcd2b52571e8e39760 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 1 Jul 2024 15:58:44 -0300 Subject: [PATCH 26/41] Fix tx data desrialization for eftests --- crates/core/src/types/transaction.rs | 3 +-- ef_tests/src/types.rs | 13 ++++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/crates/core/src/types/transaction.rs b/crates/core/src/types/transaction.rs index e95ceb7b1..bcce0f850 100644 --- a/crates/core/src/types/transaction.rs +++ b/crates/core/src/types/transaction.rs @@ -95,8 +95,7 @@ impl Transaction { tx.gas, tx.to, tx.value, - Bytes::new(), // TODO: Fix parsing so "0x" is empty bytes (Uncomment this when running add11 ef test) - //tx.data.clone(), + tx.data.clone(), ); let mut buf = vec![]; data.encode(&mut buf); diff --git a/ef_tests/src/types.rs b/ef_tests/src/types.rs index f336ed547..ed57519cb 100644 --- a/ef_tests/src/types.rs +++ b/ef_tests/src/types.rs @@ -4,7 +4,7 @@ use ethrex_core::types::{ Transaction as EthrexTransacion, }; use ethrex_core::{types::BlockHeader, Address, Bloom, H256, U256, U64}; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Deserializer, Serialize}; use std::collections::HashMap; #[derive(Debug, Deserialize)] @@ -99,6 +99,7 @@ pub struct Block { pub struct Transaction { #[serde(rename = "type")] pub transaction_type: Option, + #[serde(deserialize_with = "deser_prefixed_bytes")] pub data: Bytes, pub gas_limit: U256, pub gas_price: Option, @@ -225,3 +226,13 @@ impl Into for Account { } } } + +// Serde utils + +pub fn deser_prefixed_bytes<'de, D>(d: D) -> Result + where + D: Deserializer<'de>, + { + let value = String::deserialize(d)?; + Ok(Bytes::from(value.trim_start_matches("0x").to_string())) + } From 9e4b14136dac468d134d3686996d14f081ff5929 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 1 Jul 2024 16:01:27 -0300 Subject: [PATCH 27/41] Remove comment --- crates/core/src/types/transaction.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/core/src/types/transaction.rs b/crates/core/src/types/transaction.rs index bcce0f850..9484b634a 100644 --- a/crates/core/src/types/transaction.rs +++ b/crates/core/src/types/transaction.rs @@ -85,7 +85,6 @@ impl Transaction { match self { Transaction::LegacyTransaction(tx) => { let signature_y_parity = match self.chain_id() { - // If there is a chain_id it means the tx is protected (TODO: check if this is true) Some(chain_id) => tx.v.as_u64().saturating_sub(35 + chain_id * 2) != 0, None => tx.v.as_u64().saturating_sub(27) != 0, }; From 1f2a194880813a4c5b1232efd7304dc229c6ace5 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 1 Jul 2024 16:06:05 -0300 Subject: [PATCH 28/41] Fix code deser --- ef_tests/src/types.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/ef_tests/src/types.rs b/ef_tests/src/types.rs index ed57519cb..b16ac7eba 100644 --- a/ef_tests/src/types.rs +++ b/ef_tests/src/types.rs @@ -26,6 +26,7 @@ pub struct TestUnit { #[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone)] pub struct Account { pub balance: U256, + #[serde(deserialize_with = "deser_prefixed_bytes")] pub code: Bytes, pub nonce: U256, pub storage: HashMap, From 9549014ea513dbfaa6fb11d76fd9c625551cf70e Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 1 Jul 2024 16:29:58 -0300 Subject: [PATCH 29/41] Use correct data for EIP1555 addr calc too --- crates/core/src/rlp/encode.rs | 41 +++++++++++++++++++++++++++ crates/core/src/types/transaction.rs | 42 +++++++++++++++------------- ef_tests/src/types.rs | 12 ++++---- 3 files changed, 70 insertions(+), 25 deletions(-) diff --git a/crates/core/src/rlp/encode.rs b/crates/core/src/rlp/encode.rs index 4b1e851e5..e85d7dcad 100644 --- a/crates/core/src/rlp/encode.rs +++ b/crates/core/src/rlp/encode.rs @@ -258,6 +258,47 @@ impl RLPEncode for (A, B, C, D, E, F, G, H, I) +{ + fn encode(&self, buf: &mut dyn BufMut) { + let total_len = self.0.length() + + self.1.length() + + self.2.length() + + self.3.length() + + self.4.length() + + self.5.length() + + self.6.length() + + self.7.length() + + self.8.length(); + encode_length(total_len, buf); + self.0.encode(buf); + self.1.encode(buf); + self.2.encode(buf); + self.3.encode(buf); + self.4.encode(buf); + self.5.encode(buf); + self.6.encode(buf); + self.7.encode(buf); + self.8.encode(buf); + } + + fn length(&self) -> usize { + let mut buf = Vec::new(); + self.encode(&mut buf); + buf.len() + } +} + impl RLPEncode for Ipv4Addr { fn encode(&self, buf: &mut dyn BufMut) { self.octets().encode(buf) diff --git a/crates/core/src/types/transaction.rs b/crates/core/src/types/transaction.rs index 9484b634a..2fd947fcc 100644 --- a/crates/core/src/types/transaction.rs +++ b/crates/core/src/types/transaction.rs @@ -105,25 +105,29 @@ impl Transaction { &Bytes::from(buf) )) } - Transaction::EIP1559Transaction(tx) => - /*TODO: message = rlp.encode( - tx.nonce, - tx.gas_price, - tx.gas, - tx.to, - tx.value, - tx.data, - chain_id, - Uint(0), - Uint(0), - ) - */ - recover_address( - &tx.signature_r, - &tx.signature_s, - tx.signature_y_parity, - &tx.payload, - ), + Transaction::EIP1559Transaction(tx) => { + let data = ( + tx.signer_nonce, + // TODO: The following two fields are not part of EIP1559Transaction, other fields were used instead + // consider adding them + tx.max_fee_per_gas, // gas_price + tx.gas_limit, // gas + tx.destination, + tx.amount, + tx.payload.clone(), + tx.chain_id, + 0_u64, + 0_u64, + ); + let mut buf = vec![]; + data.encode(&mut buf); + recover_address( + &tx.signature_r, + &tx.signature_s, + tx.signature_y_parity, + &Bytes::from(buf), + ) + } } } diff --git a/ef_tests/src/types.rs b/ef_tests/src/types.rs index b16ac7eba..5ff31b59f 100644 --- a/ef_tests/src/types.rs +++ b/ef_tests/src/types.rs @@ -231,9 +231,9 @@ impl Into for Account { // Serde utils pub fn deser_prefixed_bytes<'de, D>(d: D) -> Result - where - D: Deserializer<'de>, - { - let value = String::deserialize(d)?; - Ok(Bytes::from(value.trim_start_matches("0x").to_string())) - } +where + D: Deserializer<'de>, +{ + let value = String::deserialize(d)?; + Ok(Bytes::from(value.trim_start_matches("0x").to_string())) +} From 1dbc191252dcacf158e496e09adcafcc6b8d0f6b Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 1 Jul 2024 16:31:33 -0300 Subject: [PATCH 30/41] Remove unused dep --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 1a5e1986b..fdef6bebd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,5 +31,4 @@ serde_json = "1.0.117" libmdbx = { version = "0.5.0", features = ["orm"] } bytes = "1.6.0" tokio = { version = "1.38.0", features = ["full"] } -k256 = "0.13.3" thiserror = "1.0.61" From 4da90181ad59ec9ce1479355a03743673be19ee3 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 1 Jul 2024 16:33:39 -0300 Subject: [PATCH 31/41] clippy --- crates/core/src/rlp/encode.rs | 6 -- crates/evm/src/lib.rs | 2 +- ef_tests/src/types.rs | 122 +++++++++++++++++----------------- ef_tests/tests/tests.rs | 1 - 4 files changed, 62 insertions(+), 69 deletions(-) diff --git a/crates/core/src/rlp/encode.rs b/crates/core/src/rlp/encode.rs index e85d7dcad..96220f296 100644 --- a/crates/core/src/rlp/encode.rs +++ b/crates/core/src/rlp/encode.rs @@ -291,12 +291,6 @@ impl< self.7.encode(buf); self.8.encode(buf); } - - fn length(&self) -> usize { - let mut buf = Vec::new(); - self.encode(&mut buf); - buf.len() - } } impl RLPEncode for Ipv4Addr { diff --git a/crates/evm/src/lib.rs b/crates/evm/src/lib.rs index 225ddd13c..b50898dc7 100644 --- a/crates/evm/src/lib.rs +++ b/crates/evm/src/lib.rs @@ -54,7 +54,7 @@ fn cache_state(pre: &HashMap) -> CacheState { let mut storage = HashMap::new(); for (k, v) in &account.storage { - storage.insert(U256::from_be_bytes(k.0), U256::from_be_bytes(v.0.into())); + storage.insert(U256::from_be_bytes(k.0), U256::from_be_bytes(v.0)); } cache_state.insert_account_with_storage(address.to_fixed_bytes().into(), acc_info, storage); diff --git a/ef_tests/src/types.rs b/ef_tests/src/types.rs index 5ff31b59f..50c4d16fb 100644 --- a/ef_tests/src/types.rs +++ b/ef_tests/src/types.rs @@ -120,100 +120,100 @@ pub struct Transaction { // Conversions between EFtests & Ethrex types -impl Into for Header { - fn into(self) -> BlockHeader { +impl From
for BlockHeader { + fn from(val: Header) -> Self { BlockHeader { - parent_hash: self.parent_hash, - ommers_hash: self.uncle_hash, - coinbase: self.coinbase, - state_root: self.state_root, - transactions_root: self.transactions_trie, - receipt_root: self.receipt_trie, - logs_bloom: self.bloom.into(), - difficulty: self.difficulty, - number: self.number.as_u64(), - gas_limit: self.gas_limit.as_u64(), - gas_used: self.gas_used.as_u64(), - timestamp: self.timestamp.as_u64(), - extra_data: self.extra_data, - prev_randao: self.mix_hash, - nonce: self.nonce.as_u64(), - base_fee_per_gas: self.base_fee_per_gas.unwrap().as_u64(), - withdrawals_root: self.withdrawals_root.unwrap(), - blob_gas_used: self.blob_gas_used.unwrap().as_u64(), - excess_blob_gas: self.excess_blob_gas.unwrap().as_u64(), - parent_beacon_block_root: self.parent_beacon_block_root.unwrap(), + parent_hash: val.parent_hash, + ommers_hash: val.uncle_hash, + coinbase: val.coinbase, + state_root: val.state_root, + transactions_root: val.transactions_trie, + receipt_root: val.receipt_trie, + logs_bloom: val.bloom.into(), + difficulty: val.difficulty, + number: val.number.as_u64(), + gas_limit: val.gas_limit.as_u64(), + gas_used: val.gas_used.as_u64(), + timestamp: val.timestamp.as_u64(), + extra_data: val.extra_data, + prev_randao: val.mix_hash, + nonce: val.nonce.as_u64(), + base_fee_per_gas: val.base_fee_per_gas.unwrap().as_u64(), + withdrawals_root: val.withdrawals_root.unwrap(), + blob_gas_used: val.blob_gas_used.unwrap().as_u64(), + excess_blob_gas: val.excess_blob_gas.unwrap().as_u64(), + parent_beacon_block_root: val.parent_beacon_block_root.unwrap(), } } } -impl Into for Transaction { - fn into(self) -> EthrexTransacion { - dbg!(&self); - match self.transaction_type { +impl From for EthrexTransacion { + fn from(val: Transaction) -> Self { + dbg!(&val); + match val.transaction_type { Some(tx_type) => match tx_type.as_u64() { - 2 => EthrexTransacion::EIP1559Transaction(self.into()), + 2 => EthrexTransacion::EIP1559Transaction(val.into()), _ => unimplemented!(), }, - None => EthrexTransacion::LegacyTransaction(self.into()), + None => EthrexTransacion::LegacyTransaction(val.into()), } } } -impl Into for Transaction { - fn into(self) -> EIP1559Transaction { +impl From for EIP1559Transaction { + fn from(val: Transaction) -> Self { EIP1559Transaction { // Note: gas_price is not used in this conversion as it is not part of EIP1559Transaction, this could be a problem - chain_id: self.chain_id.map(|id| id.as_u64()).unwrap_or(1 /*mainnet*/), // TODO: Consider converting this into Option - signer_nonce: self.nonce.as_u64(), - max_priority_fee_per_gas: self.max_priority_fee_per_gas.unwrap_or_default().as_u64(), // TODO: Consider converting this into Option - max_fee_per_gas: self + chain_id: val.chain_id.map(|id| id.as_u64()).unwrap_or(1 /*mainnet*/), // TODO: Consider converting this into Option + signer_nonce: val.nonce.as_u64(), + max_priority_fee_per_gas: val.max_priority_fee_per_gas.unwrap_or_default().as_u64(), // TODO: Consider converting this into Option + max_fee_per_gas: val .max_fee_per_gas - .unwrap_or(self.gas_price.unwrap_or_default()) + .unwrap_or(val.gas_price.unwrap_or_default()) .as_u64(), // TODO: Consider converting this into Option - gas_limit: self.gas_limit.as_u64(), - destination: self.to, - amount: self.value, - payload: self.data, - access_list: self + gas_limit: val.gas_limit.as_u64(), + destination: val.to, + amount: val.value, + payload: val.data, + access_list: val .access_list .unwrap_or_default() .into_iter() .map(|item| (item.address, item.storage_keys)) .collect(), - signature_y_parity: self.v.as_u64().saturating_sub(27) != 0, - signature_r: self.r, - signature_s: self.s, + signature_y_parity: val.v.as_u64().saturating_sub(27) != 0, + signature_r: val.r, + signature_s: val.s, } } } -impl Into for Transaction { - fn into(self) -> LegacyTransaction { +impl From for LegacyTransaction { + fn from(val: Transaction) -> Self { LegacyTransaction { - nonce: self.nonce.as_u64(), - gas_price: self.gas_price.unwrap_or_default().as_u64(), // TODO: Consider converting this into Option - gas: self.gas_limit.as_u64(), - to: self.to, - value: self.value, - data: self.data, - v: self.v, - r: self.r, - s: self.s, + nonce: val.nonce.as_u64(), + gas_price: val.gas_price.unwrap_or_default().as_u64(), // TODO: Consider converting this into Option + gas: val.gas_limit.as_u64(), + to: val.to, + value: val.value, + data: val.data, + v: val.v, + r: val.r, + s: val.s, } } } -impl Into for Account { - fn into(self) -> EthrexAccount { +impl From for EthrexAccount { + fn from(val: Account) -> Self { EthrexAccount { info: AccountInfo { - code_hash: code_hash(&self.code), - balance: self.balance, - nonce: self.nonce.as_u64(), + code_hash: code_hash(&val.code), + balance: val.balance, + nonce: val.nonce.as_u64(), }, - code: self.code, - storage: self + code: val.code, + storage: val .storage .into_iter() .map(|(k, v)| { diff --git a/ef_tests/tests/tests.rs b/ef_tests/tests/tests.rs index 9b58f9a5b..91bcef0be 100644 --- a/ef_tests/tests/tests.rs +++ b/ef_tests/tests/tests.rs @@ -19,7 +19,6 @@ fn execute_test(test: TestUnit) { .blocks .first() .as_ref() - .clone() .unwrap() .block_header .clone() From 69caf65c2a31802d9ec3331ee6ff0ff79ef0e17a Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 1 Jul 2024 16:35:09 -0300 Subject: [PATCH 32/41] Remove uneeded feature --- crates/core/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 935e56ed3..687dc0134 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bytes = { workspace = true, features = ["serde"] } +bytes.workspace = true tinyvec = "1.6.0" ethereum-types = "0.14.1" serde.workspace = true From 625fc21a2204e84d3cc2691f374b8a6de152d4c8 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 1 Jul 2024 16:40:45 -0300 Subject: [PATCH 33/41] Remove dbg print --- crates/core/src/types/transaction.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/crates/core/src/types/transaction.rs b/crates/core/src/types/transaction.rs index 2fd947fcc..fbefa13d9 100644 --- a/crates/core/src/types/transaction.rs +++ b/crates/core/src/types/transaction.rs @@ -98,12 +98,7 @@ impl Transaction { ); let mut buf = vec![]; data.encode(&mut buf); - dbg!(recover_address( - &tx.r, - &tx.s, - signature_y_parity, - &Bytes::from(buf) - )) + recover_address(&tx.r, &tx.s, signature_y_parity, &Bytes::from(buf)) } Transaction::EIP1559Transaction(tx) => { let data = ( From 08de5e255abc3b672a5f780ac4175cb681ddba28 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 1 Jul 2024 16:49:47 -0300 Subject: [PATCH 34/41] Move evm crate inside core --- Cargo.toml | 2 -- crates/core/Cargo.toml | 1 + crates/{evm/src/lib.rs => core/src/evm/mod.rs} | 2 +- crates/core/src/lib.rs | 1 + crates/evm/Cargo.toml | 11 ----------- ef_tests/Cargo.toml | 1 - ef_tests/tests/tests.rs | 2 +- 7 files changed, 4 insertions(+), 16 deletions(-) rename crates/{evm/src/lib.rs => core/src/evm/mod.rs} (99%) delete mode 100644 crates/evm/Cargo.toml diff --git a/Cargo.toml b/Cargo.toml index fdef6bebd..55895ad15 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,6 @@ members = [ "ethrex", "crates/consensus", "crates/core", - "crates/evm", "crates/net", "crates/rpc", "crates/storage", @@ -18,7 +17,6 @@ edition = "2021" [workspace.dependencies] ethrex-consensus = { path = "./crates/consensus" } ethrex-core = { path = "./crates/core" } -ethrex-evm = { path = "./crates/evm" } ethrex-net = { path = "./crates/net" } ethrex-rpc = { path = "./crates/rpc" } ethrex-storage = { path = "./crates/storage" } diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 687dc0134..22a5cb63c 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -18,6 +18,7 @@ secp256k1 = { version = "0.29", default-features = false, features = [ "global-context", "recovery", ] } +revm = { version = "10.0.0", features = ["serde", "std", "serde-json"] } [dev-dependencies] hex-literal = "0.4.1" diff --git a/crates/evm/src/lib.rs b/crates/core/src/evm/mod.rs similarity index 99% rename from crates/evm/src/lib.rs rename to crates/core/src/evm/mod.rs index b50898dc7..45b968d4e 100644 --- a/crates/evm/src/lib.rs +++ b/crates/core/src/evm/mod.rs @@ -1,4 +1,4 @@ -use ethrex_core::{ +use super::{ types::{Account, BlockHeader, Transaction}, Address, }; diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs index 7a5c7dc0a..83614d610 100644 --- a/crates/core/src/lib.rs +++ b/crates/core/src/lib.rs @@ -1,4 +1,5 @@ pub mod rlp; pub use ethereum_types::*; +pub mod evm; pub mod serde_utils; pub mod types; diff --git a/crates/evm/Cargo.toml b/crates/evm/Cargo.toml deleted file mode 100644 index d7f0ed390..000000000 --- a/crates/evm/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "ethrex-evm" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -revm = { version = "10.0.0", features = ["serde", "std", "serde-json"] } -bytes.workspace = true -ethrex-core.workspace = true diff --git a/ef_tests/Cargo.toml b/ef_tests/Cargo.toml index 4f5845a93..56509dda6 100644 --- a/ef_tests/Cargo.toml +++ b/ef_tests/Cargo.toml @@ -5,7 +5,6 @@ edition.workspace = true [dependencies] ethrex-core.workspace = true -ethrex-evm.workspace = true serde.workspace = true serde_json.workspace = true bytes.workspace = true diff --git a/ef_tests/tests/tests.rs b/ef_tests/tests/tests.rs index 91bcef0be..aeca688c3 100644 --- a/ef_tests/tests/tests.rs +++ b/ef_tests/tests/tests.rs @@ -1,5 +1,5 @@ use ::ef_tests::types::TestUnit; -use ethrex_evm::{execute_tx, SpecId}; +use ethrex_core::evm::{execute_tx, SpecId}; fn execute_test(test: TestUnit) { // TODO: Add support for multiple blocks and multiple transactions per block. From 0908a4a6c39f6c9102bfaedd0f4fa4388ee37369 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 1 Jul 2024 17:00:53 -0300 Subject: [PATCH 35/41] Fix desr --- ef_tests/Cargo.toml | 1 + ef_tests/src/types.rs | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ef_tests/Cargo.toml b/ef_tests/Cargo.toml index 56509dda6..e75da1e54 100644 --- a/ef_tests/Cargo.toml +++ b/ef_tests/Cargo.toml @@ -8,3 +8,4 @@ ethrex-core.workspace = true serde.workspace = true serde_json.workspace = true bytes.workspace = true +hex = "0.4.3" diff --git a/ef_tests/src/types.rs b/ef_tests/src/types.rs index 50c4d16fb..22ec4adef 100644 --- a/ef_tests/src/types.rs +++ b/ef_tests/src/types.rs @@ -26,7 +26,7 @@ pub struct TestUnit { #[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone)] pub struct Account { pub balance: U256, - #[serde(deserialize_with = "deser_prefixed_bytes")] + #[serde(deserialize_with = "deser_hex_str")] pub code: Bytes, pub nonce: U256, pub storage: HashMap, @@ -100,7 +100,7 @@ pub struct Block { pub struct Transaction { #[serde(rename = "type")] pub transaction_type: Option, - #[serde(deserialize_with = "deser_prefixed_bytes")] + #[serde(deserialize_with = "deser_hex_str")] pub data: Bytes, pub gas_limit: U256, pub gas_price: Option, @@ -230,10 +230,11 @@ impl From for EthrexAccount { // Serde utils -pub fn deser_prefixed_bytes<'de, D>(d: D) -> Result +pub fn deser_hex_str<'de, D>(d: D) -> Result where D: Deserializer<'de>, { let value = String::deserialize(d)?; - Ok(Bytes::from(value.trim_start_matches("0x").to_string())) + let bytes = hex::decode(value.trim_start_matches("0x")).unwrap(); + Ok(Bytes::from(bytes)) } From 87dab3d4894b2b039db8663b9832d66f6fa73e65 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 1 Jul 2024 17:02:19 -0300 Subject: [PATCH 36/41] map error --- ef_tests/src/types.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ef_tests/src/types.rs b/ef_tests/src/types.rs index 22ec4adef..b93638baa 100644 --- a/ef_tests/src/types.rs +++ b/ef_tests/src/types.rs @@ -229,12 +229,14 @@ impl From for EthrexAccount { } // Serde utils +use serde::de::Error; pub fn deser_hex_str<'de, D>(d: D) -> Result where D: Deserializer<'de>, { let value = String::deserialize(d)?; - let bytes = hex::decode(value.trim_start_matches("0x")).unwrap(); + let bytes = + hex::decode(value.trim_start_matches("0x")).map_err(|e| D::Error::custom(e.to_string()))?; Ok(Bytes::from(bytes)) } From 54ffef555ba4215c4e3415c15d3cd44795a5d034 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 2 Jul 2024 10:33:30 -0300 Subject: [PATCH 37/41] Remove dbg print --- ef_tests/src/types.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/ef_tests/src/types.rs b/ef_tests/src/types.rs index b93638baa..7f2b9fbc7 100644 --- a/ef_tests/src/types.rs +++ b/ef_tests/src/types.rs @@ -149,7 +149,6 @@ impl From
for BlockHeader { impl From for EthrexTransacion { fn from(val: Transaction) -> Self { - dbg!(&val); match val.transaction_type { Some(tx_type) => match tx_type.as_u64() { 2 => EthrexTransacion::EIP1559Transaction(val.into()), From 1aff2a4145fc1f72653d1f7b0e4de9a6c96d37b7 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 2 Jul 2024 10:52:48 -0300 Subject: [PATCH 38/41] Fix EOF --- ef_tests/vectors/solidityExample.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ef_tests/vectors/solidityExample.json b/ef_tests/vectors/solidityExample.json index cb5aa16cb..1b940fb60 100644 --- a/ef_tests/vectors/solidityExample.json +++ b/ef_tests/vectors/solidityExample.json @@ -155,4 +155,4 @@ }, "sealEngine" : "NoProof" } -} \ No newline at end of file +} From d3f52b2412292ae0ced05cce1abbd4611a9e7221 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 2 Jul 2024 12:28:56 -0300 Subject: [PATCH 39/41] Add ExecutionResult type --- crates/core/src/evm/mod.rs | 74 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/crates/core/src/evm/mod.rs b/crates/core/src/evm/mod.rs index 45b968d4e..10eb92f87 100644 --- a/crates/core/src/evm/mod.rs +++ b/crates/core/src/evm/mod.rs @@ -2,6 +2,7 @@ use super::{ types::{Account, BlockHeader, Transaction}, Address, }; +use bytes::Bytes; use revm::{ inspector_handle_register, inspectors::TracerEip3155, @@ -10,12 +11,81 @@ use revm::{ }; use std::collections::HashMap; // Rename imported types for clarity +use revm::primitives::result::Output as RevmOutput; +use revm::primitives::result::SuccessReason as RevmSuccessReason; use revm::primitives::AccountInfo as RevmAccountInfo; use revm::primitives::Address as RevmAddress; +use revm::primitives::ExecutionResult as RevmExecutionResult; // Export needed types -pub use revm::primitives::ExecutionResult; pub use revm::primitives::SpecId; +pub enum ExecutionResult { + Success { + reason: SuccessReason, + gas_used: u64, + gas_refunded: u64, + output: Output, + }, + /// Reverted by `REVERT` opcode + Revert { gas_used: u64, output: Bytes }, + /// Reverted for other reasons, spends all gas. + Halt { + reason: String, + /// Halting will spend all the gas, which will be equal to gas_limit. + gas_used: u64, + }, +} + +pub enum SuccessReason { + Stop, + Return, + SelfDestruct, + EofReturnContract, +} + +pub enum Output { + Call(Bytes), + Create(Bytes, Option
), +} + +impl Into for RevmExecutionResult { + fn into(self) -> ExecutionResult { + match self { + RevmExecutionResult::Success { + reason, + gas_used, + gas_refunded, + logs: _, + output, + } => ExecutionResult::Success { + reason: match reason { + RevmSuccessReason::Stop => SuccessReason::Stop, + RevmSuccessReason::Return => SuccessReason::Return, + RevmSuccessReason::SelfDestruct => SuccessReason::SelfDestruct, + RevmSuccessReason::EofReturnContract => SuccessReason::EofReturnContract, + }, + gas_used, + gas_refunded, + output: match output { + RevmOutput::Call(bytes) => Output::Call(bytes.0), + RevmOutput::Create(bytes, addr) => Output::Create( + bytes.0, + addr.map(|addr| Address::from_slice(addr.0.as_ref())), + ), + }, + }, + RevmExecutionResult::Revert { gas_used, output } => ExecutionResult::Revert { + gas_used, + output: output.0, + }, + RevmExecutionResult::Halt { reason, gas_used } => ExecutionResult::Halt { + reason: format!("{:?}", reason), + gas_used, + }, + } + } +} + pub fn execute_tx( tx: &Transaction, header: &BlockHeader, @@ -39,7 +109,7 @@ pub fn execute_tx( .append_handler_register(inspector_handle_register) .build(); let tx_result = evm.transact().unwrap(); - tx_result.result + tx_result.result.into() } fn cache_state(pre: &HashMap) -> CacheState { From f4ced4a821494af94f18f1df5f6f24d83c9752d7 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 2 Jul 2024 12:32:40 -0300 Subject: [PATCH 40/41] Push fn --- crates/core/src/evm/mod.rs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/crates/core/src/evm/mod.rs b/crates/core/src/evm/mod.rs index 10eb92f87..660d5d63e 100644 --- a/crates/core/src/evm/mod.rs +++ b/crates/core/src/evm/mod.rs @@ -48,9 +48,9 @@ pub enum Output { Create(Bytes, Option
), } -impl Into for RevmExecutionResult { - fn into(self) -> ExecutionResult { - match self { +impl From for ExecutionResult { + fn from(val: RevmExecutionResult) -> Self { + match val { RevmExecutionResult::Success { reason, gas_used, @@ -86,6 +86,20 @@ impl Into for RevmExecutionResult { } } +impl ExecutionResult { + pub fn is_success(&self) -> bool { + matches!( + self, + ExecutionResult::Success { + reason: _, + gas_used: _, + gas_refunded: _, + output: _ + } + ) + } +} + pub fn execute_tx( tx: &Transaction, header: &BlockHeader, From 4368db0199666b5afc4c0d4ee8664b4f358f423b Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 2 Jul 2024 12:39:29 -0300 Subject: [PATCH 41/41] Move ExecutionResult to its own module --- crates/core/src/evm/execution_result.rs | 86 ++++++++++++++++++++++++ crates/core/src/evm/mod.rs | 88 +------------------------ 2 files changed, 89 insertions(+), 85 deletions(-) create mode 100644 crates/core/src/evm/execution_result.rs diff --git a/crates/core/src/evm/execution_result.rs b/crates/core/src/evm/execution_result.rs new file mode 100644 index 000000000..42c638eff --- /dev/null +++ b/crates/core/src/evm/execution_result.rs @@ -0,0 +1,86 @@ +use bytes::Bytes; +use ethereum_types::Address; +use revm::primitives::result::Output as RevmOutput; +use revm::primitives::result::SuccessReason as RevmSuccessReason; +use revm::primitives::ExecutionResult as RevmExecutionResult; + +pub enum ExecutionResult { + Success { + reason: SuccessReason, + gas_used: u64, + gas_refunded: u64, + output: Output, + }, + /// Reverted by `REVERT` opcode + Revert { gas_used: u64, output: Bytes }, + /// Reverted for other reasons, spends all gas. + Halt { + reason: String, + /// Halting will spend all the gas, which will be equal to gas_limit. + gas_used: u64, + }, +} + +pub enum SuccessReason { + Stop, + Return, + SelfDestruct, + EofReturnContract, +} + +pub enum Output { + Call(Bytes), + Create(Bytes, Option
), +} + +impl From for ExecutionResult { + fn from(val: RevmExecutionResult) -> Self { + match val { + RevmExecutionResult::Success { + reason, + gas_used, + gas_refunded, + logs: _, + output, + } => ExecutionResult::Success { + reason: match reason { + RevmSuccessReason::Stop => SuccessReason::Stop, + RevmSuccessReason::Return => SuccessReason::Return, + RevmSuccessReason::SelfDestruct => SuccessReason::SelfDestruct, + RevmSuccessReason::EofReturnContract => SuccessReason::EofReturnContract, + }, + gas_used, + gas_refunded, + output: match output { + RevmOutput::Call(bytes) => Output::Call(bytes.0), + RevmOutput::Create(bytes, addr) => Output::Create( + bytes.0, + addr.map(|addr| Address::from_slice(addr.0.as_ref())), + ), + }, + }, + RevmExecutionResult::Revert { gas_used, output } => ExecutionResult::Revert { + gas_used, + output: output.0, + }, + RevmExecutionResult::Halt { reason, gas_used } => ExecutionResult::Halt { + reason: format!("{:?}", reason), + gas_used, + }, + } + } +} + +impl ExecutionResult { + pub fn is_success(&self) -> bool { + matches!( + self, + ExecutionResult::Success { + reason: _, + gas_used: _, + gas_refunded: _, + output: _ + } + ) + } +} diff --git a/crates/core/src/evm/mod.rs b/crates/core/src/evm/mod.rs index 660d5d63e..d0dba58f7 100644 --- a/crates/core/src/evm/mod.rs +++ b/crates/core/src/evm/mod.rs @@ -1,8 +1,9 @@ +mod execution_result; + use super::{ types::{Account, BlockHeader, Transaction}, Address, }; -use bytes::Bytes; use revm::{ inspector_handle_register, inspectors::TracerEip3155, @@ -11,95 +12,12 @@ use revm::{ }; use std::collections::HashMap; // Rename imported types for clarity -use revm::primitives::result::Output as RevmOutput; -use revm::primitives::result::SuccessReason as RevmSuccessReason; use revm::primitives::AccountInfo as RevmAccountInfo; use revm::primitives::Address as RevmAddress; -use revm::primitives::ExecutionResult as RevmExecutionResult; // Export needed types +pub use execution_result::*; pub use revm::primitives::SpecId; -pub enum ExecutionResult { - Success { - reason: SuccessReason, - gas_used: u64, - gas_refunded: u64, - output: Output, - }, - /// Reverted by `REVERT` opcode - Revert { gas_used: u64, output: Bytes }, - /// Reverted for other reasons, spends all gas. - Halt { - reason: String, - /// Halting will spend all the gas, which will be equal to gas_limit. - gas_used: u64, - }, -} - -pub enum SuccessReason { - Stop, - Return, - SelfDestruct, - EofReturnContract, -} - -pub enum Output { - Call(Bytes), - Create(Bytes, Option
), -} - -impl From for ExecutionResult { - fn from(val: RevmExecutionResult) -> Self { - match val { - RevmExecutionResult::Success { - reason, - gas_used, - gas_refunded, - logs: _, - output, - } => ExecutionResult::Success { - reason: match reason { - RevmSuccessReason::Stop => SuccessReason::Stop, - RevmSuccessReason::Return => SuccessReason::Return, - RevmSuccessReason::SelfDestruct => SuccessReason::SelfDestruct, - RevmSuccessReason::EofReturnContract => SuccessReason::EofReturnContract, - }, - gas_used, - gas_refunded, - output: match output { - RevmOutput::Call(bytes) => Output::Call(bytes.0), - RevmOutput::Create(bytes, addr) => Output::Create( - bytes.0, - addr.map(|addr| Address::from_slice(addr.0.as_ref())), - ), - }, - }, - RevmExecutionResult::Revert { gas_used, output } => ExecutionResult::Revert { - gas_used, - output: output.0, - }, - RevmExecutionResult::Halt { reason, gas_used } => ExecutionResult::Halt { - reason: format!("{:?}", reason), - gas_used, - }, - } - } -} - -impl ExecutionResult { - pub fn is_success(&self) -> bool { - matches!( - self, - ExecutionResult::Success { - reason: _, - gas_used: _, - gas_refunded: _, - output: _ - } - ) - } -} - pub fn execute_tx( tx: &Transaction, header: &BlockHeader,