Skip to main content

revm_interpreter/
instruction_context.rs

1use context_interface::{context::SStoreResult, Host};
2use primitives::Address;
3
4use crate::{
5    InstructionContext as Ictx, InstructionResult, Interpreter, InterpreterTypes as ITy,
6    InterpreterTypes,
7};
8
9/// Context passed to instruction implementations containing the host and interpreter.
10/// This struct provides access to both the host interface for external state operations
11/// and the interpreter state for stack, memory, and gas operations.
12pub struct InstructionContext<'a, H: ?Sized, ITy: InterpreterTypes> {
13    /// Reference to the interpreter containing execution state (stack, memory, gas, etc).
14    pub interpreter: &'a mut Interpreter<ITy>,
15    /// Reference to the host interface for accessing external blockchain state.
16    pub host: &'a mut H,
17}
18
19impl<H: ?Sized, IT: InterpreterTypes> std::fmt::Debug for InstructionContext<'_, H, IT> {
20    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21        f.debug_struct("InstructionContext")
22            .field("host", &"<host>")
23            .field("interpreter", &"<interpreter>")
24            .finish()
25    }
26}
27
28/// Result of SSTORE gas-state side effects.
29///
30/// Implementations of [`GasStateTr`] return this to let opcode-level SSTORE
31/// accounting be overridden without knowing how the gas-state backend is stored.
32#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
33#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
34pub struct GasStateOutcome {
35    /// Whether normal SSTORE refund accounting should be skipped.
36    pub skip_refund: bool,
37    /// Whether opcode-level SSTORE dynamic gas and EIP-8037 state-gas accounting should be skipped.
38    ///
39    /// When true, the gas-state policy is responsible for any replacement gas accounting.
40    pub skip_gas: bool,
41}
42
43/// Type-level SSTORE gas-state policy.
44///
45/// This hook is called after the storage write has been journaled and before
46/// the subsequent state-gas/refund accounting. The default policy is a no-op.
47pub trait GasStateTr<IT: ITy, H: Host + ?Sized> {
48    /// Called after the main SSTORE journal update and before final gas/refund accounting.
49    fn sstore_gas_state(
50        context: &mut Ictx<'_, H, IT>,
51        owner: Address,
52        vals: &SStoreResult,
53    ) -> Result<GasStateOutcome, InstructionResult>;
54}
55
56/// No-op SSTORE gas-state policy.
57#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
58pub struct NoGasState;
59
60impl<IT: ITy, H: Host + ?Sized> GasStateTr<IT, H> for NoGasState {
61    #[inline]
62    fn sstore_gas_state(
63        _context: &mut Ictx<'_, H, IT>,
64        _owner: Address,
65        _vals: &SStoreResult,
66    ) -> Result<GasStateOutcome, InstructionResult> {
67        Ok(GasStateOutcome::default())
68    }
69}