revm_context_interface/
host.rs1pub use crate::journaled_state::StateLoad;
2use database_interface::Database;
3
4use crate::{context::ContextTr, journaled_state::AccountLoad, Block, Journal};
5use primitives::{Address, Bytes, Log, B256, BLOCK_HASH_HISTORY, U256};
6
7pub trait Host: ContextTr {
9 fn set_error(&mut self, error: <Self::Db as Database>::Error) {
10 *self.error() = Err(error);
11 }
12
13 fn block_hash(&mut self, requested_number: u64) -> Option<B256> {
15 let block_number = self.block().number();
16
17 let Some(diff) = block_number.checked_sub(requested_number) else {
18 return Some(B256::ZERO);
19 };
20
21 if diff == 0 {
23 return Some(B256::ZERO);
24 }
25
26 if diff <= BLOCK_HASH_HISTORY {
27 return self
28 .journal()
29 .db()
30 .block_hash(requested_number)
31 .map_err(|e| self.set_error(e))
32 .ok();
33 }
34
35 Some(B256::ZERO)
36 }
37
38 fn load_account_delegated(&mut self, address: Address) -> Option<StateLoad<AccountLoad>> {
39 self.journal()
40 .load_account_delegated(address)
41 .map_err(|e| self.set_error(e))
42 .ok()
43 }
44
45 fn balance(&mut self, address: Address) -> Option<StateLoad<U256>> {
47 self.journal()
48 .load_account(address)
49 .map(|acc| acc.map(|a| a.info.balance))
50 .map_err(|e| self.set_error(e))
51 .ok()
52 }
53
54 fn code(&mut self, address: Address) -> Option<StateLoad<Bytes>> {
56 self.journal()
57 .code(address)
58 .map_err(|e| self.set_error(e))
59 .ok()
60 }
61
62 fn code_hash(&mut self, address: Address) -> Option<StateLoad<B256>> {
64 self.journal()
65 .code_hash(address)
66 .map_err(|e| self.set_error(e))
67 .ok()
68 }
69
70 fn sload(&mut self, address: Address, index: U256) -> Option<StateLoad<U256>> {
72 self.journal()
73 .sload(address, index)
74 .map_err(|e| self.set_error(e))
75 .ok()
76 }
77
78 fn sstore(
82 &mut self,
83 address: Address,
84 index: U256,
85 value: U256,
86 ) -> Option<StateLoad<SStoreResult>> {
87 self.journal()
88 .sstore(address, index, value)
89 .map_err(|e| self.set_error(e))
90 .ok()
91 }
92
93 fn tload(&mut self, address: Address, index: U256) -> U256 {
95 self.journal().tload(address, index)
96 }
97
98 fn tstore(&mut self, address: Address, index: U256, value: U256) {
100 self.journal().tstore(address, index, value)
101 }
102
103 fn log(&mut self, log: Log) {
105 self.journal().log(log);
106 }
107
108 fn selfdestruct(
110 &mut self,
111 address: Address,
112 target: Address,
113 ) -> Option<StateLoad<SelfDestructResult>> {
114 self.journal()
115 .selfdestruct(address, target)
116 .map_err(|e| self.set_error(e))
117 .ok()
118 }
119}
120
121impl<T: ContextTr> Host for T {}
122
123#[derive(Clone, Debug, Default, PartialEq, Eq)]
125#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
126pub struct SStoreResult {
127 pub original_value: U256,
129 pub present_value: U256,
131 pub new_value: U256,
133}
134
135impl SStoreResult {
136 #[inline]
138 pub fn is_new_eq_present(&self) -> bool {
139 self.new_value == self.present_value
140 }
141
142 #[inline]
144 pub fn is_original_eq_present(&self) -> bool {
145 self.original_value == self.present_value
146 }
147
148 #[inline]
150 pub fn is_original_eq_new(&self) -> bool {
151 self.original_value == self.new_value
152 }
153
154 #[inline]
156 pub fn is_original_zero(&self) -> bool {
157 self.original_value.is_zero()
158 }
159
160 #[inline]
162 pub fn is_present_zero(&self) -> bool {
163 self.present_value.is_zero()
164 }
165
166 #[inline]
168 pub fn is_new_zero(&self) -> bool {
169 self.new_value.is_zero()
170 }
171}
172
173#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
177#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
178pub struct SelfDestructResult {
179 pub had_value: bool,
180 pub target_exists: bool,
181 pub previously_destroyed: bool,
182}