Skip to content

Commit ef7e977

Browse files
authored
Merge pull request #2332 from CortexFoundation/dev
fix sync reset in pruned nodes
2 parents 912d8ac + 0ee6114 commit ef7e977

2 files changed

Lines changed: 47 additions & 15 deletions

File tree

core/blockchain.go

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,23 @@ func (bc *BlockChain) loadLastState() error {
486486
return bc.Reset()
487487
}
488488
// Make sure the entire head block is available
489-
currentBlock := bc.GetBlockByHash(head)
489+
currentHeader := bc.GetHeaderByHash(head)
490+
if currentHeader == nil {
491+
// Corrupt or empty database, init from scratch
492+
log.Warn("Head header missing, resetting chain", "hash", head)
493+
return bc.Reset()
494+
}
495+
496+
var currentBlock *types.Block
497+
if cmp := currentHeader.Number.Cmp(new(big.Int)); cmp == 1 {
498+
// Make sure the entire head block is available.
499+
currentBlock = bc.GetBlockByHash(head)
500+
} else if cmp == 0 {
501+
// On a pruned node the block body might not be available. But a pruned
502+
// block should never be the head block. The only exception is when, as
503+
// a last resort, chain is reset to genesis.
504+
currentBlock = bc.genesisBlock
505+
}
490506
if currentBlock == nil {
491507
// Corrupt or empty database, init from scratch
492508
log.Warn("Head block missing, resetting chain", "hash", head)
@@ -497,7 +513,6 @@ func (bc *BlockChain) loadLastState() error {
497513
headBlockGauge.Update(int64(currentBlock.NumberU64()))
498514

499515
// Restore the last known head header
500-
currentHeader := currentBlock.Header()
501516
if head := rawdb.ReadHeadHeaderHash(bc.db); head != (common.Hash{}) {
502517
if header := bc.GetHeaderByHash(head); header != nil {
503518
currentHeader = header
@@ -609,11 +624,13 @@ func (bc *BlockChain) SetHead(head uint64) error {
609624
}
610625
// Send chain head event to update the transaction pool
611626
if block := bc.CurrentBlock(); block == nil {
612-
// This should never happen. In practice, previously currentBlock
613-
// contained the entire block whereas now only a "marker", so there
614-
// is an ever so slight chance for a race we should handle.
615-
log.Error("Current block not found in database", "block", block.Number(), "hash", block.Hash())
616-
return fmt.Errorf("current block missing: #%d [%x..]", block.Number(), block.Hash().Bytes()[:4])
627+
if block.Number().Uint64() > 0 {
628+
// This should never happen. In practice, previously currentBlock
629+
// contained the entire block whereas now only a "marker", so there
630+
// is an ever so slight chance for a race we should handle.
631+
log.Error("Current block not found in database", "block", block.Number(), "hash", block.Hash())
632+
return fmt.Errorf("current block missing: #%d [%x..]", block.Number(), block.Hash().Bytes()[:4])
633+
}
617634
} else {
618635
bc.chainHeadFeed.Send(ChainHeadEvent{Header: block.Header()})
619636
}
@@ -630,11 +647,13 @@ func (bc *BlockChain) SetHeadWithTimestamp(timestamp uint64) error {
630647
}
631648
// Send chain head event to update the transaction pool
632649
if block := bc.CurrentBlock(); block == nil {
633-
// This should never happen. In practice, previously currentBlock
634-
// contained the entire block whereas now only a "marker", so there
635-
// is an ever so slight chance for a race we should handle.
636-
log.Error("Current block not found in database", "block", block.Number(), "hash", block.Hash())
637-
return fmt.Errorf("current block missing: #%d [%x..]", block.Number(), block.Hash().Bytes()[:4])
650+
if block.Number().Uint64() > 0 {
651+
// This should never happen. In practice, previously currentBlock
652+
// contained the entire block whereas now only a "marker", so there
653+
// is an ever so slight chance for a race we should handle.
654+
log.Error("Current block not found in database", "block", block.Number(), "hash", block.Hash())
655+
return fmt.Errorf("current block missing: #%d [%x..]", block.Number(), block.Hash().Bytes()[:4])
656+
}
638657
} else {
639658
bc.chainHeadFeed.Send(ChainHeadEvent{Header: block.Header()})
640659
}

core/txindexer.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,16 +196,29 @@ func (indexer *txIndexer) repair(head uint64) {
196196
}
197197
}
198198

199+
// resolveHead resolves the block number of the current chain head.
200+
func (indexer *txIndexer) resolveHead() uint64 {
201+
headBlockHash := rawdb.ReadHeadBlockHash(indexer.db)
202+
if headBlockHash == (common.Hash{}) {
203+
return 0
204+
}
205+
headBlockNumber := rawdb.ReadHeaderNumber(indexer.db, headBlockHash)
206+
if headBlockNumber == nil {
207+
return 0
208+
}
209+
return *headBlockNumber
210+
}
211+
199212
// loop is the scheduler of the indexer, assigning indexing/unindexing tasks depending
200213
// on the received chain event.
201214
func (indexer *txIndexer) loop(chain *BlockChain) {
202215
defer close(indexer.closed)
203216

204217
// Listening to chain events and manipulate the transaction indexes.
205218
var (
206-
stop chan struct{} // Non-nil if background routine is active
207-
done chan struct{} // Non-nil if background routine is active
208-
head = rawdb.ReadHeadBlock(indexer.db).NumberU64() // The latest announced chain head
219+
stop chan struct{} // Non-nil if background routine is active
220+
done chan struct{} // Non-nil if background routine is active
221+
head = indexer.resolveHead() // The latest announced chain head
209222

210223
headCh = make(chan ChainHeadEvent)
211224
sub = chain.SubscribeChainHeadEvent(headCh)

0 commit comments

Comments
 (0)