From c2c5c6bde6ec74f8eda0b21316d6c504fe743a4c Mon Sep 17 00:00:00 2001 From: Ribao Wei Date: Fri, 6 Dec 2019 17:20:32 -0800 Subject: [PATCH] Fix pending block index during startup. --- blockchain/chain.go | 9 +++++++++ consensus/engine.go | 8 ++++++++ netsync/request.go | 3 +++ 3 files changed, 20 insertions(+) diff --git a/blockchain/chain.go b/blockchain/chain.go index 8653e2e3..cdeda8cb 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -114,6 +114,15 @@ func (ch *Chain) addBlock(block *core.Block, isSnapshotRoot bool) (*core.Extende return extendedBlock, nil } +// FixBlockIndex fixes index for given block. +func (ch *Chain) FixBlockIndex(block *core.ExtendedBlock) { + ch.mu.Lock() + defer ch.mu.Unlock() + + ch.AddBlockByHeightIndex(block.Height, block.Hash()) + ch.AddTxsToIndex(block, false) +} + // blockByHeightIndexKey constructs the DB key for the given block height. func blockByHeightIndexKey(height uint64) common.Bytes { // convert uint64 to []byte diff --git a/consensus/engine.go b/consensus/engine.go index c001e890..c06c4e93 100644 --- a/consensus/engine.go +++ b/consensus/engine.go @@ -329,6 +329,14 @@ func (e *ConsensusEngine) validateBlock(block *core.Block, parent *core.Extended return result.Error("Block epoch must be greater than parent epoch") } if !parent.Status.IsValid() { + if parent.Status.IsPending() { + // Should never happen + e.logger.WithFields(log.Fields{ + "parent": block.Parent.Hex(), + "parent.status": parent.Status, + "block": block.Hash().Hex(), + }).Panic("Parent block is pending") + } e.logger.WithFields(log.Fields{ "parent": block.Parent.Hex(), "parent.status": parent.Status, diff --git a/netsync/request.go b/netsync/request.go index 957e308d..459f6ebb 100644 --- a/netsync/request.go +++ b/netsync/request.go @@ -661,6 +661,9 @@ func (rm *RequestManager) resumePendingBlocks() { block := queue[0] queue = queue[1:] if block.Status.IsPending() { + // In rare cases a block is saved but index is not yet saved before the process is + // killed. + rm.chain.FixBlockIndex(block) rm.addBlock(block.Block) } for _, hash := range block.Children {