1//! Support for snapshotting different states
23use alloy_primitives::{map::HashMap, U256};
4use std::ops::Add;
56/// Represents all state snapshots
7#[derive(Clone, Debug)]
8pub struct StateSnapshots<T> {
9 id: U256,
10 state_snapshots: HashMap<U256, T>,
11}
1213impl<T> StateSnapshots<T> {
14fn next_id(&mut self) -> U256 {
15let id = self.id;
16self.id = id.saturating_add(U256::from(1));
17id18 }
1920/// Returns the state snapshot with the given id `id`
21pub fn get(&self, id: U256) -> Option<&T> {
22self.state_snapshots.get(&id)
23 }
2425/// Removes the state snapshot with the given `id`.
26 ///
27 /// This will also remove any state snapshots taken after the state snapshot with the `id`.
28 /// e.g.: reverting to id 1 will delete snapshots with ids 1, 2, 3, etc.)
29pub fn remove(&mut self, id: U256) -> Option<T> {
30let snapshot_state = self.state_snapshots.remove(&id);
3132// Revert all state snapshots taken after the state snapshot with the `id`
33let mut to_revert = id.add(U256::from(1));
34while to_revert < self.id {
35self.state_snapshots.remove(&to_revert);
36 to_revert += U256::from(1);
37 }
3839snapshot_state40 }
4142/// Removes all state snapshots.
43pub fn clear(&mut self) {
44self.state_snapshots.clear();
45 }
4647/// Removes the state snapshot with the given `id`.
48 ///
49 /// Does not remove state snapshots after it.
50pub fn remove_at(&mut self, id: U256) -> Option<T> {
51self.state_snapshots.remove(&id)
52 }
5354/// Inserts the new state snapshot and returns the id.
55pub fn insert(&mut self, state_snapshot: T) -> U256 {
56let id = self.next_id();
57self.state_snapshots.insert(id, state_snapshot);
58id59 }
6061/// Inserts the new state snapshot at the given `id`.
62 ///
63 /// Does not auto-increment the next `id`.
64pub fn insert_at(&mut self, state_snapshot: T, id: U256) -> U256 {
65self.state_snapshots.insert(id, state_snapshot);
66id67 }
68}
6970impl<T> Defaultfor StateSnapshots<T> {
71fn default() -> Self {
72Self { id: U256::ZERO, state_snapshots: HashMap::default() }
73 }
74}