Skip to main content

tempo_precompiles/storage/
actions.rs

1use std::{
2    cell::{Cell, RefCell},
3    rc::Rc,
4};
5
6use alloy_primitives::{Address, U256};
7
8#[derive(Debug, Clone, PartialEq)]
9pub enum StorageAction {
10    /// Records an SLOAD opcode.
11    Sload(Address, U256, U256),
12    /// Records an SSTORE opcode.
13    Sstore(Address, U256, U256),
14}
15
16/// Buffer for recording EVM [storage actions](StorageAction).
17#[derive(Debug, Clone)]
18pub struct StorageActions {
19    enabled: Rc<Cell<bool>>,
20    actions: Rc<RefCell<Vec<StorageAction>>>,
21}
22
23impl StorageActions {
24    /// Returns an [`StorageActions`] instance with actions recording disabled.
25    pub fn disabled() -> Self {
26        Self {
27            enabled: Rc::new(Cell::new(false)),
28            actions: Rc::default(),
29        }
30    }
31
32    /// Returns an [`StorageActions`] instance with actions recording enabled.
33    pub fn enabled() -> Self {
34        Self {
35            enabled: Rc::new(Cell::new(true)),
36            actions: Rc::default(),
37        }
38    }
39
40    /// Enables actions recording.
41    pub fn enable(&self) {
42        self.enabled.set(true);
43        self.actions.borrow_mut().clear();
44    }
45
46    /// Replaces the recorded storage actions with an empty buffer, returning the previous actions.
47    pub fn take(&self) -> Option<Vec<StorageAction>> {
48        self.replace(Vec::new())
49    }
50
51    /// Replaces the recorded storage actions with the given ones, returning the previous actions.
52    pub fn replace(&self, actions: Vec<StorageAction>) -> Option<Vec<StorageAction>> {
53        if !self.enabled.get() {
54            return None;
55        }
56
57        Some(std::mem::replace(&mut *self.actions.borrow_mut(), actions))
58    }
59
60    /// Records an action if recording is enabled.
61    pub fn record(&self, action: StorageAction) {
62        if !self.enabled.get() {
63            return;
64        }
65
66        self.actions.borrow_mut().push(action);
67    }
68}