rtvm_interpreter/host/
dummy.rs

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