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