diff --git a/Cargo.toml b/Cargo.toml index ace3a8b..fdac468 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "trevm" -version = "0.27.9" +version = "0.29.0" rust-version = "1.83.0" edition = "2021" authors = ["init4"] @@ -34,7 +34,7 @@ name = "fork_ref_transact" required-features = ["alloy-db"] [dependencies] -alloy = { version = "1.0.25", default-features = false, features = [ +alloy = { version = "1.0.35", default-features = false, features = [ "consensus", "rpc-types-mev", "eips", @@ -44,8 +44,8 @@ alloy = { version = "1.0.25", default-features = false, features = [ "sol-types", ] } -revm = { version = "27.1", default-features = false } -revm-inspectors = { version = "0.27.3", optional = true } +revm = { version = "29.0.1", default-features = false } +revm-inspectors = { version = "0.30", optional = true } dashmap = { version = "6.1.0", optional = true } tracing = { version = "0.1.41", optional = true } @@ -54,10 +54,10 @@ thiserror = "2.0.11" tokio = { version = "1.44", optional = true } [dev-dependencies] -revm = { version = "27.0.1", features = ["serde-json", "std", "alloydb"] } +revm = { version = "29.0.1", features = ["serde-json", "std", "alloydb"] } trevm = { path = ".", features = ["test-utils"] } -alloy = { version = "1.0.13", features = ["providers", "transports"] } +alloy = { version = "1.0.35", features = ["providers", "transports"] } # misc eyre = "0.6" diff --git a/src/evm/all_states.rs b/src/evm/all_states.rs index 5879968..09a174b 100644 --- a/src/evm/all_states.rs +++ b/src/evm/all_states.rs @@ -247,7 +247,7 @@ where /// Disable an opcode by replacing it with unknown opcode behavior. This is /// a shortcut for [`Self::override_opcode`] with [`crate::helpers::forbidden`]. pub fn disable_opcode(&mut self, opcode: u8) -> Instruction { - self.override_opcode(opcode, crate::helpers::forbidden) + self.override_opcode(opcode, Instruction::new(crate::helpers::forbidden, 0)) } /// Run some closure with an opcode override, then restore the previous @@ -278,7 +278,7 @@ where /// Enable the prevrandao opcode. If the prevrandao opcode was not /// previously disabled or replaced, this will have no effect on behavior. pub fn enable_prevrandao(&mut self) -> Instruction { - self.override_opcode(DIFFICULTY, block_info::difficulty) + self.override_opcode(DIFFICULTY, Instruction::new(block_info::difficulty, 2)) } /// Run some code with the prevrandao opcode disabled, then restore the @@ -288,7 +288,7 @@ where where F: FnOnce(Self) -> Trevm, { - self.with_opcode_override(DIFFICULTY, crate::helpers::forbidden, f) + self.with_opcode_override(DIFFICULTY, Instruction::new(crate::helpers::forbidden, 0), f) } /// Set the precompiles for the EVM. This will replace the current diff --git a/src/evm/has_cfg.rs b/src/evm/has_cfg.rs index 285a60d..99e0e03 100644 --- a/src/evm/has_cfg.rs +++ b/src/evm/has_cfg.rs @@ -57,6 +57,35 @@ where self.set_code_size_limit(0x6000) } + /// Disable the [EIP-155] chain ID check. + /// + /// [`EIP-155`]: https://eips.ethereum.org/EIPS/eip-155 + pub fn disable_chain_id_check(&mut self) { + self.inner.ctx.modify_cfg(|cfg| cfg.tx_chain_id_check = false); + } + + /// Enable the [EIP-155] chain ID check. + /// + /// [`EIP-155`]: https://eips.ethereum.org/EIPS/eip-155 + pub fn enable_chain_id_check(&mut self) { + self.inner.ctx.modify_cfg(|cfg| cfg.tx_chain_id_check = true); + } + + /// Run a closure with the chain ID check disabled, then restore the previous + /// setting. + /// + /// [`EIP-155`]: https://eips.ethereum.org/EIPS/eip-155 + pub fn without_chain_id_check(mut self, f: F) -> Trevm + where + F: FnOnce(Self) -> Trevm, + { + let previous = self.inner.cfg().tx_chain_id_check; + self.disable_chain_id_check(); + let mut new = f(self); + new.inner.ctx.modify_cfg(|cfg| cfg.tx_chain_id_check = previous); + new + } + /// Run a function with the provided configuration, then restore the /// previous configuration. This will not affect the block and tx, if those /// have been filled. diff --git a/src/evm/has_tx.rs b/src/evm/has_tx.rs index c2e8a21..2f0f787 100644 --- a/src/evm/has_tx.rs +++ b/src/evm/has_tx.rs @@ -219,6 +219,7 @@ where #[cfg(test)] mod tests { use crate::{ + fillers::DisableChainIdCheck, test_utils::{test_trevm_with_funds, ALICE, BOB, LOG_DEPLOYED_BYTECODE}, NoopBlock, NoopCfg, TrevmBuilder, }; @@ -285,8 +286,12 @@ mod tests { .with_authorization_list(vec![signed_authorization]) .with_input(bytes!("0x7b3ab2d0")); // emitHello() - let (estimation, trevm) = - trevm.fill_cfg(&NoopCfg).fill_block(&NoopBlock).fill_tx(&tx).estimate_gas().unwrap(); + let (estimation, trevm) = trevm + .fill_cfg(&DisableChainIdCheck) + .fill_block(&NoopBlock) + .fill_tx(&tx) + .estimate_gas() + .unwrap(); assert!(estimation.is_success()); diff --git a/src/fill/fillers.rs b/src/fill/fillers.rs index 9b0a486..42ea8fe 100644 --- a/src/fill/fillers.rs +++ b/src/fill/fillers.rs @@ -31,6 +31,19 @@ impl Cfg for DisableGasChecks { } } +/// A [`Cfg`] that disables the chain ID check, while leaving other [`CfgEnv`] +/// attributes untouched. +#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)] +pub struct DisableChainIdCheck; + +impl Cfg for DisableChainIdCheck { + fn fill_cfg_env(&self, cfg_env: &mut CfgEnv) { + { + cfg_env.tx_chain_id_check = false; + } + } +} + /// A [`Cfg`] that disables the nonce check, while leaving other [`CfgEnv`] /// attributes untouched. #[derive(Debug, Clone, Copy, Default, PartialEq, Eq)] diff --git a/src/fill/noop.rs b/src/fill/noop.rs index d71b873..ebc976c 100644 --- a/src/fill/noop.rs +++ b/src/fill/noop.rs @@ -15,5 +15,5 @@ impl Block for NoopBlock { pub struct NoopCfg; impl Cfg for NoopCfg { - fn fill_cfg_env(&self, _: &mut CfgEnv) {} + fn fill_cfg_env(&self, _env: &mut CfgEnv) {} } diff --git a/src/fill/traits.rs b/src/fill/traits.rs index c01e0cc..777616e 100644 --- a/src/fill/traits.rs +++ b/src/fill/traits.rs @@ -230,4 +230,40 @@ mod test { *chain_id = 1; } } + + // This test exists to ensure that if fields are added to BlockEnv or TxEnv, + // the compiler will emit an error to remind us to update the fillers to + // handle the new fields. The change canary is not present for [`CfgEnv`] + // because it is marked `#[non_exhaustive]`, which prevents compiler errors + // when fields are added. This is moderately annoying. + #[allow(unused_variables)] + fn _change_canary(block: &BlockEnv, tx: &TxEnv) { + let BlockEnv { + number, + beneficiary, + timestamp, + gas_limit, + basefee, + difficulty, + prevrandao, + blob_excess_gas_and_price, + } = block; + + let TxEnv { + tx_type, + caller, + gas_limit, + gas_price, + kind, + value, + data, + nonce, + chain_id, + access_list, + gas_priority_fee, + blob_hashes, + max_fee_per_blob_gas, + authorization_list, + } = tx; + } }