anvil/eth/backend/
genesis.rs
1use 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};
8use tokio::sync::RwLockWriteGuard;
9
10#[derive(Clone, Debug, Default)]
12pub struct GenesisConfig {
13 pub number: u64,
15 pub timestamp: u64,
17 pub balance: U256,
19 pub accounts: Vec<Address>,
21 pub genesis_init: Option<Genesis>,
23}
24
25impl GenesisConfig {
26 pub fn account_infos(&self) -> impl Iterator<Item = (Address, AccountInfo)> + '_ {
28 self.accounts.iter().copied().map(|address| {
29 let info = AccountInfo {
30 balance: self.balance,
31 code_hash: KECCAK_EMPTY,
32 code: Some(Default::default()),
34 nonce: 0,
35 };
36 (address, info)
37 })
38 }
39
40 pub fn apply_genesis_json_alloc(
42 &self,
43 mut db: RwLockWriteGuard<'_, Box<dyn Db>>,
44 ) -> DatabaseResult<()> {
45 if let Some(ref genesis) = self.genesis_init {
46 for (addr, mut acc) in genesis.alloc.clone() {
47 let storage = std::mem::take(&mut acc.storage);
48 db.insert_account(addr, self.genesis_to_account_info(&acc));
50 for (k, v) in &storage.unwrap_or_default() {
52 db.set_storage_at(addr, *k, *v)?;
53 }
54 }
55 }
56 Ok(())
57 }
58
59 fn genesis_to_account_info(&self, acc: &GenesisAccount) -> AccountInfo {
61 let GenesisAccount { code, balance, nonce, .. } = acc.clone();
62 let code = code.map(Bytecode::new_raw);
63 AccountInfo {
64 balance,
65 nonce: nonce.unwrap_or_default(),
66 code_hash: code.as_ref().map(|code| code.hash_slow()).unwrap_or(KECCAK_EMPTY),
67 code,
68 }
69 }
70}