From e35abf8423dcaae8d82fc2334ee88a7020b9294c Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Sat, 20 Apr 2024 12:55:36 +0200 Subject: [PATCH] feat(op): init genesis alloc (#7748) --- bin/reth/src/commands/stage/drop.rs | 5 +-- crates/node-core/src/init.rs | 56 +++++++++++++++-------------- crates/primitives/src/account.rs | 6 ++-- crates/trie/src/proof.rs | 5 ++- 4 files changed, 37 insertions(+), 35 deletions(-) diff --git a/bin/reth/src/commands/stage/drop.rs b/bin/reth/src/commands/stage/drop.rs index 3e33183cb..e79a4c33b 100644 --- a/bin/reth/src/commands/stage/drop.rs +++ b/bin/reth/src/commands/stage/drop.rs @@ -133,7 +133,8 @@ impl Command { StageId::Execution.to_string(), Default::default(), )?; - insert_genesis_state::(tx, self.chain.genesis())?; + let alloc = &self.chain.genesis().alloc; + insert_genesis_state::(tx, alloc.len(), alloc.iter())?; } StageEnum::AccountHashing => { tx.clear::()?; @@ -191,7 +192,7 @@ impl Command { StageId::IndexStorageHistory.to_string(), Default::default(), )?; - insert_genesis_history(&provider_rw, &self.chain.genesis)?; + insert_genesis_history(&provider_rw, self.chain.genesis.alloc.iter())?; } StageEnum::TxLookup => { tx.clear::()?; diff --git a/crates/node-core/src/init.rs b/crates/node-core/src/init.rs index 23d91e8d5..b0a9c9c92 100644 --- a/crates/node-core/src/init.rs +++ b/crates/node-core/src/init.rs @@ -7,8 +7,8 @@ use reth_db::{ }; use reth_interfaces::{db::DatabaseError, provider::ProviderResult}; use reth_primitives::{ - stage::StageId, Account, Bytecode, ChainSpec, Receipts, StaticFileSegment, StorageEntry, B256, - U256, + stage::StageId, Account, Address, Bytecode, ChainSpec, GenesisAccount, Receipts, + StaticFileSegment, StorageEntry, B256, U256, }; use reth_provider::{ bundle_state::{BundleStateInit, RevertsInit}, @@ -72,17 +72,19 @@ pub fn init_genesis(factory: ProviderFactory) -> Result(&tx, &static_file_provider, chain.clone())?; - insert_genesis_state::(&tx, genesis)?; + insert_genesis_state::(&tx, alloc.len(), alloc.iter())?; // insert sync stage for stage in StageId::ALL.iter() { @@ -96,16 +98,16 @@ pub fn init_genesis(factory: ProviderFactory) -> Result( +pub fn insert_genesis_state<'a, 'b, DB: Database>( tx: &::TXMut, - genesis: &reth_primitives::Genesis, + capacity: usize, + alloc: impl Iterator, ) -> ProviderResult<()> { - let capacity = genesis.alloc.len(); let mut state_init: BundleStateInit = HashMap::with_capacity(capacity); let mut reverts_init = HashMap::with_capacity(capacity); let mut contracts: HashMap = HashMap::with_capacity(capacity); - for (address, account) in &genesis.alloc { + for (address, account) in alloc { let bytecode_hash = if let Some(code) = &account.code { let bytecode = Bytecode::new_raw(code.clone()); let hash = bytecode.hash_slow(); @@ -163,24 +165,24 @@ pub fn insert_genesis_state( } /// Inserts hashes for the genesis state. -pub fn insert_genesis_hashes( +pub fn insert_genesis_hashes<'a, 'b, DB: Database>( provider: &DatabaseProviderRW, - genesis: &reth_primitives::Genesis, + alloc: impl Iterator + Clone, ) -> ProviderResult<()> { // insert and hash accounts to hashing table - let alloc_accounts = genesis - .alloc - .clone() - .into_iter() - .map(|(addr, account)| (addr, Some(Account::from_genesis_account(account)))); + let alloc_accounts = + alloc.clone().map(|(addr, account)| (*addr, Some(Account::from_genesis_account(account)))); provider.insert_account_for_hashing(alloc_accounts)?; - let alloc_storage = genesis.alloc.clone().into_iter().filter_map(|(addr, account)| { + let alloc_storage = alloc.filter_map(|(addr, account)| { // only return Some if there is storage - account.storage.map(|storage| { + account.storage.as_ref().map(|storage| { ( - addr, - storage.into_iter().map(|(key, value)| StorageEntry { key, value: value.into() }), + *addr, + storage + .clone() + .into_iter() + .map(|(key, value)| StorageEntry { key, value: value.into() }), ) }) }); @@ -190,17 +192,15 @@ pub fn insert_genesis_hashes( } /// Inserts history indices for genesis accounts and storage. -pub fn insert_genesis_history( +pub fn insert_genesis_history<'a, 'b, DB: Database>( provider: &DatabaseProviderRW, - genesis: &reth_primitives::Genesis, + alloc: impl Iterator + Clone, ) -> ProviderResult<()> { let account_transitions = - genesis.alloc.keys().map(|addr| (*addr, vec![0])).collect::>(); + alloc.clone().map(|(addr, _)| (*addr, vec![0])).collect::>(); provider.insert_account_history_index(account_transitions)?; - let storage_transitions = genesis - .alloc - .iter() + let storage_transitions = alloc .filter_map(|(addr, account)| account.storage.as_ref().map(|storage| (addr, storage))) .flat_map(|(addr, storage)| storage.iter().map(|(key, _)| ((*addr, *key), vec![0]))) .collect::>(); @@ -235,6 +235,8 @@ pub fn insert_genesis_header( #[cfg(test)] mod tests { + use std::sync::Arc; + use super::*; use reth_db::{ @@ -244,7 +246,7 @@ mod tests { DatabaseEnv, }; use reth_primitives::{ - Address, Chain, ForkTimestamps, Genesis, GenesisAccount, IntegerList, GOERLI, + Address, Chain, ChainSpec, ForkTimestamps, Genesis, GenesisAccount, IntegerList, GOERLI, GOERLI_GENESIS_HASH, MAINNET, MAINNET_GENESIS_HASH, SEPOLIA, SEPOLIA_GENESIS_HASH, }; use reth_provider::test_utils::create_test_provider_factory_with_chain_spec; diff --git a/crates/primitives/src/account.rs b/crates/primitives/src/account.rs index 712e5e341..d0bc3788e 100644 --- a/crates/primitives/src/account.rs +++ b/crates/primitives/src/account.rs @@ -35,13 +35,13 @@ impl Account { self.bytecode_hash.map_or(true, |hash| hash == KECCAK_EMPTY) } - /// Converts [GenesisAccount] to [Account] type - pub fn from_genesis_account(value: GenesisAccount) -> Self { + /// Makes an [Account] from [GenesisAccount] type + pub fn from_genesis_account(value: &GenesisAccount) -> Self { Account { // nonce must exist, so we default to zero when converting a genesis account nonce: value.nonce.unwrap_or_default(), balance: value.balance, - bytecode_hash: value.code.map(keccak256), + bytecode_hash: value.code.as_ref().map(keccak256), } } diff --git a/crates/trie/src/proof.rs b/crates/trie/src/proof.rs index 1af1650e5..55eb47710 100644 --- a/crates/trie/src/proof.rs +++ b/crates/trie/src/proof.rs @@ -207,9 +207,8 @@ mod tests { let genesis = chain_spec.genesis(); let alloc_accounts = genesis .alloc - .clone() - .into_iter() - .map(|(addr, account)| (addr, Some(Account::from_genesis_account(account)))); + .iter() + .map(|(addr, account)| (*addr, Some(Account::from_genesis_account(account)))); provider.insert_account_for_hashing(alloc_accounts).unwrap(); let alloc_storage = genesis.alloc.clone().into_iter().filter_map(|(addr, account)| {