Skip to content

Revert "pruner: fall back to disk snapshot root when journal is missing (#300)"#309

Merged
curryxbo merged 1 commit intomainfrom
revert/pr-300-only
Apr 7, 2026
Merged

Revert "pruner: fall back to disk snapshot root when journal is missing (#300)"#309
curryxbo merged 1 commit intomainfrom
revert/pr-300-only

Conversation

@curryxbo
Copy link
Copy Markdown
Contributor

@curryxbo curryxbo commented Apr 7, 2026

Reverts #300.

The fallback logic introduced in #300 (using the snapshot disk root when the journal is missing) is overly broad and masks the real cause of snapshot/journal mismatches. Reverting it to keep the pruner behavior explicit and predictable.

A follow-up PR will replace this with a cleaner approach using a teeWriter that writes the target trie directly to disk during pruning, ensuring zero height drop after restart without relying on snapshot state.

Summary by CodeRabbit

  • Refactor
    • Simplified snapshot pruning logic by removing fallback mechanisms and direct error handling. The pruning process now consistently derives targets from the snapshot tree, with explicit error reporting when snapshot requirements are unmet.

@curryxbo curryxbo requested a review from a team as a code owner April 7, 2026 02:54
@curryxbo curryxbo requested review from r3aker86 and removed request for a team April 7, 2026 02:54
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 7, 2026

📝 Walkthrough

Walkthrough

This PR removes the snapDiskRoot fallback field and related logic from the Pruner struct. Instead of falling back to the disk-layer root when snapshot initialization fails, errors are now returned directly. The pruning target selection is simplified to always derive from the active snapshot tree without alternatives.

Changes

Cohort / File(s) Summary
Pruner Snapshot Fallback Removal
core/state/pruner/pruner.go
Removed snapDiskRoot struct field, eliminated fallback logic in NewPruner that re-initialized snapshots from disk-layer root on failure, removed conditional in prune that skipped snaptree.Cap when target equaled disk root, and simplified Prune to always derive pruning target from snapshot tree without fallback alternatives.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested labels

bug

Suggested reviewers

  • twcctop
  • panos-xyz

Poem

🐰 A snapDiskRoot once held sway,
A fallback for a rainy day,
But simpler paths lead us home,
No more roots to make us roam!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically describes the main change: reverting the fallback logic for disk snapshot root when journal is missing, which aligns with the file changes removing snapDiskRoot and related logic.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch revert/pr-300-only

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.11.4)

Error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions
The command is terminated due to an error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions


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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
core/state/pruner/pruner.go (2)

251-264: Increased strictness: pruning requires exactly 128 diff layers.

The reverted fallback to snapDiskRoot is removed. Now if fewer than 128 diff layers exist, the pruner returns an error rather than falling back to the disk root.

This means:

  • Recently pruned chains must wait for 128 new blocks before pruning again
  • Chains with fewer than 128 total blocks cannot be pruned

The error message at line 260 is helpful, but operators should be aware of this behavioral change. Consider documenting this requirement in the CLI help text or release notes.

