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