Skip to content

feat: add kona validator binary#151

Merged
flyq merged 3 commits into
liquan/refactor/executor-abstractionfrom
clay/feat/kona-validator-on-executor-abstraction
Jul 10, 2026
Merged

feat: add kona validator binary#151
flyq merged 3 commits into
liquan/refactor/executor-abstractionfrom
clay/feat/kona-validator-on-executor-abstraction

Conversation

@claymega

@claymega claymega commented Jul 9, 2026

Copy link
Copy Markdown

Summary

  • Add a KonaValidator backend and a kona-validator binary so the same stateless validator pipeline can validate blocks with either the MegaEVM or Kona execution backend.

Background
The validator pipeline already separates block fetching, contract caching, chain advancement, and reorg handling from per-block execution through the BlockValidator abstraction.
This branch uses that abstraction to add Kona replay as a second execution backend without duplicating the pipeline.
That gives us a dedicated binary for running and debugging the Kona validation path while keeping the existing MegaEVM validator behavior intact.

One important difference between the backends is that Kona replay needs the parent header to re-derive parts of the header / payload, while the MegaEVM backend reads the execution parameters from the current block header.
For that reason, this PR does not make parent headers mandatory for every validator path.
Instead, the fetcher has a fetch_parent_header switch that is enabled by kona-validator and left disabled by the default stateless-validator binary.

Approach

  • Add the kona_replay module in stateless-core and export KonaValidator.
  • Implement BlockValidator for KonaValidator, replaying through Kona and validating the derived block hash, state root, withdrawals root, receipts root, logs bloom, and gas used.
  • Keep ValidationInput::parent_header optional for MegaEVM, while the Kona backend returns a backend error when it is missing.
  • Add a fetch_parent_header switch to ValidatorFetcher so only the Kona path performs the extra parent-header RPC read.
  • Generalize ValidatorProcessor<V> and workers::run_with_signals<V> over any BlockValidator<Block<Transaction>>, leaving production wiring to choose the backend.
  • Keep stateless-validator wired to MegaEvmValidator, and add kona-validator wired to KonaValidator with the same CLI surface.
  • Replace local mega-kona path dependencies with Git dependencies on megaeth-labs/mega-kona branch clay/feat/regist_pnet_config.

Tests

  • cargo test --package stateless-core --lib -- kona_replay::tests::kona_validator_validate_block_mainnet_fixtures --exact --nocapture
  • cargo test --package stateless-validator --test integration -- kona_validator_binary_exposes_cli --exact --nocapture
  • cargo test --package stateless-validator --test integration -- kona_fetcher_includes_parent_header --exact --nocapture
  • cargo test -p stateless-validator integration_test_ --test integration

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2f605f43d9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

let witness_verification_time = 0.0_f64; // no_std: timing unavailable

// Replay block transactions
let (accounts, output) = replay_block_with_kona(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Compare the Kona-built header before accepting blocks

In Kona mode, replay_block_with_kona returns the header fields Kona derived, but validate_block never compares output.block_hash (or the derived withdrawals root) with the RPC block header before continuing with the local state-root checks. For blocks whose execution side effects still match the claimed state/receipt/gas fields, such as empty or no-op blocks with an invalid base fee or extra-data-derived header field, this accepts a block even though Kona rebuilt a different header; the existing BlockHashMismatch/WithdrawalsRootMismatch errors suggest these checks were intended here.

Useful? React with 👍 / 👎.

Comment on lines +348 to +352
let execution_context = MegaBlockExecutionCtx::new(
parent_hash,
attrs.payload_attributes.parent_beacon_block_root,
Default::default(),
block_limits,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Pass block extra data into bundle replay

generate_bundle_state is the state update later fed into SALT and withdrawal verification, but it creates MegaBlockExecutionCtx with empty extra data while the MegaEVM replay path passes header.extra_data.clone(). For blocks where MegaEVM hardfork logic or system-contract handling consults block extra data, the Kona bundle replay runs under a different context than the block and can reject otherwise valid blocks with state or withdrawal mismatches.

Useful? React with 👍 / 👎.

&header.extra_data,
rollup_config,
)),
min_base_fee: Some(1_000_000),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use the decoded Jovian min base fee

payload_attrs_from_block always sets min_base_fee to 1_000_000, so kona_evm_env's attrs.min_base_fee.unwrap_or(config_min_base_fee) never uses the min base fee decoded from the parent header. On Jovian-active blocks where the parent extra data carries any other min base fee, Kona rebuilds the payload with the wrong base fee and can halt on otherwise valid blocks or compute state for the wrong BASEFEE value.

Useful? React with 👍 / 👎.

let parent_header = if self.fetch_parent_header {
Some(
self.rpc_client
.get_header(BlockId::Hash(block.header.parent_hash.into()), false)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Verify fetched parent headers before validation

When kona-validator fetches a corrupt parent header whose hash field matches the requested parent hash but whose contents do not hash to it, this unverified fetch succeeds and the mismatch is only detected later inside Kona validation, where it is classified as a deterministic fatal validation failure. Fetching with hash verification here keeps the error in the RPC retry path, matching how full blocks are handled, instead of halting the validator because one provider returned a bad header.

Useful? React with 👍 / 👎.

@claymega claymega requested a review from SilasZhr July 9, 2026 11:43
@flyq flyq merged commit 185b214 into liquan/refactor/executor-abstraction Jul 10, 2026
22 of 28 checks passed
@flyq flyq deleted the clay/feat/kona-validator-on-executor-abstraction branch July 10, 2026 09:20
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