mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
chore: check genesis mismatch in init_genesis (#1560)
This commit is contained in:
@ -49,16 +49,7 @@ impl InitCommand {
|
||||
info!(target: "reth::cli", "Database opened");
|
||||
|
||||
info!(target: "reth::cli", "Writing genesis block");
|
||||
let genesis_hash = init_genesis(db, self.chain.clone())?;
|
||||
|
||||
if genesis_hash != self.chain.genesis_hash() {
|
||||
// TODO: better error text
|
||||
return Err(eyre::eyre!(
|
||||
"Genesis hash mismatch: expected {}, got {}",
|
||||
self.chain.genesis_hash(),
|
||||
genesis_hash
|
||||
))
|
||||
}
|
||||
init_genesis(db, self.chain.clone())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@ tracing = "0.1.37"
|
||||
rand = { version = "0.8", optional = true }
|
||||
|
||||
# errors
|
||||
thiserror = { version = "1", optional = true }
|
||||
thiserror = "1"
|
||||
|
||||
# enr
|
||||
enr = { version = "0.7.0", features = ["serde", "rust-secp256k1"], optional = true }
|
||||
@ -89,7 +89,6 @@ test-utils = [
|
||||
"dep:enr",
|
||||
"dep:ethers-core",
|
||||
"dep:tempfile",
|
||||
"dep:thiserror",
|
||||
"dep:hex",
|
||||
"dep:rand",
|
||||
"dep:tokio",
|
||||
|
||||
@ -21,16 +21,39 @@ pub fn init_db<P: AsRef<Path>>(path: P) -> eyre::Result<Env<WriteMap>> {
|
||||
Ok(db)
|
||||
}
|
||||
|
||||
/// Database initialization error type.
|
||||
#[derive(Debug, thiserror::Error, PartialEq, Eq, Clone)]
|
||||
pub enum InitDatabaseError {
|
||||
/// Attempted to reinitialize database with inconsistent genesis block
|
||||
#[error("Genesis hash mismatch: expected {expected}, got {actual}")]
|
||||
GenesisHashMismatch { expected: H256, actual: H256 },
|
||||
|
||||
/// Low-level database error.
|
||||
#[error(transparent)]
|
||||
DBError(#[from] reth_db::Error),
|
||||
}
|
||||
|
||||
/// Write the genesis block if it has not already been written
|
||||
#[allow(clippy::field_reassign_with_default)]
|
||||
pub fn init_genesis<DB: Database>(db: Arc<DB>, chain: ChainSpec) -> Result<H256, reth_db::Error> {
|
||||
pub fn init_genesis<DB: Database>(
|
||||
db: Arc<DB>,
|
||||
chain: ChainSpec,
|
||||
) -> Result<H256, InitDatabaseError> {
|
||||
let genesis = chain.genesis();
|
||||
|
||||
let header = chain.genesis_header();
|
||||
let hash = header.hash_slow();
|
||||
|
||||
let tx = db.tx()?;
|
||||
if let Some((_, hash)) = tx.cursor_read::<tables::CanonicalHeaders>()?.first()? {
|
||||
if let Some((_, db_hash)) = tx.cursor_read::<tables::CanonicalHeaders>()?.first()? {
|
||||
if db_hash == hash {
|
||||
debug!("Genesis already written, skipping.");
|
||||
return Ok(hash)
|
||||
}
|
||||
|
||||
return Err(InitDatabaseError::GenesisHashMismatch { expected: hash, actual: db_hash })
|
||||
}
|
||||
|
||||
drop(tx);
|
||||
debug!("Writing genesis block.");
|
||||
let tx = db.tx_mut()?;
|
||||
@ -48,9 +71,6 @@ pub fn init_genesis<DB: Database>(db: Arc<DB>, chain: ChainSpec) -> Result<H256,
|
||||
}
|
||||
|
||||
// Insert header
|
||||
let header = chain.genesis_header();
|
||||
|
||||
let hash = header.hash_slow();
|
||||
tx.put::<tables::CanonicalHeaders>(0, hash)?;
|
||||
tx.put::<tables::HeaderNumbers>(hash, 0)?;
|
||||
tx.put::<tables::BlockBodies>(0, Default::default())?;
|
||||
@ -65,7 +85,7 @@ pub fn init_genesis<DB: Database>(db: Arc<DB>, chain: ChainSpec) -> Result<H256,
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use super::init_genesis;
|
||||
use super::{init_genesis, InitDatabaseError};
|
||||
use reth_db::mdbx::test_utils::create_test_rw_db;
|
||||
use reth_primitives::{
|
||||
GOERLI, GOERLI_GENESIS, MAINNET, MAINNET_GENESIS, SEPOLIA, SEPOLIA_GENESIS,
|
||||
@ -97,4 +117,21 @@ mod tests {
|
||||
// actual, expected
|
||||
assert_eq!(genesis_hash, SEPOLIA_GENESIS);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fail_init_inconsistent_db() {
|
||||
let db = create_test_rw_db();
|
||||
init_genesis(db.clone(), SEPOLIA.clone()).unwrap();
|
||||
|
||||
// Try to init db with a different genesis block
|
||||
let genesis_hash = init_genesis(db, MAINNET.clone());
|
||||
|
||||
assert_eq!(
|
||||
genesis_hash.unwrap_err(),
|
||||
InitDatabaseError::GenesisHashMismatch {
|
||||
expected: MAINNET_GENESIS,
|
||||
actual: SEPOLIA_GENESIS
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user