anvil/eth/backend/
genesis.rs1use crate::eth::backend::db::Db;
4use alloy_genesis::{Genesis, GenesisAccount};
5use alloy_primitives::{Address, U256};
6use foundry_evm::backend::DatabaseResult;
7use revm::{bytecode::Bytecode, primitives::KECCAK_EMPTY, state::AccountInfo};
8
9#[derive(Clone, Debug, Default)]
11pub struct GenesisConfig {
12 pub number: u64,
14 pub timestamp: u64,
16 pub balance: U256,
18 pub accounts: Vec<Address>,
20 pub genesis_init: Option<Genesis>,
22}
23
24impl GenesisConfig {
25 pub fn account_infos(&self) -> impl Iterator<Item = (Address, AccountInfo)> + '_ {
27 self.accounts.iter().copied().map(|address| {
28 let info = AccountInfo {
29 balance: self.balance,
30 code_hash: KECCAK_EMPTY,
31 code: Some(Default::default()),
33 nonce: 0,
34 account_id: None,
35 };
36 (address, info)
37 })
38 }
39
40 pub fn apply_genesis_json_alloc(&self, db: &mut dyn Db) -> DatabaseResult<()> {
42 if let Some(ref genesis) = self.genesis_init {
43 for (addr, mut acc) in genesis.alloc.clone() {
44 let storage = std::mem::take(&mut acc.storage);
45 db.insert_account(addr, self.genesis_to_account_info(&acc));
47 for (k, v) in &storage.unwrap_or_default() {
49 db.set_storage_at(addr, *k, *v)?;
50 }
51 }
52 }
53 Ok(())
54 }
55
56 fn genesis_to_account_info(&self, acc: &GenesisAccount) -> AccountInfo {
58 let GenesisAccount { code, balance, nonce, .. } = acc.clone();
59 let code = code.map(Bytecode::new_raw);
60 AccountInfo {
61 balance,
62 nonce: nonce.unwrap_or_default(),
63 code_hash: code.as_ref().map(|code| code.hash_slow()).unwrap_or(KECCAK_EMPTY),
64 code,
65 account_id: None,
66 }
67 }
68}