|
|
|
@ -51,6 +51,7 @@ var ( |
|
|
|
|
headHeaderGauge = metrics.NewRegisteredGauge("chain/head/header", nil) |
|
|
|
|
headFastBlockGauge = metrics.NewRegisteredGauge("chain/head/receipt", nil) |
|
|
|
|
headFinalizedBlockGauge = metrics.NewRegisteredGauge("chain/head/finalized", nil) |
|
|
|
|
headSafeBlockGauge = metrics.NewRegisteredGauge("chain/head/safe", nil) |
|
|
|
|
|
|
|
|
|
accountReadTimer = metrics.NewRegisteredTimer("chain/account/reads", nil) |
|
|
|
|
accountHashTimer = metrics.NewRegisteredTimer("chain/account/hashes", nil) |
|
|
|
@ -191,6 +192,7 @@ type BlockChain struct { |
|
|
|
|
currentBlock atomic.Value // Current head of the block chain
|
|
|
|
|
currentFastBlock atomic.Value // Current head of the fast-sync chain (may be above the block chain!)
|
|
|
|
|
currentFinalizedBlock atomic.Value // Current finalized head
|
|
|
|
|
currentSafeBlock atomic.Value // Current safe head
|
|
|
|
|
|
|
|
|
|
stateCache state.Database // State database to reuse between imports (contains state cache)
|
|
|
|
|
bodyCache *lru.Cache // Cache for the most recent block bodies
|
|
|
|
@ -267,6 +269,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par |
|
|
|
|
bc.currentBlock.Store(nilBlock) |
|
|
|
|
bc.currentFastBlock.Store(nilBlock) |
|
|
|
|
bc.currentFinalizedBlock.Store(nilBlock) |
|
|
|
|
bc.currentSafeBlock.Store(nilBlock) |
|
|
|
|
|
|
|
|
|
// Initialize the chain with ancient data if it isn't empty.
|
|
|
|
|
var txIndexBlock uint64 |
|
|
|
@ -464,11 +467,15 @@ func (bc *BlockChain) loadLastState() error { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Restore the last known finalized block
|
|
|
|
|
// Restore the last known finalized block and safe block
|
|
|
|
|
// Note: the safe block is not stored on disk and it is set to the last
|
|
|
|
|
// known finalized block on startup
|
|
|
|
|
if head := rawdb.ReadFinalizedBlockHash(bc.db); head != (common.Hash{}) { |
|
|
|
|
if block := bc.GetBlockByHash(head); block != nil { |
|
|
|
|
bc.currentFinalizedBlock.Store(block) |
|
|
|
|
headFinalizedBlockGauge.Update(int64(block.NumberU64())) |
|
|
|
|
bc.currentSafeBlock.Store(block) |
|
|
|
|
headSafeBlockGauge.Update(int64(block.NumberU64())) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// Issue a status log for the user
|
|
|
|
@ -504,8 +511,23 @@ func (bc *BlockChain) SetHead(head uint64) error { |
|
|
|
|
// SetFinalized sets the finalized block.
|
|
|
|
|
func (bc *BlockChain) SetFinalized(block *types.Block) { |
|
|
|
|
bc.currentFinalizedBlock.Store(block) |
|
|
|
|
rawdb.WriteFinalizedBlockHash(bc.db, block.Hash()) |
|
|
|
|
headFinalizedBlockGauge.Update(int64(block.NumberU64())) |
|
|
|
|
if block != nil { |
|
|
|
|
rawdb.WriteFinalizedBlockHash(bc.db, block.Hash()) |
|
|
|
|
headFinalizedBlockGauge.Update(int64(block.NumberU64())) |
|
|
|
|
} else { |
|
|
|
|
rawdb.WriteFinalizedBlockHash(bc.db, common.Hash{}) |
|
|
|
|
headFinalizedBlockGauge.Update(0) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// SetSafe sets the safe block.
|
|
|
|
|
func (bc *BlockChain) SetSafe(block *types.Block) { |
|
|
|
|
bc.currentSafeBlock.Store(block) |
|
|
|
|
if block != nil { |
|
|
|
|
headSafeBlockGauge.Update(int64(block.NumberU64())) |
|
|
|
|
} else { |
|
|
|
|
headSafeBlockGauge.Update(0) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// setHeadBeyondRoot rewinds the local chain to a new head with the extra condition
|
|
|
|
@ -663,6 +685,16 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, root common.Hash, repair bo |
|
|
|
|
bc.txLookupCache.Purge() |
|
|
|
|
bc.futureBlocks.Purge() |
|
|
|
|
|
|
|
|
|
// Clear safe block, finalized block if needed
|
|
|
|
|
if safe := bc.CurrentSafeBlock(); safe != nil && head < safe.NumberU64() { |
|
|
|
|
log.Warn("SetHead invalidated safe block") |
|
|
|
|
bc.SetSafe(nil) |
|
|
|
|
} |
|
|
|
|
if finalized := bc.CurrentFinalizedBlock(); finalized != nil && head < finalized.NumberU64() { |
|
|
|
|
log.Error("SetHead invalidated finalized block") |
|
|
|
|
bc.SetFinalized(nil) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return rootNumber, bc.loadLastState() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|