revm_state/
account_info.rs

1use bytecode::Bytecode;
2use core::hash::{Hash, Hasher};
3use primitives::{B256, KECCAK_EMPTY, U256};
4
5/// AccountInfo account information
6#[derive(Clone, Debug, Eq, Ord, PartialOrd)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8pub struct AccountInfo {
9    /// Account balance
10    pub balance: U256,
11    /// Account nonce
12    pub nonce: u64,
13    /// code hash
14    pub code_hash: B256,
15    /// [`Bytecode`] data associated with this account
16    ///
17    /// If [None], `code_hash` will be used to fetch it if code needs to be loaded from
18    /// inside `revm`.
19    pub code: Option<Bytecode>,
20}
21
22impl Default for AccountInfo {
23    fn default() -> Self {
24        Self {
25            balance: U256::ZERO,
26            code_hash: KECCAK_EMPTY,
27            code: Some(Bytecode::default()),
28            nonce: 0,
29        }
30    }
31}
32
33impl PartialEq for AccountInfo {
34    fn eq(&self, other: &Self) -> bool {
35        self.balance == other.balance
36            && self.nonce == other.nonce
37            && self.code_hash == other.code_hash
38    }
39}
40
41impl Hash for AccountInfo {
42    fn hash<H: Hasher>(&self, state: &mut H) {
43        self.balance.hash(state);
44        self.nonce.hash(state);
45        self.code_hash.hash(state);
46    }
47}
48
49impl AccountInfo {
50    /// Creates a new [`AccountInfo`] with the given fields.
51    #[inline]
52    pub fn new(balance: U256, nonce: u64, code_hash: B256, code: Bytecode) -> Self {
53        Self {
54            balance,
55            nonce,
56            code: Some(code),
57            code_hash,
58        }
59    }
60
61    /// Returns a copy of this account with the [`Bytecode`] removed.
62    ///
63    /// This is useful when creating journals or snapshots of the state, where it is
64    /// desirable to store the code blobs elsewhere.
65    ///
66    /// ## Note
67    ///
68    /// This is distinct from [`without_code`][Self::without_code] in that it returns
69    /// a new [`AccountInfo`] instance with the code removed.
70    ///
71    /// [`without_code`][Self::without_code] will modify and return the same instance.
72    #[inline]
73    pub fn copy_without_code(&self) -> Self {
74        Self {
75            balance: self.balance,
76            nonce: self.nonce,
77            code_hash: self.code_hash,
78            code: None,
79        }
80    }
81
82    /// Strips the [`Bytecode`] from this account and drop it.
83    ///
84    /// This is useful when creating journals or snapshots of the state, where it is
85    /// desirable to store the code blobs elsewhere.
86    ///
87    /// ## Note
88    ///
89    /// This is distinct from [`copy_without_code`][Self::copy_without_code] in that it
90    /// modifies the account in place.
91    ///
92    /// [`copy_without_code`][Self::copy_without_code]
93    /// will copy the non-code fields and return a new [`AccountInfo`] instance.
94    pub fn without_code(mut self) -> Self {
95        self.take_bytecode();
96        self
97    }
98
99    /// Returns if an account is empty.
100    ///
101    /// An account is empty if the following conditions are met.
102    /// - code hash is zero or set to the Keccak256 hash of the empty string `""`
103    /// - balance is zero
104    /// - nonce is zero
105    #[inline]
106    pub fn is_empty(&self) -> bool {
107        let code_empty = self.is_empty_code_hash() || self.code_hash.is_zero();
108        code_empty && self.balance.is_zero() && self.nonce == 0
109    }
110
111    /// Returns `true` if the account is not empty.
112    #[inline]
113    pub fn exists(&self) -> bool {
114        !self.is_empty()
115    }
116
117    /// Returns `true` if account has no nonce and code.
118    #[inline]
119    pub fn has_no_code_and_nonce(&self) -> bool {
120        self.is_empty_code_hash() && self.nonce == 0
121    }
122
123    /// Returns bytecode hash associated with this account.
124    ///
125    /// If account does not have code, it returns `KECCAK_EMPTY` hash.
126    #[inline]
127    pub fn code_hash(&self) -> B256 {
128        self.code_hash
129    }
130
131    /// Returns true if the code hash is the Keccak256 hash of the empty string `""`.
132    #[inline]
133    pub fn is_empty_code_hash(&self) -> bool {
134        self.code_hash == KECCAK_EMPTY
135    }
136
137    /// Takes bytecode from account.
138    ///
139    /// Code will be set to [None].
140    #[inline]
141    pub fn take_bytecode(&mut self) -> Option<Bytecode> {
142        self.code.take()
143    }
144
145    /// Initializes an [`AccountInfo`] with the given balance, setting all other fields to their
146    /// default values.
147    #[inline]
148    pub fn from_balance(balance: U256) -> Self {
149        AccountInfo {
150            balance,
151            ..Default::default()
152        }
153    }
154
155    /// Initializes an [`AccountInfo`] with the given bytecode, setting its balance to zero, its
156    /// nonce to `1`, and calculating the code hash from the given bytecode.
157    #[inline]
158    pub fn from_bytecode(bytecode: Bytecode) -> Self {
159        let hash = bytecode.hash_slow();
160
161        AccountInfo {
162            balance: U256::ZERO,
163            nonce: 1,
164            code: Some(bytecode),
165            code_hash: hash,
166        }
167    }
168}