reth_trie_common/bundle_state/
transition_account.rs1use super::{AccountRevert, AccountStatus, BundleAccount, StorageWithOriginalValues};
2use alloy_primitives::{B256, U256};
3use evm2::{bytecode::Bytecode, evm::AccountInfo};
4
5#[derive(Clone, Debug, PartialEq, Eq, Default)]
11pub struct TransitionAccount<S = StorageWithOriginalValues> {
12 pub info: Option<AccountInfo>,
14 pub status: AccountStatus,
16 pub previous_info: Option<AccountInfo>,
20 pub previous_status: AccountStatus,
22 pub storage: S,
24 pub storage_was_destroyed: bool,
30}
31
32impl TransitionAccount {
33 pub fn new_empty_eip161(storage: StorageWithOriginalValues) -> Self {
35 Self {
36 info: Some(AccountInfo::default()),
37 status: AccountStatus::InMemoryChange,
38 previous_info: None,
39 previous_status: AccountStatus::LoadedNotExisting,
40 storage,
41 storage_was_destroyed: false,
42 }
43 }
44
45 pub fn has_new_contract(&self) -> Option<(B256, &Bytecode)> {
47 let present_new_codehash = self.info.as_ref().map(|info| &info.code_hash);
48 let previous_codehash = self.previous_info.as_ref().map(|info| &info.code_hash);
49 if present_new_codehash != previous_codehash {
50 return self
51 .info
52 .as_ref()
53 .and_then(|info| info.code.as_ref().map(|c| (info.code_hash, c)));
54 }
55 None
56 }
57
58 pub fn previous_balance(&self) -> U256 {
60 self.previous_info.as_ref().map(|info| info.balance).unwrap_or_default()
61 }
62
63 pub fn current_balance(&self) -> U256 {
65 self.info.as_ref().map(|info| info.balance).unwrap_or_default()
66 }
67
68 pub fn create_revert(self) -> Option<AccountRevert> {
70 let mut previous_account = self.original_bundle_account();
71 previous_account.update_and_create_revert(self)
72 }
73
74 pub fn present_bundle_account(&self) -> BundleAccount {
76 BundleAccount {
77 info: self.info.clone(),
78 original_info: self.previous_info.clone(),
79 storage: self.storage.clone(),
80 status: self.status,
81 }
82 }
83
84 fn original_bundle_account(&self) -> BundleAccount {
86 BundleAccount {
87 info: self.previous_info.clone(),
88 original_info: self.previous_info.clone(),
89 storage: StorageWithOriginalValues::default(),
90 status: self.previous_status,
91 }
92 }
93}
94
95impl<S> TransitionAccount<S> {
96 pub fn map_storage<F, N>(self, f: F) -> TransitionAccount<N>
98 where
99 F: FnOnce(S) -> N,
100 {
101 let Self { info, status, previous_info, previous_status, storage, storage_was_destroyed } =
102 self;
103 TransitionAccount {
104 info,
105 status,
106 previous_info,
107 previous_status,
108 storage: f(storage),
109 storage_was_destroyed,
110 }
111 }
112}