revm_context_interface/
context.rs

1//! Context trait and related types.
2pub use crate::journaled_state::StateLoad;
3use crate::{
4    result::FromStringError, Block, Cfg, Database, JournalTr, LocalContextTr, Transaction,
5};
6use auto_impl::auto_impl;
7use primitives::StorageValue;
8use std::string::String;
9
10/// Trait that defines the context of the EVM execution.
11///
12/// This trait is used to access the environment and state of the EVM.
13/// It is used to access the transaction, block, configuration, database, journal, and chain.
14/// It is also used to set the error of the EVM.
15///
16/// All function has a `*_mut` variant except the function for [`ContextTr::tx`] and [`ContextTr::block`].
17#[auto_impl(&mut, Box)]
18pub trait ContextTr {
19    /// Block type
20    type Block: Block;
21    /// Transaction type
22    type Tx: Transaction;
23    /// Configuration type
24    type Cfg: Cfg;
25    /// Database type
26    type Db: Database;
27    /// Journal type
28    type Journal: JournalTr<Database = Self::Db>;
29    /// Chain type
30    type Chain;
31    /// Local context type
32    type Local: LocalContextTr;
33
34    /// Get the transaction
35    fn tx(&self) -> &Self::Tx;
36    /// Get the block
37    fn block(&self) -> &Self::Block;
38    /// Get the configuration
39    fn cfg(&self) -> &Self::Cfg;
40    /// Get the journal
41    fn journal(&self) -> &Self::Journal;
42    /// Get the journal mutably
43    fn journal_mut(&mut self) -> &mut Self::Journal;
44    /// Get the journal reference
45    fn journal_ref(&self) -> &Self::Journal {
46        self.journal()
47    }
48    /// Get the database
49    fn db(&self) -> &Self::Db;
50    /// Get the database mutably
51    fn db_mut(&mut self) -> &mut Self::Db;
52    /// Get the database reference
53    fn db_ref(&self) -> &Self::Db {
54        self.db()
55    }
56    /// Get the chain
57    fn chain(&self) -> &Self::Chain;
58    /// Get the chain mutably
59    fn chain_mut(&mut self) -> &mut Self::Chain;
60    /// Get the chain reference
61    fn chain_ref(&self) -> &Self::Chain {
62        self.chain()
63    }
64    /// Get the local context
65    fn local(&self) -> &Self::Local;
66    /// Get the local context mutably
67    fn local_mut(&mut self) -> &mut Self::Local;
68    /// Get the local context reference
69    fn local_ref(&self) -> &Self::Local {
70        self.local()
71    }
72    /// Get the error
73    fn error(&mut self) -> &mut Result<(), ContextError<<Self::Db as Database>::Error>>;
74    /// Get the transaction and journal. It is used to efficiently load access list
75    /// into journal without copying them from transaction.
76    fn tx_journal_mut(&mut self) -> (&Self::Tx, &mut Self::Journal);
77    /// Get the transaction and local context. It is used to efficiently load initcode
78    /// into local context without copying them from transaction.
79    fn tx_local_mut(&mut self) -> (&Self::Tx, &mut Self::Local);
80}
81
82/// Inner Context error used for Interpreter to set error without returning it frm instruction
83#[derive(Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
84#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
85pub enum ContextError<DbError> {
86    /// Database error.
87    Db(DbError),
88    /// Custom string error.
89    Custom(String),
90}
91
92impl<DbError> FromStringError for ContextError<DbError> {
93    fn from_string(value: String) -> Self {
94        Self::Custom(value)
95    }
96}
97
98impl<DbError> From<DbError> for ContextError<DbError> {
99    fn from(value: DbError) -> Self {
100        Self::Db(value)
101    }
102}
103
104/// Represents the result of an `sstore` operation.
105#[derive(Clone, Debug, Default, PartialEq, Eq)]
106#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
107pub struct SStoreResult {
108    /// Value of the storage when it is first read
109    pub original_value: StorageValue,
110    /// Current value of the storage
111    pub present_value: StorageValue,
112    /// New value that is set
113    pub new_value: StorageValue,
114}
115
116impl SStoreResult {
117    /// Returns `true` if the new value is equal to the present value.
118    #[inline]
119    pub fn is_new_eq_present(&self) -> bool {
120        self.new_value == self.present_value
121    }
122
123    /// Returns `true` if the original value is equal to the present value.
124    #[inline]
125    pub fn is_original_eq_present(&self) -> bool {
126        self.original_value == self.present_value
127    }
128
129    /// Returns `true` if the original value is equal to the new value.
130    #[inline]
131    pub fn is_original_eq_new(&self) -> bool {
132        self.original_value == self.new_value
133    }
134
135    /// Returns `true` if the original value is zero.
136    #[inline]
137    pub fn is_original_zero(&self) -> bool {
138        self.original_value.is_zero()
139    }
140
141    /// Returns `true` if the present value is zero.
142    #[inline]
143    pub fn is_present_zero(&self) -> bool {
144        self.present_value.is_zero()
145    }
146
147    /// Returns `true` if the new value is zero.
148    #[inline]
149    pub fn is_new_zero(&self) -> bool {
150        self.new_value.is_zero()
151    }
152}
153
154/// Result of a selfdestruct action
155///
156/// Value returned are needed to calculate the gas spent.
157#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
158#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
159pub struct SelfDestructResult {
160    /// Whether the account had a value.
161    pub had_value: bool,
162    /// Whether the target account exists.
163    pub target_exists: bool,
164    /// Whether the account was previously destroyed.
165    pub previously_destroyed: bool,
166}
167
168/// Trait for setting the transaction and block in the context.
169pub trait ContextSetters: ContextTr {
170    /// Set the transaction
171    fn set_tx(&mut self, tx: Self::Tx);
172    /// Set the block
173    fn set_block(&mut self, block: Self::Block);
174}