Skip to content

Commit

Permalink
feat: add format validation to era2-stats binary (#1555)
Browse files Browse the repository at this point in the history
  • Loading branch information
morph-dev authored Oct 27, 2024
1 parent fd4a212 commit bf02bc3
Showing 1 changed file with 44 additions and 5 deletions.
49 changes: 44 additions & 5 deletions e2store/src/bin/era2-stats.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use std::path::PathBuf;

use alloy::primitives::{keccak256, B256};
use anyhow::bail;
use clap::Parser;
use e2store::era2::{AccountOrStorageEntry, Era2Reader};
use e2store::era2::{self, AccountOrStorageEntry, Era2Reader};
use tracing::info;

#[derive(Debug, Parser)]
#[command(
name = "Era2 stats",
about = "Reads the era2 file and prints stats about it."
about = "Reads the era2 file, validates the format, and prints stats about it."
)]
struct Config {
#[arg(help = "The path to the era2 file.")]
Expand All @@ -23,12 +24,12 @@ struct Stats {
storage_item_count: usize,
}

/// Reads the era2 file and prints stats about it.
/// Reads the era2 file, validates the format, and prints stats about it.
///
/// It can be run with following command:
///
/// ```bash
/// cargo run -p e2store --bin era2-stats --features era2-stats-binary -- <path>
/// cargo run --release -p e2store --bin era2-stats --features era2-stats-binary -- <path>
/// ```
fn main() -> anyhow::Result<()> {
trin_utils::log::init_tracing_logger();
Expand All @@ -41,18 +42,34 @@ fn main() -> anyhow::Result<()> {
reader.header.header.number
);

let mut last_address_hash = B256::ZERO;

let mut stats = Stats::default();
while let Some(entry) = reader.next() {
let AccountOrStorageEntry::Account(account) = entry else {
bail!("Expected account entry");
};
stats.account_count += 1;

assert!(
account.address_hash > last_address_hash,
"Expected increasing order of accounts: {last_address_hash} is before {}",
account.address_hash
);
last_address_hash = account.address_hash;

assert_eq!(
keccak256(&account.bytecode),
account.account_state.code_hash,
"Invalid code hash",
);

if !account.bytecode.is_empty() {
stats.bytecode_count += 1;
}

for _ in 0..account.storage_count {
let mut last_storage_item = B256::ZERO;
for index in 0..account.storage_count {
let Some(AccountOrStorageEntry::Storage(storage)) = reader.next() else {
bail!(
"Expected storage entry for account: {}",
Expand All @@ -61,6 +78,28 @@ fn main() -> anyhow::Result<()> {
};
stats.storage_entry_count += 1;
stats.storage_item_count += storage.len();

// Check that every storage entry is full (has 10M items), except the last one.
if index + 1 < account.storage_count {
assert_eq!(
storage.len(),
era2::MAX_STORAGE_ITEMS,
"Non-final storage entry (address_hash: {}, index: {index}/{}) should be full, but has {} items instead",
account.address_hash,
account.storage_count,
storage.len(),
);
}

for item in storage.iter() {
assert!(
item.storage_index_hash > last_storage_item,
"Expected increasing order of storage items (address hash: {}): {last_storage_item} is before {}",
account.address_hash,
item.storage_index_hash,
);
last_storage_item = item.storage_index_hash;
}
}

if stats.account_count % 1_000_000 == 0 {
Expand Down

0 comments on commit bf02bc3

Please # to comment.