Skip to content

Commit 5eecb99

Browse files
committed
refactor: generalize
1 parent 148b3aa commit 5eecb99

File tree

2 files changed

+45
-19
lines changed

2 files changed

+45
-19
lines changed

src/evm.rs

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{
22
db::{StateAcc, TryStateAcc},
33
driver::DriveBlockResult,
4-
helpers::{Ctx, Evm},
4+
helpers::{Ctx, Evm, Instruction},
55
Block, BlockDriver, BundleDriver, Cfg, ChainDriver, DriveBundleResult, DriveChainResult,
66
ErroredState, EvmErrored, EvmExtUnchecked, EvmNeedsBlock, EvmNeedsCfg, EvmNeedsTx, EvmReady,
77
EvmTransacted, HasBlock, HasCfg, HasTx, NeedsCfg, NeedsTx, TransactedState, Tx,
@@ -188,33 +188,57 @@ where
188188
}
189189
}
190190

191+
/// Overide an opcode with a custom handler. Returns the previous
192+
/// instruction handler for the opcode.
193+
pub fn override_opcode(&mut self, opcode: u8, handler: Instruction<Db>) -> Instruction<Db> {
194+
std::mem::replace(&mut self.inner.instruction.instruction_table[opcode as usize], handler)
195+
}
196+
197+
/// Disable an opcode by replacing it with unknown opcode behavior. This is
198+
/// a shortcut for [`Self::override_opcode`] with [`control::unknown`].
199+
pub fn disable_opcode(&mut self, opcode: u8) -> Instruction<Db> {
200+
self.override_opcode(opcode, control::unknown)
201+
}
202+
203+
/// Run some closure with an opcode override, then restore the previous
204+
/// setting.
205+
pub fn with_opcode_override<F, NewState>(
206+
mut self,
207+
opcode: u8,
208+
handler: Instruction<Db>,
209+
f: F,
210+
) -> Trevm<Db, Insp, NewState>
211+
where
212+
F: FnOnce(Self) -> Trevm<Db, Insp, NewState>,
213+
{
214+
let old = self.override_opcode(opcode, handler);
215+
self.inner.instruction.insert_instruction(opcode, handler);
216+
let mut this = f(self);
217+
this.override_opcode(opcode, old);
218+
this
219+
}
220+
191221
/// Disable the prevrandao opcode, by replacing it with unknown opcode
192222
/// behavior. This is useful for block simulation, where the prevrandao
193223
/// opcode may produce incorrect results.
194-
pub fn disable_prevrandao(&mut self) {
195-
self.inner.instruction.insert_instruction(DIFFICULTY, control::unknown);
224+
pub fn disable_prevrandao(&mut self) -> Instruction<Db> {
225+
self.disable_opcode(DIFFICULTY)
196226
}
197227

198228
/// Enable the prevrandao opcode. If the prevrandao opcode was not
199229
/// previously disabled or replaced, this will have no effect on behavior.
200-
pub fn enable_prevrandao(&mut self) {
201-
self.inner.instruction.insert_instruction(DIFFICULTY, block_info::difficulty);
230+
pub fn enable_prevrandao(&mut self) -> Instruction<Db> {
231+
self.override_opcode(DIFFICULTY, block_info::difficulty)
202232
}
203233

204234
/// Run some code with the prevrandao opcode disabled, then restore the
205235
/// previous setting. This is useful for block simulation, where the
206236
/// prevrandao opcode may produce incorrect results.
207-
pub fn without_prevrandao<F, NewState>(mut self, f: F) -> Trevm<Db, Insp, NewState>
237+
pub fn without_prevrandao<F, NewState>(self, f: F) -> Trevm<Db, Insp, NewState>
208238
where
209239
F: FnOnce(Self) -> Trevm<Db, Insp, NewState>,
210240
{
211-
let handler = std::mem::replace(
212-
&mut self.inner.instruction.instruction_table[DIFFICULTY as usize],
213-
control::unknown,
214-
);
215-
let mut new = f(self);
216-
new.inner.instruction.insert_instruction(DIFFICULTY, handler);
217-
new
241+
self.with_opcode_override(DIFFICULTY, control::unknown, f)
218242
}
219243
}
220244

src/helpers.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ use revm::{
1010
pub type Ctx<Db, J = Journal<Db>, C = ()> = Context<BlockEnv, TxEnv, CfgEnv, Db, J, C>;
1111

1212
/// EVM with default env types and adjustable DB.
13-
pub type Evm<
14-
Db,
15-
Insp = NoOpInspector,
16-
Inst = EthInstructions<EthInterpreter, Ctx<Db>>,
17-
Prec = EthPrecompiles,
18-
> = revm::context::Evm<Ctx<Db>, Insp, Inst, Prec>;
13+
pub type Evm<Db, Insp = NoOpInspector, Inst = Instructions<Db>, Prec = EthPrecompiles> =
14+
revm::context::Evm<Ctx<Db>, Insp, Inst, Prec>;
15+
16+
/// Handler table for EVM opcodes.
17+
pub type Instructions<Db> = EthInstructions<EthInterpreter, Ctx<Db>>;
18+
19+
/// The handler type for an EVM opcode.
20+
pub type Instruction<Db> = revm::interpreter::Instruction<EthInterpreter, Ctx<Db>>;

0 commit comments

Comments
 (0)