Skip to content

feat(derivation): SPEC-005 narrow scope — validator removal + Path A/B startup-time verification mode select#951

Open
curryxbo wants to merge 15 commits into
feat/multi_batchfrom
feat/derivation-batch-verify
Open

feat(derivation): SPEC-005 narrow scope — validator removal + Path A/B startup-time verification mode select#951
curryxbo wants to merge 15 commits into
feat/multi_batchfrom
feat/derivation-batch-verify

Conversation

@curryxbo
Copy link
Copy Markdown
Contributor

@curryxbo curryxbo commented May 12, 2026

Scope

Aligns with the current narrow SPEC-005 scope (morph-l2/morph-specs#19 / spec PR #18):

  • Goal A: Delete `node/validator/` and all its references in derivation / main / flags / docker. ✅
  • Goal B: Add Path A / Path B startup-time mutually-exclusive verification modes to derivation. ✅
    • Default mode `pathA` preserves current behaviour.
    • `pathB` skips the beacon blob fetch entirely; instead reads local L2 blocks for the batch range, replays the sequencer's encoding to rebuild the blob, and compares the resulting versioned hashes against the values from L1 calldata.

Relationship to PR #948

This PR replaces PR #948. Items from PR #948 that fall outside the narrow scope (reorg detection, halted state, rollback executor, admin RPC, sequencer mutex, 4-stage state model, etc.) are split into a separate `[DEFER]` PR #950.

Commits

  1. `c82a1456` refactor(node): remove validator/challenge bypass per SPEC-005
  2. `09a2c725` merge: bring in feat/multi_batch (PR feat: multi blob #935) for SPEC-005 baseline
  3. `e2c6f577` refactor(derivation): extract verifyBatchRoots into verify.go
  4. `9f01c530` feat(derivation): SPEC-005 Path B — local-rebuild blob verification

Design

The two modes are completely independent. There is no automatic fallback under any circumstance: if Path A's blob fetch fails, the node does not silently switch to Path B. Switching modes requires changing config and restarting.

`verifyBatchRoots` (state root + withdrawal root, read from L1 calldata) is shared by both modes; it is independent of blob data.

Prerequisite

PR #935 (`feat/multi_batch`): Path B implementation reuses `common/batch` and `common/blob` packages introduced by it. While PR #935 is unmerged, this PR's base is conceptually `feat/multi_batch`; once #935 lands in main, this PR can be rebased onto main.

Key code points

Component Path
`ParsingTxs` / `BuildBlockContext` `common/batch/batch_cache.go` (renamed from package-private to exported)
`BatchData.{Append, TxsPayload, TxsPayloadV2}` `common/batch/batch_data.go`
`CompressBatchBytes` / `MakeBlobTxSidecar` `common/blob/payload.go` (using this one, not the duplicate in `common/batch/blob.go` — must match the sequencer's actual call site)
`BatchInfo.blobHashes` field `node/derivation/batch_info.go`
`ParseBatchMetadataOnly` (calldata-only parse) `node/derivation/batch_info.go`
`fetchBatchInfoPathB` / `verifyBatchContentPathB` / `fetchLocalLastHeader` `node/derivation/verify_path_b.go`
`--derivation.verify-mode` flag `node/flags/flags.go`
`path_b_triggered_total` / `path_b_failed_total` metrics `node/derivation/metrics.go`

TODO (separate commits / follow-up sessions)

  • Unit tests covering the SPEC-005 §5.1 cases (V1/V2 batch payload, local block missing, versioned hash match/mismatch, mode dispatch, default-is-pathA, unknown-mode fail-fast).
  • Devnet validation: 4-node devnet 30min on Path A default; one node restarted on Path B mode; manual local-block tampering should produce a versioned hash mismatch and increment `path_b_failed_total`.

Test plan

  • `go build ./node/... ./common/...` clean
  • `go vet ./node/... ./common/...` clean
  • Test compilation clean
  • Unit tests (per TODO above)
  • Devnet 4-node 30min smoke + Path B mode switch (per TODO above)

panos-xyz and others added 14 commits May 7, 2026 15:34
Replace the internal codename "bitget" with the neutral term "polyrepo"
in build context references, variable names, and container paths.
Cover the rest of the file with one-line docstrings to satisfy
CodeRabbit's docstring coverage threshold.
…g Dockerfile.l2-geth

Move the morph-el-0 build: section from docker-compose-4nodes.yml into a
dedicated docker-compose-geth-build.yml, included only when
EXECUTION_CLIENT=geth. The reth overlay now sees no build: on morph-el-0,
eliminating the risk of docker compose up building geth code and tagging
it as the reth image when the reth image is absent.
Keep the base devnet compose file self-contained for geth while using the reth overlay to explicitly reset inherited geth build definitions.

Constraint: Do not include the devnet execution-client test file in this commit
Rejected: Keep a separate geth build compose file | changes direct base compose usage
Confidence: high
Scope-risk: narrow
[codex] support reth execution client in devnet
- Delete node/validator package (config.go, validator.go, validator_test.go)
- Drop validator wiring from node/cmd/node/main.go and derivation.NewDerivationClient signature
- Drop validator field from Derivation struct
- Drop ChallengeEnable/ChallengeState invocation in derivation rollback path
- Remove validator.challengeEnable / validator.privateKey CLI flags
- Remove MORPH_NODE_VALIDATOR_PRIVATE_KEY env from docker compose files

Refs: morph-l2/morph-specs SPEC-005 §4.1
Equivalent in intent to PR #948 commit 3e49457, but applied directly to
main without the Phase A reorg/halted/rollback context that 3e49457
brought along.
Same as the merge previously applied to PR #948's branch — needed because
PR #935 (multi_batch / Batch Header v2) hasn't landed in main yet, but
SPEC-005 narrow scope's Path B implementation depends on common/batch +
common/blob packages introduced by it.

Resolutions:
- ops/docker/docker-compose-4nodes.yml: take origin/feat/multi_batch's
  TX_SUBMITTER_PRIORITY_ROLLUP=true and drop TX_SUBMITTER_SEAL_BATCH;
  that env block is owned by tx-submitter, which feat/derivation-batch-verify
  should not be modifying.
- go-ethereum submodule: keep at 045be0fd (v2.2.2). Multi_batch's 53aee9b
  internal merge accidentally regressed the pointer to 1d460577; that
  regression is unrelated to multi_batch's design intent and should not
  propagate to feat/derivation-batch-verify.
Pull the inline state-root / withdrawal-root mismatch check out of
derivationBlock into a standalone verifyBatchRoots(batchInfo, lastHeader)
function in a new node/derivation/verify.go.

Both roots are read from L1 calldata at parse time, so verifyBatchRoots
is independent of blob data — this is the SPEC-005 §3.4 invariant that
later allows Path B (local-rebuild verification) to reuse this same
check without modification.

No behavior change: the main loop still logs + returns on mismatch, sets
stateException on the metric, and continues otherwise. Only the location
and error-message format change.

Refs: morph-l2/morph-specs SPEC-005 §4.2 / §6 ("两种模式共享同一份 verifyBatchRoots")
@curryxbo curryxbo requested a review from a team as a code owner May 12, 2026 10:08
@curryxbo curryxbo requested review from tomatoishealthy and removed request for a team May 12, 2026 10:08
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 12, 2026

Warning

Rate limit exceeded

@curryxbo has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 42 minutes and 58 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 318a290f-f6a3-403f-8fc6-a8e362abb656

📥 Commits

Reviewing files that changed from the base of the PR and between 58c70f9 and 9f01c53.

⛔ Files ignored due to path filters (4)
  • common/go.sum is excluded by !**/*.sum
  • go.work is excluded by !**/*.work
  • go.work.sum is excluded by !**/*.sum
  • tx-submitter/go.sum is excluded by !**/*.sum
📒 Files selected for processing (79)
  • MakefileEks.mk
  • common/batch/batch_cache.go
  • common/batch/batch_cache_genesis_header_test.go
  • common/batch/batch_cache_test.go
  • common/batch/batch_data.go
  • common/batch/batch_header.go
  • common/batch/batch_header_test.go
  • common/batch/batch_query.go
  • common/batch/batch_restart_test.go
  • common/batch/batch_storage.go
  • common/batch/blob.go
  • common/batch/commit_test.go
  • common/batch/encoding.go
  • common/batch/helpers_test.go
  • common/batch/interfaces.go
  • common/batch/l2_gov.go
  • common/blob/fee.go
  • common/blob/payload.go
  • common/go.mod
  • contracts/contracts/l1/rollup/Rollup.sol
  • contracts/contracts/test/Rollup.t.sol
  • contracts/src/deploy-config/holesky.ts
  • contracts/src/deploy-config/hoodi.ts
  • contracts/src/deploy-config/l1.ts
  • contracts/src/deploy-config/qanetl1.ts
  • contracts/src/deploy-config/sepolia.ts
  • contracts/src/deploy-config/testnetl1.ts
  • gas-oracle/app/src/da_scalar/blob.rs
  • gas-oracle/app/src/da_scalar/calculate.rs
  • gas-oracle/app/src/da_scalar/l1_scalar.rs
  • node/cmd/node/main.go
  • node/derivation/batch_info.go
  • node/derivation/batch_info_test.go
  • node/derivation/beacon.go
  • node/derivation/config.go
  • node/derivation/derivation.go
  • node/derivation/metrics.go
  • node/derivation/verify.go
  • node/derivation/verify_path_b.go
  • node/flags/flags.go
  • node/ops-morph/docker-compose-validator.yml
  • node/types/batch_header.go
  • node/validator/config.go
  • node/validator/validator.go
  • node/validator/validator_test.go
  • ops/docker/docker-compose-4nodes.yml
  • ops/docker/layer1/configs/values.env.template
  • ops/l2-genesis/deploy-config/devnet-deploy-config.json
  • oracle/oracle/batch.go
  • prover/bin/challenge/src/handler.rs
  • prover/bin/client/elf/verifier-client
  • prover/bin/host/src/execute.rs
  • prover/bin/host/src/main.rs
  • prover/bin/server/src/queue.rs
  • prover/bin/shadow-prove/src/execute.rs
  • prover/bin/shadow-prove/src/main.rs
  • prover/bin/shadow-prove/src/shadow_prove.rs
  • prover/bin/shadow-prove/src/shadow_rollup.rs
  • prover/bin/shadow-prove/src/util.rs
  • prover/crates/executor/client/src/lib.rs
  • prover/crates/executor/client/src/types/batch.rs
  • prover/crates/executor/client/src/types/blob.rs
  • prover/crates/executor/client/src/types/input.rs
  • prover/crates/executor/client/src/verifier/blob_verifier.rs
  • prover/crates/executor/host/src/blob.rs
  • prover/crates/executor/host/src/execute.rs
  • prover/crates/executor/host/src/utils.rs
  • tx-submitter/batch/batch_storage_test.go
  • tx-submitter/batch/blob.go
  • tx-submitter/flags/flags.go
  • tx-submitter/go.mod
  • tx-submitter/iface/client.go
  • tx-submitter/services/rollup.go
  • tx-submitter/types/blob.go
  • tx-submitter/types/blob_compat.go
  • tx-submitter/types/blob_params.go
  • tx-submitter/types/converter.go
  • tx-submitter/types/l2Caller.go
  • tx-submitter/utils/config.go
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/derivation-batch-verify

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Introduces Path B verification mode (SPEC-005 §4) as a startup-time
mutually-exclusive alternative to Path A. Selected via
`--derivation.verify-mode` (default "pathA", preserves current
behaviour). The two modes do not interact: under no circumstance does
the node fall back from one to the other; switching requires changing
the config and restarting.

Path B mode:
  - Skips beacon-side blob fetch entirely.
  - Reads L1 commitBatch tx calldata + tx.BlobHashes() only.
  - Reads local L2 blocks for the batch range, replays the sequencer's
    encoding (parsingTxs + buildBlockContext + BatchData) to rebuild
    the blob bytes.
  - Compresses + builds a BlobTxSidecar; compares its versioned hashes
    against the values from L1 calldata.
  - Reuses the shared verifyBatchRoots for state/withdrawal root
    verification (independent of blob).

Touches:
  - common/batch: export ParsingTxs / BuildBlockContext (rename from
    package-private). No semantic change for tx-submitter.
  - node/derivation/batch_info.go: add BatchInfo.blobHashes field;
    add ParseBatchMetadataOnly (calldata-only parse, no blob).
  - node/derivation/config.go + flags: add VerifyMode + flag with
    fail-fast validation on unknown values.
  - node/derivation/derivation.go: dispatch in main loop based on
    verifyMode; populate blobHashes in Path A's fetch helper too so
    BatchInfo is consistent across modes.
  - node/derivation/verify_path_b.go: fetchBatchInfoPathB +
    verifyBatchContentPathB + fetchLocalLastHeader.
  - node/derivation/metrics.go: path_b_triggered_total /
    path_b_failed_total counters.

Verified clean: `go build ./node/... ./common/...`, `go vet`,
test compile.

Refs: morph-l2/morph-specs SPEC-005 §4 / §5 / §6
Resolves the WIP item flagged in PR #951.
@curryxbo curryxbo changed the title [WIP] feat(derivation): SPEC-005 narrow scope — validator removal + Path A/B mode select + Path B impl pending feat(derivation): SPEC-005 narrow scope — validator removal + Path A/B startup-time verification mode select May 12, 2026
@curryxbo curryxbo changed the base branch from main to feat/multi_batch May 12, 2026 10:24
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