diff --git a/eth/stagedsync/stage_snapshots.go b/eth/stagedsync/stage_snapshots.go index f0774186b7d..bed540a60f6 100644 --- a/eth/stagedsync/stage_snapshots.go +++ b/eth/stagedsync/stage_snapshots.go @@ -334,7 +334,11 @@ func FillDBFromSnapshots(logPrefix string, ctx context.Context, tx kv.RwTx, dirs if err := blockReader.HeadersRange(ctx, func(header *types.Header) error { blockNum, blockHash := header.Number.Uint64(), header.Hash() td.Add(td, header.Difficulty) - + // What can happen if chaindata is deleted is that maybe header.seg progress is lower or higher than + // body.seg progress. In this case we need to skip the header, and "normalize" the progress to keep them in sync. + if blockNum > blocksAvailable { + return nil // This can actually happen as FrozenBlocks() is SegmentIdMax() and not the last .seg + } if err := rawdb.WriteTd(tx, blockHash, blockNum, td); err != nil { return err } @@ -393,6 +397,11 @@ func FillDBFromSnapshots(logPrefix string, ctx context.Context, tx kv.RwTx, dirs panic(baseTxNum + txAmount) //uint-underflow } maxTxNum := baseTxNum + txAmount - 1 + // What can happen if chaindata is deleted is that maybe header.seg progress is lower or higher than + // body.seg progress. In this case we need to skip the header, and "normalize" the progress to keep them in sync. + if blockNum > blocksAvailable { + return nil // This can actually happen as FrozenBlocks() is SegmentIdMax() and not the last .seg + } if err := rawdbv3.TxNums.Append(tx, blockNum, maxTxNum); err != nil { return fmt.Errorf("%w. blockNum=%d, maxTxNum=%d", err, blockNum, maxTxNum) diff --git a/turbo/execution/eth1/forkchoice.go b/turbo/execution/eth1/forkchoice.go index 2cfff407332..36a83b618ba 100644 --- a/turbo/execution/eth1/forkchoice.go +++ b/turbo/execution/eth1/forkchoice.go @@ -135,6 +135,7 @@ func (e *EthereumExecutionModule) updateForkChoice(ctx context.Context, original if err := stages2.ProcessFrozenBlocks(ctx, e.db, e.blockReader, e.executionPipeline); err != nil { sendForkchoiceErrorWithoutWaiting(outcomeCh, err) + e.logger.Warn("ProcessFrozenBlocks", "error", err) return } @@ -196,7 +197,7 @@ func (e *EthereumExecutionModule) updateForkChoice(ctx context.Context, original log.Info("[sync] limited big jump", "from", finishProgressBefore, "amount", uint64(e.syncCfg.LoopBlockLimit)) } - canonicalHash, err := e.blockReader.CanonicalHash(ctx, tx, fcuHeader.Number.Uint64()) + canonicalHash, err := rawdb.ReadCanonicalHash(tx, fcuHeader.Number.Uint64()) if err != nil { sendForkchoiceErrorWithoutWaiting(outcomeCh, err) return @@ -334,7 +335,6 @@ func (e *EthereumExecutionModule) updateForkChoice(ctx context.Context, original return } } - if len(newCanonicals) > 0 { if err := rawdbv3.TxNums.Truncate(tx, newCanonicals[0].number); err != nil { sendForkchoiceErrorWithoutWaiting(outcomeCh, err) @@ -347,6 +347,10 @@ func (e *EthereumExecutionModule) updateForkChoice(ctx context.Context, original } } if isDomainAheadOfBlocks(tx) { + if err := tx.Commit(); err != nil { + sendForkchoiceErrorWithoutWaiting(outcomeCh, err) + return + } sendForkchoiceReceiptWithoutWaiting(outcomeCh, &execution.ForkChoiceReceipt{ LatestValidHash: gointerfaces.ConvertHashToH256(common.Hash{}), Status: execution.ExecutionStatus_TooFarAway, @@ -383,6 +387,7 @@ func (e *EthereumExecutionModule) updateForkChoice(ctx context.Context, original initialCycle := limitedBigJump if _, err := e.executionPipeline.Run(e.db, wrap.TxContainer{Tx: tx}, initialCycle); err != nil { err = fmt.Errorf("updateForkChoice: %w", err) + e.logger.Warn("Cannot update chain head", "hash", blockHash, "err", err) sendForkchoiceErrorWithoutWaiting(outcomeCh, err) return }