Skip to content

Commit 92a5432

Browse files
committed
refactor(examples): Use OpEvm from op-alloy-evm instead of op-revm for CustomEvm in custom_node example
Removes the duplicated implementation already contained in the `op-alloy-evm` version
1 parent b347d9d commit 92a5432

File tree

2 files changed

+143
-160
lines changed

2 files changed

+143
-160
lines changed
Lines changed: 51 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,33 @@
11
use crate::evm::{CustomEvmTransaction, CustomTxEnv};
22
use alloy_evm::{precompiles::PrecompilesMap, Database, Evm, EvmEnv, EvmFactory};
3-
use alloy_primitives::{Address, Bytes, TxKind, U256};
4-
use op_alloy_consensus::OpTxType;
3+
use alloy_op_evm::OpEvm;
4+
use alloy_primitives::{Address, Bytes};
55
use op_revm::{
6-
precompiles::OpPrecompiles, transaction::deposit::DepositTransactionParts, DefaultOp,
7-
L1BlockInfo, OpBuilder, OpHaltReason, OpSpecId, OpTransaction, OpTransactionError,
6+
precompiles::OpPrecompiles, DefaultOp, L1BlockInfo, OpBuilder, OpContext, OpHaltReason,
7+
OpSpecId, OpTransaction, OpTransactionError,
88
};
99
use reth_ethereum::evm::revm::{
10-
context::{result::ResultAndState, BlockEnv, CfgEnv, TxEnv},
11-
handler::{instructions::EthInstructions, PrecompileProvider},
12-
interpreter::{interpreter::EthInterpreter, InterpreterResult},
10+
context::{result::ResultAndState, BlockEnv, CfgEnv},
11+
handler::PrecompileProvider,
12+
interpreter::InterpreterResult,
1313
Context, Inspector, Journal,
1414
};
15-
use revm::{
16-
context_interface::result::EVMError, handler::EvmTr, inspector::NoOpInspector, ExecuteEvm,
17-
InspectEvm,
18-
};
15+
use revm::{context_interface::result::EVMError, inspector::NoOpInspector};
1916
use std::error::Error;
2017

2118
/// EVM context contains data that EVM needs for execution of [`CustomEvmTransaction`].
2219
pub type CustomContext<DB> =
2320
Context<BlockEnv, OpTransaction<CustomTxEnv>, CfgEnv<OpSpecId>, DB, Journal<DB>, L1BlockInfo>;
2421

2522
pub struct CustomEvm<DB: Database, I, P = OpPrecompiles> {
26-
inner:
27-
op_revm::OpEvm<CustomContext<DB>, I, EthInstructions<EthInterpreter, CustomContext<DB>>, P>,
28-
inspect: bool,
23+
inner: OpEvm<DB, I, P>,
2924
}
3025

