mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: write account and storage hashes in genesis (#2441)
This commit is contained in:
@ -5,7 +5,7 @@ use crate::{
|
||||
proofs::{KeccakHasher, EMPTY_ROOT},
|
||||
serde_helper::deserialize_json_u256,
|
||||
utils::serde_helpers::deserialize_stringified_u64,
|
||||
Address, Bytes, H256, KECCAK_EMPTY, U256,
|
||||
Account, Address, Bytes, H256, KECCAK_EMPTY, U256,
|
||||
};
|
||||
use ethers_core::utils::GenesisAccount as EthersGenesisAccount;
|
||||
use reth_rlp::{encode_fixed_size, length_of_length, Encodable, Header as RlpHeader};
|
||||
@ -193,6 +193,17 @@ impl From<EthersGenesisAccount> for GenesisAccount {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<GenesisAccount> for Account {
|
||||
fn from(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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@ -6,6 +6,7 @@ use reth_db::{
|
||||
transaction::{DbTx, DbTxMut},
|
||||
};
|
||||
use reth_primitives::{keccak256, Account, Bytecode, ChainSpec, StorageEntry, H256};
|
||||
use reth_provider::{Transaction, TransactionError};
|
||||
use reth_stages::StageKind;
|
||||
use std::{path::Path, sync::Arc};
|
||||
use tracing::debug;
|
||||
@ -31,6 +32,10 @@ pub enum InitDatabaseError {
|
||||
actual: H256,
|
||||
},
|
||||
|
||||
/// Higher level error encountered when using a Transaction.
|
||||
#[error(transparent)]
|
||||
TransactionError(#[from] TransactionError),
|
||||
|
||||
/// Low-level database error.
|
||||
#[error(transparent)]
|
||||
DBError(#[from] reth_db::Error),
|
||||
@ -62,7 +67,12 @@ pub fn init_genesis<DB: Database>(
|
||||
let tx = db.tx_mut()?;
|
||||
insert_genesis_state::<DB>(&tx, genesis)?;
|
||||
|
||||
// use transaction to insert genesis header
|
||||
let transaction = Transaction::new_raw(&db, tx);
|
||||
insert_genesis_hashes(transaction, genesis)?;
|
||||
|
||||
// Insert header
|
||||
let tx = db.tx_mut()?;
|
||||
tx.put::<tables::CanonicalHeaders>(0, hash)?;
|
||||
tx.put::<tables::HeaderNumbers>(hash, 0)?;
|
||||
tx.put::<tables::BlockBodyIndices>(0, Default::default())?;
|
||||
@ -115,7 +125,25 @@ pub fn insert_genesis_state<DB: Database>(
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Inserts hashes for the genesis state.
|
||||
pub fn insert_genesis_hashes<DB: Database>(
|
||||
mut transaction: Transaction<'_, DB>,
|
||||
genesis: &reth_primitives::Genesis,
|
||||
) -> Result<(), InitDatabaseError> {
|
||||
// insert and hash accounts to hashing table
|
||||
let alloc_accounts =
|
||||
genesis.alloc.clone().into_iter().map(|(addr, account)| (addr, Some(account.into())));
|
||||
transaction.insert_account_for_hashing(alloc_accounts)?;
|
||||
|
||||
let alloc_storage = genesis.alloc.clone().into_iter().filter_map(|(addr, account)| {
|
||||
// only return Some if there is storage
|
||||
account.storage.map(|storage| (addr, storage.into_iter().map(|(k, v)| (k, v.into()))))
|
||||
});
|
||||
transaction.insert_storage_for_hashing(alloc_storage)?;
|
||||
transaction.commit()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@ -1391,7 +1391,7 @@ fn unwind_storage_history_shards<DB: Database>(
|
||||
}
|
||||
|
||||
/// An error that can occur when using the transaction container
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, thiserror::Error)]
|
||||
pub enum TransactionError {
|
||||
/// The transaction encountered a database error.
|
||||
#[error(transparent)]
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use thiserror::Error;
|
||||
|
||||
/// State root error.
|
||||
#[derive(Error, Debug)]
|
||||
#[derive(Error, Debug, PartialEq, Eq, Clone)]
|
||||
pub enum StateRootError {
|
||||
/// Internal database error.
|
||||
#[error(transparent)]
|
||||
@ -21,7 +21,7 @@ impl From<StateRootError> for reth_db::Error {
|
||||
}
|
||||
|
||||
/// Storage root error.
|
||||
#[derive(Error, Debug)]
|
||||
#[derive(Error, PartialEq, Eq, Clone, Debug)]
|
||||
pub enum StorageRootError {
|
||||
/// Internal database error.
|
||||
#[error(transparent)]
|
||||
|
||||
Reference in New Issue
Block a user