Skip to main content

revm_inspector/
lib.rs

1//! Inspector is a crate that provides a set of traits that allow inspecting the EVM execution.
2//!
3//! It is used to implement tracers that can be used to inspect the EVM execution.
4//! Implementing inspection is optional and it does not effect the core execution.
5#![cfg_attr(not(test), warn(unused_crate_dependencies))]
6#![cfg_attr(not(feature = "std"), no_std)]
7
8mod count_inspector;
9#[cfg(feature = "tracer")]
10mod eip3155;
11mod either;
12mod gas;
13/// Handler implementations for inspector integration.
14pub mod handler;
15mod inspect;
16mod inspector;
17mod mainnet_inspect;
18mod noop;
19/// Test inspector for testing EVM execution.
20pub mod test_inspector;
21mod traits;
22
23#[cfg(test)]
24mod inspector_tests;
25
26/// Inspector implementations.
27pub mod inspectors {
28    #[cfg(feature = "tracer")]
29    pub use super::eip3155::TracerEip3155;
30    pub use super::gas::GasInspector;
31}
32
33pub use context;
34pub use database_interface;
35pub use handler as evm_handler;
36pub use interpreter;
37pub use primitives;
38pub use state;
39
40pub use count_inspector::CountInspector;
41pub use handler::{inspect_instructions, InspectorHandler};
42pub use inspect::{InspectCommitEvm, InspectEvm, InspectSystemCallEvm};
43pub use inspector::*;
44pub use noop::NoOpInspector;
45pub use test_inspector::{InspectorEvent, InterpreterState, StepRecord, TestInspector};
46pub use traits::*;
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51    use ::handler::{MainBuilder, MainContext};
52    use context::{BlockEnv, CfgEnv, Context, Journal, TxEnv};
53    use database::{BenchmarkDB, BENCH_CALLER, BENCH_TARGET};
54    use interpreter::{interpreter::EthInterpreter, InstructionResult, InterpreterTypes};
55    use primitives::TxKind;
56    use state::{bytecode::opcode, Bytecode};
57
58    struct HaltInspector;
59    impl<CTX, INTR: InterpreterTypes> Inspector<CTX, INTR> for HaltInspector {
60        fn step(&mut self, interp: &mut interpreter::Interpreter<INTR>, _context: &mut CTX) {
61            interp.halt(InstructionResult::Stop);
62        }
63    }
64
65    #[test]
66    fn test_step_halt() {
67        let bytecode = [opcode::INVALID];
68        let r = run(&bytecode, HaltInspector);
69        assert!(r.is_success());
70    }
71
72    fn run(
73        bytecode: &[u8],
74        inspector: impl Inspector<
75            Context<BlockEnv, TxEnv, CfgEnv, BenchmarkDB, Journal<BenchmarkDB>, ()>,
76            EthInterpreter,
77        >,
78    ) -> context::result::ExecutionResult {
79        let bytecode = Bytecode::new_raw(bytecode.to_vec().into());
80        let ctx = Context::mainnet().with_db(BenchmarkDB::new_bytecode(bytecode));
81        let mut evm = ctx.build_mainnet_with_inspector(inspector);
82        evm.inspect_one_tx(
83            TxEnv::builder()
84                .caller(BENCH_CALLER)
85                .kind(TxKind::Call(BENCH_TARGET))
86                .gas_limit(21100)
87                .build()
88                .unwrap(),
89        )
90        .unwrap()
91    }
92}