1use super::{
2 changes::PlainStorageRevert, AccountStatus, BundleAccount, PlainStateReverts,
3 StorageWithOriginalValues,
4};
5use core::ops::{Deref, DerefMut};
6use revm_interpreter::primitives::{AccountInfo, Address, HashMap, U256};
7use std::vec::Vec;
8
9#[derive(Clone, Debug, Default, PartialEq, Eq)]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12pub struct Reverts(Vec<Vec<(Address, AccountRevert)>>);
13
14impl Deref for Reverts {
15 type Target = Vec<Vec<(Address, AccountRevert)>>;
16
17 fn deref(&self) -> &Self::Target {
18 &self.0
19 }
20}
21
22impl DerefMut for Reverts {
23 fn deref_mut(&mut self) -> &mut Self::Target {
24 &mut self.0
25 }
26}
27
28impl Reverts {
29 pub fn new(reverts: Vec<Vec<(Address, AccountRevert)>>) -> Self {
31 Self(reverts)
32 }
33
34 pub fn sort(&mut self) {
36 for revert in &mut self.0 {
37 revert.sort_by_key(|(address, _)| *address);
38 }
39 }
40
41 pub fn extend(&mut self, other: Reverts) {
43 self.0.extend(other.0);
44 }
45
46 pub fn to_plain_state_reverts(&self) -> PlainStateReverts {
50 let mut state_reverts = PlainStateReverts::with_capacity(self.0.len());
51 for reverts in &self.0 {
52 let mut accounts = Vec::with_capacity(reverts.len());
54 let mut storage = Vec::with_capacity(reverts.len());
55 for (address, revert_account) in reverts {
56 match &revert_account.account {
57 AccountInfoRevert::RevertTo(acc) => {
58 accounts.push((*address, Some(acc.clone())))
61 }
62 AccountInfoRevert::DeleteIt => accounts.push((*address, None)),
63 AccountInfoRevert::DoNothing => (),
64 }
65 if revert_account.wipe_storage || !revert_account.storage.is_empty() {
66 storage.push(PlainStorageRevert {
67 address: *address,
68 wiped: revert_account.wipe_storage,
69 storage_revert: revert_account
70 .storage
71 .iter()
72 .map(|(k, v)| (*k, *v))
73 .collect::<Vec<_>>(),
74 });
75 }
76 }
77 state_reverts.accounts.push(accounts);
78 state_reverts.storage.push(storage);
79 }
80 state_reverts
81 }
82
83 #[deprecated = "Use `to_plain_state_reverts` instead"]
87 pub fn into_plain_state_reverts(self) -> PlainStateReverts {
88 self.to_plain_state_reverts()
89 }
90}
91
92#[derive(Clone, Default, Debug, PartialEq, Eq)]
100#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
101pub struct AccountRevert {
102 pub account: AccountInfoRevert,
103 pub storage: HashMap<U256, RevertToSlot>,
104 pub previous_status: AccountStatus,
105 pub wipe_storage: bool,
106}
107
108impl AccountRevert {
109 pub fn size_hint(&self) -> usize {
112 1 + self.storage.len()
113 }
114
115 pub fn new_selfdestructed_again(
118 status: AccountStatus,
119 account: AccountInfoRevert,
120 mut previous_storage: StorageWithOriginalValues,
121 updated_storage: StorageWithOriginalValues,
122 ) -> Self {
123 let mut previous_storage: HashMap<U256, RevertToSlot> = previous_storage
126 .drain()
127 .map(|(key, value)| (key, RevertToSlot::Some(value.present_value)))
128 .collect();
129 for (key, _) in updated_storage {
130 previous_storage
131 .entry(key)
132 .or_insert(RevertToSlot::Destroyed);
133 }
134 AccountRevert {
135 account,
136 storage: previous_storage,
137 previous_status: status,
138 wipe_storage: false,
139 }
140 }
141
142 pub fn new_selfdestructed_from_bundle(
144 account_info_revert: AccountInfoRevert,
145 bundle_account: &mut BundleAccount,
146 updated_storage: &StorageWithOriginalValues,
147 ) -> Option<Self> {
148 match bundle_account.status {
149 AccountStatus::InMemoryChange
150 | AccountStatus::Changed
151 | AccountStatus::LoadedEmptyEIP161
152 | AccountStatus::Loaded => {
153 let mut ret = AccountRevert::new_selfdestructed_again(
154 bundle_account.status,
155 account_info_revert,
156 bundle_account.storage.drain().collect(),
157 updated_storage.clone(),
158 );
159 ret.wipe_storage = true;
160 Some(ret)
161 }
162 _ => None,
163 }
164 }
165
166 pub fn new_selfdestructed(
168 status: AccountStatus,
169 account: AccountInfoRevert,
170 mut storage: StorageWithOriginalValues,
171 ) -> Self {
172 let previous_storage = storage
174 .iter_mut()
175 .map(|(key, value)| {
176 (*key, RevertToSlot::Some(value.present_value))
178 })
179 .collect();
180
181 Self {
182 account,
183 storage: previous_storage,
184 previous_status: status,
185 wipe_storage: true,
186 }
187 }
188
189 pub fn is_empty(&self) -> bool {
194 self.account == AccountInfoRevert::DoNothing
195 && self.storage.is_empty()
196 && !self.wipe_storage
197 }
198}
199
200#[derive(Clone, Default, Debug, PartialEq, Eq, Hash)]
203#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
204pub enum AccountInfoRevert {
205 #[default]
206 DoNothing,
208 DeleteIt,
210 RevertTo(AccountInfo),
212}
213
214#[derive(Clone, Debug, Copy, PartialEq, Eq, Hash)]
222#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
223pub enum RevertToSlot {
224 Some(U256),
225 Destroyed,
226}
227
228impl RevertToSlot {
229 pub fn to_previous_value(self) -> U256 {
230 match self {
231 RevertToSlot::Some(value) => value,
232 RevertToSlot::Destroyed => U256::ZERO,
233 }
234 }
235}