📝 Optional: Add more context to the error message
 		if len(layers) != 128 {
 			// Reject if the accumulated diff layers are less than 128. It
 			// means in most of normal cases, there is no associated state
 			// with bottom-most diff layer.
-			return fmt.Errorf("snapshot not old enough yet: need %d more blocks", 128-len(layers))
+			return fmt.Errorf("snapshot not old enough yet: have %d diff layers, need 128 (wait for %d more blocks)", len(layers), 128-len(layers))
 		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@core/state/pruner/pruner.go` around lines 251 - 264, The pruner now fails
when fewer than 128 diff layers exist (root, layers computed via
p.snaptree.Snapshots(p.headHeader.Root,...)) and returns fmt.Errorf(...) instead
of falling back to snapDiskRoot; update the error reporting and user docs:
change the fmt.Errorf call to include the actual len(layers) and an explicit
statement that pruning requires exactly 128 diff layers (e.g. "pruning requires
128 diff layers; have %d; need %d more blocks"), and also add a corresponding
note to the CLI help text or release notes explaining the 128-block requirement
so operators are aware of the new behavior.

191-193: Consider adding early validation to reject disk-layer roots explicitly.

Lines 191-193 now unconditionally call Cap(), which will fail with "snapshot [%#x] is disk layer" if the user specifies a disk-layer root (see snapshot.go:378).

For auto-selected roots this is safe since Snapshots(..., 128, true) excludes disk layers. However, when users explicitly specify a root via the CLI, there's no validation before prune() is called, so an error will only surface deep in Cap().

While this explicit failure may be intentional (avoiding silent masking), adding an early check in Prune() to reject disk-layer roots with a clearer error message would improve user experience.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@core/state/pruner/pruner.go` around lines 191 - 193, Add an explicit early
validation in Prune() before calling snaptree.Cap: detect if the provided root
is a disk-layer snapshot (use the existing predicate in the snapshot/snaptree
package—e.g., snaptree.IsDiskLayer(root) or the equivalent method on the
snapshot type) and return a clear error like "specified root is a disk-layer
snapshot; pruning requires a non-disk root" instead of letting snaptree.Cap fail
later; place this check immediately before the snaptree.Cap(root, 0) call in
Prune().
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@core/state/pruner/pruner.go`:
- Around line 251-264: The pruner now fails when fewer than 128 diff layers
exist (root, layers computed via p.snaptree.Snapshots(p.headHeader.Root,...))
and returns fmt.Errorf(...) instead of falling back to snapDiskRoot; update the
error reporting and user docs: change the fmt.Errorf call to include the actual
len(layers) and an explicit statement that pruning requires exactly 128 diff
layers (e.g. "pruning requires 128 diff layers; have %d; need %d more blocks"),
and also add a corresponding note to the CLI help text or release notes
explaining the 128-block requirement so operators are aware of the new behavior.
- Around line 191-193: Add an explicit early validation in Prune() before
calling snaptree.Cap: detect if the provided root is a disk-layer snapshot (use
the existing predicate in the snapshot/snaptree package—e.g.,
snaptree.IsDiskLayer(root) or the equivalent method on the snapshot type) and
return a clear error like "specified root is a disk-layer snapshot; pruning
requires a non-disk root" instead of letting snaptree.Cap fail later; place this
check immediately before the snaptree.Cap(root, 0) call in Prune().

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 55796b60-e7ab-4e28-8d8c-011cde21f5b1

📥 Commits

Reviewing files that changed from the base of the PR and between b3c5552 and 7f9af56.

📒 Files selected for processing (1)
  • core/state/pruner/pruner.go

@curryxbo
Copy link
Copy Markdown
Contributor Author

curryxbo commented Apr 7, 2026

This PR is intentionally just a revert of #300. We're aware it removes the fallback fix — a proper replacement will come in a follow-up PR. The goal here is to cleanly revert first, then address the fix separately.

@panos-xyz
Copy link
Copy Markdown
Contributor

This PR is intentionally just a revert of #300. We're aware it removes the fallback fix — a proper replacement will come in a follow-up PR. The goal here is to cleanly revert first, then address the fix separately.

LGTM

@curryxbo curryxbo merged commit af017cb into main Apr 7, 2026
8 checks passed
@curryxbo curryxbo deleted the revert/pr-300-only branch April 7, 2026 07:40
FletcherMan added a commit that referenced this pull request Apr 23, 2026
* ci: support multi-platform Docker image build (amd64 + arm64) (#298)

* ci: support multi-platform Docker image build (amd64 + arm64)

Use docker/build-push-action with QEMU and buildx to build multi-arch
images. Mac arm64 users can now pull and run the image natively.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* ci: add workflow_dispatch for manual Docker image build

Allow manually triggering the Docker build from GitHub Actions UI
with a tag name input, useful for re-building existing tags.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* ci: fix incorrect COMMIT and VERSION on manual dispatch

Use git rev-parse HEAD for COMMIT and stripped version for VERSION
build-arg, so they are correct in both tag-push and workflow_dispatch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: fletcher.fan <fletcher.fan@bitget.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* Fix RLP decoding for MorphTx (#299)

* implement version-aware RLP decoding for MorphTx

* fix morph tx

* pruner: fall back to disk snapshot root when journal is missing (#300)

* pruner: fall back to disk snapshot root when journal is missing

When geth is killed uncleanly (SIGKILL before BlockChain.Stop writes
the snapshot journal), prune-state fails with:

  WARN Loaded snapshot journal  diskroot=XXX  diffs=missing
  ERROR head doesn't match snapshot: have XXX, want YYY

NewPruner now reads the persisted disk snapshot root via
rawdb.ReadSnapshotRoot and retries snapshot initialisation with that
root when the normal head-based init fails.  Prune() then uses the
disk root as the pruning target directly, bypassing the requirement
for 128 in-memory diff layers that cannot exist when the journal was
not written.

Normal flow (clean shutdown, journal present) is unchanged.

Made-with: Cursor

* pruner: fix Cap panic on disk-layer-only tree and add generation wait log

Two follow-up fixes to the journal-missing fallback (56ae344):

1. Skip snaptree.Cap(root, 0) when root is already the disk layer.
   Cap requires a diffLayer as its target; calling it on a disk-layer-only
   tree (which is exactly what the fallback produces) returns
   "snapshot is disk layer" and aborts after all the heavy bloom-filter
   and DB-sweep work is done. Guard with DiskRoot() != root.

2. Add log lines around the fallback snapshot.New() call to make it
   visible when snapshot generation must be resumed (async=false blocks
   until generation finishes, which can take hours for large state).

* pruner: rename diskRoot to snapDiskRoot to avoid confusion with diskStateRoot

---------

Co-authored-by: corey <corey.zhang@bitget.com>

* Revert "pruner: fall back to disk snapshot root when journal is missing (#300)" (#309)

This reverts commit b3c5552.

Co-authored-by: corey <corey.zhang@bitget.com>

* tracers: fix Morph fee-token tracing paths (#308)

* tracers: fix Morph fee-token tracing paths

Keep Morph fee-token system calls bracketed consistently, forward system-call hooks through mux tracers, and make traceCall precredit alt-fee balances so tracing matches execution more closely.

Constraint: Preserve user-visible tracer output while keeping prestate and traceCall behavior correct for Morph fee-token transactions
Confidence: medium
Scope-risk: moderate
Not-tested: Full eth/tracers/internal/tracetest suite still has pre-existing fixture and VM failures on this branch

* tracers: fix prestateTracer account discovery when DisableStorage is set

* tracers: harden Morph fee-token trace edge cases

Prevent flatCallTracer from touching hidden system-call frames and keep traceCall's synthetic fee-token precredits out of prestate views so debug RPCs stay stable and prestate output matches chain state.

Constraint: Preserve Morph alt-fee trace execution without leaking synthetic prestate or hidden system-call frames
Confidence: high
Scope-risk: moderate

* core: require balanced system-call trace hooks

Only bracket fee-token helper calls when both start and end hooks are present so partial tracer wiring cannot leak system-call depth across a trace.

Constraint: Preserve existing V2-over-legacy hook selection while restoring balanced start/end semantics
Confidence: high
Scope-risk: narrow
Not-tested: Full core package outside TestStartSystemCallTrace

* fix: handle nil parameter in morph_diskRoot RPC to prevent panic (#311)

When morph_diskRoot is called without parameters, blockNrOrHash is nil,
causing a nil pointer dereference crash. Default to latest block when
no parameter is provided, consistent with other eth RPC methods.

* pruner: use teeWriter and HEAD as prune target, fix genesis root validation (#310)

* pruner: use teeWriter and HEAD as prune target, fix genesis root validation

- Add teeWriter to persist trie nodes to disk during GenerateTrie, ensuring
  pruning works correctly even after unclean shutdowns.
- Use HEAD directly as the pruning target instead of HEAD-127, eliminating
  unnecessary height rollback on L2 chains where reorgs don't occur.
- Resolve genesis root via ReadDiskStateRoot in extractGenesis so that
  zkTrie roots (overridden via GenesisStateRoot) are correctly mapped to
  the actual MPT disk root.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* handle error

* remove accidentally committed local test zip

Keep local-test.zip untracked and out of repository history from this point.

Made-with: Cursor

* pruner: enforce genesis disk-root mapping

Treat missing or invalid disk-state-root mapping for genesis as an explicit error during pruning instead of silently falling back.

Made-with: Cursor

---------

Co-authored-by: corey <corey.zhang@bitget.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: fletcher.fan <fletcher.fan@bitget.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Segue <huoda.china@163.com>
Co-authored-by: corey <coreyx1992@gmail.com>
Co-authored-by: corey <corey.zhang@bitget.com>
Co-authored-by: panos <pan107104@outlook.com>
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