3126
impl<DB, I, P> Evm for CustomEvm<DB, I, P>
3227
where
3328
DB: Database,
34-
I: Inspector<CustomContext<DB>>,
35-
P: PrecompileProvider<CustomContext<DB>, Output = InterpreterResult>,
29+
I: Inspector<OpContext<DB>>,
30+
P: PrecompileProvider<OpContext<DB>, Output = InterpreterResult>,
3631
{
3732
type DB = DB;
3833
type Tx = CustomEvmTransaction;
@@ -43,22 +38,20 @@ where
4338
type Inspector = I;
4439

4540
fn block(&self) -> &BlockEnv {
46-
&self.inner.ctx_ref().block
41+
Evm::block(&self.inner)
4742
}
4843

4944
fn chain_id(&self) -> u64 {
50-
self.inner.ctx_ref().cfg.chain_id
45+
Evm::chain_id(&self.inner)
5146
}
5247

5348
fn transact_raw(
5449
&mut self,
5550
tx: Self::Tx,
5651
) -> Result<ResultAndState<Self::HaltReason>, Self::Error> {
57-
if self.inspect {
58-
self.inner.set_tx(tx.0);
59-
self.inner.inspect_replay()
60-
} else {
61-
self.inner.transact(tx.0)
52+
match tx {
53+
CustomEvmTransaction::Op(tx) => Evm::transact_raw(&mut self.inner, tx),
54+
CustomEvmTransaction::Payment(..) => todo!(),
6255
}
6356
}
6457

@@ -68,116 +61,43 @@ where
6861
contract: Address,
6962
data: Bytes,
7063
) -> Result<ResultAndState<Self::HaltReason>, Self::Error> {
71-
let tx = CustomEvmTransaction(OpTransaction {
72-
base: CustomTxEnv(TxEnv {
73-
caller,
74-
kind: TxKind::Call(contract),
75-
// Explicitly set nonce to 0 so revm does not do any nonce checks
76-
nonce: 0,
77-
gas_limit: 30_000_000,
78-
value: U256::ZERO,
79-
data,
80-
// Setting the gas price to zero enforces that no value is transferred as part of
81-
// the call, and that the call will not count against the block's
82-
// gas limit
83-
gas_price: 0,
84-
// The chain ID check is not relevant here and is disabled if set to None
85-
chain_id: None,
86-
// Setting the gas priority fee to None ensures the effective gas price is derived
87-
// from the `gas_price` field, which we need to be zero
88-
gas_priority_fee: None,
89-
access_list: Default::default(),
90-
// blob fields can be None for this tx
91-
blob_hashes: Vec::new(),
92-
max_fee_per_blob_gas: 0,
93-
tx_type: OpTxType::Deposit as u8,
94-
authorization_list: Default::default(),
95-
}),
96-
// The L1 fee is not charged for the EIP-4788 transaction, submit zero bytes for the
97-
// enveloped tx size.
98-
enveloped_tx: Some(Bytes::default()),
99-
deposit: Default::default(),
100-
});
101-
102-
let mut gas_limit = tx.0.base.0.gas_limit;
103-
let mut basefee = 0;
104-
let mut disable_nonce_check = true;
105-
106-
// ensure the block gas limit is >= the tx
107-
core::mem::swap(&mut self.inner.ctx().block.gas_limit, &mut gas_limit);
108-
// disable the base fee check for this call by setting the base fee to zero
109-
core::mem::swap(&mut self.inner.ctx().block.basefee, &mut basefee);
110-
// disable the nonce check
111-
core::mem::swap(&mut self.inner.ctx().cfg.disable_nonce_check, &mut disable_nonce_check);
112-
113-
let mut res = self.transact(tx);
114-
115-
// swap back to the previous gas limit
116-
core::mem::swap(&mut self.inner.ctx().block.gas_limit, &mut gas_limit);
117-
// swap back to the previous base fee
118-
core::mem::swap(&mut self.inner.ctx().block.basefee, &mut basefee);
119-
// swap back to the previous nonce check flag
120-
core::mem::swap(&mut self.inner.ctx().cfg.disable_nonce_check, &mut disable_nonce_check);
121-
122-
// NOTE: We assume that only the contract storage is modified. Revm currently marks the
123-
// caller and block beneficiary accounts as "touched" when we do the above transact calls,
124-
// and includes them in the result.
125-
//
126-
// We're doing this state cleanup to make sure that changeset only includes the changed
127-
// contract storage.
128-
if let Ok(res) = &mut res {
129-
res.state.retain(|addr, _| *addr == contract);
130-
}
131-
132-
res
64+
Evm::transact_system_call(&mut self.inner, caller, contract, data)
13365
}
13466

13567
fn db_mut(&mut self) -> &mut Self::DB {
136-
&mut self.inner.ctx().journaled_state.database
68+
Evm::db_mut(&mut self.inner)
13769
}
13870

13971
fn finish(self) -> (Self::DB, EvmEnv<Self::Spec>) {
140-
let Context { block: block_env, cfg: cfg_env, journaled_state, .. } = self.inner.0.ctx;
141-
142-
(journaled_state.database, EvmEnv { block_env, cfg_env })
72+
Evm::finish(self.inner)
14373
}
14474

14575
fn set_inspector_enabled(&mut self, enabled: bool) {
146-
self.inspect = enabled;
76+
Evm::set_inspector_enabled(&mut self.inner, enabled)
14777
}
14878

14979
fn precompiles(&self) -> &Self::Precompiles {
150-
&self.inner.0.precompiles
80+
Evm::precompiles(&self.inner)
15181
}
15282

15383
fn precompiles_mut(&mut self) -> &mut Self::Precompiles {
154-
&mut self.inner.0.precompiles
84+
Evm::precompiles_mut(&mut self.inner)
15585
}
15686

15787
fn inspector(&self) -> &Self::Inspector {
158-
&self.inner.0.inspector
88+
Evm::inspector(&self.inner)
15989
}
16090

16191
fn inspector_mut(&mut self) -> &mut Self::Inspector {
162-
&mut self.inner.0.inspector
92+
Evm::inspector_mut(&mut self.inner)
16393
}
16494
}
16595

