From ac5b2d649d1d39505cbe2212fefc5efd6e1c6025 Mon Sep 17 00:00:00 2001 From: James Date: Fri, 31 Jan 2025 12:12:50 -0500 Subject: [PATCH 1/4] feat: impl tx for transactionrequest --- src/fill/alloy.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/fill/alloy.rs b/src/fill/alloy.rs index d690b6a..b379c0a 100644 --- a/src/fill/alloy.rs +++ b/src/fill/alloy.rs @@ -284,6 +284,60 @@ impl Block for alloy::rpc::types::eth::Block { } } +impl Tx for alloy::rpc::types::TransactionRequest { + fn fill_tx_env(&self, tx_env: &mut TxEnv) { + let TxEnv { + caller, + gas_limit, + gas_price, + transact_to, + value, + data, + nonce, + chain_id, + access_list, + gas_priority_fee, + blob_hashes, + max_fee_per_blob_gas, + authorization_list, + } = tx_env; + + *caller = self.from.unwrap_or_default(); + *gas_limit = self.gas.unwrap_or_default(); + *gas_price = U256::from(self.gas_price.unwrap_or_default()); + *transact_to = self.to.unwrap_or_default(); + *value = self.value.unwrap_or_default(); + *data = self.input.input().cloned().unwrap_or_default(); + *nonce = self.nonce; + *chain_id = self.chain_id; + if let Some(al) = &self.access_list { + access_list.clone_from(al); + } else { + access_list.clear(); + } + if let Some(gpf) = &self.max_priority_fee_per_gas { + *gas_priority_fee = Some(U256::from(*gpf)); + } else { + gas_priority_fee.take(); + } + if let Some(bh) = &self.blob_versioned_hashes { + blob_hashes.clone_from(bh); + } else { + blob_hashes.clear(); + } + if let Some(mfbg) = &self.max_fee_per_blob_gas { + *max_fee_per_blob_gas = Some(U256::from(*mfbg)); + } else { + max_fee_per_blob_gas.take(); + } + if let Some(al) = &self.authorization_list { + *authorization_list = Some(al.clone().into()); + } else { + authorization_list.take(); + } + } +} + #[cfg(test)] mod tests { use crate::{NoopBlock, NoopCfg, TrevmBuilder}; From 47269b4c2a32d22babf772c5f843359b937a1fd7 Mon Sep 17 00:00:00 2001 From: James Date: Fri, 31 Jan 2025 12:23:10 -0500 Subject: [PATCH 2/4] feat: block overrides --- src/fill/alloy.rs | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/fill/alloy.rs b/src/fill/alloy.rs index b379c0a..1702d17 100644 --- a/src/fill/alloy.rs +++ b/src/fill/alloy.rs @@ -338,6 +338,42 @@ impl Tx for alloy::rpc::types::TransactionRequest { } } +impl Block for alloy::rpc::types::BlockOverrides { + fn fill_block_env(&self, block_env: &mut BlockEnv) { + let BlockEnv { + number, + coinbase, + timestamp, + gas_limit, + basefee, + difficulty, + prevrandao, + blob_excess_gas_and_price: _, + } = block_env; + if let Some(n) = &self.number { + *number = U256::from(*n); + } + if let Some(d) = &self.difficulty { + *difficulty = U256::from(*d); + } + if let Some(t) = &self.time { + *timestamp = U256::from(*t); + } + if let Some(g) = &self.gas_limit { + *gas_limit = U256::from(*g); + } + if let Some(c) = &self.coinbase { + *coinbase = *c; + } + if let Some(r) = self.random { + *prevrandao = Some(r); + } + if let Some(b) = &self.base_fee { + *basefee = U256::from(*b); + } + } +} + #[cfg(test)] mod tests { use crate::{NoopBlock, NoopCfg, TrevmBuilder}; From 946f29166d10ce501d2b94effe294151827c6285 Mon Sep 17 00:00:00 2001 From: James Date: Fri, 31 Jan 2025 12:39:28 -0500 Subject: [PATCH 3/4] feat: apply block and state overrides --- src/evm.rs | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/src/evm.rs b/src/evm.rs index 27fe9e4..d4cb7a9 100644 --- a/src/evm.rs +++ b/src/evm.rs @@ -4,7 +4,10 @@ use crate::{ EvmNeedsCfg, EvmNeedsTx, EvmReady, EvmTransacted, HasBlock, HasCfg, HasTx, NeedsCfg, NeedsTx, TransactedState, Tx, }; -use alloy::primitives::{Address, Bytes, U256}; +use alloy::{ + primitives::{Address, Bytes, U256}, + rpc::types::{state::StateOverride, BlockOverrides}, +}; use core::convert::Infallible; use revm::{ db::{states::bundle_state::BundleRetention, BundleState, State}, @@ -137,6 +140,42 @@ impl<'a, Ext, Db: Database + DatabaseCommit, TrevmState> Trevm<'a, Ext, Db, Trev None => Ok(None), } } + + /// Apply [`StateOverride`]s to the current state. + pub fn apply_state_overrides( + mut self, + overrides: &StateOverride, + ) -> Result> { + for (address, account_override) in overrides { + if let Some(balance) = account_override.balance { + self.inner.set_balance(*address, balance).map_err(EVMError::Database)?; + } + if let Some(nonce) = account_override.nonce { + self.inner.set_nonce(*address, nonce).map_err(EVMError::Database)?; + } + if let Some(code) = account_override.code.as_ref() { + self.inner + .set_bytecode( + *address, + Bytecode::new_raw_checked(code.clone()) + .map_err(|_| EVMError::Custom("Invalid bytecode".to_string()))?, + ) + .map_err(EVMError::Database)?; + } + if let Some(state) = account_override.state.as_ref() { + for (slot, value) in state { + self.inner + .set_storage( + *address, + U256::from_be_bytes((*slot).into()), + U256::from_be_bytes((*value).into()), + ) + .map_err(EVMError::Database)?; + } + } + } + Ok(self) + } } impl Trevm<'_, Ext, Db, TrevmState> { @@ -981,6 +1020,21 @@ impl<'a, Ext, Db: Database + DatabaseCommit, TrevmState: HasTx> Trevm<'a, Ext, D } } +// -- HAS TX with State + +impl EvmNeedsTx<'_, Ext, State> { + /// Apply block overrides to the current block. + pub fn apply_block_overrides(mut self, overrides: BlockOverrides) -> Self { + overrides.fill_block(&mut self.inner); + + if let Some(hashes) = overrides.block_hash { + self.inner.db_mut().block_hashes.extend(hashes) + } + + self + } +} + // --- READY impl<'a, Ext, Db: Database + DatabaseCommit> EvmReady<'a, Ext, Db> { From 7be7a51275bf35f24f7b04023298d982f7ca77c3 Mon Sep 17 00:00:00 2001 From: James Date: Fri, 31 Jan 2025 12:54:07 -0500 Subject: [PATCH 4/4] chore: bump version --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 8c8ed1f..764d560 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "trevm" -version = "0.19.0" +version = "0.19.1" rust-version = "1.83.0" edition = "2021" authors = ["init4"]