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}