16696
pub struct CustomEvmFactory;
16797

168-
impl CustomEvmFactory {
169-
fn default_tx() -> CustomEvmTransaction {
170-
CustomEvmTransaction(OpTransaction {
171-
base: CustomTxEnv::default(),
172-
enveloped_tx: Some(vec![0x00].into()),
173-
deposit: DepositTransactionParts::default(),
174-
})
175-
}
176-
}
177-
17898
impl EvmFactory for CustomEvmFactory {
179-
type Evm<DB: Database, I: Inspector<CustomContext<DB>>> = CustomEvm<DB, I, Self::Precompiles>;
180-
type Context<DB: Database> = CustomContext<DB>;
99+
type Evm<DB: Database, I: Inspector<OpContext<DB>>> = CustomEvm<DB, I, Self::Precompiles>;
100+
type Context<DB: Database> = OpContext<DB>;
181101
type Tx = CustomEvmTransaction;
182102
type Error<DBError: Error + Send + Sync + 'static> = EVMError<DBError, OpTransactionError>;
183103
type HaltReason = OpHaltReason;
@@ -191,16 +111,18 @@ impl EvmFactory for CustomEvmFactory {
191111
) -> Self::Evm<DB, NoOpInspector> {
192112
let spec_id = input.cfg_env.spec;
193113
CustomEvm {
194-
inner: Context::op()
195-
.with_tx(Self::default_tx().0)
196-
.with_db(db)
197-
.with_block(input.block_env)
198-
.with_cfg(input.cfg_env)
199-
.build_op_with_inspector(NoOpInspector {})
200-
.with_precompiles(PrecompilesMap::from_static(
201-
OpPrecompiles::new_with_spec(spec_id).precompiles(),
202-
)),
203-
inspect: false,
114+
inner: OpEvm::new(
115+
Context::op()
116+
.with_tx(OpTransaction::default())
117+
.with_db(db)
118+
.with_block(input.block_env)
119+
.with_cfg(input.cfg_env)
120+
.build_op_with_inspector(NoOpInspector {})
121+
.with_precompiles(PrecompilesMap::from_static(
122+
OpPrecompiles::new_with_spec(spec_id).precompiles(),
123+
)),
124+
false,
125+
),
204126
}
205127
}
206128

@@ -211,17 +133,20 @@ impl EvmFactory for CustomEvmFactory {
211133
inspector: I,
212134
) -> Self::Evm<DB, I> {
213135
let spec_id = input.cfg_env.spec;
136+
214137
CustomEvm {
215-
inner: Context::op()
216-
.with_tx(Self::default_tx().0)
217-
.with_db(db)
218-
.with_block(input.block_env)
219-
.with_cfg(input.cfg_env)
220-
.build_op_with_inspector(inspector)
221-
.with_precompiles(PrecompilesMap::from_static(
222-
OpPrecompiles::new_with_spec(spec_id).precompiles(),
223-
)),
224-
inspect: true,
138+
inner: OpEvm::new(
139+
Context::op()
140+
.with_tx(OpTransaction::default())
141+
.with_db(db)
142+
.with_block(input.block_env)
143+
.with_cfg(input.cfg_env)
144+
.build_op_with_inspector(inspector)
145+
.with_precompiles(PrecompilesMap::from_static(
146+
OpPrecompiles::new_with_spec(spec_id).precompiles(),
147+
)),
148+
true,
149+
),
225150
}
226151
}
227152
}

0 commit comments

Comments
 (0)