1use super::{
2 changes::{PlainStorageChangeset, StateChangeset},
3 reverts::{AccountInfoRevert, Reverts},
4 AccountRevert, AccountStatus, BundleAccount, PlainStateReverts, RevertToSlot, StorageSlot,
5 TransitionState,
6};
7use bytecode::Bytecode;
8use core::{mem, ops::RangeInclusive};
9use primitives::{
10 hash_map::Entry, Address, AddressMap, AddressSet, B256Map, HashMap, StorageKey, StorageKeyMap,
11 StorageValue, B256, KECCAK_EMPTY,
12};
13use state::AccountInfo;
14use std::{
15 collections::{BTreeMap, BTreeSet},
16 vec::Vec,
17};
18
19#[derive(Debug)]
21pub struct BundleBuilder {
22 states: AddressSet,
23 state_original: AddressMap<AccountInfo>,
24 state_present: AddressMap<AccountInfo>,
25 state_storage: AddressMap<StorageKeyMap<(StorageValue, StorageValue)>>,
26
27 reverts: BTreeSet<(u64, Address)>,
28 revert_range: RangeInclusive<u64>,
29 revert_account: HashMap<(u64, Address), Option<Option<AccountInfo>>>,
30 revert_storage: HashMap<(u64, Address), Vec<(StorageKey, StorageValue)>>,
31
32 contracts: B256Map<Bytecode>,
33}
34
35#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
37pub enum OriginalValuesKnown {
38 Yes,
43 No,
49}
50impl OriginalValuesKnown {
51 pub fn is_not_known(&self) -> bool {
53 matches!(self, Self::No)
54 }
55}
56
57impl Default for BundleBuilder {
58 fn default() -> Self {
59 BundleBuilder {
60 states: AddressSet::default(),
61 state_original: AddressMap::default(),
62 state_present: AddressMap::default(),
63 state_storage: AddressMap::default(),
64 reverts: BTreeSet::new(),
65 revert_range: 0..=0,
66 revert_account: HashMap::default(),
67 revert_storage: HashMap::default(),
68 contracts: B256Map::default(),
69 }
70 }
71}
72
73impl BundleBuilder {
74 pub fn new(revert_range: RangeInclusive<u64>) -> Self {
78 BundleBuilder {
79 revert_range,
80 ..Default::default()
81 }
82 }
83
84 pub fn apply<F>(self, f: F) -> Self
86 where
87 F: FnOnce(Self) -> Self,
88 {
89 f(self)
90 }
91
92 pub fn apply_mut<F>(&mut self, f: F) -> &mut Self
94 where
95 F: FnOnce(&mut Self),
96 {
97 f(self);
98 self
99 }
100
101 pub fn state_address(mut self, address: Address) -> Self {
103 self.set_state_address(address);
104 self
105 }
106
107 pub fn state_original_account_info(mut self, address: Address, original: AccountInfo) -> Self {
109 self.set_state_original_account_info(address, original);
110 self
111 }
112
113 pub fn state_present_account_info(mut self, address: Address, present: AccountInfo) -> Self {
115 self.set_state_present_account_info(address, present);
116 self
117 }
118
119 pub fn state_storage(
121 mut self,
122 address: Address,
123 storage: StorageKeyMap<(StorageValue, StorageValue)>,
124 ) -> Self {
125 self.set_state_storage(address, storage);
126 self
127 }
128
129 pub fn revert_address(mut self, block_number: u64, address: Address) -> Self {
134 self.set_revert_address(block_number, address);
135 self
136 }
137
138 pub fn revert_account_info(
143 mut self,
144 block_number: u64,
145 address: Address,
146 account: Option<Option<AccountInfo>>,
147 ) -> Self {
148 self.set_revert_account_info(block_number, address, account);
149 self
150 }
151
152 pub fn revert_storage(
157 mut self,
158 block_number: u64,
159 address: Address,
160 storage: Vec<(StorageKey, StorageValue)>,
161 ) -> Self {
162 self.set_revert_storage(block_number, address, storage);
163 self
164 }
165
166 pub fn contract(mut self, address: B256, bytecode: Bytecode) -> Self {
168 self.set_contract(address, bytecode);
169 self
170 }
171
172 pub fn set_state_address(&mut self, address: Address) -> &mut Self {
174 self.states.insert(address);
175 self
176 }
177
178 pub fn set_state_original_account_info(
180 &mut self,
181 address: Address,
182 original: AccountInfo,
183 ) -> &mut Self {
184 self.states.insert(address);
185 self.state_original.insert(address, original);
186 self
187 }
188
189 pub fn set_state_present_account_info(
191 &mut self,
192 address: Address,
193 present: AccountInfo,
194 ) -> &mut Self {
195 self.states.insert(address);
196 self.state_present.insert(address, present);
197 self
198 }
199
200 pub fn set_state_storage(
202 &mut self,
203 address: Address,
204 storage: StorageKeyMap<(StorageValue, StorageValue)>,
205 ) -> &mut Self {
206 self.states.insert(address);
207 self.state_storage.insert(address, storage);
208 self
209 }
210
211 pub fn set_revert_address(&mut self, block_number: u64, address: Address) -> &mut Self {
213 self.reverts.insert((block_number, address));
214 self
215 }
216
217 pub fn set_revert_account_info(
219 &mut self,
220 block_number: u64,
221 address: Address,
222 account: Option<Option<AccountInfo>>,
223 ) -> &mut Self {
224 self.reverts.insert((block_number, address));
225 self.revert_account.insert((block_number, address), account);
226 self
227 }
228
229 pub fn set_revert_storage(
231 &mut self,
232 block_number: u64,
233 address: Address,
234 storage: Vec<(StorageKey, StorageValue)>,
235 ) -> &mut Self {
236 self.reverts.insert((block_number, address));
237 self.revert_storage.insert((block_number, address), storage);
238 self
239 }
240
241 pub fn set_contract(&mut self, address: B256, bytecode: Bytecode) -> &mut Self {
243 self.contracts.insert(address, bytecode);
244 self
245 }
246
247 pub fn build(mut self) -> BundleState {
249 let mut state_size = 0;
250 let state = self
251 .states
252 .into_iter()
253 .map(|address| {
254 let storage = self
255 .state_storage
256 .remove(&address)
257 .map(|s| {
258 s.into_iter()
259 .map(|(k, (o_val, p_val))| (k, StorageSlot::new_changed(o_val, p_val)))
260 .collect()
261 })
262 .unwrap_or_default();
263 let bundle_account = BundleAccount::new(
264 self.state_original.remove(&address),
265 self.state_present.remove(&address),
266 storage,
267 AccountStatus::Changed,
268 );
269 state_size += bundle_account.size_hint();
270 (address, bundle_account)
271 })
272 .collect();
273
274 let mut reverts_size = 0;
275 let mut reverts_map = BTreeMap::new();
276 for block_number in self.revert_range {
277 reverts_map.insert(block_number, Vec::new());
278 }
279 self.reverts
280 .into_iter()
281 .for_each(|(block_number, address)| {
282 let account = match self
283 .revert_account
284 .remove(&(block_number, address))
285 .unwrap_or_default()
286 {
287 Some(Some(account)) => AccountInfoRevert::RevertTo(account),
288 Some(None) => AccountInfoRevert::DeleteIt,
289 None => AccountInfoRevert::DoNothing,
290 };
291 let storage = self
292 .revert_storage
293 .remove(&(block_number, address))
294 .map(|s| {
295 s.into_iter()
296 .map(|(k, v)| (k, RevertToSlot::Some(v)))
297 .collect()
298 })
299 .unwrap_or_default();
300 let account_revert = AccountRevert {
301 account,
302 storage,
303 previous_status: AccountStatus::Changed,
304 wipe_storage: false,
305 };
306
307 if let Some(vec) = reverts_map.get_mut(&block_number) {
308 reverts_size += account_revert.size_hint();
309 vec.push((address, account_revert));
310 }
311 });
312
313 BundleState {
314 state,
315 contracts: self.contracts,
316 reverts: Reverts::new(reverts_map.into_values().collect()),
317 state_size,
318 reverts_size,
319 }
320 }
321
322 pub fn get_states(&self) -> &AddressSet {
324 &self.states
325 }
326
327 pub fn get_states_mut(&mut self) -> &mut AddressSet {
329 &mut self.states
330 }
331
332 pub fn get_state_original_mut(&mut self) -> &mut AddressMap<AccountInfo> {
334 &mut self.state_original
335 }
336
337 pub fn get_state_present_mut(&mut self) -> &mut AddressMap<AccountInfo> {
339 &mut self.state_present
340 }
341
342 pub fn get_state_storage_mut(
344 &mut self,
345 ) -> &mut AddressMap<StorageKeyMap<(StorageValue, StorageValue)>> {
346 &mut self.state_storage
347 }
348
349 pub fn get_reverts_mut(&mut self) -> &mut BTreeSet<(u64, Address)> {
351 &mut self.reverts
352 }
353
354 pub fn get_revert_range_mut(&mut self) -> &mut RangeInclusive<u64> {
356 &mut self.revert_range
357 }
358
359 pub fn get_revert_account_mut(
361 &mut self,
362 ) -> &mut HashMap<(u64, Address), Option<Option<AccountInfo>>> {
363 &mut self.revert_account
364 }
365
366 pub fn get_revert_storage_mut(
368 &mut self,
369 ) -> &mut HashMap<(u64, Address), Vec<(StorageKey, StorageValue)>> {
370 &mut self.revert_storage
371 }
372
373 pub fn get_contracts_mut(&mut self) -> &mut B256Map<Bytecode> {
375 &mut self.contracts
376 }
377}
378
379#[derive(Debug)]
381pub enum BundleRetention {
382 PlainState,
384 Reverts,
386}
387
388impl BundleRetention {
389 pub fn includes_reverts(&self) -> bool {
391 matches!(self, Self::Reverts)
392 }
393}
394
395#[derive(Default, Clone, Debug, PartialEq, Eq)]
405#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
406pub struct BundleState {
407 pub state: AddressMap<BundleAccount>,
409 pub contracts: B256Map<Bytecode>,
411 pub reverts: Reverts,
417 pub state_size: usize,
419 pub reverts_size: usize,
421}
422
423impl BundleState {
424 pub fn builder(revert_range: RangeInclusive<u64>) -> BundleBuilder {
426 BundleBuilder::new(revert_range)
427 }
428
429 pub fn new(
431 state: impl IntoIterator<
432 Item = (
433 Address,
434 Option<AccountInfo>,
435 Option<AccountInfo>,
436 HashMap<StorageKey, (StorageValue, StorageValue)>,
437 ),
438 >,
439 reverts: impl IntoIterator<
440 Item = impl IntoIterator<
441 Item = (
442 Address,
443 Option<Option<AccountInfo>>,
444 impl IntoIterator<Item = (StorageKey, StorageValue)>,
445 ),
446 >,
447 >,
448 contracts: impl IntoIterator<Item = (B256, Bytecode)>,
449 ) -> Self {
450 let mut state_size = 0;
452 let state = state
453 .into_iter()
454 .map(|(address, original, present, storage)| {
455 let account = BundleAccount::new(
456 original,
457 present,
458 storage
459 .into_iter()
460 .map(|(k, (o_val, p_val))| (k, StorageSlot::new_changed(o_val, p_val)))
461 .collect(),
462 AccountStatus::Changed,
463 );
464 state_size += account.size_hint();
465 (address, account)
466 })
467 .collect();
468
469 let mut reverts_size = 0;
471 let reverts = reverts
472 .into_iter()
473 .map(|block_reverts| {
474 block_reverts
475 .into_iter()
476 .map(|(address, account, storage)| {
477 let account = match account {
478 Some(Some(account)) => AccountInfoRevert::RevertTo(account),
479 Some(None) => AccountInfoRevert::DeleteIt,
480 None => AccountInfoRevert::DoNothing,
481 };
482 let revert = AccountRevert {
483 account,
484 storage: storage
485 .into_iter()
486 .map(|(k, v)| (k, RevertToSlot::Some(v)))
487 .collect(),
488 previous_status: AccountStatus::Changed,
489 wipe_storage: false,
490 };
491 reverts_size += revert.size_hint();
492 (address, revert)
493 })
494 .collect::<Vec<_>>()
495 })
496 .collect::<Vec<_>>();
497
498 Self {
499 state,
500 contracts: contracts.into_iter().collect(),
501 reverts: Reverts::new(reverts),
502 state_size,
503 reverts_size,
504 }
505 }
506
507 pub fn size_hint(&self) -> usize {
512 self.state_size + self.reverts_size + self.contracts.len()
513 }
514
515 pub fn state(&self) -> &AddressMap<BundleAccount> {
517 &self.state
518 }
519
520 pub fn is_empty(&self) -> bool {
522 self.len() == 0
523 }
524
525 pub fn len(&self) -> usize {
527 self.state.len()
528 }
529
530 pub fn account(&self, address: &Address) -> Option<&BundleAccount> {
532 self.state.get(address)
533 }
534
535 pub fn bytecode(&self, hash: &B256) -> Option<Bytecode> {
537 self.contracts.get(hash).cloned()
538 }
539
540 pub fn storage(&self, address: &Address, storage_key: StorageKey) -> Option<StorageValue> {
544 self.account(address)
545 .and_then(|account| account.storage_slot(storage_key))
546 }
547
548 pub fn apply_transitions_and_create_reverts(
554 &mut self,
555 transitions: TransitionState,
556 retention: BundleRetention,
557 ) {
558 let include_reverts = retention.includes_reverts();
559 let reverts_capacity = if include_reverts {
561 transitions.transitions.len()
562 } else {
563 0
564 };
565 let mut reverts = Vec::with_capacity(reverts_capacity);
566
567 self.state.reserve(transitions.transitions.len());
568 for (address, transition) in transitions.transitions.into_iter() {
569 if let Some((hash, new_bytecode)) = transition.has_new_contract() {
571 self.contracts.insert(hash, new_bytecode.clone());
572 }
573 let revert = match self.state.entry(address) {
575 Entry::Occupied(mut entry) => {
576 let entry = entry.get_mut();
577 self.state_size -= entry.size_hint();
578 let revert = entry.update_and_create_revert(transition);
580 self.state_size += entry.size_hint();
582 revert
583 }
584 Entry::Vacant(entry) => {
585 let present_bundle = transition.present_bundle_account();
587 let revert = transition.create_revert();
588 if revert.is_some() {
589 self.state_size += present_bundle.size_hint();
590 entry.insert(present_bundle);
591 }
592 revert
593 }
594 };
595
596 if let Some(revert) = revert.filter(|_| include_reverts) {
598 self.reverts_size += revert.size_hint();
599 reverts.push((address, revert));
600 }
601 }
602
603 self.reverts.push(reverts);
604 }
605
606 pub fn to_plain_state(&self, is_value_known: OriginalValuesKnown) -> StateChangeset {
609 let state_len = self.state.len();
611 let mut accounts = Vec::with_capacity(state_len);
612 let mut storage = Vec::with_capacity(state_len);
613
614 for (address, account) in &self.state {
615 let was_destroyed = account.was_destroyed();
617 if is_value_known.is_not_known() || account.is_info_changed() {
618 let info = account.info.as_ref().map(AccountInfo::copy_without_code);
619 accounts.push((*address, info));
620 }
621
622 let mut account_storage_changed = Vec::with_capacity(account.storage.len());
627
628 for (&key, &slot) in account.storage.iter() {
629 let destroyed_and_not_zero = was_destroyed && !slot.present_value.is_zero();
632
633 let not_destroyed_and_changed = !was_destroyed && slot.is_changed();
636
637 if is_value_known.is_not_known()
638 || destroyed_and_not_zero
639 || not_destroyed_and_changed
640 {
641 account_storage_changed.push((key, slot.present_value));
642 }
643 }
644
645 if !account_storage_changed.is_empty() || was_destroyed {
646 storage.push(PlainStorageChangeset {
648 address: *address,
649 wipe_storage: was_destroyed,
650 storage: account_storage_changed,
651 });
652 }
653 }
654
655 let contracts = self
656 .contracts
657 .iter()
658 .filter(|(b, _)| **b != KECCAK_EMPTY)
660 .map(|(b, code)| (*b, code.clone()))
661 .collect::<Vec<_>>();
662 StateChangeset {
663 accounts,
664 storage,
665 contracts,
666 }
667 }
668
669 pub fn to_plain_state_and_reverts(
672 &self,
673 is_value_known: OriginalValuesKnown,
674 ) -> (StateChangeset, PlainStateReverts) {
675 (
676 self.to_plain_state(is_value_known),
677 self.reverts.to_plain_state_reverts(),
678 )
679 }
680
681 #[deprecated = "Use `to_plain_state_and_reverts` instead"]
684 pub fn into_plain_state_and_reverts(
685 self,
686 is_value_known: OriginalValuesKnown,
687 ) -> (StateChangeset, PlainStateReverts) {
688 self.to_plain_state_and_reverts(is_value_known)
689 }
690
691 pub fn extend_state(&mut self, other_state: AddressMap<BundleAccount>) {
695 self.state.reserve(other_state.len());
696 for (address, other_account) in other_state {
697 match self.state.entry(address) {
698 Entry::Occupied(mut entry) => {
699 let this = entry.get_mut();
700 self.state_size -= this.size_hint();
701
702 if other_account.was_destroyed() {
705 this.storage = other_account.storage;
706 } else {
707 this.storage.reserve(other_account.storage.len());
709 for (key, storage_slot) in other_account.storage {
710 this.storage
712 .entry(key)
713 .or_insert(storage_slot)
714 .present_value = storage_slot.present_value;
715 }
716 }
717 this.info = other_account.info;
718 this.status.transition(other_account.status);
719
720 self.state_size += this.size_hint();
722 }
723 Entry::Vacant(entry) => {
724 self.state_size += other_account.size_hint();
726 entry.insert(other_account);
727 }
728 }
729 }
730 }
731 pub fn extend(&mut self, mut other: Self) {
742 for (address, revert) in other.reverts.iter_mut().flatten() {
745 if revert.wipe_storage {
746 if let Some(this_account) = self.state.get_mut(address) {
749 for (key, value) in this_account.storage.drain() {
752 revert
753 .storage
754 .entry(key)
755 .or_insert(RevertToSlot::Some(value.present_value));
756 }
757
758 if this_account.was_destroyed() {
760 revert.wipe_storage = false;
761 }
762 }
763 }
764
765 self.reverts_size += revert.size_hint();
767 }
768 self.extend_state(other.state);
770 self.contracts.extend(other.contracts);
772 self.reverts.extend(other.reverts);
774 }
775
776 pub fn take_n_reverts(&mut self, reverts_to_take: usize) -> Reverts {
778 if reverts_to_take > self.reverts.len() {
780 return self.take_all_reverts();
781 }
782 let (detach, this) = self.reverts.split_at(reverts_to_take);
783 let detached_reverts = Reverts::new(detach.to_vec());
784 self.reverts_size = this
785 .iter()
786 .flatten()
787 .fold(0, |acc, (_, revert)| acc + revert.size_hint());
788 self.reverts = Reverts::new(this.to_vec());
789 detached_reverts
790 }
791
792 pub fn take_all_reverts(&mut self) -> Reverts {
794 self.reverts_size = 0;
795 mem::take(&mut self.reverts)
796 }
797
798 pub fn revert_latest(&mut self) -> bool {
804 if let Some(reverts) = self.reverts.pop() {
806 for (address, revert_account) in reverts.into_iter() {
807 self.reverts_size -= revert_account.size_hint();
808 match self.state.entry(address) {
809 Entry::Occupied(mut entry) => {
810 let account = entry.get_mut();
811 self.state_size -= account.size_hint();
812 if account.revert(revert_account) {
813 entry.remove();
814 } else {
815 self.state_size += account.size_hint();
816 }
817 }
818 Entry::Vacant(entry) => {
819 let mut account = BundleAccount::new(
822 None,
823 None,
824 HashMap::default(),
825 AccountStatus::LoadedNotExisting,
826 );
827 if !account.revert(revert_account) {
828 self.state_size += account.size_hint();
829 entry.insert(account);
830 }
831 }
832 }
833 }
834 return true;
835 }
836
837 false
838 }
839
840 pub fn revert(&mut self, mut num_transitions: usize) {
844 if num_transitions == 0 {
845 return;
846 }
847
848 while self.revert_latest() {
849 num_transitions -= 1;
850 if num_transitions == 0 {
851 break;
853 }
854 }
855 }
856
857 pub fn prepend_state(&mut self, mut other: BundleState) {
863 let this_bundle = mem::take(self);
865 other.extend_state(this_bundle.state);
867 other.contracts.extend(this_bundle.contracts);
869 mem::swap(self, &mut other)
871 }
872}
873
874#[cfg(test)]
875mod tests {
876 use super::*;
877 use crate::{StorageWithOriginalValues, TransitionAccount};
878 use primitives::U256;
879
880 #[test]
881 fn transition_states() {
882 let address = Address::new([0x01; 20]);
884 let acc1 = AccountInfo {
885 balance: U256::from(10),
886 nonce: 1,
887 ..Default::default()
888 };
889
890 let mut bundle_state = BundleState::default();
891
892 let transition = TransitionAccount {
895 info: Some(acc1),
896 status: AccountStatus::InMemoryChange,
897 previous_info: None,
898 previous_status: AccountStatus::LoadedNotExisting,
899 storage: StorageWithOriginalValues::default(),
900 storage_was_destroyed: false,
901 };
902
903 bundle_state.apply_transitions_and_create_reverts(
905 TransitionState::single(address, transition.clone()),
906 BundleRetention::Reverts,
907 );
908 }
909
910 const fn account1() -> Address {
911 Address::new([0x60; 20])
912 }
913
914 const fn account2() -> Address {
915 Address::new([0x61; 20])
916 }
917
918 fn slot1() -> StorageKey {
919 StorageKey::from(5)
920 }
921
922 fn slot2() -> StorageKey {
923 StorageKey::from(7)
924 }
925
926 fn test_bundle1() -> BundleState {
928 BundleState::new(
930 vec![
931 (
932 account1(),
933 None,
934 Some(AccountInfo {
935 nonce: 1,
936 balance: U256::from(10),
937 ..Default::default()
938 }),
939 HashMap::from_iter([
940 (slot1(), (StorageValue::from(0), StorageValue::from(10))),
941 (slot2(), (StorageValue::from(0), StorageValue::from(15))),
942 ]),
943 ),
944 (
945 account2(),
946 None,
947 Some(AccountInfo {
948 nonce: 1,
949 balance: U256::from(10),
950 ..Default::default()
951 }),
952 HashMap::default(),
953 ),
954 ],
955 vec![vec![
956 (
957 account1(),
958 Some(None),
959 vec![
960 (slot1(), StorageValue::from(0)),
961 (slot2(), StorageValue::from(0)),
962 ],
963 ),
964 (account2(), Some(None), vec![]),
965 ]],
966 vec![],
967 )
968 }
969
970 fn test_bundle2() -> BundleState {
972 BundleState::new(
974 vec![(
975 account1(),
976 None,
977 Some(AccountInfo {
978 nonce: 3,
979 balance: U256::from(20),
980 ..Default::default()
981 }),
982 HashMap::from_iter([(slot1(), (StorageValue::from(0), StorageValue::from(15)))]),
983 )],
984 vec![vec![(
985 account1(),
986 Some(Some(AccountInfo {
987 nonce: 1,
988 balance: U256::from(10),
989 ..Default::default()
990 })),
991 vec![(slot1(), StorageValue::from(10))],
992 )]],
993 vec![],
994 )
995 }
996
997 fn test_bundle3() -> BundleState {
999 BundleState::builder(0..=0)
1000 .state_present_account_info(
1001 account1(),
1002 AccountInfo {
1003 nonce: 1,
1004 balance: U256::from(10),
1005 ..Default::default()
1006 },
1007 )
1008 .state_storage(
1009 account1(),
1010 HashMap::from_iter([(slot1(), (StorageValue::from(0), StorageValue::from(10)))]),
1011 )
1012 .state_address(account2())
1013 .state_present_account_info(
1014 account2(),
1015 AccountInfo {
1016 nonce: 1,
1017 balance: U256::from(10),
1018 ..Default::default()
1019 },
1020 )
1021 .revert_address(0, account1())
1022 .revert_account_info(0, account1(), Some(None))
1023 .revert_storage(0, account1(), vec![(slot1(), StorageValue::from(0))])
1024 .revert_account_info(0, account2(), Some(None))
1025 .build()
1026 }
1027
1028 fn test_bundle4() -> BundleState {
1030 BundleState::builder(0..=0)
1031 .state_present_account_info(
1032 account1(),
1033 AccountInfo {
1034 nonce: 3,
1035 balance: U256::from(20),
1036 ..Default::default()
1037 },
1038 )
1039 .state_storage(
1040 account1(),
1041 HashMap::from_iter([(slot1(), (StorageValue::from(0), StorageValue::from(15)))]),
1042 )
1043 .revert_address(0, account1())
1044 .revert_account_info(
1045 0,
1046 account1(),
1047 Some(Some(AccountInfo {
1048 nonce: 1,
1049 balance: U256::from(10),
1050 ..Default::default()
1051 })),
1052 )
1053 .revert_storage(0, account1(), vec![(slot1(), StorageValue::from(10))])
1054 .build()
1055 }
1056
1057 fn sanity_path(bundle1: BundleState, bundle2: BundleState) {
1058 let mut extended = bundle1.clone();
1059 extended.extend(bundle2.clone());
1060
1061 let mut reverted = extended.clone();
1062 reverted.revert(0);
1064 assert_eq!(reverted, extended);
1065
1066 reverted.revert(1);
1068 assert_eq!(reverted, bundle1);
1069
1070 reverted.revert(1);
1072 assert_eq!(reverted, BundleState::default());
1073
1074 let mut reverted = extended.clone();
1075
1076 reverted.revert(10);
1078 assert_eq!(reverted, BundleState::default());
1079 }
1080
1081 #[test]
1082 fn extend_on_destroyed_values() {
1083 let base_bundle1 = test_bundle1();
1084 let base_bundle2 = test_bundle2();
1085
1086 let mut b1 = base_bundle1.clone();
1091 let mut b2 = base_bundle2.clone();
1092 b1.state.get_mut(&account1()).unwrap().status = AccountStatus::Destroyed;
1093 b2.state.get_mut(&account1()).unwrap().status = AccountStatus::Changed;
1094 b1.extend(b2);
1095 assert_eq!(
1096 b1.state.get_mut(&account1()).unwrap().status,
1097 AccountStatus::DestroyedChanged
1098 );
1099
1100 let mut b1 = base_bundle1.clone();
1105 let mut b2 = base_bundle2.clone();
1106 b1.state.get_mut(&account1()).unwrap().status = AccountStatus::Changed;
1107 b2.state.get_mut(&account1()).unwrap().status = AccountStatus::Destroyed;
1108 b2.reverts[0][0].1.wipe_storage = true;
1109 b1.extend(b2);
1110 assert_eq!(
1111 b1.state.get_mut(&account1()).unwrap().status,
1112 AccountStatus::Destroyed
1113 );
1114
1115 let mut revert1 = base_bundle2.reverts[0][0].clone();
1118 revert1.1.wipe_storage = true;
1119 revert1
1120 .1
1121 .storage
1122 .insert(slot2(), RevertToSlot::Some(StorageValue::from(15)));
1123
1124 assert_eq!(
1125 b1.reverts.as_ref(),
1126 vec![base_bundle1.reverts[0].clone(), vec![revert1]],
1127 );
1128
1129 let mut b1 = base_bundle1.clone();
1135 let mut b2 = base_bundle2.clone();
1136 b1.state.get_mut(&account1()).unwrap().status = AccountStatus::InMemoryChange;
1137 b2.state.get_mut(&account1()).unwrap().status = AccountStatus::Changed;
1138 b1.extend(b2);
1139 assert_eq!(
1140 b1.state.get_mut(&account1()).unwrap().status,
1141 AccountStatus::InMemoryChange
1142 );
1143 }
1144
1145 #[test]
1146 fn test_sanity_path() {
1147 sanity_path(test_bundle1(), test_bundle2());
1148 sanity_path(test_bundle3(), test_bundle4());
1149 }
1150
1151 #[test]
1152 fn test_multi_reverts_with_delete() {
1153 let mut state = BundleBuilder::new(0..=3)
1154 .revert_address(0, account1())
1155 .revert_account_info(2, account1(), Some(Some(AccountInfo::default())))
1156 .revert_account_info(3, account1(), Some(None))
1157 .build();
1158
1159 state.revert_latest();
1160 assert_eq!(state.state.get(&account1()), None);
1162
1163 state.revert_latest();
1164 assert_eq!(
1166 state.state.get(&account1()),
1167 Some(&BundleAccount::new(
1168 None,
1169 Some(AccountInfo::default()),
1170 HashMap::default(),
1171 AccountStatus::Changed
1172 ))
1173 );
1174 }
1175
1176 #[test]
1177 fn test_revert_capacity() {
1178 let state = BundleState::builder(0..=3)
1179 .revert_address(0, account1())
1180 .revert_address(2, account2())
1181 .revert_account_info(0, account1(), Some(None))
1182 .revert_account_info(2, account2(), None)
1183 .revert_storage(0, account1(), vec![(slot1(), StorageValue::from(10))])
1184 .build();
1185
1186 assert_eq!(state.reverts.len(), 4);
1187 assert_eq!(state.reverts[1], vec![]);
1188 assert_eq!(state.reverts[3], vec![]);
1189 assert_eq!(state.reverts[0].len(), 1);
1190 assert_eq!(state.reverts[2].len(), 1);
1191
1192 let (addr1, revert1) = &state.reverts[0][0];
1193 assert_eq!(addr1, &account1());
1194 assert_eq!(revert1.account, AccountInfoRevert::DeleteIt);
1195
1196 let (addr2, revert2) = &state.reverts[2][0];
1197 assert_eq!(addr2, &account2());
1198 assert_eq!(revert2.account, AccountInfoRevert::DoNothing);
1199 }
1200
1201 #[test]
1202 fn take_reverts() {
1203 let bundle1 = test_bundle1();
1204 let bundle2 = test_bundle2();
1205
1206 let mut extended = bundle1.clone();
1207 extended.extend(bundle2.clone());
1208
1209 assert_eq!(extended.reverts.len(), 2);
1211
1212 let mut extended2 = extended.clone();
1214 assert_eq!(extended2.take_n_reverts(100), extended.reverts);
1215
1216 let mut extended2 = extended.clone();
1218 assert_eq!(extended2.take_all_reverts(), extended.reverts);
1219
1220 let taken_reverts = extended.take_n_reverts(0);
1222 assert_eq!(taken_reverts, Reverts::default());
1223 assert_eq!(extended.reverts.len(), 2);
1224
1225 let taken_reverts = extended.take_n_reverts(1);
1227 assert_eq!(taken_reverts, bundle1.reverts);
1228
1229 let taken_reverts = extended.take_n_reverts(1);
1231 assert_eq!(taken_reverts, bundle2.reverts);
1232 }
1233
1234 #[test]
1235 fn prepend_state() {
1236 let address1 = account1();
1237 let address2 = account2();
1238
1239 let account1 = AccountInfo {
1240 nonce: 1,
1241 ..Default::default()
1242 };
1243 let account1_changed = AccountInfo {
1244 nonce: 1,
1245 ..Default::default()
1246 };
1247 let account2 = AccountInfo {
1248 nonce: 1,
1249 ..Default::default()
1250 };
1251
1252 let present_state = BundleState::builder(2..=2)
1253 .state_present_account_info(address1, account1_changed.clone())
1254 .build();
1255 assert_eq!(present_state.reverts.len(), 1);
1256 let previous_state = BundleState::builder(1..=1)
1257 .state_present_account_info(address1, account1)
1258 .state_present_account_info(address2, account2.clone())
1259 .build();
1260 assert_eq!(previous_state.reverts.len(), 1);
1261
1262 let mut test = present_state;
1263
1264 test.prepend_state(previous_state);
1265
1266 assert_eq!(test.state.len(), 2);
1267 assert_eq!(test.reverts.len(), 1);
1269 assert_eq!(
1271 test.state.get(&address1).unwrap().info,
1272 Some(account1_changed)
1273 );
1274 assert_eq!(test.state.get(&address2).unwrap().info, Some(account2));
1276 }
1277
1278 #[test]
1279 fn test_getters() {
1280 let mut builder = BundleBuilder::new(0..=3);
1281
1282 assert!(builder.get_states().is_empty());
1284 builder.get_states_mut().insert(account1());
1285 assert!(builder.get_states().contains(&account1()));
1286
1287 assert!(builder.get_state_original_mut().is_empty());
1289 builder
1290 .get_state_original_mut()
1291 .insert(account1(), AccountInfo::default());
1292 assert!(builder.get_state_original_mut().contains_key(&account1()));
1293
1294 assert!(builder.get_state_present_mut().is_empty());
1296 builder
1297 .get_state_present_mut()
1298 .insert(account1(), AccountInfo::default());
1299 assert!(builder.get_state_present_mut().contains_key(&account1()));
1300
1301 assert!(builder.get_state_storage_mut().is_empty());
1303 builder
1304 .get_state_storage_mut()
1305 .insert(account1(), HashMap::default());
1306 assert!(builder.get_state_storage_mut().contains_key(&account1()));
1307
1308 assert!(builder.get_reverts_mut().is_empty());
1310 builder.get_reverts_mut().insert((0, account1()));
1311 assert!(builder.get_reverts_mut().contains(&(0, account1())));
1312
1313 assert_eq!(builder.get_revert_range_mut().clone(), 0..=3);
1315
1316 assert!(builder.get_revert_account_mut().is_empty());
1318 builder
1319 .get_revert_account_mut()
1320 .insert((0, account1()), Some(None));
1321 assert!(builder
1322 .get_revert_account_mut()
1323 .contains_key(&(0, account1())));
1324
1325 assert!(builder.get_revert_storage_mut().is_empty());
1327 builder
1328 .get_revert_storage_mut()
1329 .insert((0, account1()), vec![(slot1(), StorageValue::from(0))]);
1330 assert!(builder
1331 .get_revert_storage_mut()
1332 .contains_key(&(0, account1())));
1333
1334 assert!(builder.get_contracts_mut().is_empty());
1336 builder
1337 .get_contracts_mut()
1338 .insert(B256::default(), Bytecode::default());
1339 assert!(builder.get_contracts_mut().contains_key(&B256::default()));
1340 }
1341}