From 43cc92e68ae0da69b2463a539e6cd8bb8c6e75fb Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Wed, 1 Apr 2026 15:40:46 +0000 Subject: [PATCH] dont do runtime pruning --- core/blockchain.go | 26 ++++++++++----------- core/history_pruner_test.go | 45 ++++++++++++++++++++++--------------- 2 files changed, 39 insertions(+), 32 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 913a408e89..025107cc52 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -764,22 +764,20 @@ func (bc *BlockChain) initializeHistoryPruning(latest uint64) error { log.Error("Database pruned beyond configured history mode", "tail", freezerTail, "target", target, "mode", policy.Mode) return fmt.Errorf("database pruned beyond requested history (tail=%d, target=%d)", freezerTail, target) } - // Need to prune (freezerTail < target). Ensure the target is frozen. - if latest < target+params.FullImmutabilityThreshold { - return fmt.Errorf("chain not far enough past target block %d, need %d more blocks", - target, target+params.FullImmutabilityThreshold-latest) - } - // For static prune points, verify the canonical hash matches. - if policy.Target != nil { - hash := bc.GetCanonicalHash(target) - if hash != policy.Target.BlockHash { - return fmt.Errorf("target block hash mismatch at block %d: got %s, want %s", target, hash.Hex(), policy.Target.BlockHash.Hex()) + // Need to prune (freezerTail < target). + switch policy.Mode { + case history.KeepPostMerge, history.KeepPostPrague: + // Static modes require the user to run 'geth prune-history' offline + // rather than blocking startup for hours (tx index pruning is slow). + return fmt.Errorf("history not pruned to target block %d (current tail %d), run 'geth prune-history --history.chain=%s' first", target, freezerTail, policy.Mode) + + case history.KeepRecent: + // The rolling pruner will gradually catch up in the background. + if freezerTail > 0 { + bc.updateHistoryPrunePoint(freezerTail) } + log.Warn("Chain history is behind pruning target, rolling pruner will catch up", "tail", freezerTail, "target", target) } - if err := bc.pruneChainHistory(target); err != nil { - return fmt.Errorf("failed to prune chain history: %w", err) - } - log.Info("Pruned chain history at startup", "from", freezerTail, "to", target) return nil } diff --git a/core/history_pruner_test.go b/core/history_pruner_test.go index eaeee06eb8..c9bfd3bbd7 100644 --- a/core/history_pruner_test.go +++ b/core/history_pruner_test.go @@ -156,36 +156,45 @@ func TestPruneChainHistory(t *testing.T) { } } -func TestInitHistoryPruningStartupPrune(t *testing.T) { - if testing.Short() { - t.Skip("skipping slow test") - } - db, gspec, blocks := newTestChain(t, 91000) +func TestInitHistoryPruningStaticModeRequiresPruneHistory(t *testing.T) { + db, gspec, blocks := newTestChain(t, 200) defer db.Close() - // Reopen with a static target at block 500. The chain is long enough - // (91000 >= 500 + 90000) so initializeHistoryPruning should prune. + // Reopen with a static target at block 50. The database is not yet + // pruned to that target, so startup should fail and tell the user to + // run 'geth prune-history'. policy := history.HistoryPolicy{ Mode: history.KeepPostMerge, Target: &history.PrunePoint{ - BlockNumber: 500, - BlockHash: blocks[499].Hash(), + BlockNumber: 50, + BlockHash: blocks[49].Hash(), }, } + _, err := reopenChain(db, gspec, policy) + if err == nil { + t.Fatal("expected error when history not pruned to static target, got nil") + } + + // Freezer tail should remain at 0 — no pruning happened. + tail, _ := db.Tail() + if tail != 0 { + t.Errorf("freezer tail: got %d, want 0 (startup should not prune)", tail) + } +} + +func TestInitHistoryPruningKeepRecentAllowsStartup(t *testing.T) { + db, gspec, _ := newTestChain(t, 200) + defer db.Close() + + // Reopen with KeepRecent and a small window. The tail (0) is behind the + // target but KeepRecent should still allow startup — the rolling pruner + // handles catch-up in the background. + policy := history.HistoryPolicy{Mode: history.KeepRecent, Window: 50} chain, err := reopenChain(db, gspec, policy) if err != nil { t.Fatalf("unexpected error: %v", err) } defer chain.Stop() - - tail, _ := db.Tail() - if tail != 500 { - t.Errorf("freezer tail: got %d, want 500", tail) - } - cutoff, _ := chain.HistoryPruningCutoff() - if cutoff != 500 { - t.Errorf("prune cutoff: got %d, want 500", cutoff) - } } func TestInitHistoryPruningStaticModeBeyondTarget(t *testing.T) {