revm_interpreter/host/
dummy.rs

1use crate::{
2    primitives::{hash_map::Entry, Address, Bytes, Env, HashMap, Log, B256, KECCAK_EMPTY, U256},
3    Host, SStoreResult, SelfDestructResult,
4};
5use std::vec::Vec;
6
7use super::{AccountLoad, Eip7702CodeLoad, StateLoad};
8
9/// A dummy [Host] implementation.
10#[derive(Clone, Debug, Default, PartialEq, Eq)]
11pub struct DummyHost {
12    pub env: Env,
13    pub storage: HashMap<U256, U256>,
14    pub transient_storage: HashMap<U256, U256>,
15    pub log: Vec<Log>,
16}
17
18impl DummyHost {
19    /// Create a new dummy host with the given [`Env`].
20    #[inline]
21    pub fn new(env: Env) -> Self {
22        Self {
23            env,
24            ..Default::default()
25        }
26    }
27
28    /// Clears the storage and logs of the dummy host.
29    #[inline]
30    pub fn clear(&mut self) {
31        self.storage.clear();
32        self.log.clear();
33    }
34}
35
36impl Host for DummyHost {
37    #[inline]
38    fn env(&self) -> &Env {
39        &self.env
40    }
41
42    #[inline]
43    fn env_mut(&mut self) -> &mut Env {
44        &mut self.env
45    }
46
47    #[inline]
48    fn load_account_delegated(&mut self, _address: Address) -> Option<AccountLoad> {
49        Some(AccountLoad::default())
50    }
51
52    #[inline]
53    fn block_hash(&mut self, _number: u64) -> Option<B256> {
54        Some(B256::ZERO)
55    }
56
57    #[inline]
58    fn balance(&mut self, _address: Address) -> Option<StateLoad<U256>> {
59        Some(Default::default())
60    }
61
62    #[inline]
63    fn code(&mut self, _address: Address) -> Option<Eip7702CodeLoad<Bytes>> {
64        Some(Default::default())
65    }
66
67    #[inline]
68    fn code_hash(&mut self, _address: Address) -> Option<Eip7702CodeLoad<B256>> {
69        Some(Eip7702CodeLoad::new_not_delegated(KECCAK_EMPTY, false))
70    }
71
72    #[inline]
73    fn sload(&mut self, _address: Address, index: U256) -> Option<StateLoad<U256>> {
74        match self.storage.entry(index) {
75            Entry::Occupied(entry) => Some(StateLoad::new(*entry.get(), false)),
76            Entry::Vacant(entry) => {
77                entry.insert(U256::ZERO);
78                Some(StateLoad::new(U256::ZERO, true))
79            }
80        }
81    }
82
83    #[inline]
84    fn sstore(
85        &mut self,
86        _address: Address,
87        index: U256,
88        value: U256,
89    ) -> Option<StateLoad<SStoreResult>> {
90        let present = self.storage.insert(index, value);
91        Some(StateLoad {
92            data: SStoreResult {
93                original_value: U256::ZERO,
94                present_value: present.unwrap_or(U256::ZERO),
95                new_value: value,
96            },
97            is_cold: present.is_none(),
98        })
99    }
100
101    #[inline]
102    fn tload(&mut self, _address: Address, index: U256) -> U256 {
103        self.transient_storage
104            .get(&index)
105            .copied()
106            .unwrap_or_default()
107    }
108
109    #[inline]
110    fn tstore(&mut self, _address: Address, index: U256, value: U256) {
111        self.transient_storage.insert(index, value);
112    }
113
114    #[inline]
115    fn log(&mut self, log: Log) {
116        self.log.push(log)
117    }
118
119    #[inline]
120    fn selfdestruct(
121        &mut self,
122        _address: Address,
123        _target: Address,
124    ) -> Option<StateLoad<SelfDestructResult>> {
125        Some(StateLoad::default())
126    }
127}