Skip to content

Commit 7ec3a2b

Browse files
authored
freezeblocks, eth1: fix block retirement timing and prune backlog detection (#92)
1 parent 3e3ef3e commit 7ec3a2b

File tree

3 files changed

+118
-4
lines changed

3 files changed

+118
-4
lines changed

db/snapshotsync/freezeblocks/block_snapshots.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ func (br *BlockRetire) RetireBlocks(ctx context.Context, requestedMinBlockNum ui
455455
}
456456
includeBor := br.chainConfig.Bor != nil
457457

458-
if includeBor && time.Now().After(br.borDataNotReadyBefore) {
458+
if includeBor && time.Now().Before(br.borDataNotReadyBefore) {
459459
return nil
460460
}
461461

execution/eth1/forkchoice.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ import (
4646

4747
const startPruneFrom = 1024
4848

49+
// Track prune mode for logging only on transitions
50+
var lastPruneModeAggressive bool
51+
4952
type forkchoiceOutcome struct {
5053
receipt *executionproto.ForkChoiceReceipt
5154
err error
@@ -446,10 +449,48 @@ func (e *EthereumExecutionModule) updateForkChoice(ctx context.Context, original
446449
}
447450
}
448451
// Run the forkchoice
452+
// initialCycle enables aggressive prune rate (10K blocks vs 10 blocks per cycle).
453+
// Enable if: big jump OR too many blocks in mdbx need retirement/pruning.
449454
initialCycle := limitedBigJump
455+
initialCycleReason := ""
456+
if limitedBigJump {
457+
initialCycleReason = "bigJump"
458+
}
459+
460+
// Always calculate blocksInDB for logging
461+
chainTip := fcuHeader.Number.Uint64()
462+
frozenBlocks := e.blockReader.FrozenBlocks()
463+
firstBlockInDB, ok, _ := rawdb.ReadFirstNonGenesisHeaderNumber(tx)
464+
var blocksInDB uint64
465+
if ok && firstBlockInDB > 0 && chainTip > firstBlockInDB {
466+
blocksInDB = chainTip - firstBlockInDB
467+
}
468+
469+
if !initialCycle && blocksInDB > 5_000 {
470+
initialCycle = true
471+
initialCycleReason = "backlog"
472+
}
473+
474+
// Log only on mode transitions
475+
if initialCycle != lastPruneModeAggressive {
476+
lastPruneModeAggressive = initialCycle
477+
if initialCycle {
478+
e.logger.Info("[forkchoice] backlog prune: on",
479+
"reason", initialCycleReason,
480+
"blocksInDB", blocksInDB,
481+
"frozenBlocks", frozenBlocks)
482+
} else {
483+
e.logger.Info("[forkchoice] backlog prune: off",
484+
"blocksInDB", blocksInDB,
485+
"frozenBlocks", frozenBlocks)
486+
}
487+
}
488+
450489
firstCycle := false
490+
loopIter := 0
451491
for {
452492
hasMore, err := e.executionPipeline.Run(e.db, wrap.NewTxContainer(tx, nil), initialCycle, firstCycle)
493+
loopIter++
453494
if err != nil {
454495
err = fmt.Errorf("updateForkChoice: %w", err)
455496
e.logger.Warn("Cannot update chain head", "hash", blockHash, "err", err)
@@ -465,8 +506,10 @@ func (e *EthereumExecutionModule) updateForkChoice(ctx context.Context, original
465506
return
466507
}
467508
if !hasMore {
509+
e.logger.Debug("[forkchoice] execution loop done", "iterations", loopIter)
468510
break
469511
}
512+
e.logger.Debug("[forkchoice] RunPrune in loop", "iteration", loopIter, "initialCycle", initialCycle)
470513
err = e.executionPipeline.RunPrune(e.db, tx, initialCycle)
471514
if err != nil {
472515
err = fmt.Errorf("updateForkChoice: RunPrune after hasMore: %w", err)

execution/stagedsync/stage_snapshots.go

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import (
3838
"github.com/erigontech/erigon/db/kv/prune"
3939
"github.com/erigontech/erigon/db/kv/rawdbv3"
4040
"github.com/erigontech/erigon/db/kv/temporal"
41+
"github.com/erigontech/erigon/db/rawdb"
4142
"github.com/erigontech/erigon/db/snapshotsync"
4243
"github.com/erigontech/erigon/db/snapshotsync/freezeblocks"
4344
"github.com/erigontech/erigon/db/snaptype"
@@ -54,6 +55,10 @@ import (
5455
"github.com/erigontech/erigon/turbo/silkworm"
5556
)
5657

58+
// Track mode for logging only on transitions
59+
var lastRetireMode string
60+
var lastPruneMode string
61+
5762
type SnapshotsCfg struct {
5863
db kv.TemporalRwDB
5964
chainConfig *chain.Config
@@ -393,10 +398,42 @@ func SnapshotsPrune(s *PruneState, cfg SnapshotsCfg, ctx context.Context, tx kv.
393398

394399
var minBlockNumber uint64
395400

401+
// Calculate blocksInDB to detect backlog needing aggressive retirement
402+
var blocksInDB uint64
403+
chainTip, err := stages.GetStageProgress(tx, stages.Execution)
404+
if err == nil && chainTip > 0 {
405+
firstBlockInDB, ok, _ := rawdb.ReadFirstNonGenesisHeaderNumber(tx)
406+
if ok && firstBlockInDB > 0 && chainTip > firstBlockInDB {
407+
blocksInDB = chainTip - firstBlockInDB
408+
}
409+
}
410+
frozenBlocks := cfg.blockReader.FrozenBlocks()
411+
412+
// Use aggressive workers when backlog exists, not just during initial sync
413+
retireWorkers := 1
414+
retireMode := "normal"
396415
if s.CurrentSyncCycle.IsInitialCycle {
397-
cfg.blockRetire.SetWorkers(estimate.CompressSnapshot.Workers())
398-
} else {
399-
cfg.blockRetire.SetWorkers(1)
416+
retireWorkers = estimate.CompressSnapshot.Workers()
417+
retireMode = "initialCycle"
418+
} else if blocksInDB > 5_000 {
419+
retireWorkers = estimate.CompressSnapshot.Workers()
420+
retireMode = "backlog"
421+
}
422+
cfg.blockRetire.SetWorkers(retireWorkers)
423+
424+
// Log only on mode transitions
425+
if retireMode != lastRetireMode {
426+
lastRetireMode = retireMode
427+
if retireMode == "backlog" {
428+
logger.Info("[OtterSync] retire backlog: on",
429+
"workers", retireWorkers,
430+
"blocksInDB", blocksInDB,
431+
"frozenBlocks", frozenBlocks)
432+
} else if retireMode == "normal" {
433+
logger.Info("[OtterSync] retire backlog: off",
434+
"blocksInDB", blocksInDB,
435+
"frozenBlocks", frozenBlocks)
436+
}
400437
}
401438

402439
noDl := cfg.snapshotDownloader == nil || reflect.ValueOf(cfg.snapshotDownloader).IsNil()
@@ -438,10 +475,44 @@ func SnapshotsPrune(s *PruneState, cfg SnapshotsCfg, ctx context.Context, tx kv.
438475

439476
pruneLimit := 10
440477
pruneTimeout := 125 * time.Millisecond
478+
pruneMode := "normal"
479+
var pruneBlocksInDB uint64
480+
441481
if s.CurrentSyncCycle.IsInitialCycle {
442482
pruneLimit = 10_000
443483
pruneTimeout = time.Hour
484+
pruneMode = "initialCycle"
485+
} else {
486+
// Check for backlog even when not initial cycle
487+
chainTip, _ := stages.GetStageProgress(tx, stages.Execution)
488+
firstBlockInDB, ok, _ := rawdb.ReadFirstNonGenesisHeaderNumber(tx)
489+
if ok && firstBlockInDB > 0 && chainTip > firstBlockInDB {
490+
pruneBlocksInDB = chainTip - firstBlockInDB
491+
if pruneBlocksInDB > 5_000 {
492+
pruneLimit = 10_000
493+
pruneTimeout = time.Hour
494+
pruneMode = "aggressive"
495+
} else if pruneBlocksInDB > 2_500 {
496+
pruneLimit = 1_000
497+
pruneTimeout = 10 * time.Minute
498+
pruneMode = "medium"
499+
}
500+
}
501+
}
502+
503+
// Log only on mode transitions
504+
if pruneMode != lastPruneMode {
505+
prevMode := lastPruneMode
506+
lastPruneMode = pruneMode
507+
if pruneMode == "aggressive" {
508+
logger.Info("[OtterSync] prune backlog: aggressive", "limit", pruneLimit, "blocksInDB", pruneBlocksInDB)
509+
} else if pruneMode == "medium" {
510+
logger.Info("[OtterSync] prune backlog: medium", "limit", pruneLimit, "blocksInDB", pruneBlocksInDB)
511+
} else if pruneMode == "normal" && (prevMode == "aggressive" || prevMode == "medium") {
512+
logger.Info("[OtterSync] prune backlog: off", "blocksInDB", pruneBlocksInDB)
513+
}
444514
}
515+
445516
if _, err := cfg.blockRetire.PruneAncientBlocks(tx, pruneLimit, pruneTimeout); err != nil {
446517
return err
447518
}

0 commit comments

Comments
 (0)