alloy_consensus/
account.rsuse crate::constants::{EMPTY_ROOT_HASH, KECCAK_EMPTY};
use alloy_primitives::{keccak256, B256, U256};
use alloy_rlp::{RlpDecodable, RlpEncodable};
#[derive(Copy, Clone, Debug, PartialEq, Eq, RlpDecodable, RlpEncodable)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub struct Account {
#[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))]
pub nonce: u64,
pub balance: U256,
pub storage_root: B256,
pub code_hash: B256,
}
impl Default for Account {
fn default() -> Self {
Self {
nonce: 0,
balance: U256::ZERO,
storage_root: EMPTY_ROOT_HASH,
code_hash: KECCAK_EMPTY,
}
}
}
impl Account {
pub fn trie_hash_slow(&self) -> B256 {
keccak256(alloy_rlp::encode(self))
}
}
#[cfg(test)]
mod tests {
use super::*;
use alloy_primitives::{hex, U256};
use alloy_rlp::Decodable;
#[test]
fn test_account_encoding() {
let account = Account {
nonce: 1,
balance: U256::from(1000),
storage_root: B256::from_slice(&hex!(
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
)),
code_hash: keccak256(hex!("5a465a905090036002900360015500")),
};
let encoded = alloy_rlp::encode(account);
let decoded = Account::decode(&mut &encoded[..]).unwrap();
assert_eq!(account, decoded);
}
#[test]
fn test_trie_hash_slow() {
let account = Account {
nonce: 1,
balance: U256::from(1000),
storage_root: B256::from_slice(&hex!(
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
)),
code_hash: keccak256(hex!("5a465a905090036002900360015500")),
};
let expected_hash = keccak256(alloy_rlp::encode(account));
let actual_hash = account.trie_hash_slow();
assert_eq!(expected_hash, actual_hash);
}
}