Skip to content

chore(el): derive reth chainspecs from base-alloy-chains vs. duplicating configs#1592

Open
danyalprout wants to merge 5 commits intomainfrom
danyal/dedup-configs-4
Open

chore(el): derive reth chainspecs from base-alloy-chains vs. duplicating configs#1592
danyalprout wants to merge 5 commits intomainfrom
danyal/dedup-configs-4

Conversation

@danyalprout
Copy link
Collaborator

Description

Part one of deduplicating chain configurations and settings. Creates base-alloy-chains which has the chain configurations defined in Rust.

Upstream consumers will map this generic type into CL/EL specific types via a TryFrom/From impl.

@cb-heimdall
Copy link
Collaborator

cb-heimdall commented Mar 23, 2026

🟡 Heimdall Review Status

Requirement Status More Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 1
1
1 if commit is unverified 0
Sum 1

@vercel
Copy link

vercel bot commented Mar 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
base Ignored Ignored Preview Mar 23, 2026 5:09am

Request Review

@danyalprout danyalprout changed the title Danyal/dedup configs 4 chore(el): derive reth chainspecs from base-alloy-chains vs. duplicating configs Mar 23, 2026
@danyalprout danyalprout marked this pull request as ready for review March 23, 2026 02:04
}

/// Looks up a chain config by CLI name.
pub fn by_name(name: &str) -> Option<&'static Self> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by_name does a linear scan with contains on each config's cli_names slice. With only 4 configs this is fine, but the &str parameter requires exact equality — consider documenting that this is case-sensitive. No functional issue, just noting for API clarity.

"base-devnet-0-sepolia-dev-0" => Some(BASE_DEVNET_0_SEPOLIA_DEV_0.clone()),
_ => None,
}
BaseChainConfig::by_name(s).map(|cfg| Arc::new(Self::from(cfg)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parse_chain now constructs a fresh OpChainSpec (including deserializing the embedded genesis JSON) on every call. The old implementation returned Arc::clone() of LazyLock statics, which was essentially free after first access.

This is called from CLI parsing so it's unlikely to be a hot path, but if anything else calls parse_chain repeatedly (e.g., in tests or validation loops), the repeated deserialization is wasteful. Consider caching the result per chain, or documenting that callers should cache the Arc themselves.


bootnodes: &[],

prune_delete_limit: 0,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Behavioral change for dev chain base fee params. The deleted dev.rs used BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()) which is { denominator: 8, elasticity: 2 }. The new From<&BaseChainConfig> impl derives params from these config values, producing BaseFeeParamsKind::Variable([(London, {50, 6}), (Canyon, {250, 6})]) because eip1559_denominator (50) != eip1559_denominator_canyon (250).

This changes the dev chain from Ethereum-style constant base fee params to OP-style variable params. If this is intentional (aligning devnet with production behavior), it's fine — but if the old Ethereum-style params were needed for dev/test compatibility, this is a regression.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a correct change

danyalprout added a commit that referenced this pull request Mar 23, 2026
Add base-alloy-chains to udeps ignore list (used in doc-test but
undetectable by cargo-udeps). Improve genesis deserialization panic
message to include chain_id.
@danyalprout danyalprout requested a review from refcell March 23, 2026 03:47
Consolidate chain configuration so adding a new chain only requires
touching config.rs. Add cli_names field to BaseChainConfig, derive
by_name/by_chain_id lookups from all(), simplify parse_chain(), and
remove the 4 LazyLock statics from chainspec.
Add base-alloy-chains to udeps ignore list (used in doc-test but
undetectable by cargo-udeps). Improve genesis deserialization panic
message to include chain_id.
@danyalprout danyalprout force-pushed the danyal/dedup-configs-4 branch from fece2c1 to 354facd Compare March 23, 2026 05:07

/// All supported chain names for the CLI.
pub const SUPPORTED_CHAINS: &[&str] =
&["base", "base_sepolia", "base-sepolia", "base-devnet-0-sepolia-dev-0", "dev"];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SUPPORTED_CHAINS duplicates data already embedded in each config's cli_names. The test at the bottom catches drift, but this const could be derived at compile-time or as a function to eliminate the maintenance hazard entirely:

pub fn supported_chains() -> impl Iterator<Item = &'static str> {
    BaseChainConfig::all().into_iter().flat_map(|cfg| cfg.cli_names.iter().copied())
}

This would also remove the need for the sync test. If the const form is needed for CLI help strings (e.g., clap's possible_values), consider generating it from cli_names via a const fn or LazyLock instead of manually maintaining the list.

@danyalprout danyalprout force-pushed the danyal/dedup-configs-4 branch from 354facd to 57e8e61 Compare March 23, 2026 05:09
@github-actions
Copy link
Contributor

Review Summary

This PR consolidates four per-chain LazyLock<Arc<OpChainSpec>> statics (BASE_MAINNET, BASE_SEPOLIA, BASE_DEVNET_0_SEPOLIA_DEV_0, OP_DEV) and their corresponding hardfork statics into a single From<&BaseChainConfig> for OpChainSpec impl, deriving chain specs on demand from BaseChainConfig data. It also moves SUPPORTED_CHAINS into base-alloy-chains and adds cli_names/prune_delete_limit fields to BaseChainConfig.

What looks good

  • Base fee params are equivalent. Verified that the derived BaseFeeParams from config values match what the old named constructors (BaseFeeParams::optimism(), optimism_canyon(), base_sepolia(), base_sepolia_canyon()) produced. The fork-id and genesis hash tests confirm no regressions for mainnet and sepolia.
  • Genesis header handling is correct. The genesis_l2_hash.is_zero() check correctly differentiates dev (slow-sealed) from production (pre-known hash) genesis headers.
  • Test migration is mechanical and correct. All test changes are straightforward replacements of static refs with freshly constructed specs.
  • Hardfork consolidation is clean. Only BASE_MAINNET_HARDFORKS is retained as a Lazy static (used in the OpChainSpec::from(Genesis) fallback path); the rest are properly derived via BaseChainUpgrades::new(BaseUpgrade::forks_for(cfg)).to_chain_hardforks().

Findings (inline comments posted)

All findings were posted as inline comments on this and prior review passes:

  1. Dev chain base fee behavioral change — The old OP_DEV used BaseFeeParams::ethereum() ({8, 2}), the new path produces OP-style params ({50, 6} / {250, 6}). Should be confirmed intentional.
  2. parse_chain no longer caches — Each call now deserializes genesis JSON. Not a regression for CLI use, but worth noting if called in loops.
  3. SUPPORTED_CHAINS duplication — The const duplicates data from cli_names; a derived function would be more robust (though the sync test mitigates drift).
  4. Panic in From implunwrap_or_else with chain ID in the message was adopted (good).
  5. by_name linear scan — Fine at 4 configs, but exact-match / case-sensitivity is undocumented.

No blocking issues found. The main item requiring explicit confirmation is the dev chain base fee parameter change (#1 above).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants