1use crate::backend::{Apply, Backend, Basic, Log};
2use crate::core::utils::{U256_ONE, U256_ZERO, U64_MAX};
3use crate::executor::stack::executor::{
4 Accessed, Authorization, StackState, StackSubstateMetadata,
5};
6use crate::prelude::*;
7use crate::{ExitError, Transfer};
8use core::mem;
9use primitive_types::{H160, H256, U256};
10
11#[derive(Clone, Debug)]
12pub struct MemoryStackAccount {
13 pub basic: Basic,
14 pub code: Option<Vec<u8>>,
15 pub reset: bool,
16}
17
18#[derive(Clone, Debug)]
19pub struct MemoryStackSubstate<'config> {
20 metadata: StackSubstateMetadata<'config>,
21 parent: Option<Box<MemoryStackSubstate<'config>>>,
22 logs: Vec<Log>,
23 accounts: BTreeMap<H160, MemoryStackAccount>,
24 storages: BTreeMap<(H160, H256), H256>,
25 tstorages: BTreeMap<(H160, H256), U256>,
26 deletes: BTreeSet<H160>,
27 creates: BTreeSet<H160>,
28}
29
30impl<'config> MemoryStackSubstate<'config> {
31 #[must_use]
32 pub const fn new(metadata: StackSubstateMetadata<'config>) -> Self {
33 Self {
34 metadata,
35 parent: None::<Box<_>>,
36 logs: Vec::new(),
37 accounts: BTreeMap::new(),
38 storages: BTreeMap::new(),
39 tstorages: BTreeMap::new(),
40 deletes: BTreeSet::new(),
41 creates: BTreeSet::new(),
42 }
43 }
44
45 #[must_use]
46 pub fn logs(&self) -> &[Log] {
47 &self.logs
48 }
49
50 pub fn logs_mut(&mut self) -> &mut Vec<Log> {
51 &mut self.logs
52 }
53
54 #[must_use]
55 pub const fn metadata(&self) -> &StackSubstateMetadata<'config> {
56 &self.metadata
57 }
58
59 pub fn metadata_mut(&mut self) -> &mut StackSubstateMetadata<'config> {
60 &mut self.metadata
61 }
62
63 #[must_use]
69 pub fn deconstruct<B: Backend>(
70 mut self,
71 backend: &B,
72 ) -> (
73 impl IntoIterator<Item = Apply<impl IntoIterator<Item = (H256, H256)>>>,
74 impl IntoIterator<Item = Log>,
75 ) {
76 assert!(self.parent.is_none());
77
78 let mut applies = Vec::<Apply<BTreeMap<H256, H256>>>::new();
79
80 let mut addresses = BTreeSet::new();
81
82 for address in self.accounts.keys() {
83 addresses.insert(*address);
84 }
85
86 for (address, _) in self.storages.keys() {
87 addresses.insert(*address);
88 }
89
90 for address in addresses {
91 if self.deletes.contains(&address) {
92 continue;
93 }
94
95 let mut storage = BTreeMap::new();
96 for ((oa, ok), ov) in &self.storages {
97 if *oa == address {
98 storage.insert(*ok, *ov);
99 }
100 }
101
102 let apply = {
103 let account = if self.is_created(address) {
104 let account = self
105 .accounts
106 .get_mut(&address)
107 .expect("New account was just inserted");
108 account.reset = true;
111 account
112 } else {
113 self.account_mut(address, backend)
114 };
115
116 Apply::Modify {
117 address,
118 basic: account.basic.clone(),
119 code: account.code.clone(),
120 storage,
121 reset_storage: account.reset,
122 }
123 };
124
125 applies.push(apply);
126 }
127
128 for address in self.deletes {
129 applies.push(Apply::Delete { address });
130 }
131
132 (applies, self.logs)
133 }
134
135 pub fn enter(&mut self, gas_limit: u64, is_static: bool) {
136 let mut entering = Self {
137 metadata: self.metadata.spit_child(gas_limit, is_static),
138 parent: None,
139 logs: Vec::new(),
140 accounts: BTreeMap::new(),
141 storages: BTreeMap::new(),
142 tstorages: BTreeMap::new(),
143 deletes: BTreeSet::new(),
144 creates: BTreeSet::new(),
145 };
146 mem::swap(&mut entering, self);
147
148 self.parent = Some(Box::new(entering));
149 }
150
151 pub fn exit_commit(&mut self) -> Result<(), ExitError> {
167 let mut exited = *self.parent.take().expect("Cannot commit on root substate");
168 mem::swap(&mut exited, self);
169
170 self.metadata.swallow_commit(exited.metadata)?;
171 self.logs.append(&mut exited.logs);
172
173 let mut resets = BTreeSet::new();
174 for (address, account) in &exited.accounts {
175 if account.reset {
176 resets.insert(*address);
177 }
178 }
179 let mut reset_keys = BTreeSet::new();
180 for (address, key) in self.storages.keys() {
181 if resets.contains(address) {
182 reset_keys.insert((*address, *key));
183 }
184 }
185 for (address, key) in reset_keys {
186 self.storages.remove(&(address, key));
187 }
188
189 self.accounts.append(&mut exited.accounts);
190 self.storages.append(&mut exited.storages);
191 self.tstorages.append(&mut exited.tstorages);
192 self.deletes.append(&mut exited.deletes);
193 self.creates.append(&mut exited.creates);
194 Ok(())
195 }
196
197 pub fn exit_revert(&mut self) -> Result<(), ExitError> {
205 let mut exited = *self.parent.take().expect("Cannot discard on root substate");
206 mem::swap(&mut exited, self);
207 self.metadata.swallow_revert(&exited.metadata)?;
208 Ok(())
209 }
210
211 pub fn exit_discard(&mut self) -> Result<(), ExitError> {
219 let mut exited = *self.parent.take().expect("Cannot discard on root substate");
220 mem::swap(&mut exited, self);
221 self.metadata.swallow_discard(&exited.metadata);
222 Ok(())
223 }
224
225 pub fn known_account(&self, address: H160) -> Option<&MemoryStackAccount> {
226 self.accounts.get(&address).map_or_else(
227 || {
228 self.parent
229 .as_ref()
230 .and_then(|parent| parent.known_account(address))
231 },
232 Some,
233 )
234 }
235
236 #[must_use]
237 pub fn known_basic(&self, address: H160) -> Option<Basic> {
238 self.known_account(address).map(|acc| acc.basic.clone())
239 }
240
241 #[must_use]
242 pub fn known_code(&self, address: H160) -> Option<Vec<u8>> {
243 self.known_account(address).and_then(|acc| acc.code.clone())
244 }
245
246 #[must_use]
247 pub fn known_empty(&self, address: H160) -> Option<bool> {
248 if let Some(account) = self.known_account(address) {
249 if account.basic.balance != U256_ZERO {
250 return Some(false);
251 }
252
253 if account.basic.nonce != U256_ZERO {
254 return Some(false);
255 }
256
257 if let Some(code) = &account.code {
258 return Some(
259 account.basic.balance == U256_ZERO
260 && account.basic.nonce == U256_ZERO
261 && code.is_empty(),
262 );
263 }
264 }
265
266 None
267 }
268
269 #[must_use]
270 pub fn known_storage(&self, address: H160, key: H256) -> Option<H256> {
271 if let Some(value) = self.storages.get(&(address, key)) {
272 return Some(*value);
273 }
274
275 if let Some(account) = self.accounts.get(&address) {
276 if account.reset {
277 return Some(H256::default());
278 }
279 }
280
281 if let Some(parent) = self.parent.as_ref() {
282 return parent.known_storage(address, key);
283 }
284
285 None
286 }
287
288 #[must_use]
289 pub fn known_original_storage(&self, address: H160) -> Option<H256> {
290 if let Some(account) = self.accounts.get(&address) {
291 if account.reset {
292 return Some(H256::default());
293 }
294 }
295
296 if let Some(parent) = self.parent.as_ref() {
297 return parent.known_original_storage(address);
298 }
299
300 None
301 }
302
303 #[must_use]
304 pub fn is_cold(&self, address: H160) -> bool {
305 self.recursive_is_cold(&|a| a.accessed_addresses.contains(&address))
306 }
307
308 #[must_use]
309 pub fn is_storage_cold(&self, address: H160, key: H256) -> bool {
310 self.recursive_is_cold(&|a: &Accessed| a.accessed_storage.contains(&(address, key)))
311 }
312
313 fn recursive_is_cold<F: Fn(&Accessed) -> bool>(&self, f: &F) -> bool {
314 let local_is_accessed = self.metadata.accessed().as_ref().is_some_and(f);
315 if local_is_accessed {
316 false
317 } else {
318 self.parent
319 .as_ref()
320 .map_or(true, |p| p.recursive_is_cold(f))
321 }
322 }
323
324 #[must_use]
325 pub fn deleted(&self, address: H160) -> bool {
326 if self.deletes.contains(&address) {
327 return true;
328 }
329
330 if let Some(parent) = self.parent.as_ref() {
331 return parent.deleted(address);
332 }
333
334 false
335 }
336
337 #[allow(clippy::map_entry)]
338 fn account_mut<B: Backend>(&mut self, address: H160, backend: &B) -> &mut MemoryStackAccount {
339 if !self.accounts.contains_key(&address) {
340 let account = self.known_account(address).cloned().map_or_else(
341 || MemoryStackAccount {
342 basic: backend.basic(address),
343 code: None::<Vec<_>>,
344 reset: false,
345 },
346 |mut v| {
347 v.reset = false;
348 v
349 },
350 );
351 self.accounts.insert(address, account);
352 }
353
354 self.accounts
355 .get_mut(&address)
356 .expect("New account was just inserted")
357 }
358
359 pub fn inc_nonce<B: Backend>(&mut self, address: H160, backend: &B) -> Result<(), ExitError> {
362 let nonce = &mut self.account_mut(address, backend).basic.nonce;
363 if *nonce >= U64_MAX {
364 return Err(ExitError::MaxNonce);
365 }
366 *nonce += U256_ONE;
367 Ok(())
368 }
369
370 pub fn set_storage(&mut self, address: H160, key: H256, value: H256) {
371 #[cfg(feature = "print-debug")]
372 println!(" [SSTORE {address:?}] {key:?}:{value:?}");
373 self.storages.insert((address, key), value);
374 }
375
376 pub fn reset_storage<B: Backend>(&mut self, address: H160, backend: &B) {
377 let mut removing = Vec::new();
378
379 for (oa, ok) in self.storages.keys() {
380 if *oa == address {
381 removing.push(*ok);
382 }
383 }
384
385 for ok in removing {
386 self.storages.remove(&(address, ok));
387 }
388 self.account_mut(address, backend).reset = true;
389 }
390
391 pub fn log(&mut self, address: H160, topics: Vec<H256>, data: Vec<u8>) {
392 self.logs.push(Log {
393 address,
394 topics,
395 data,
396 });
397 }
398
399 pub fn set_deleted(&mut self, address: H160) {
400 self.deletes.insert(address);
401 }
402
403 pub fn set_created(&mut self, address: H160) {
404 self.creates.insert(address);
405 }
406
407 #[must_use]
408 pub fn is_created(&self, address: H160) -> bool {
409 if self.creates.contains(&address) {
410 return true;
411 }
412
413 if let Some(parent) = self.parent.as_ref() {
414 return parent.is_created(address);
415 }
416
417 false
418 }
419
420 pub fn set_code<B: Backend>(&mut self, address: H160, code: Vec<u8>, backend: &B) {
421 self.account_mut(address, backend).code = Some(code);
422 }
423
424 pub fn transfer<B: Backend>(
427 &mut self,
428 transfer: &Transfer,
429 backend: &B,
430 ) -> Result<(), ExitError> {
431 {
432 let source = self.account_mut(transfer.source, backend);
433 if source.basic.balance < transfer.value {
434 return Err(ExitError::OutOfFund);
435 }
436 source.basic.balance -= transfer.value;
437 }
438
439 {
440 let target = self.account_mut(transfer.target, backend);
441 target.basic.balance = target.basic.balance.saturating_add(transfer.value);
442 }
443
444 Ok(())
445 }
446
447 pub fn withdraw<B: Backend>(
451 &mut self,
452 address: H160,
453 value: U256,
454 backend: &B,
455 ) -> Result<(), ExitError> {
456 let source = self.account_mut(address, backend);
457 if source.basic.balance < value {
458 return Err(ExitError::OutOfFund);
459 }
460 source.basic.balance -= value;
461
462 Ok(())
463 }
464
465 pub fn deposit<B: Backend>(&mut self, address: H160, value: U256, backend: &B) {
467 let target = self.account_mut(address, backend);
468 target.basic.balance = target.basic.balance.saturating_add(value);
469 }
470
471 pub fn reset_balance<B: Backend>(&mut self, address: H160, backend: &B) {
472 self.account_mut(address, backend).basic.balance = U256_ZERO;
473 }
474
475 pub fn touch<B: Backend>(&mut self, address: H160, backend: &B) {
476 self.account_mut(address, backend);
477 }
478
479 #[must_use]
480 pub fn get_tstorage(&self, address: H160, key: H256) -> U256 {
481 self.known_tstorage(address, key).unwrap_or_default()
482 }
483
484 #[must_use]
485 pub fn known_tstorage(&self, address: H160, key: H256) -> Option<U256> {
486 if let Some(value) = self.tstorages.get(&(address, key)) {
487 return Some(*value);
488 }
489 if let Some(parent) = self.parent.as_ref() {
490 return parent.known_tstorage(address, key);
491 }
492 None
493 }
494
495 pub fn set_tstorage(&mut self, address: H160, key: H256, value: U256) {
496 self.tstorages.insert((address, key), value);
497 }
498
499 fn get_authority_target_recursive(&self, authority: H160) -> Option<H160> {
502 if let Some(target) = self
503 .metadata
504 .accessed()
505 .as_ref()
506 .and_then(|accessed| accessed.get_authority_target(authority))
507 {
508 return Some(target);
509 }
510 self.parent
511 .as_ref()
512 .and_then(|p| p.get_authority_target_recursive(authority))
513 }
514}
515
516#[derive(Clone, Debug)]
517pub struct MemoryStackState<'backend, 'config, B> {
518 backend: &'backend B,
519 substate: MemoryStackSubstate<'config>,
520}
521
522impl<B: Backend> Backend for MemoryStackState<'_, '_, B> {
523 fn gas_price(&self) -> U256 {
524 self.backend.gas_price()
525 }
526 fn origin(&self) -> H160 {
527 self.backend.origin()
528 }
529 fn block_hash(&self, number: U256) -> H256 {
530 self.backend.block_hash(number)
531 }
532 fn block_number(&self) -> U256 {
533 self.backend.block_number()
534 }
535 fn block_coinbase(&self) -> H160 {
536 self.backend.block_coinbase()
537 }
538 fn block_timestamp(&self) -> U256 {
539 self.backend.block_timestamp()
540 }
541 fn block_difficulty(&self) -> U256 {
542 self.backend.block_difficulty()
543 }
544 fn block_randomness(&self) -> Option<H256> {
545 self.backend.block_randomness()
546 }
547 fn block_gas_limit(&self) -> U256 {
548 self.backend.block_gas_limit()
549 }
550 fn block_base_fee_per_gas(&self) -> U256 {
551 self.backend.block_base_fee_per_gas()
552 }
553
554 fn chain_id(&self) -> U256 {
555 self.backend.chain_id()
556 }
557
558 fn exists(&self, address: H160) -> bool {
559 self.substate.known_account(address).is_some() || self.backend.exists(address)
560 }
561
562 fn basic(&self, address: H160) -> Basic {
563 self.substate
564 .known_basic(address)
565 .unwrap_or_else(|| self.backend.basic(address))
566 }
567
568 fn code(&self, address: H160) -> Vec<u8> {
569 self.substate
570 .known_code(address)
571 .unwrap_or_else(|| self.backend.code(address))
572 }
573
574 fn storage(&self, address: H160, key: H256) -> H256 {
575 self.substate
576 .known_storage(address, key)
577 .unwrap_or_else(|| self.backend.storage(address, key))
578 }
579
580 fn is_empty_storage(&self, address: H160) -> bool {
581 self.backend.is_empty_storage(address)
582 }
583
584 fn original_storage(&self, address: H160, key: H256) -> Option<H256> {
585 if let Some(value) = self.substate.known_original_storage(address) {
586 return Some(value);
587 }
588
589 self.backend.original_storage(address, key)
590 }
591 fn blob_gas_price(&self) -> Option<u128> {
592 self.backend.blob_gas_price()
593 }
594 fn get_blob_hash(&self, index: usize) -> Option<U256> {
595 self.backend.get_blob_hash(index)
596 }
597}
598
599impl<'config, B: Backend> StackState<'config> for MemoryStackState<'_, 'config, B> {
600 fn metadata(&self) -> &StackSubstateMetadata<'config> {
601 self.substate.metadata()
602 }
603
604 fn metadata_mut(&mut self) -> &mut StackSubstateMetadata<'config> {
605 self.substate.metadata_mut()
606 }
607
608 fn enter(&mut self, gas_limit: u64, is_static: bool) {
609 self.substate.enter(gas_limit, is_static);
610 }
611
612 fn exit_commit(&mut self) -> Result<(), ExitError> {
613 self.substate.exit_commit()
614 }
615
616 fn exit_revert(&mut self) -> Result<(), ExitError> {
617 self.substate.exit_revert()
618 }
619
620 fn exit_discard(&mut self) -> Result<(), ExitError> {
621 self.substate.exit_discard()
622 }
623
624 fn is_empty(&self, address: H160) -> bool {
625 if let Some(known_empty) = self.substate.known_empty(address) {
626 return known_empty;
627 }
628
629 self.backend.basic(address).balance == U256_ZERO
630 && self.backend.basic(address).nonce == U256_ZERO
631 && self.backend.code(address).is_empty()
632 }
633
634 fn deleted(&self, address: H160) -> bool {
635 self.substate.deleted(address)
636 }
637
638 fn is_cold(&self, address: H160) -> bool {
639 self.substate.is_cold(address)
640 }
641
642 fn is_storage_cold(&self, address: H160, key: H256) -> bool {
643 self.substate.is_storage_cold(address, key)
644 }
645
646 fn inc_nonce(&mut self, address: H160) -> Result<(), ExitError> {
647 self.substate.inc_nonce(address, self.backend)
648 }
649
650 fn set_storage(&mut self, address: H160, key: H256, value: H256) {
651 self.substate.set_storage(address, key, value);
652 }
653
654 fn reset_storage(&mut self, address: H160) {
655 self.substate.reset_storage(address, self.backend);
656 }
657
658 fn log(&mut self, address: H160, topics: Vec<H256>, data: Vec<u8>) {
659 self.substate.log(address, topics, data);
660 }
661
662 fn set_deleted(&mut self, address: H160) {
663 self.substate.set_deleted(address);
664 }
665
666 fn set_created(&mut self, address: H160) {
667 self.substate.set_created(address);
668 }
669
670 fn is_created(&self, address: H160) -> bool {
671 self.substate.is_created(address)
672 }
673
674 fn set_code(&mut self, address: H160, code: Vec<u8>) {
675 self.substate.set_code(address, code, self.backend);
676 }
677
678 fn transfer(&mut self, transfer: Transfer) -> Result<(), ExitError> {
679 self.substate.transfer(&transfer, self.backend)
680 }
681
682 fn reset_balance(&mut self, address: H160) {
683 self.substate.reset_balance(address, self.backend);
684 }
685
686 fn touch(&mut self, address: H160) {
687 self.substate.touch(address, self.backend);
688 }
689
690 fn tload(&mut self, address: H160, index: H256) -> Result<U256, ExitError> {
691 Ok(self.substate.get_tstorage(address, index))
692 }
693
694 fn tstore(&mut self, address: H160, index: H256, value: U256) -> Result<(), ExitError> {
695 self.substate.set_tstorage(address, index, value);
696 Ok(())
697 }
698
699 fn is_authority_cold(&mut self, address: H160) -> Option<bool> {
701 self.get_authority_target(address)
702 .map(|target| self.is_cold(target))
703 }
704
705 fn get_authority_target(&mut self, authority: H160) -> Option<H160> {
710 if let Some(target_address) = self.substate.get_authority_target_recursive(authority) {
712 Some(target_address)
713 } else {
714 let authority_code = self.code(authority);
717 if let Some(target) = Authorization::get_delegated_address(&authority_code) {
718 self.metadata_mut().add_authority(authority, target);
720 return Some(target);
721 }
722 None
723 }
724 }
725}
726
727impl<'backend, 'config, B: Backend> MemoryStackState<'backend, 'config, B> {
728 pub const fn new(metadata: StackSubstateMetadata<'config>, backend: &'backend B) -> Self {
729 Self {
730 backend,
731 substate: MemoryStackSubstate::new(metadata),
732 }
733 }
734
735 pub fn account_mut(&mut self, address: H160) -> &mut MemoryStackAccount {
737 self.substate.account_mut(address, self.backend)
738 }
739
740 #[must_use]
741 pub fn deconstruct(
742 self,
743 ) -> (
744 impl IntoIterator<Item = Apply<impl IntoIterator<Item = (H256, H256)>>>,
745 impl IntoIterator<Item = Log>,
746 ) {
747 self.substate.deconstruct(self.backend)
748 }
749
750 pub fn withdraw(&mut self, address: H160, value: U256) -> Result<(), ExitError> {
753 self.substate.withdraw(address, value, self.backend)
754 }
755
756 pub fn deposit(&mut self, address: H160, value: U256) {
757 self.substate.deposit(address, value, self.backend);
758 }
759}