From 4cd7b3ba6cb7d805e8e91e0503755239bb34c431 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Sun, 8 Feb 2026 15:07:26 +0100 Subject: [PATCH] core, eth: disable pathdb snapshot generation for partial state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Geth has two independent snapshot tiers, each with its own disable mechanism: 1. In-memory snapshot cache: controlled by SnapshotLimit (derived from ethconfig.SnapshotCache). Setting SnapshotCache=0 disables it. 2. On-disk snapshot generator: a background goroutine in pathdb that iterates the entire state trie to build flat key-value snapshots. Controlled by pathdb.Config.SnapshotNoBuild. The partial state configuration (cmd/utils/flags.go) already set SnapshotCache=0 to disable the in-memory cache. However, SnapshotNoBuild was never set, so pathdb.Enable() — called after snap sync completes — still launched the background generator goroutine. This generator immediately hits missing storage tries for untracked contracts (whose storage was intentionally skipped during partial sync), logs "Trie missing, snapshotting paused", and blocks forever on its abort channel — a permanent goroutine leak with no recovery path. Additionally, BlockChainConfig.SnapshotNoBuild was never propagated to pathdb.Config.SnapshotNoBuild in the triedbConfig() conversion. The field only reached the hash-scheme snapshot module (core/blockchain.go setupSnapshot), which is already skipped for path-scheme databases. This plumbing gap meant pathdb.Config.SnapshotNoBuild was never set in production code — only in tests. Fix both issues: - Set SnapshotNoBuild=true when partial state is enabled - Propagate BlockChainConfig.SnapshotNoBuild into pathdb.Config --- core/blockchain.go | 3 ++- eth/backend.go | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/core/blockchain.go b/core/blockchain.go index 5b574b9a33..e1a09943a9 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -314,7 +314,8 @@ func (cfg *BlockChainConfig) triedbConfig(isVerkle bool) *triedb.Config { FullValueCheckpoint: cfg.NodeFullValueCheckpoint, // Testing configurations - NoAsyncFlush: cfg.TrieNoAsyncFlush, + NoAsyncFlush: cfg.TrieNoAsyncFlush, + SnapshotNoBuild: cfg.SnapshotNoBuild, } } return config diff --git a/eth/backend.go b/eth/backend.go index 516227695d..57e722e044 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -290,6 +290,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { options.PartialStateContracts = config.PartialState.Contracts options.PartialStateBALRetention = config.PartialState.BALRetention options.PartialStateChainRetention = config.PartialState.ChainRetention + options.SnapshotNoBuild = true } eth.blockchain, err = core.NewBlockChain(chainDb, config.Genesis, eth.engine, options)