1use crate::backend::{Apply, Backend, Basic, Log};
2use crate::executor::stack::executor::{Accessed, StackState, StackSubstateMetadata};
3use crate::{ExitError, Transfer};
4use alloc::{
5 boxed::Box,
6 collections::{BTreeMap, BTreeSet},
7 vec::Vec,
8};
9use core::mem;
10use primitive_types::{H160, H256, U256};
11
12#[derive(Clone, Debug)]
13pub struct MemoryStackAccount {
14 pub basic: Basic,
15 pub code: Option<Vec<u8>>,
16 pub reset: bool,
17}
18
19#[derive(Clone, Debug)]
20pub struct MemoryStackSubstate {
21 metadata: StackSubstateMetadata,
22 parent: Option<Box<MemoryStackSubstate>>,
23 logs: Vec<Log>,
24 accounts: BTreeMap<H160, MemoryStackAccount>,
25 storages: BTreeMap<(H160, H256), H256>,
26 deletes: BTreeSet<H160>,
27}
28
29impl MemoryStackSubstate {
30 pub fn new(metadata: StackSubstateMetadata) -> Self {
31 Self {
32 metadata,
33 parent: None,
34 logs: Vec::new(),
35 accounts: BTreeMap::new(),
36 storages: BTreeMap::new(),
37 deletes: BTreeSet::new(),
38 }
39 }
40
41 pub fn logs(&self) -> &[Log] {
42 &self.logs
43 }
44
45 pub fn logs_mut(&mut self) -> &mut Vec<Log> {
46 &mut self.logs
47 }
48
49 pub fn metadata(&self) -> &StackSubstateMetadata {
50 &self.metadata
51 }
52
53 pub fn metadata_mut(&mut self) -> &mut StackSubstateMetadata {
54 &mut self.metadata
55 }
56
57 #[must_use]
60 pub fn deconstruct<B: Backend>(
61 mut self,
62 backend: &B,
63 ) -> (
64 impl IntoIterator<Item = Apply<impl IntoIterator<Item = (H256, H256)>>>,
65 impl IntoIterator<Item = Log>,
66 ) {
67 assert!(self.parent.is_none());
68
69 let mut applies = Vec::<Apply<BTreeMap<H256, H256>>>::new();
70
71 let mut addresses = BTreeSet::new();
72
73 for address in self.accounts.keys() {
74 addresses.insert(*address);
75 }
76
77 for (address, _) in self.storages.keys() {
78 addresses.insert(*address);
79 }
80
81 for address in addresses {
82 if self.deletes.contains(&address) {
83 continue;
84 }
85
86 let mut storage = BTreeMap::new();
87 for ((oa, ok), ov) in &self.storages {
88 if *oa == address {
89 storage.insert(*ok, *ov);
90 }
91 }
92
93 let apply = {
94 let account = self.account_mut(address, backend);
95
96 Apply::Modify {
97 address,
98 basic: account.basic.clone(),
99 code: account.code.clone(),
100 storage,
101 reset_storage: account.reset,
102 }
103 };
104
105 applies.push(apply);
106 }
107
108 for address in self.deletes {
109 applies.push(Apply::Delete { address });
110 }
111
112 (applies, self.logs)
113 }
114
115 pub fn enter(&mut self, is_static: bool) {
116 let mut entering = Self {
117 metadata: self.metadata.spit_child(is_static),
118 parent: None,
119 logs: Vec::new(),
120 accounts: BTreeMap::new(),
121 storages: BTreeMap::new(),
122 deletes: BTreeSet::new(),
123 };
124 mem::swap(&mut entering, self);
125
126 self.parent = Some(Box::new(entering));
127 }
128
129 pub fn exit_commit(&mut self) -> Result<(), ExitError> {
130 let mut exited = *self.parent.take().expect("Cannot commit on root substate");
131 mem::swap(&mut exited, self);
132
133 self.metadata.swallow_commit(exited.metadata)?;
134 self.logs.append(&mut exited.logs);
135
136 let mut resets = BTreeSet::new();
137 for (address, account) in &exited.accounts {
138 if account.reset {
139 resets.insert(*address);
140 }
141 }
142 let mut reset_keys = BTreeSet::new();
143 for (address, key) in self.storages.keys() {
144 if resets.contains(address) {
145 reset_keys.insert((*address, *key));
146 }
147 }
148 for (address, key) in reset_keys {
149 self.storages.remove(&(address, key));
150 }
151
152 self.accounts.append(&mut exited.accounts);
153 self.storages.append(&mut exited.storages);
154 self.deletes.append(&mut exited.deletes);
155
156 Ok(())
157 }
158
159 pub fn exit_revert(&mut self) -> Result<(), ExitError> {
160 let mut exited = *self.parent.take().expect("Cannot discard on root substate");
161 mem::swap(&mut exited, self);
162
163 self.metadata.swallow_revert(exited.metadata)?;
164
165 Ok(())
166 }
167
168 pub fn exit_discard(&mut self) -> Result<(), ExitError> {
169 let mut exited = *self.parent.take().expect("Cannot discard on root substate");
170 mem::swap(&mut exited, self);
171
172 self.metadata.swallow_discard(exited.metadata)?;
173
174 Ok(())
175 }
176
177 pub fn known_account(&self, address: H160) -> Option<&MemoryStackAccount> {
178 if let Some(account) = self.accounts.get(&address) {
179 Some(account)
180 } else if let Some(parent) = self.parent.as_ref() {
181 parent.known_account(address)
182 } else {
183 None
184 }
185 }
186
187 pub fn known_basic(&self, address: H160) -> Option<Basic> {
188 self.known_account(address).map(|acc| acc.basic.clone())
189 }
190
191 pub fn known_code(&self, address: H160) -> Option<Vec<u8>> {
192 self.known_account(address).and_then(|acc| acc.code.clone())
193 }
194
195 pub fn known_empty(&self, address: H160) -> Option<bool> {
196 if let Some(account) = self.known_account(address) {
197 if account.basic.balance != U256::zero() {
198 return Some(false);
199 }
200
201 if account.basic.nonce != U256::zero() {
202 return Some(false);
203 }
204
205 if let Some(code) = &account.code {
206 return Some(
207 account.basic.balance == U256::zero()
208 && account.basic.nonce == U256::zero()
209 && code.is_empty(),
210 );
211 }
212 }
213
214 None
215 }
216
217 pub fn known_storage(&self, address: H160, key: H256) -> Option<H256> {
218 if let Some(value) = self.storages.get(&(address, key)) {
219 return Some(*value);
220 }
221
222 if let Some(account) = self.accounts.get(&address) {
223 if account.reset {
224 return Some(H256::default());
225 }
226 }
227
228 if let Some(parent) = self.parent.as_ref() {
229 return parent.known_storage(address, key);
230 }
231
232 None
233 }
234
235 pub fn known_original_storage(&self, address: H160, key: H256) -> Option<H256> {
236 if let Some(account) = self.accounts.get(&address) {
237 if account.reset {
238 return Some(H256::default());
239 }
240 }
241
242 if let Some(parent) = self.parent.as_ref() {
243 return parent.known_original_storage(address, key);
244 }
245
246 None
247 }
248
249 pub fn is_cold(&self, address: H160) -> bool {
250 self.recursive_is_cold(&|a| a.accessed_addresses.contains(&address))
251 }
252
253 pub fn is_storage_cold(&self, address: H160, key: H256) -> bool {
254 self.recursive_is_cold(&|a: &Accessed| a.accessed_storage.contains(&(address, key)))
255 }
256
257 fn recursive_is_cold<F: Fn(&Accessed) -> bool>(&self, f: &F) -> bool {
258 let local_is_accessed = self.metadata.accessed().as_ref().map(f).unwrap_or(false);
259 if local_is_accessed {
260 false
261 } else {
262 self.parent
263 .as_ref()
264 .map(|p| p.recursive_is_cold(f))
265 .unwrap_or(true)
266 }
267 }
268
269 pub fn deleted(&self, address: H160) -> bool {
270 if self.deletes.contains(&address) {
271 return true;
272 }
273
274 if let Some(parent) = self.parent.as_ref() {
275 return parent.deleted(address);
276 }
277
278 false
279 }
280
281 #[allow(clippy::map_entry)]
282 fn account_mut<B: Backend>(&mut self, address: H160, backend: &B) -> &mut MemoryStackAccount {
283 if !self.accounts.contains_key(&address) {
284 let account = self
285 .known_account(address)
286 .cloned()
287 .map(|mut v| {
288 v.reset = false;
289 v
290 })
291 .unwrap_or_else(|| MemoryStackAccount {
292 basic: backend.basic(address),
293 code: None,
294 reset: false,
295 });
296 self.accounts.insert(address, account);
297 }
298
299 self.accounts
300 .get_mut(&address)
301 .expect("New account was just inserted")
302 }
303
304 pub fn inc_nonce<B: Backend>(&mut self, address: H160, backend: &B) {
305 self.account_mut(address, backend).basic.nonce += U256::one();
306 }
307
308 pub fn set_storage(&mut self, address: H160, key: H256, value: H256) {
309 self.storages.insert((address, key), value);
310 }
311
312 pub fn reset_storage<B: Backend>(&mut self, address: H160, backend: &B) {
313 let mut removing = Vec::new();
314
315 for (oa, ok) in self.storages.keys() {
316 if *oa == address {
317 removing.push(*ok);
318 }
319 }
320
321 for ok in removing {
322 self.storages.remove(&(address, ok));
323 }
324
325 self.account_mut(address, backend).reset = true;
326 }
327
328 pub fn log(&mut self, address: H160, topics: Vec<H256>, data: Vec<u8>) {
329 self.logs.push(Log {
330 address,
331 topics,
332 data,
333 });
334 }
335
336 pub fn set_deleted(&mut self, address: H160) {
337 self.deletes.insert(address);
338 }
339
340 pub fn set_code<B: Backend>(&mut self, address: H160, code: Vec<u8>, backend: &B) {
341 self.account_mut(address, backend).code = Some(code);
342 }
343
344 pub fn transfer<B: Backend>(
345 &mut self,
346 transfer: Transfer,
347 backend: &B,
348 ) -> Result<(), ExitError> {
349 {
350 let source = self.account_mut(transfer.source, backend);
351 if source.basic.balance < transfer.value {
352 return Err(ExitError::OutOfFund);
353 }
354 source.basic.balance -= transfer.value;
355 }
356
357 {
358 let target = self.account_mut(transfer.target, backend);
359 target.basic.balance = target.basic.balance.saturating_add(transfer.value);
360 }
361
362 Ok(())
363 }
364
365 pub fn withdraw<B: Backend>(
367 &mut self,
368 address: H160,
369 value: U256,
370 backend: &B,
371 ) -> Result<(), ExitError> {
372 let source = self.account_mut(address, backend);
373 if source.basic.balance < value {
374 return Err(ExitError::OutOfFund);
375 }
376 source.basic.balance -= value;
377
378 Ok(())
379 }
380
381 pub fn deposit<B: Backend>(&mut self, address: H160, value: U256, backend: &B) {
383 let target = self.account_mut(address, backend);
384 target.basic.balance = target.basic.balance.saturating_add(value);
385 }
386
387 pub fn reset_balance<B: Backend>(&mut self, address: H160, backend: &B) {
388 self.account_mut(address, backend).basic.balance = U256::zero();
389 }
390
391 pub fn touch<B: Backend>(&mut self, address: H160, backend: &B) {
392 self.account_mut(address, backend);
393 }
394}
395
396#[derive(Clone, Debug)]
397pub struct MemoryStackState<'backend, B> {
398 backend: &'backend B,
399 substate: MemoryStackSubstate,
400}
401
402impl<'backend, B: Backend> Backend for MemoryStackState<'backend, B> {
403 fn gas_price(&self) -> U256 {
404 self.backend.gas_price()
405 }
406 fn origin(&self) -> H160 {
407 self.backend.origin()
408 }
409 fn block_hash(&self, number: U256) -> H256 {
410 self.backend.block_hash(number)
411 }
412 fn block_number(&self) -> U256 {
413 self.backend.block_number()
414 }
415 fn block_coinbase(&self) -> H160 {
416 self.backend.block_coinbase()
417 }
418 fn block_timestamp(&self) -> U256 {
419 self.backend.block_timestamp()
420 }
421 fn block_difficulty(&self) -> U256 {
422 self.backend.block_difficulty()
423 }
424 fn block_gas_limit(&self) -> U256 {
425 self.backend.block_gas_limit()
426 }
427 fn block_base_fee_per_gas(&self) -> U256 {
428 self.backend.block_base_fee_per_gas()
429 }
430
431 fn gas_left(&self) -> U256 {
432 self.backend.gas_left()
433 }
434
435 fn chain_id(&self) -> U256 {
436 self.backend.chain_id()
437 }
438
439 fn exists(&self, address: H160) -> bool {
440 self.substate.known_account(address).is_some() || self.backend.exists(address)
441 }
442
443 fn basic(&self, address: H160) -> Basic {
444 self.substate
445 .known_basic(address)
446 .unwrap_or_else(|| self.backend.basic(address))
447 }
448
449 fn code(&self, address: H160) -> Vec<u8> {
450 self.substate
451 .known_code(address)
452 .unwrap_or_else(|| self.backend.code(address))
453 }
454
455 fn storage(&self, address: H160, key: H256) -> H256 {
456 self.substate
457 .known_storage(address, key)
458 .unwrap_or_else(|| self.backend.storage(address, key))
459 }
460
461 fn original_storage(&self, address: H160, key: H256) -> Option<H256> {
462 if let Some(value) = self.substate.known_original_storage(address, key) {
463 return Some(value);
464 }
465
466 self.backend.original_storage(address, key)
467 }
468}
469
470impl<'backend, B: Backend> StackState for MemoryStackState<'backend, B> {
471 fn metadata(&self) -> &StackSubstateMetadata {
472 self.substate.metadata()
473 }
474
475 fn metadata_mut(&mut self) -> &mut StackSubstateMetadata {
476 self.substate.metadata_mut()
477 }
478
479 fn enter(&mut self, is_static: bool) {
480 self.substate.enter(is_static)
481 }
482
483 fn exit_commit(&mut self) -> Result<(), ExitError> {
484 self.substate.exit_commit()
485 }
486
487 fn exit_revert(&mut self) -> Result<(), ExitError> {
488 self.substate.exit_revert()
489 }
490
491 fn exit_discard(&mut self) -> Result<(), ExitError> {
492 self.substate.exit_discard()
493 }
494
495 fn is_empty(&self, address: H160) -> bool {
496 if let Some(known_empty) = self.substate.known_empty(address) {
497 return known_empty;
498 }
499
500 self.backend.basic(address).balance == U256::zero()
501 && self.backend.basic(address).nonce == U256::zero()
502 && self.backend.code(address).len() == 0
503 }
504
505 fn deleted(&self, address: H160) -> bool {
506 self.substate.deleted(address)
507 }
508
509 fn is_cold(&self, address: H160) -> bool {
510 self.substate.is_cold(address)
511 }
512
513 fn is_storage_cold(&self, address: H160, key: H256) -> bool {
514 self.substate.is_storage_cold(address, key)
515 }
516
517 fn inc_nonce(&mut self, address: H160) {
518 self.substate.inc_nonce(address, self.backend);
519 }
520
521 fn set_storage(&mut self, address: H160, key: H256, value: H256) {
522 self.substate.set_storage(address, key, value)
523 }
524
525 fn reset_storage(&mut self, address: H160) {
526 self.substate.reset_storage(address, self.backend);
527 }
528
529 fn log(&mut self, address: H160, topics: Vec<H256>, data: Vec<u8>) {
530 self.substate.log(address, topics, data);
531 }
532
533 fn set_deleted(&mut self, address: H160) {
534 self.substate.set_deleted(address)
535 }
536
537 fn set_code(&mut self, address: H160, code: Vec<u8>) {
538 self.substate.set_code(address, code, self.backend)
539 }
540
541 fn transfer(&mut self, transfer: Transfer) -> Result<(), ExitError> {
542 self.substate.transfer(transfer, self.backend)
543 }
544
545 fn reset_balance(&mut self, address: H160) {
546 self.substate.reset_balance(address, self.backend)
547 }
548
549 fn touch(&mut self, address: H160) {
550 self.substate.touch(address, self.backend)
551 }
552}
553
554impl<'backend, B: Backend> MemoryStackState<'backend, B> {
555 pub fn new(metadata: StackSubstateMetadata, backend: &'backend B) -> Self {
556 Self {
557 backend,
558 substate: MemoryStackSubstate::new(metadata),
559 }
560 }
561
562 pub fn account_mut(&mut self, address: H160) -> &mut MemoryStackAccount {
564 self.substate.account_mut(address, self.backend)
565 }
566
567 #[must_use]
568 pub fn deconstruct(
569 self,
570 ) -> (
571 impl IntoIterator<Item = Apply<impl IntoIterator<Item = (H256, H256)>>>,
572 impl IntoIterator<Item = Log>,
573 ) {
574 self.substate.deconstruct(self.backend)
575 }
576
577 pub fn withdraw(&mut self, address: H160, value: U256) -> Result<(), ExitError> {
578 self.substate.withdraw(address, value, self.backend)
579 }
580
581 pub fn deposit(&mut self, address: H160, value: U256) {
582 self.substate.deposit(address, value, self.backend)
583 }
584}