use crate::precompiles::OpPrecompiles;
use revm::{
context::{ContextSetters, Evm},
context_interface::ContextTr,
handler::{
instructions::{EthInstructions, InstructionProvider},
EvmTr, PrecompileProvider,
},
inspector::{InspectorEvmTr, JournalExt},
interpreter::{interpreter::EthInterpreter, Interpreter, InterpreterAction, InterpreterTypes},
Inspector,
};
pub struct OpEvm<CTX, INSP, I = EthInstructions<EthInterpreter, CTX>, P = OpPrecompiles>(
pub Evm<CTX, INSP, I, P>,
);
impl<CTX: ContextTr, INSP> OpEvm<CTX, INSP, EthInstructions<EthInterpreter, CTX>, OpPrecompiles> {
pub fn new(ctx: CTX, inspector: INSP) -> Self {
Self(Evm {
ctx,
inspector,
instruction: EthInstructions::new_mainnet(),
precompiles: OpPrecompiles::default(),
})
}
}
impl<CTX, INSP, I, P> OpEvm<CTX, INSP, I, P> {
pub fn with_inspector<OINSP>(self, inspector: OINSP) -> OpEvm<CTX, OINSP, I, P> {
OpEvm(self.0.with_inspector(inspector))
}
pub fn with_precompiles<OP>(self, precompiles: OP) -> OpEvm<CTX, INSP, I, OP> {
OpEvm(self.0.with_precompiles(precompiles))
}
pub fn into_inspector(self) -> INSP {
self.0.into_inspector()
}
}
impl<CTX, INSP, I, P> InspectorEvmTr for OpEvm<CTX, INSP, I, P>
where
CTX: ContextTr<Journal: JournalExt> + ContextSetters,
I: InstructionProvider<
Context = CTX,
InterpreterTypes: InterpreterTypes<Output = InterpreterAction>,
>,
P: PrecompileProvider<CTX>,
INSP: Inspector<CTX, I::InterpreterTypes>,
{
type Inspector = INSP;
fn inspector(&mut self) -> &mut Self::Inspector {
&mut self.0.inspector
}
fn ctx_inspector(&mut self) -> (&mut Self::Context, &mut Self::Inspector) {
(&mut self.0.ctx, &mut self.0.inspector)
}
fn run_inspect_interpreter(
&mut self,
interpreter: &mut Interpreter<
<Self::Instructions as InstructionProvider>::InterpreterTypes,
>,
) -> <<Self::Instructions as InstructionProvider>::InterpreterTypes as InterpreterTypes>::Output
{
self.0.run_inspect_interpreter(interpreter)
}
}
impl<CTX, INSP, I, P> EvmTr for OpEvm<CTX, INSP, I, P>
where
CTX: ContextTr,
I: InstructionProvider<
Context = CTX,
InterpreterTypes: InterpreterTypes<Output = InterpreterAction>,
>,
P: PrecompileProvider<CTX>,
{
type Context = CTX;
type Instructions = I;
type Precompiles = P;
fn run_interpreter(
&mut self,
interpreter: &mut Interpreter<
<Self::Instructions as InstructionProvider>::InterpreterTypes,
>,
) -> <<Self::Instructions as InstructionProvider>::InterpreterTypes as InterpreterTypes>::Output
{
let context = &mut self.0.ctx;
let instructions = &mut self.0.instruction;
interpreter.run_plain(instructions.instruction_table(), context)
}
fn ctx(&mut self) -> &mut Self::Context {
&mut self.0.ctx
}
fn ctx_ref(&self) -> &Self::Context {
&self.0.ctx
}
fn ctx_instructions(&mut self) -> (&mut Self::Context, &mut Self::Instructions) {
(&mut self.0.ctx, &mut self.0.instruction)
}
fn ctx_precompiles(&mut self) -> (&mut Self::Context, &mut Self::Precompiles) {
(&mut self.0.ctx, &mut self.0.precompiles)
}
}