1mod config;
8mod gasometer;
9mod invoker;
10
11use alloc::vec::Vec;
12use core::marker::PhantomData;
13
14use evm_interpreter::uint::{H160, H256, U256};
15use evm_interpreter::{
16 Control, ExitError, etable, eval,
17 runtime::{GasState, RuntimeBackend, RuntimeConfig, RuntimeEnvironment, RuntimeState},
18 trap::CallCreateTrap,
19};
20
21pub use self::{
22 config::Config,
23 gasometer::{GasometerState, eval as eval_gasometer},
24 invoker::{
25 EtableResolver, Invoker, InvokerState, PrecompileSet, Resolver, ResolverOrigin,
26 SubstackInvoke, TransactArgs, TransactArgsCallCreate, TransactGasPrice, TransactInvoke,
27 TransactValue, TransactValueCallCreate, routines,
28 },
29};
30use crate::{MergeStrategy, gasometer::GasMutState};
31
32pub type Machine<'config> = evm_interpreter::Machine<State<'config>>;
34
35pub type Efn<'config, H> = etable::Efn<State<'config>, H, CallCreateTrap>;
37
38pub type DispatchEtable<'config, H, F = Efn<'config, H>> =
40 etable::DispatchEtable<State<'config>, H, CallCreateTrap, F>;
41
42pub struct GasometerEtable<'config>(PhantomData<&'config ()>);
44
45impl<'config> GasometerEtable<'config> {
46 pub const fn new() -> Self {
48 Self(PhantomData)
49 }
50}
51
52impl<'config> Default for GasometerEtable<'config> {
53 fn default() -> Self {
54 Self::new()
55 }
56}
57
58impl<'config, H> etable::Etable<H> for GasometerEtable<'config>
59where
60 H: RuntimeBackend,
61{
62 type State = State<'config>;
63 type Trap = CallCreateTrap;
64
65 fn eval(
66 &self,
67 machine: &mut Machine<'config>,
68 handle: &mut H,
69 position: usize,
70 ) -> Control<Self::Trap> {
71 eval_gasometer(machine, handle, position)
72 }
73}
74
75pub struct ExecutionEtable<'config>(PhantomData<&'config ()>);
77
78impl<'config> ExecutionEtable<'config> {
79 pub const fn new() -> Self {
81 Self(PhantomData)
82 }
83}
84
85impl<'config> Default for ExecutionEtable<'config> {
86 fn default() -> Self {
87 Self::new()
88 }
89}
90
91impl<'config, H> etable::Etable<H> for ExecutionEtable<'config>
92where
93 H: RuntimeBackend + RuntimeEnvironment,
94{
95 type State = State<'config>;
96 type Trap = CallCreateTrap;
97
98 fn eval(
99 &self,
100 machine: &mut Machine<'config>,
101 handle: &mut H,
102 position: usize,
103 ) -> Control<Self::Trap> {
104 eval::eval_any(machine, handle, position)
105 }
106}
107
108pub struct State<'config> {
110 pub runtime: RuntimeState,
112 pub gasometer: GasometerState,
114 pub config: &'config Config,
116}
117
118impl<'config> AsRef<RuntimeState> for State<'config> {
119 fn as_ref(&self) -> &RuntimeState {
120 &self.runtime
121 }
122}
123
124impl<'config> AsMut<RuntimeState> for State<'config> {
125 fn as_mut(&mut self) -> &mut RuntimeState {
126 &mut self.runtime
127 }
128}
129
130impl<'config> AsRef<GasometerState> for State<'config> {
131 fn as_ref(&self) -> &GasometerState {
132 &self.gasometer
133 }
134}
135
136impl<'config> AsMut<GasometerState> for State<'config> {
137 fn as_mut(&mut self) -> &mut GasometerState {
138 &mut self.gasometer
139 }
140}
141
142impl<'config> AsRef<Config> for State<'config> {
143 fn as_ref(&self) -> &Config {
144 self.config
145 }
146}
147
148impl<'config> AsRef<RuntimeConfig> for State<'config> {
149 fn as_ref(&self) -> &RuntimeConfig {
150 &self.config.runtime
151 }
152}
153
154impl<'config> GasState for State<'config> {
155 fn gas(&self) -> U256 {
156 self.gasometer.gas()
157 }
158}
159
160impl<'config> GasMutState for State<'config> {
161 fn record_gas(&mut self, gas: U256) -> Result<(), ExitError> {
162 self.gasometer.record_gas(gas)
163 }
164}
165
166impl<'config> InvokerState for State<'config> {
167 type TransactArgs = TransactArgs<'config>;
168
169 fn new_transact_call(
170 runtime: RuntimeState,
171 gas_limit: U256,
172 data: &[u8],
173 access_list: &[(H160, Vec<H256>)],
174 args: &TransactArgs<'config>,
175 ) -> Result<Self, ExitError> {
176 let config = args.config;
177 Ok(Self {
178 runtime,
179 gasometer: GasometerState::new_transact_call(gas_limit, data, access_list, config)?,
180 config,
181 })
182 }
183
184 fn new_transact_create(
185 runtime: RuntimeState,
186 gas_limit: U256,
187 code: &[u8],
188 access_list: &[(H160, Vec<H256>)],
189 args: &TransactArgs<'config>,
190 ) -> Result<Self, ExitError> {
191 let config = args.config;
192 Ok(Self {
193 runtime,
194 gasometer: GasometerState::new_transact_create(gas_limit, code, access_list, config)?,
195 config,
196 })
197 }
198
199 fn substate(
200 &mut self,
201 runtime: RuntimeState,
202 gas_limit: U256,
203 is_static: bool,
204 call_has_value: bool,
205 ) -> Result<Self, ExitError> {
206 Ok(Self {
207 runtime,
208 gasometer: self.gasometer.submeter(
209 gas_limit,
210 is_static,
211 call_has_value,
212 self.config,
213 )?,
214 config: self.config,
215 })
216 }
217
218 fn merge(&mut self, substate: Self, strategy: MergeStrategy) {
219 self.gasometer.merge(substate.gasometer, strategy)
220 }
221
222 fn record_codedeposit(&mut self, len: usize) -> Result<(), ExitError> {
223 self.gasometer.record_codedeposit(len)
224 }
225
226 fn is_static(&self) -> bool {
227 self.gasometer.is_static
228 }
229
230 fn effective_gas(&self, with_refund: bool) -> U256 {
231 self.gasometer.effective_gas(with_refund, self.config)
232 }
233}