revm_database/states/
account_status.rs1#[derive(Clone, Copy, Default, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
18#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
19pub enum AccountStatus {
20 #[default]
21 LoadedNotExisting,
22 Loaded,
23 LoadedEmptyEIP161,
24 InMemoryChange,
25 Changed,
26 Destroyed,
27 DestroyedChanged,
28 DestroyedAgain,
29}
30
31impl AccountStatus {
32 pub fn is_not_modified(&self) -> bool {
34 matches!(
35 self,
36 AccountStatus::LoadedNotExisting
37 | AccountStatus::Loaded
38 | AccountStatus::LoadedEmptyEIP161
39 )
40 }
41
42 pub fn was_destroyed(&self) -> bool {
45 matches!(
46 self,
47 AccountStatus::Destroyed
48 | AccountStatus::DestroyedChanged
49 | AccountStatus::DestroyedAgain
50 )
51 }
52
53 pub fn is_storage_known(&self) -> bool {
55 matches!(
56 self,
57 AccountStatus::LoadedNotExisting
58 | AccountStatus::InMemoryChange
59 | AccountStatus::Destroyed
60 | AccountStatus::DestroyedChanged
61 | AccountStatus::DestroyedAgain
62 )
63 }
64
65 pub fn is_modified_and_not_destroyed(&self) -> bool {
69 matches!(self, AccountStatus::Changed | AccountStatus::InMemoryChange)
70 }
71
72 pub fn on_created(&self) -> AccountStatus {
74 match self {
75 AccountStatus::DestroyedAgain
77 | AccountStatus::Destroyed
78 | AccountStatus::DestroyedChanged => AccountStatus::DestroyedChanged,
79 AccountStatus::LoadedNotExisting
81 | AccountStatus::LoadedEmptyEIP161
83 | AccountStatus::Loaded
84 | AccountStatus::Changed
85 | AccountStatus::InMemoryChange => {
86 AccountStatus::InMemoryChange
90 }
91 }
92 }
93
94 pub fn on_touched_empty_post_eip161(&self) -> AccountStatus {
100 match self {
101 AccountStatus::LoadedNotExisting => AccountStatus::LoadedNotExisting,
103 AccountStatus::InMemoryChange
105 | AccountStatus::Destroyed
106 | AccountStatus::LoadedEmptyEIP161 => AccountStatus::Destroyed,
107 AccountStatus::DestroyedAgain | AccountStatus::DestroyedChanged => {
109 AccountStatus::DestroyedAgain
110 }
111 AccountStatus::Loaded | AccountStatus::Changed => {
113 unreachable!("Wrong state transition, touch empty is not possible from {self:?}");
114 }
115 }
116 }
117
118 pub fn on_touched_created_pre_eip161(&self, had_no_info: bool) -> Option<AccountStatus> {
125 match self {
126 AccountStatus::LoadedEmptyEIP161 => None,
127 AccountStatus::DestroyedChanged => {
128 if had_no_info {
129 None
130 } else {
131 Some(AccountStatus::DestroyedChanged)
132 }
133 }
134 AccountStatus::Destroyed | AccountStatus::DestroyedAgain => {
135 Some(AccountStatus::DestroyedChanged)
136 }
137 AccountStatus::InMemoryChange | AccountStatus::LoadedNotExisting => {
138 Some(AccountStatus::InMemoryChange)
139 }
140 AccountStatus::Loaded | AccountStatus::Changed => {
141 unreachable!("Wrong state transition, touch crate is not possible from {self:?}")
142 }
143 }
144 }
145
146 pub fn on_changed(&self, had_no_nonce_and_code: bool) -> AccountStatus {
148 match self {
149 AccountStatus::LoadedNotExisting => AccountStatus::InMemoryChange,
152 AccountStatus::LoadedEmptyEIP161 => AccountStatus::InMemoryChange,
156 AccountStatus::Loaded => {
158 if had_no_nonce_and_code {
159 AccountStatus::InMemoryChange
161 } else {
162 AccountStatus::Changed
164 }
165 }
166
167 AccountStatus::Changed => AccountStatus::Changed,
170 AccountStatus::InMemoryChange => AccountStatus::InMemoryChange,
171 AccountStatus::DestroyedChanged => AccountStatus::DestroyedChanged,
172
173 AccountStatus::Destroyed | AccountStatus::DestroyedAgain => {
176 AccountStatus::DestroyedChanged
177 }
178 }
179 }
180
181 pub fn on_selfdestructed(&self) -> AccountStatus {
183 match self {
184 AccountStatus::LoadedNotExisting => AccountStatus::LoadedNotExisting,
186 AccountStatus::DestroyedChanged
190 | AccountStatus::DestroyedAgain
191 | AccountStatus::Destroyed => AccountStatus::DestroyedAgain,
192
193 _ => AccountStatus::Destroyed,
195 }
196 }
197
198 pub fn transition(&mut self, other: Self) {
211 *self = match (self.was_destroyed(), other.was_destroyed()) {
212 (true, false) => Self::DestroyedChanged,
213 (false, false) if *self == Self::InMemoryChange => Self::InMemoryChange,
214 _ => other,
215 };
216 }
217}
218
219#[cfg(test)]
220mod test {
221
222 use super::*;
223
224 #[test]
225 fn test_account_status() {
226 assert!(AccountStatus::Loaded.is_not_modified());
228 assert!(AccountStatus::LoadedEmptyEIP161.is_not_modified());
229 assert!(AccountStatus::LoadedNotExisting.is_not_modified());
230 assert!(!AccountStatus::Changed.is_not_modified());
231 assert!(!AccountStatus::InMemoryChange.is_not_modified());
232 assert!(!AccountStatus::Destroyed.is_not_modified());
233 assert!(!AccountStatus::DestroyedChanged.is_not_modified());
234 assert!(!AccountStatus::DestroyedAgain.is_not_modified());
235
236 assert!(!AccountStatus::LoadedEmptyEIP161.is_storage_known());
238 assert!(AccountStatus::LoadedNotExisting.is_storage_known());
239 assert!(AccountStatus::InMemoryChange.is_storage_known());
240 assert!(AccountStatus::Destroyed.is_storage_known());
241 assert!(AccountStatus::DestroyedChanged.is_storage_known());
242 assert!(AccountStatus::DestroyedAgain.is_storage_known());
243 assert!(!AccountStatus::Loaded.is_storage_known());
244 assert!(!AccountStatus::Changed.is_storage_known());
245
246 assert!(!AccountStatus::LoadedEmptyEIP161.was_destroyed());
248 assert!(!AccountStatus::LoadedNotExisting.was_destroyed());
249 assert!(!AccountStatus::InMemoryChange.was_destroyed());
250 assert!(AccountStatus::Destroyed.was_destroyed());
251 assert!(AccountStatus::DestroyedChanged.was_destroyed());
252 assert!(AccountStatus::DestroyedAgain.was_destroyed());
253 assert!(!AccountStatus::Loaded.was_destroyed());
254 assert!(!AccountStatus::Changed.was_destroyed());
255
256 assert!(AccountStatus::Changed.is_modified_and_not_destroyed());
258 assert!(AccountStatus::InMemoryChange.is_modified_and_not_destroyed());
259 assert!(!AccountStatus::Loaded.is_modified_and_not_destroyed());
260 assert!(!AccountStatus::LoadedEmptyEIP161.is_modified_and_not_destroyed());
261 assert!(!AccountStatus::LoadedNotExisting.is_modified_and_not_destroyed());
262 assert!(!AccountStatus::Destroyed.is_modified_and_not_destroyed());
263 assert!(!AccountStatus::DestroyedChanged.is_modified_and_not_destroyed());
264 assert!(!AccountStatus::DestroyedAgain.is_modified_and_not_destroyed());
265 }
266}