Reth ChainSpec
ChainSpec is the type that says what makes a chain different from Ethereum mainnet at the protocol level: its chain ID, its genesis, when each hardfork activates and which base-fee parameters apply. A Reth node is built from one; NodeConfig carries it as chain: Arc<ChainSpec>.
Code that has to work with any chain (an Ethereum, OP or custom one) takes the EthChainSpec trait from reth_chainspec rather than the concrete struct. The struct ChainSpec implements it, and also has the same accessors as inherent methods.
API at a glance
fn genesis_hash(&self) -> B256- The hash of the genesis block. On ChainSpec it is the sealed genesis header's hash (genesis_header.hash()); it is also a method of the EthChainSpec trait.
fn genesis_header(&self) -> &Header- The genesis block's header. sealed_genesis_header() returns it as a SealedHeader together with its hash.
fn genesis(&self) -> &Genesis- The genesis specification (allocations, gas limit, timestamp …), not the header. ChainSpec::from_genesis(genesis) builds a spec from one.
fn chain(&self) -> Chain / fn chain_id(&self) -> u64- The chain, and its numeric ID (chain_id() is chain().id()).
fn base_fee_params_at_timestamp(&self, timestamp: u64) -> BaseFeeParams- The EIP-1559 parameters in force at a timestamp: the latest hardfork-keyed entry active then. With per-fork parameters and none active it falls back to the first entry, and to Ethereum's defaults if the list is empty.
ChainSpec::builder()- A ChainSpecBuilder for assembling a custom spec (chain, genesis, hardforks) in code, as tests and custom chains do.
Checked against paradigmxyz/reth at eb4c15e (2026-04-07): crates/chainspec/src/api.rs, crates/chainspec/src/spec.rs
Lessons on this topic
ChainSpec = genesis + forks + precompile schedule + chain ID. Customise per chain. Reth's NodeBuilder takes one as input.
validate_payload calls Reth's EthBeaconConsensus to validate proposed payloads against the chain spec. Real Ethereum consensus rules running inside…
bridge.commit(block_hash) calls Reth's Engine API engine_forkchoiceUpdatedV3 to finalise the block. State persisted; head advanced. The full integration…
Reth creates a new EVM instance for every block. OpenHlEvmFactory is the hook — it lets you inject precompiles + custom Database bindings into every EVM…