Skip to content

Commit 01298e4

Browse files
mattsseclaudeklkvrrakita
authored
chore: bump revm 25 (#100)
* chore: bump revm 25 * more saturating * feat: complete revm v25 migration with proper type conversions ## Original Task Complete the migration to revm v25 and follow the hints in issue #99: - Change `ResultAndState<Halt, EvmState>` to `ResultAndState<ExecutionResult<Halt>, EvmState>` - For block numbers and timestamps, use `saturating_to()` when converting from U256 to u64 ## Changes Applied ### Type System Updates - Updated all `ResultAndState` signatures from `ResultAndState<HaltReason, EvmState>` to `ResultAndState<ExecutionResult<HaltReason>, EvmState>` across: - Core `Evm` trait definitions in `src/evm.rs` - Ethereum implementation in `src/eth/mod.rs` - OP implementation in `src/lib.rs` - Either wrapper in `src/either.rs` - All system call implementations (EIP-2935, EIP-4788, EIP-7002, EIP-7251) ### U256 to u64 Conversions - Added `saturating_to()` method calls for all U256 to u64 conversions: - `block().number.saturating_to()` for block number conversions - `block().timestamp.saturating_to()` for timestamp conversions - Applied across both `alloy-evm` and `alloy-op-evm` crates ### EVM Integration Updates - Replaced manual `transact()` + `journaled_state.finalize()` pattern with `transact_finalize()` - Updated Account struct initialization to include required `transaction_id: 0` field - Simplified transaction execution logic using revm v25's improved API ### Import Updates - Added `ExecutionResult` and `EvmState` imports where needed - Removed unused `InspectEvm` imports - Updated import paths for revm v25 module structure ## Testing - All existing tests pass - Build completes without warnings - Both `alloy-evm` and `alloy-op-evm` crates compile successfully 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * rusfmt * bump * bumo * chore: bump revm 26 * chore: bump revm v26.0.0 (#105) fix compilation --------- Co-authored-by: Claude <[email protected]> Co-authored-by: Arsenii Kulikov <[email protected]> Co-authored-by: rakita <[email protected]>
1 parent 5110194 commit 01298e4

File tree

10 files changed

+64
-34
lines changed

10 files changed

+64
-34
lines changed

Cargo.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,16 @@ alloy-op-hardforks = { version = "0.2" }
5252
op-alloy-consensus = { version = "0.18", default-features = false }
5353

5454
# revm
55-
revm = { version = "24.0.0", default-features = false }
56-
op-revm = { version = "5.0.0", default-features = false }
55+
revm = { version = "26.0.0", default-features = false }
56+
op-revm = { version = "7.0.0", default-features = false }
5757

5858
# misc
5959
auto_impl = "1"
6060
derive_more = { version = "2", default-features = false, features = ["full"] }
6161
serde = { version = "1", default-features = false, features = ["derive"] }
6262
thiserror = { version = "2.0.0", default-features = false }
6363
serde_json = "1"
64+
65+
#[patch.crates-io]
66+
#revm = { git = "https://github.com/bluealloy/revm", rev = "11b16259" }
67+
#op-revm = { git = "https://github.com/bluealloy/revm", rev = "11b16259" }

crates/evm/src/block/state_changes.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,16 @@ where
2929
let mut balance_increments = HashMap::default();
3030

3131
// Add block rewards if they are enabled.
32-
if let Some(base_block_reward) = calc::base_block_reward(&spec, block_env.number) {
32+
if let Some(base_block_reward) =
33+
calc::base_block_reward(&spec, block_env.number.saturating_to())
34+
{
3335
// Ommer rewards
3436
for ommer in ommers {
35-
*balance_increments.entry(ommer.beneficiary()).or_default() +=
36-
calc::ommer_reward(base_block_reward, block_env.number, ommer.number());
37+
*balance_increments.entry(ommer.beneficiary()).or_default() += calc::ommer_reward(
38+
base_block_reward,
39+
block_env.number.saturating_to(),
40+
ommer.number(),
41+
);
3742
}
3843

3944
// Full block reward
@@ -44,7 +49,7 @@ where
4449
// process withdrawals
4550
insert_post_block_withdrawals_balance_increments(
4651
spec,
47-
block_env.timestamp,
52+
block_env.timestamp.saturating_to(),
4853
withdrawals.map(|w| w.as_slice()),
4954
&mut balance_increments,
5055
);
@@ -122,6 +127,7 @@ where
122127
info: account.info.clone(),
123128
storage: Default::default(),
124129
status: AccountStatus::Touched,
130+
transaction_id: 0,
125131
},
126132
))
127133
};

