Skip to content

Conversation

@calbera
Copy link
Collaborator

@calbera calbera commented Aug 9, 2025

PBSS Init Fix

The Problem

Running geth init multiple times on a PBSS database causes state history truncation errors. The truncation happens when the trie database is opened/initialized, BEFORE SetupGenesisBlockWithOverride is even called.

ethereum#25523 explains that for PBSS, the trie db has issues when being re-created.

Root Cause Timeline

  1. MakeChainDatabase - Opens the chain database
  2. MakeTrieDatabase - Creates trie database which triggers:
    • "Load database journal from disk"
    • State history truncation (PROBLEM OCCURS HERE)
  3. SetupGenesisBlockWithOverride - Too late to prevent the issue

The Solution

Check if genesis already exists BEFORE creating the trie database. This prevents the truncation from ever happening.

Code Changes

In cmd/bera-geth/chaincmd.go

	// Berachain: Check if genesis already exists for PBSS databases BEFORE opening trie database.
	// This prevents the state history truncation that happens during trie database initialization.
	var triedb *triedb.Database
	if rawdb.ReadStateScheme(chaindb) == rawdb.PathScheme &&
		rawdb.ReadChainConfig(chaindb, rawdb.ReadCanonicalHash(chaindb, 0)) != nil {
		log.Info("PBSS db already initialized with genesis, skipping trie db initialization")
	} else {
		// Only create triedb if we're not using PBSS or genesis is empty on disk. Refer to
		// https://github.com/ethereum/go-ethereum/pull/25523 for why the triedb cannot be
		// re-created when using PBSS.
		triedb = utils.MakeTrieDatabase(ctx, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsVerkle())
		defer triedb.Close()
	}

Why This Works

  1. Prevents Trie DB Creation: By returning early, we never call MakeTrieDatabase
  2. No Truncation: The problematic state history truncation never happens
  3. Truly Idempotent: The init command becomes a complete no-op for existing PBSS databases
  4. Clean Exit: Returns immediately without any database modifications

Testing

# First init - creates database normally
bera-geth init --datadir .tmp/eth-home genesis.json

# Second init - now completely skips, no truncation
bera-geth init --datadir .tmp/eth-home genesis.json
# Should see: "PBSS database already initialized with matching genesis, skipping init"
# Should NOT see any "Truncating freezer table" warnings

# Node starts without errors
bera-geth --datadir .tmp/eth-home
# No "out of range" errors!

Key Insight

The fix must happen at the command level (chaincmd.go), not in the genesis setup logic, because the damage is done when the trie database is opened, before any genesis logic runs.

Benefits

  • Complete Prevention: Truncation never happens on repeat init
  • Early Exit: Minimal resource usage
  • Clear Logging: Single log message shows init was skipped
  • Safe for Automation: Operators can safely run init multiple times

Note

This fix is specific to PBSS (state.scheme = path). Hash-based databases continue to work normally as they don't have the state history truncation issue.

References

@calbera calbera linked an issue Aug 9, 2025 that may be closed by this pull request
@calbera
Copy link
Collaborator Author

calbera commented Aug 9, 2025

TODO: Open upstream issue + fix PR

@calbera calbera merged commit 186b956 into main Aug 10, 2025
3 checks passed
@calbera calbera deleted the pbss-init-fix branch August 10, 2025 03:56
calbera added a commit that referenced this pull request Aug 10, 2025
* fix(pbss): idempotent init cmd if stored db

* rename + nits

* fix

* handles all cases

* remove docs

* comments

* nit

* fix and add unit tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Loading node with PBSS has issues upon repeat init commands

2 participants