feat: write account and storage hashes in genesis (#2441)

This commit is contained in:
Dan Cline
2023-05-01 21:06:15 +02:00
committed by GitHub
parent cafb31aa53
commit 7ea801f456
4 changed files with 43 additions and 4 deletions

View File

@ -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::*;

View File

@ -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(())
}

View File

@ -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)]

View File

@ -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)]