crates/evm/src/block/system_calls/eip2935.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ pub(crate) fn transact_blockhashes_contract_call<Halt>(
2828
parent_block_hash: B256,
2929
evm: &mut impl Evm<HaltReason = Halt>,
3030
) -> Result<Option<ResultAndState<Halt>>, BlockExecutionError> {
31-
if !spec.is_prague_active_at_timestamp(evm.block().timestamp) {
31+
if !spec.is_prague_active_at_timestamp(evm.block().timestamp.saturating_to()) {
3232
return Ok(None);
3333
}
3434

3535
// if the block number is zero (genesis block) then no system transaction may occur as per
3636
// EIP-2935
37-
if evm.block().number == 0 {
37+
if evm.block().number.is_zero() {
3838
return Ok(None);
3939
}
4040

crates/evm/src/block/system_calls/eip4788.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub(crate) fn transact_beacon_root_contract_call<Halt>(
2525
parent_beacon_block_root: Option<B256>,
2626
evm: &mut impl Evm<HaltReason = Halt>,
2727
) -> Result<Option<ResultAndState<Halt>>, BlockExecutionError> {
28-
if !spec.is_cancun_active_at_timestamp(evm.block().timestamp) {
28+
if !spec.is_cancun_active_at_timestamp(evm.block().timestamp.saturating_to()) {
2929
return Ok(None);
3030
}
3131

@@ -34,7 +34,7 @@ pub(crate) fn transact_beacon_root_contract_call<Halt>(
3434

3535
// if the block number is zero (genesis block) then the parent beacon block root must
3636
// be 0x0 and no system transaction may occur as per EIP-4788
37-
if evm.block().number == 0 {
37+
if evm.block().number.is_zero() {
3838
if !parent_beacon_block_root.is_zero() {
3939
return Err(BlockValidationError::CancunGenesisParentBeaconBlockRootNotZero {
4040
parent_beacon_block_root,

crates/evm/src/eth/block.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ where
9595
fn apply_pre_execution_changes(&mut self) -> Result<(), BlockExecutionError> {
9696
// Set state clear flag if the block is after the Spurious Dragon hardfork.
9797
let state_clear_flag =
98-
self.spec.is_spurious_dragon_active_at_block(self.evm.block().number);
98+
self.spec.is_spurious_dragon_active_at_block(self.evm.block().number.saturating_to());
9999
self.evm.db_mut().set_state_clear_flag(state_clear_flag);
100100

101101
self.system_caller.apply_blockhashes_contract_call(self.ctx.parent_hash, &mut self.evm)?;
@@ -157,7 +157,10 @@ where
157157
fn finish(
158158
mut self,
159159
) -> Result<(Self::Evm, BlockExecutionResult<R::Receipt>), BlockExecutionError> {
160-
let requests = if self.spec.is_prague_active_at_timestamp(self.evm.block().timestamp) {
160+
let requests = if self
161+
.spec
162+
.is_prague_active_at_timestamp(self.evm.block().timestamp.saturating_to())
163+
{
161164
// Collect all EIP-6110 deposits
162165
let deposit_requests =
163166
eip6110::parse_deposits_from_receipts(&self.spec, &self.receipts)?;
@@ -185,7 +188,7 @@ where
185188
if self
186189
.spec
187190
.ethereum_fork_activation(EthereumHardfork::Dao)
188-
.transitions_at_block(self.evm.block().number)
191+
.transitions_at_block(self.evm.block().number.saturating_to())
189192
{
190193
// drain balances from hardcoded addresses.
191194
let drained_balance: u128 = self

crates/evm/src/eth/mod.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use core::{
1010
use revm::{
1111
context::{BlockEnv, CfgEnv, Evm as RevmEvm, TxEnv},
1212
context_interface::result::{EVMError, HaltReason, ResultAndState},
13-
handler::{instructions::EthInstructions, EthPrecompiles, PrecompileProvider},
13+
handler::{instructions::EthInstructions, EthFrame, EthPrecompiles, PrecompileProvider},
1414
inspector::NoOpInspector,
1515
interpreter::{interpreter::EthInterpreter, InterpreterResult},
1616
precompile::{PrecompileSpecId, Precompiles},
@@ -41,6 +41,7 @@ pub struct EthEvm<DB: Database, I, PRECOMPILE = EthPrecompiles> {
4141
I,
4242
EthInstructions<EthInterpreter, EthEvmContext<DB>>,
4343
PRECOMPILE,
44+
EthFrame,
4445
>,
4546
inspect: bool,
4647
}
@@ -56,6 +57,7 @@ impl<DB: Database, I, PRECOMPILE> EthEvm<DB, I, PRECOMPILE> {
5657
I,
5758
EthInstructions<EthInterpreter, EthEvmContext<DB>>,
5859
PRECOMPILE,
60+
EthFrame,
5961
>,
6062
inspect: bool,
6163
) -> Self {
@@ -65,8 +67,13 @@ impl<DB: Database, I, PRECOMPILE> EthEvm<DB, I, PRECOMPILE> {
6567
/// Consumes self and return the inner EVM instance.
6668
pub fn into_inner(
6769
self,
68-
) -> RevmEvm<EthEvmContext<DB>, I, EthInstructions<EthInterpreter, EthEvmContext<DB>>, PRECOMPILE>
69-
{
70+
) -> RevmEvm<
71+
EthEvmContext<DB>,
72+
I,
73+
EthInstructions<EthInterpreter, EthEvmContext<DB>>,
74+
PRECOMPILE,
75+
EthFrame,
76+
> {
7077
self.inner
7178
}
7279

@@ -119,10 +126,12 @@ where
119126
self.cfg.chain_id
120127
}
121128

122-
fn transact_raw(&mut self, tx: Self::Tx) -> Result<ResultAndState, Self::Error> {
129+
fn transact_raw(
130+
&mut self,
131+
tx: Self::Tx,
132+
) -> Result<ResultAndState<Self::HaltReason>, Self::Error> {
123133
if self.inspect {
124-
self.inner.set_tx(tx);
125-
self.inner.inspect_replay()
134+
self.inner.inspect_tx(tx)
126135
} else {
127136
self.inner.transact(tx)
128137
}
@@ -133,7 +142,7 @@ where
133142
caller: Address,
134143
contract: Address,
135144
data: Bytes,
136-
) -> Result<ResultAndState, Self::Error> {
145+
) -> Result<ResultAndState<Self::HaltReason>, Self::Error> {
137146
let tx = TxEnv {
138147
caller,
139148
kind: TxKind::Call(contract),

crates/evm/src/precompiles.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -231,12 +231,14 @@ impl<CTX: ContextTr> PrecompileProvider<CTX> for PrecompilesMap {
231231
let r;
232232
let input_bytes = match &inputs.input {
233233
CallInput::SharedBuffer(range) => {
234-
match context.local().shared_memory_buffer_slice(range.clone()) {
235-
Some(slice) => {
236-
r = slice;
237-
&*r
238-
}
239-
None => &[],
234+
// `map_or` does not work here as we use `r` to extend lifetime of the slice
235+
// and return it.
236+
#[allow(clippy::option_if_let_else)]
237+
if let Some(slice) = context.local().shared_memory_buffer_slice(range.clone()) {
238+
r = slice;
239+
r.as_ref()
240+
} else {
241+
&[]
240242
}
241243
}
242244
CallInput::Bytes(bytes) => bytes.as_ref(),

crates/evm/src/tracing.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ impl<E: Evm, Txs: Iterator, F> TracerIter<'_, E, Txs, F> {
112112
}
113113
}
114114

115-
impl<'a, E, T, Txs, F, O, Err> Iterator for TracerIter<'a, E, Txs, F>
115+
impl<E, T, Txs, F, O, Err> Iterator for TracerIter<'_, E, Txs, F>
116116
where
117117
E: Evm<DB: DatabaseCommit, Inspector: Clone>,
118118
T: IntoTxEnv<E::Tx> + Clone,

crates/op-evm/src/block/mod.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ where
7272
/// Creates a new [`OpBlockExecutor`].
7373
pub fn new(evm: E, ctx: OpBlockExecutionCtx, spec: Spec, receipt_builder: R) -> Self {
7474
Self {
75-
is_regolith: spec.is_regolith_active_at_timestamp(evm.block().timestamp),
75+
is_regolith: spec
76+
.is_regolith_active_at_timestamp(evm.block().timestamp.saturating_to()),
7677
evm,
7778
system_caller: SystemCaller::new(spec.clone()),
7879
spec,
@@ -101,7 +102,7 @@ where
101102
fn apply_pre_execution_changes(&mut self) -> Result<(), BlockExecutionError> {
102103
// Set state clear flag if the block is after the Spurious Dragon hardfork.
103104
let state_clear_flag =
104-
self.spec.is_spurious_dragon_active_at_block(self.evm.block().number);
105+
self.spec.is_spurious_dragon_active_at_block(self.evm.block().number.saturating_to());
105106
self.evm.db_mut().set_state_clear_flag(state_clear_flag);
106107

107108
self.system_caller.apply_blockhashes_contract_call(self.ctx.parent_hash, &mut self.evm)?;
@@ -112,8 +113,12 @@ where
112113
// blocks will always have at least a single transaction in them (the L1 info transaction),
113114
// so we can safely assume that this will always be triggered upon the transition and that
114115
// the above check for empty blocks will never be hit on OP chains.
115-
ensure_create2_deployer(&self.spec, self.evm.block().timestamp, self.evm.db_mut())
116-
.map_err(BlockExecutionError::other)?;
116+
ensure_create2_deployer(
117+
&self.spec,
118+
self.evm.block().timestamp.saturating_to(),
119+
self.evm.db_mut(),
120+
)
121+
.map_err(BlockExecutionError::other)?;
117122

118123
Ok(())
119124
}
@@ -195,7 +200,9 @@ where
195200
// this is only set for post-Canyon deposit
196201
// transactions.
197202
deposit_receipt_version: (is_deposit
198-
&& self.spec.is_canyon_active_at_timestamp(self.evm.block().timestamp))
203+
&& self.spec.is_canyon_active_at_timestamp(
204+
self.evm.block().timestamp.saturating_to(),
205+
))
199206
.then_some(1),
200207
})
201208
}

crates/op-evm/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,7 @@ where
112112
tx: Self::Tx,
113113
) -> Result<ResultAndState<Self::HaltReason>, Self::Error> {
114114
if self.inspect {
115-
self.inner.set_tx(tx);
116-
self.inner.inspect_replay()
115+
self.inner.inspect_tx(tx)
117116
} else {
118117
self.inner.transact(tx)
119118
}

0 commit comments

Comments
 (0)