foundry_evm/inspectors/
chisel_state.rs

1use alloy_primitives::U256;
2use foundry_evm_core::backend::DatabaseError;
3use revm::{
4    context::ContextTr,
5    inspector::JournalExt,
6    interpreter::{
7        interpreter::EthInterpreter, interpreter_types::Jumps, InstructionResult, Interpreter,
8    },
9    Database, Inspector,
10};
11
12/// An inspector for Chisel
13#[derive(Clone, Debug, Default)]
14pub struct ChiselState {
15    /// The PC of the final instruction
16    pub final_pc: usize,
17    /// The final state of the REPL contract call
18    pub state: Option<(Vec<U256>, Vec<u8>, InstructionResult)>,
19}
20
21impl ChiselState {
22    /// Create a new Chisel state inspector.
23    #[inline]
24    pub fn new(final_pc: usize) -> Self {
25        Self { final_pc, state: None }
26    }
27}
28
29impl<CTX, D> Inspector<CTX, EthInterpreter> for ChiselState
30where
31    D: Database<Error = DatabaseError>,
32    CTX: ContextTr<Db = D>,
33    CTX::Journal: JournalExt,
34{
35    #[cold]
36    fn step_end(&mut self, interp: &mut Interpreter, _context: &mut CTX) {
37        // If we are at the final pc of the REPL contract execution, set the state.
38        // Subtraction can't overflow because `pc` is always at least 1 in `step_end`.
39        if self.final_pc == interp.bytecode.pc() - 1 {
40            self.state = Some((
41                interp.stack.data().clone(),
42                interp.memory.context_memory().to_vec(),
43                interp.control.instruction_result,
44            ))
45        }
46    }
47}