core,chainstats: implement setting chainstats

This commit is contained in:
Martin Holst Swende 2018-01-27 12:29:52 +01:00
parent 70fbc87379
commit 88202c656f
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0
2 changed files with 88 additions and 1 deletions

View file

@ -0,0 +1,61 @@
// Copyright 2018 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
// Package chainstats implements some chain utilities for sync-free blockchain info lookup
package chainstats
import (
"github.com/ethereum/go-ethereum/core/types"
"math/big"
"sync/atomic"
)
type Chainstats struct {
currentBlockNumber atomic.Value
currentFastBlockNumber atomic.Value
currentTd atomic.Value
currentFastTd atomic.Value
}
func NewChainstats() *Chainstats {
return &Chainstats{}
}
func (stats *Chainstats) GetNumber() uint64 {
return stats.currentBlockNumber.Load().(*big.Int).Uint64()
}
func (stats *Chainstats) UpdateNumbers(currentBlock, currentFastBlock *types.Block) {
stats.currentBlockNumber.Store(currentBlock.Number())
stats.currentFastBlockNumber.Store(currentFastBlock.Number())
}
func (stats *Chainstats) SetNumber(number *big.Int) {
stats.currentBlockNumber.Store(number)
}
func (stats *Chainstats) GetFastNumber() uint64 {
return stats.currentFastBlockNumber.Load().(*big.Int).Uint64()
}
func (stats *Chainstats) SetFastNumber(number *big.Int) {
stats.currentFastBlockNumber.Store(number)
}
func (stats *Chainstats) GetTotalDifficulty() *big.Int {
return new(big.Int).Set(stats.currentTd.Load().(*big.Int))
}
func (stats *Chainstats) SetTotalDifficulty(newTd *big.Int) {
stats.currentTd.Store(newTd)
}
func (stats *Chainstats) SetTotalFastDifficulty(newTd *big.Int) {
stats.currentFastTd.Store(newTd)
}

View file

@ -28,6 +28,7 @@ import (
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/chainstats"
"github.com/ethereum/go-ethereum/common/mclock"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/core/state"
@ -127,7 +128,8 @@ type BlockChain struct {
validator Validator // block and state validator interface
vmConfig vm.Config
badBlocks *lru.Cache // Bad block cache
badBlocks *lru.Cache // Bad block cache
chainStats *chainstats.Chainstats // Mutex-free lookups of chain stats
}
// NewBlockChain returns a fully initialised block chain using information
@ -160,6 +162,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
engine: engine,
vmConfig: vmConfig,
badBlocks: badBlocks,
chainStats: chainstats.NewChainstats(),
}
bc.SetValidator(NewBlockValidator(chainConfig, bc, engine))
bc.SetProcessor(NewStateProcessor(chainConfig, bc, engine))
@ -248,6 +251,10 @@ func (bc *BlockChain) loadLastState() error {
blockTd := bc.GetTd(bc.currentBlock.Hash(), bc.currentBlock.NumberU64())
fastTd := bc.GetTd(bc.currentFastBlock.Hash(), bc.currentFastBlock.NumberU64())
bc.chainStats.SetTotalDifficulty(blockTd)
bc.chainStats.SetTotalFastDifficulty(fastTd)
bc.chainStats.UpdateNumbers(bc.currentBlock, bc.currentFastBlock)
log.Info("Loaded most recent local header", "number", currentHeader.Number, "hash", currentHeader.Hash(), "td", headerTd)
log.Info("Loaded most recent local full block", "number", bc.currentBlock.Number(), "hash", bc.currentBlock.Hash(), "td", blockTd)
log.Info("Loaded most recent local fast block", "number", bc.currentFastBlock.Number(), "hash", bc.currentFastBlock.Hash(), "td", fastTd)
@ -305,6 +312,11 @@ func (bc *BlockChain) SetHead(head uint64) error {
if err := WriteHeadFastBlockHash(bc.db, bc.currentFastBlock.Hash()); err != nil {
log.Crit("Failed to reset head fast block", "err", err)
}
bc.chainStats.UpdateNumbers(bc.currentBlock, bc.currentFastBlock)
bc.chainStats.SetTotalDifficulty(bc.GetTd(bc.currentBlock.Hash(), bc.currentBlock.NumberU64()))
bc.chainStats.SetTotalFastDifficulty(bc.GetTd(bc.currentFastBlock.Hash(), bc.currentFastBlock.NumberU64()))
return bc.loadLastState()
}
@ -322,6 +334,8 @@ func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error {
// If all checks out, manually set the head block
bc.mu.Lock()
bc.currentBlock = block
bc.chainStats.SetNumber(block.Number())
bc.chainStats.SetTotalDifficulty(bc.GetTd(block.Hash(), block.NumberU64()))
bc.mu.Unlock()
log.Info("Committed new head block", "number", block.Number(), "hash", hash)
@ -421,6 +435,10 @@ func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error {
bc.hc.SetCurrentHeader(bc.genesisBlock.Header())
bc.currentFastBlock = bc.genesisBlock
bc.chainStats.UpdateNumbers(bc.currentBlock, bc.currentFastBlock)
bc.chainStats.SetTotalDifficulty(bc.genesisBlock.Difficulty())
bc.chainStats.SetTotalFastDifficulty(bc.genesisBlock.Difficulty())
return nil
}
@ -499,6 +517,9 @@ func (bc *BlockChain) insert(block *types.Block) {
}
bc.currentFastBlock = block
}
bc.chainStats.UpdateNumbers(bc.currentBlock, bc.currentFastBlock)
bc.chainStats.SetTotalDifficulty(bc.GetTd(block.Hash(), block.NumberU64()))
bc.chainStats.SetTotalFastDifficulty(bc.GetTd(bc.currentFastBlock.Hash(), bc.currentFastBlock.NumberU64()))
}
// Genesis retrieves the chain's genesis block.
@ -724,6 +745,9 @@ func (bc *BlockChain) Rollback(chain []common.Hash) {
WriteHeadBlockHash(bc.db, bc.currentBlock.Hash())
}
}
bc.chainStats.UpdateNumbers(bc.currentBlock, bc.currentFastBlock)
bc.chainStats.SetTotalDifficulty(bc.GetTd(bc.currentBlock.Hash(), bc.currentBlock.NumberU64()))
bc.chainStats.SetTotalFastDifficulty(bc.GetTd(bc.currentFastBlock.Hash(), bc.currentFastBlock.NumberU64()))
}
// SetReceiptsData computes all the non-consensus fields of the receipts
@ -835,6 +859,8 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
log.Crit("Failed to update head fast block hash", "err", err)
}
bc.currentFastBlock = head
bc.chainStats.SetFastNumber(bc.currentFastBlock.Number())
bc.chainStats.SetTotalFastDifficulty(td)
}
}
bc.mu.Unlock()