1#[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]
22 LoadedNotExisting,
23 Loaded,
25 LoadedEmptyEIP161,
27 InMemoryChange,
29 Changed,
31 Destroyed,
33 DestroyedChanged,
35 DestroyedAgain,
37}
38
39impl AccountStatus {
40 pub fn is_not_modified(&self) -> bool {
42 matches!(
43 self,
44 Self::LoadedNotExisting | Self::Loaded | Self::LoadedEmptyEIP161
45 )
46 }
47
48 pub fn was_destroyed(&self) -> bool {
51 matches!(
52 self,
53 Self::Destroyed | Self::DestroyedChanged | Self::DestroyedAgain
54 )
55 }
56
57 pub fn is_storage_known(&self) -> bool {
59 matches!(
60 self,
61 Self::LoadedNotExisting
62 | Self::InMemoryChange
63 | Self::Destroyed
64 | Self::DestroyedChanged
65 | Self::DestroyedAgain
66 )
67 }
68
69 pub fn is_modified_and_not_destroyed(&self) -> bool {
73 matches!(self, Self::Changed | Self::InMemoryChange)
74 }
75
76 pub fn on_created(&self) -> Self {
78 match self {
79 Self::DestroyedAgain
81 | Self::Destroyed
82 | Self::DestroyedChanged => Self::DestroyedChanged,
83 Self::LoadedNotExisting
85 | Self::LoadedEmptyEIP161
87 | Self::Loaded
88 | Self::Changed
89 | Self::InMemoryChange => {
90 Self::InMemoryChange
94 }
95 }
96 }
97
98 pub fn on_touched_empty_post_eip161(&self) -> Self {
100 match self {
101 Self::LoadedNotExisting => Self::LoadedNotExisting,
103 Self::InMemoryChange | Self::Destroyed | Self::LoadedEmptyEIP161 => Self::Destroyed,
105 Self::DestroyedAgain | Self::DestroyedChanged => Self::DestroyedAgain,
107 Self::Changed | Self::Loaded => Self::Destroyed,
109 }
110 }
111
112 pub fn on_changed(&self, had_no_nonce_and_code: bool) -> Self {
114 match self {
115 Self::LoadedNotExisting => Self::InMemoryChange,
118 Self::LoadedEmptyEIP161 => Self::InMemoryChange,
122 Self::Loaded => {
124 if had_no_nonce_and_code {
125 Self::InMemoryChange
127 } else {
128 Self::Changed
130 }
131 }
132
133 Self::Changed => Self::Changed,
136 Self::InMemoryChange => Self::InMemoryChange,
137 Self::DestroyedChanged => Self::DestroyedChanged,
138
139 Self::Destroyed | Self::DestroyedAgain => Self::DestroyedChanged,
142 }
143 }
144
145 pub fn on_selfdestructed(&self) -> Self {
147 match self {
148 Self::LoadedNotExisting => Self::LoadedNotExisting,
150 Self::DestroyedChanged | Self::DestroyedAgain | Self::Destroyed => Self::DestroyedAgain,
154
155 _ => Self::Destroyed,
157 }
158 }
159
160 pub fn transition(&mut self, other: Self) {
173 *self = match (self.was_destroyed(), other.was_destroyed()) {
174 (true, false) => Self::DestroyedChanged,
175 (false, false) if *self == Self::InMemoryChange => Self::InMemoryChange,
176 _ => other,
177 };
178 }
179}
180
181#[cfg(test)]
182mod test {
183
184 use super::*;
185
186 #[test]
187 fn test_account_status() {
188 assert!(AccountStatus::Loaded.is_not_modified());
190 assert!(AccountStatus::LoadedEmptyEIP161.is_not_modified());
191 assert!(AccountStatus::LoadedNotExisting.is_not_modified());
192 assert!(!AccountStatus::Changed.is_not_modified());
193 assert!(!AccountStatus::InMemoryChange.is_not_modified());
194 assert!(!AccountStatus::Destroyed.is_not_modified());
195 assert!(!AccountStatus::DestroyedChanged.is_not_modified());
196 assert!(!AccountStatus::DestroyedAgain.is_not_modified());
197
198 assert!(!AccountStatus::LoadedEmptyEIP161.is_storage_known());
200 assert!(AccountStatus::LoadedNotExisting.is_storage_known());
201 assert!(AccountStatus::InMemoryChange.is_storage_known());
202 assert!(AccountStatus::Destroyed.is_storage_known());
203 assert!(AccountStatus::DestroyedChanged.is_storage_known());
204 assert!(AccountStatus::DestroyedAgain.is_storage_known());
205 assert!(!AccountStatus::Loaded.is_storage_known());
206 assert!(!AccountStatus::Changed.is_storage_known());
207
208 assert!(!AccountStatus::LoadedEmptyEIP161.was_destroyed());
210 assert!(!AccountStatus::LoadedNotExisting.was_destroyed());
211 assert!(!AccountStatus::InMemoryChange.was_destroyed());
212 assert!(AccountStatus::Destroyed.was_destroyed());
213 assert!(AccountStatus::DestroyedChanged.was_destroyed());
214 assert!(AccountStatus::DestroyedAgain.was_destroyed());
215 assert!(!AccountStatus::Loaded.was_destroyed());
216 assert!(!AccountStatus::Changed.was_destroyed());
217
218 assert!(AccountStatus::Changed.is_modified_and_not_destroyed());
220 assert!(AccountStatus::InMemoryChange.is_modified_and_not_destroyed());
221 assert!(!AccountStatus::Loaded.is_modified_and_not_destroyed());
222 assert!(!AccountStatus::LoadedEmptyEIP161.is_modified_and_not_destroyed());
223 assert!(!AccountStatus::LoadedNotExisting.is_modified_and_not_destroyed());
224 assert!(!AccountStatus::Destroyed.is_modified_and_not_destroyed());
225 assert!(!AccountStatus::DestroyedChanged.is_modified_and_not_destroyed());
226 assert!(!AccountStatus::DestroyedAgain.is_modified_and_not_destroyed());
227 }
228
229 #[test]
230 fn test_on_created() {
231 assert_eq!(
232 AccountStatus::Destroyed.on_created(),
233 AccountStatus::DestroyedChanged
234 );
235 assert_eq!(
236 AccountStatus::DestroyedAgain.on_created(),
237 AccountStatus::DestroyedChanged
238 );
239 assert_eq!(
240 AccountStatus::DestroyedChanged.on_created(),
241 AccountStatus::DestroyedChanged
242 );
243
244 assert_eq!(
245 AccountStatus::LoadedNotExisting.on_created(),
246 AccountStatus::InMemoryChange
247 );
248 assert_eq!(
249 AccountStatus::Loaded.on_created(),
250 AccountStatus::InMemoryChange
251 );
252 assert_eq!(
253 AccountStatus::LoadedEmptyEIP161.on_created(),
254 AccountStatus::InMemoryChange
255 );
256 assert_eq!(
257 AccountStatus::Changed.on_created(),
258 AccountStatus::InMemoryChange
259 );
260 assert_eq!(
261 AccountStatus::InMemoryChange.on_created(),
262 AccountStatus::InMemoryChange
263 );
264 }
265
266 #[test]
267 fn test_on_touched_empty_post_eip161() {
268 assert_eq!(
269 AccountStatus::LoadedNotExisting.on_touched_empty_post_eip161(),
270 AccountStatus::LoadedNotExisting
271 );
272 assert_eq!(
273 AccountStatus::InMemoryChange.on_touched_empty_post_eip161(),
274 AccountStatus::Destroyed
275 );
276 assert_eq!(
277 AccountStatus::Destroyed.on_touched_empty_post_eip161(),
278 AccountStatus::Destroyed
279 );
280 assert_eq!(
281 AccountStatus::LoadedEmptyEIP161.on_touched_empty_post_eip161(),
282 AccountStatus::Destroyed
283 );
284 assert_eq!(
285 AccountStatus::DestroyedAgain.on_touched_empty_post_eip161(),
286 AccountStatus::DestroyedAgain
287 );
288 assert_eq!(
289 AccountStatus::DestroyedChanged.on_touched_empty_post_eip161(),
290 AccountStatus::DestroyedAgain
291 );
292 assert_eq!(
293 AccountStatus::Loaded.on_touched_empty_post_eip161(),
294 AccountStatus::Destroyed
295 );
296 assert_eq!(
297 AccountStatus::Changed.on_touched_empty_post_eip161(),
298 AccountStatus::Destroyed
299 );
300 }
301
302 #[test]
303 fn test_on_changed() {
304 assert_eq!(
305 AccountStatus::LoadedNotExisting.on_changed(true),
306 AccountStatus::InMemoryChange
307 );
308 assert_eq!(
309 AccountStatus::LoadedNotExisting.on_changed(false),
310 AccountStatus::InMemoryChange
311 );
312
313 assert_eq!(
314 AccountStatus::LoadedEmptyEIP161.on_changed(true),
315 AccountStatus::InMemoryChange
316 );
317 assert_eq!(
318 AccountStatus::LoadedEmptyEIP161.on_changed(false),
319 AccountStatus::InMemoryChange
320 );
321
322 assert_eq!(
323 AccountStatus::Loaded.on_changed(true),
324 AccountStatus::InMemoryChange
325 );
326 assert_eq!(
327 AccountStatus::Loaded.on_changed(false),
328 AccountStatus::Changed
329 );
330
331 assert_eq!(
332 AccountStatus::Changed.on_changed(true),
333 AccountStatus::Changed
334 );
335 assert_eq!(
336 AccountStatus::Changed.on_changed(false),
337 AccountStatus::Changed
338 );
339
340 assert_eq!(
341 AccountStatus::InMemoryChange.on_changed(true),
342 AccountStatus::InMemoryChange
343 );
344 assert_eq!(
345 AccountStatus::InMemoryChange.on_changed(false),
346 AccountStatus::InMemoryChange
347 );
348
349 assert_eq!(
350 AccountStatus::DestroyedChanged.on_changed(true),
351 AccountStatus::DestroyedChanged
352 );
353 assert_eq!(
354 AccountStatus::DestroyedChanged.on_changed(false),
355 AccountStatus::DestroyedChanged
356 );
357
358 assert_eq!(
359 AccountStatus::Destroyed.on_changed(true),
360 AccountStatus::DestroyedChanged
361 );
362 assert_eq!(
363 AccountStatus::Destroyed.on_changed(false),
364 AccountStatus::DestroyedChanged
365 );
366
367 assert_eq!(
368 AccountStatus::DestroyedAgain.on_changed(true),
369 AccountStatus::DestroyedChanged
370 );
371 assert_eq!(
372 AccountStatus::DestroyedAgain.on_changed(false),
373 AccountStatus::DestroyedChanged
374 );
375 }
376
377 #[test]
378 fn test_on_selfdestructed() {
379 assert_eq!(
380 AccountStatus::LoadedNotExisting.on_selfdestructed(),
381 AccountStatus::LoadedNotExisting
382 );
383
384 assert_eq!(
385 AccountStatus::DestroyedChanged.on_selfdestructed(),
386 AccountStatus::DestroyedAgain
387 );
388 assert_eq!(
389 AccountStatus::DestroyedAgain.on_selfdestructed(),
390 AccountStatus::DestroyedAgain
391 );
392 assert_eq!(
393 AccountStatus::Destroyed.on_selfdestructed(),
394 AccountStatus::DestroyedAgain
395 );
396
397 assert_eq!(
398 AccountStatus::Loaded.on_selfdestructed(),
399 AccountStatus::Destroyed
400 );
401 assert_eq!(
402 AccountStatus::LoadedEmptyEIP161.on_selfdestructed(),
403 AccountStatus::Destroyed
404 );
405 assert_eq!(
406 AccountStatus::InMemoryChange.on_selfdestructed(),
407 AccountStatus::Destroyed
408 );
409 assert_eq!(
410 AccountStatus::Changed.on_selfdestructed(),
411 AccountStatus::Destroyed
412 );
413 }
414
415 #[test]
416 fn test_transition() {
417 let mut status = AccountStatus::Destroyed;
418 status.transition(AccountStatus::Loaded);
419 assert_eq!(status, AccountStatus::DestroyedChanged);
420
421 let mut status = AccountStatus::DestroyedChanged;
422 status.transition(AccountStatus::InMemoryChange);
423 assert_eq!(status, AccountStatus::DestroyedChanged);
424
425 let mut status = AccountStatus::DestroyedAgain;
426 status.transition(AccountStatus::Changed);
427 assert_eq!(status, AccountStatus::DestroyedChanged);
428
429 let mut status = AccountStatus::InMemoryChange;
430 status.transition(AccountStatus::Loaded);
431 assert_eq!(status, AccountStatus::InMemoryChange);
432
433 let mut status = AccountStatus::InMemoryChange;
434 status.transition(AccountStatus::Changed);
435 assert_eq!(status, AccountStatus::InMemoryChange);
436
437 let mut status = AccountStatus::Loaded;
438 status.transition(AccountStatus::Changed);
439 assert_eq!(status, AccountStatus::Changed);
440
441 let mut status = AccountStatus::LoadedNotExisting;
442 status.transition(AccountStatus::InMemoryChange);
443 assert_eq!(status, AccountStatus::InMemoryChange);
444
445 let mut status = AccountStatus::LoadedEmptyEIP161;
446 status.transition(AccountStatus::Loaded);
447 assert_eq!(status, AccountStatus::Loaded);
448
449 let mut status = AccountStatus::Destroyed;
450 status.transition(AccountStatus::DestroyedChanged);
451 assert_eq!(status, AccountStatus::DestroyedChanged);
452
453 let mut status = AccountStatus::DestroyedAgain;
454 status.transition(AccountStatus::Destroyed);
455 assert_eq!(status, AccountStatus::Destroyed);
456
457 let mut status = AccountStatus::Loaded;
458 status.transition(AccountStatus::Destroyed);
459 assert_eq!(status, AccountStatus::Destroyed);
460
461 let mut status = AccountStatus::Changed;
462 status.transition(AccountStatus::DestroyedAgain);
463 assert_eq!(status, AccountStatus::DestroyedAgain);
464 }
465}