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};
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 account_id: None,
36 };
37 (address, info)
38 })
39 }
40
41 pub fn apply_genesis_json_alloc(
43 &self,
44 mut db: RwLockWriteGuard<'_, Box<dyn Db>>,
45 ) -> DatabaseResult<()> {
46 if let Some(ref genesis) = self.genesis_init {
47 for (addr, mut acc) in genesis.alloc.clone() {
48 let storage = std::mem::take(&mut acc.storage);
49 db.insert_account(addr, self.genesis_to_account_info(&acc));
51 for (k, v) in &storage.unwrap_or_default() {
53 db.set_storage_at(addr, *k, *v)?;
54 }
55 }
56 }
57 Ok(())
58 }
59
60 fn genesis_to_account_info(&self, acc: &GenesisAccount) -> AccountInfo {
62 let GenesisAccount { code, balance, nonce, .. } = acc.clone();
63 let code = code.map(Bytecode::new_raw);
64 AccountInfo {
65 balance,
66 nonce: nonce.unwrap_or_default(),
67 code_hash: code.as_ref().map(|code| code.hash_slow()).unwrap_or(KECCAK_EMPTY),
68 code,
69 account_id: None,
70 }
71 }
72}