mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat(op): init genesis alloc (#7748)
This commit is contained in:
@ -133,7 +133,8 @@ impl Command {
|
|||||||
StageId::Execution.to_string(),
|
StageId::Execution.to_string(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
)?;
|
)?;
|
||||||
insert_genesis_state::<DatabaseEnv>(tx, self.chain.genesis())?;
|
let alloc = &self.chain.genesis().alloc;
|
||||||
|
insert_genesis_state::<DatabaseEnv>(tx, alloc.len(), alloc.iter())?;
|
||||||
}
|
}
|
||||||
StageEnum::AccountHashing => {
|
StageEnum::AccountHashing => {
|
||||||
tx.clear::<tables::HashedAccounts>()?;
|
tx.clear::<tables::HashedAccounts>()?;
|
||||||
@ -191,7 +192,7 @@ impl Command {
|
|||||||
StageId::IndexStorageHistory.to_string(),
|
StageId::IndexStorageHistory.to_string(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
)?;
|
)?;
|
||||||
insert_genesis_history(&provider_rw, &self.chain.genesis)?;
|
insert_genesis_history(&provider_rw, self.chain.genesis.alloc.iter())?;
|
||||||
}
|
}
|
||||||
StageEnum::TxLookup => {
|
StageEnum::TxLookup => {
|
||||||
tx.clear::<tables::TransactionHashNumbers>()?;
|
tx.clear::<tables::TransactionHashNumbers>()?;
|
||||||
|
|||||||
@ -7,8 +7,8 @@ use reth_db::{
|
|||||||
};
|
};
|
||||||
use reth_interfaces::{db::DatabaseError, provider::ProviderResult};
|
use reth_interfaces::{db::DatabaseError, provider::ProviderResult};
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
stage::StageId, Account, Bytecode, ChainSpec, Receipts, StaticFileSegment, StorageEntry, B256,
|
stage::StageId, Account, Address, Bytecode, ChainSpec, GenesisAccount, Receipts,
|
||||||
U256,
|
StaticFileSegment, StorageEntry, B256, U256,
|
||||||
};
|
};
|
||||||
use reth_provider::{
|
use reth_provider::{
|
||||||
bundle_state::{BundleStateInit, RevertsInit},
|
bundle_state::{BundleStateInit, RevertsInit},
|
||||||
@ -72,17 +72,19 @@ pub fn init_genesis<DB: Database>(factory: ProviderFactory<DB>) -> Result<B256,
|
|||||||
|
|
||||||
debug!("Writing genesis block.");
|
debug!("Writing genesis block.");
|
||||||
|
|
||||||
|
let alloc = &genesis.alloc;
|
||||||
|
|
||||||
// use transaction to insert genesis header
|
// use transaction to insert genesis header
|
||||||
let provider_rw = factory.provider_rw()?;
|
let provider_rw = factory.provider_rw()?;
|
||||||
insert_genesis_hashes(&provider_rw, genesis)?;
|
insert_genesis_hashes(&provider_rw, alloc.iter())?;
|
||||||
insert_genesis_history(&provider_rw, genesis)?;
|
insert_genesis_history(&provider_rw, alloc.iter())?;
|
||||||
|
|
||||||
// Insert header
|
// Insert header
|
||||||
let tx = provider_rw.into_tx();
|
let tx = provider_rw.into_tx();
|
||||||
let static_file_provider = factory.static_file_provider();
|
let static_file_provider = factory.static_file_provider();
|
||||||
insert_genesis_header::<DB>(&tx, &static_file_provider, chain.clone())?;
|
insert_genesis_header::<DB>(&tx, &static_file_provider, chain.clone())?;
|
||||||
|
|
||||||
insert_genesis_state::<DB>(&tx, genesis)?;
|
insert_genesis_state::<DB>(&tx, alloc.len(), alloc.iter())?;
|
||||||
|
|
||||||
// insert sync stage
|
// insert sync stage
|
||||||
for stage in StageId::ALL.iter() {
|
for stage in StageId::ALL.iter() {
|
||||||
@ -96,16 +98,16 @@ pub fn init_genesis<DB: Database>(factory: ProviderFactory<DB>) -> Result<B256,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Inserts the genesis state into the database.
|
/// Inserts the genesis state into the database.
|
||||||
pub fn insert_genesis_state<DB: Database>(
|
pub fn insert_genesis_state<'a, 'b, DB: Database>(
|
||||||
tx: &<DB as Database>::TXMut,
|
tx: &<DB as Database>::TXMut,
|
||||||
genesis: &reth_primitives::Genesis,
|
capacity: usize,
|
||||||
|
alloc: impl Iterator<Item = (&'a Address, &'b GenesisAccount)>,
|
||||||
) -> ProviderResult<()> {
|
) -> ProviderResult<()> {
|
||||||
let capacity = genesis.alloc.len();
|
|
||||||
let mut state_init: BundleStateInit = HashMap::with_capacity(capacity);
|
let mut state_init: BundleStateInit = HashMap::with_capacity(capacity);
|
||||||
let mut reverts_init = HashMap::with_capacity(capacity);
|
let mut reverts_init = HashMap::with_capacity(capacity);
|
||||||
let mut contracts: HashMap<B256, Bytecode> = HashMap::with_capacity(capacity);
|
let mut contracts: HashMap<B256, Bytecode> = 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_hash = if let Some(code) = &account.code {
|
||||||
let bytecode = Bytecode::new_raw(code.clone());
|
let bytecode = Bytecode::new_raw(code.clone());
|
||||||
let hash = bytecode.hash_slow();
|
let hash = bytecode.hash_slow();
|
||||||
@ -163,24 +165,24 @@ pub fn insert_genesis_state<DB: Database>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Inserts hashes for the genesis state.
|
/// Inserts hashes for the genesis state.
|
||||||
pub fn insert_genesis_hashes<DB: Database>(
|
pub fn insert_genesis_hashes<'a, 'b, DB: Database>(
|
||||||
provider: &DatabaseProviderRW<DB>,
|
provider: &DatabaseProviderRW<DB>,
|
||||||
genesis: &reth_primitives::Genesis,
|
alloc: impl Iterator<Item = (&'a Address, &'b GenesisAccount)> + Clone,
|
||||||
) -> ProviderResult<()> {
|
) -> ProviderResult<()> {
|
||||||
// insert and hash accounts to hashing table
|
// insert and hash accounts to hashing table
|
||||||
let alloc_accounts = genesis
|
let alloc_accounts =
|
||||||
.alloc
|
alloc.clone().map(|(addr, account)| (*addr, Some(Account::from_genesis_account(account))));
|
||||||
.clone()
|
|
||||||
.into_iter()
|
|
||||||
.map(|(addr, account)| (addr, Some(Account::from_genesis_account(account))));
|
|
||||||
provider.insert_account_for_hashing(alloc_accounts)?;
|
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
|
// only return Some if there is storage
|
||||||
account.storage.map(|storage| {
|
account.storage.as_ref().map(|storage| {
|
||||||
(
|
(
|
||||||
addr,
|
*addr,
|
||||||
storage.into_iter().map(|(key, value)| StorageEntry { key, value: value.into() }),
|
storage
|
||||||
|
.clone()
|
||||||
|
.into_iter()
|
||||||
|
.map(|(key, value)| StorageEntry { key, value: value.into() }),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@ -190,17 +192,15 @@ pub fn insert_genesis_hashes<DB: Database>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Inserts history indices for genesis accounts and storage.
|
/// Inserts history indices for genesis accounts and storage.
|
||||||
pub fn insert_genesis_history<DB: Database>(
|
pub fn insert_genesis_history<'a, 'b, DB: Database>(
|
||||||
provider: &DatabaseProviderRW<DB>,
|
provider: &DatabaseProviderRW<DB>,
|
||||||
genesis: &reth_primitives::Genesis,
|
alloc: impl Iterator<Item = (&'a Address, &'b GenesisAccount)> + Clone,
|
||||||
) -> ProviderResult<()> {
|
) -> ProviderResult<()> {
|
||||||
let account_transitions =
|
let account_transitions =
|
||||||
genesis.alloc.keys().map(|addr| (*addr, vec![0])).collect::<BTreeMap<_, _>>();
|
alloc.clone().map(|(addr, _)| (*addr, vec![0])).collect::<BTreeMap<_, _>>();
|
||||||
provider.insert_account_history_index(account_transitions)?;
|
provider.insert_account_history_index(account_transitions)?;
|
||||||
|
|
||||||
let storage_transitions = genesis
|
let storage_transitions = alloc
|
||||||
.alloc
|
|
||||||
.iter()
|
|
||||||
.filter_map(|(addr, account)| account.storage.as_ref().map(|storage| (addr, storage)))
|
.filter_map(|(addr, account)| account.storage.as_ref().map(|storage| (addr, storage)))
|
||||||
.flat_map(|(addr, storage)| storage.iter().map(|(key, _)| ((*addr, *key), vec![0])))
|
.flat_map(|(addr, storage)| storage.iter().map(|(key, _)| ((*addr, *key), vec![0])))
|
||||||
.collect::<BTreeMap<_, _>>();
|
.collect::<BTreeMap<_, _>>();
|
||||||
@ -235,6 +235,8 @@ pub fn insert_genesis_header<DB: Database>(
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use reth_db::{
|
use reth_db::{
|
||||||
@ -244,7 +246,7 @@ mod tests {
|
|||||||
DatabaseEnv,
|
DatabaseEnv,
|
||||||
};
|
};
|
||||||
use reth_primitives::{
|
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,
|
GOERLI_GENESIS_HASH, MAINNET, MAINNET_GENESIS_HASH, SEPOLIA, SEPOLIA_GENESIS_HASH,
|
||||||
};
|
};
|
||||||
use reth_provider::test_utils::create_test_provider_factory_with_chain_spec;
|
use reth_provider::test_utils::create_test_provider_factory_with_chain_spec;
|
||||||
|
|||||||
@ -35,13 +35,13 @@ impl Account {
|
|||||||
self.bytecode_hash.map_or(true, |hash| hash == KECCAK_EMPTY)
|
self.bytecode_hash.map_or(true, |hash| hash == KECCAK_EMPTY)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts [GenesisAccount] to [Account] type
|
/// Makes an [Account] from [GenesisAccount] type
|
||||||
pub fn from_genesis_account(value: GenesisAccount) -> Self {
|
pub fn from_genesis_account(value: &GenesisAccount) -> Self {
|
||||||
Account {
|
Account {
|
||||||
// nonce must exist, so we default to zero when converting a genesis account
|
// nonce must exist, so we default to zero when converting a genesis account
|
||||||
nonce: value.nonce.unwrap_or_default(),
|
nonce: value.nonce.unwrap_or_default(),
|
||||||
balance: value.balance,
|
balance: value.balance,
|
||||||
bytecode_hash: value.code.map(keccak256),
|
bytecode_hash: value.code.as_ref().map(keccak256),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -207,9 +207,8 @@ mod tests {
|
|||||||
let genesis = chain_spec.genesis();
|
let genesis = chain_spec.genesis();
|
||||||
let alloc_accounts = genesis
|
let alloc_accounts = genesis
|
||||||
.alloc
|
.alloc
|
||||||
.clone()
|
.iter()
|
||||||
.into_iter()
|
.map(|(addr, account)| (*addr, Some(Account::from_genesis_account(account))));
|
||||||
.map(|(addr, account)| (addr, Some(Account::from_genesis_account(account))));
|
|
||||||
provider.insert_account_for_hashing(alloc_accounts).unwrap();
|
provider.insert_account_for_hashing(alloc_accounts).unwrap();
|
||||||
|
|
||||||
let alloc_storage = genesis.alloc.clone().into_iter().filter_map(|(addr, account)| {
|
let alloc_storage = genesis.alloc.clone().into_iter().filter_map(|(addr, account)| {
|
||||||
|
|||||||
Reference in New Issue
Block a user