mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 18:02:24 +00:00
Merge f10832685c into ae9f97221a
This commit is contained in:
commit
3c519a44f3
6 changed files with 155 additions and 20 deletions
83
common/chainstats/chainstats.go
Normal file
83
common/chainstats/chainstats.go
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
// 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 (
|
||||||
|
"math/big"
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Chainstats struct {
|
||||||
|
currentBlockNumber uint64
|
||||||
|
currentFastBlockNumber uint64
|
||||||
|
currentTd atomic.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewChainstats() *Chainstats {
|
||||||
|
stats := &Chainstats{}
|
||||||
|
stats.currentTd.Store(big.NewInt(0))
|
||||||
|
return stats
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetNumber returns the latest block number
|
||||||
|
func (stats *Chainstats) GetNumber() uint64 {
|
||||||
|
return stats.currentBlockNumber
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update is a convenience method to set all values
|
||||||
|
func (stats *Chainstats) Update(currentBlock, currentFastBlock *types.Block, totalDifficulty *big.Int) {
|
||||||
|
stats.SetNumber(currentBlock.NumberU64())
|
||||||
|
stats.SetFastNumber(currentFastBlock.NumberU64())
|
||||||
|
stats.SetTotalDifficulty(totalDifficulty)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetNumbers convenience-method to get all values
|
||||||
|
func (stats *Chainstats) Get() (uint64, uint64, *big.Int) {
|
||||||
|
return stats.currentBlockNumber,
|
||||||
|
stats.currentFastBlockNumber,
|
||||||
|
new(big.Int).Set(stats.currentTd.Load().(*big.Int))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNumber stores latest block number
|
||||||
|
func (stats *Chainstats) SetNumber(number uint64) {
|
||||||
|
atomic.StoreUint64(&stats.currentBlockNumber, number)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFastNumber return latest fast block number
|
||||||
|
func (stats *Chainstats) GetFastNumber() uint64 {
|
||||||
|
return stats.currentFastBlockNumber
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetFastNumber stores latest fast block number
|
||||||
|
func (stats *Chainstats) SetFastNumber(number uint64) {
|
||||||
|
atomic.StoreUint64(&stats.currentFastBlockNumber, number)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTotalDifficulty return latest total difficulty
|
||||||
|
func (stats *Chainstats) GetTotalDifficulty() *big.Int {
|
||||||
|
return new(big.Int).Set(stats.currentTd.Load().(*big.Int))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTotalDifficulty sets latest total difficulty
|
||||||
|
func (stats *Chainstats) SetTotalDifficulty(newTd *big.Int) {
|
||||||
|
stats.currentTd.Store(newTd)
|
||||||
|
}
|
||||||
|
|
@ -28,6 +28,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"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/common/mclock"
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
|
|
@ -127,7 +128,8 @@ type BlockChain struct {
|
||||||
validator Validator // block and state validator interface
|
validator Validator // block and state validator interface
|
||||||
vmConfig vm.Config
|
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
|
// NewBlockChain returns a fully initialised block chain using information
|
||||||
|
|
@ -160,6 +162,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
|
||||||
engine: engine,
|
engine: engine,
|
||||||
vmConfig: vmConfig,
|
vmConfig: vmConfig,
|
||||||
badBlocks: badBlocks,
|
badBlocks: badBlocks,
|
||||||
|
chainStats: chainstats.NewChainstats(),
|
||||||
}
|
}
|
||||||
bc.SetValidator(NewBlockValidator(chainConfig, bc, engine))
|
bc.SetValidator(NewBlockValidator(chainConfig, bc, engine))
|
||||||
bc.SetProcessor(NewStateProcessor(chainConfig, bc, engine))
|
bc.SetProcessor(NewStateProcessor(chainConfig, bc, engine))
|
||||||
|
|
@ -248,6 +251,8 @@ func (bc *BlockChain) loadLastState() error {
|
||||||
blockTd := bc.GetTd(bc.currentBlock.Hash(), bc.currentBlock.NumberU64())
|
blockTd := bc.GetTd(bc.currentBlock.Hash(), bc.currentBlock.NumberU64())
|
||||||
fastTd := bc.GetTd(bc.currentFastBlock.Hash(), bc.currentFastBlock.NumberU64())
|
fastTd := bc.GetTd(bc.currentFastBlock.Hash(), bc.currentFastBlock.NumberU64())
|
||||||
|
|
||||||
|
bc.chainStats.Update(bc.currentBlock, bc.currentFastBlock, blockTd)
|
||||||
|
|
||||||
log.Info("Loaded most recent local header", "number", currentHeader.Number, "hash", currentHeader.Hash(), "td", headerTd)
|
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 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)
|
log.Info("Loaded most recent local fast block", "number", bc.currentFastBlock.Number(), "hash", bc.currentFastBlock.Hash(), "td", fastTd)
|
||||||
|
|
@ -305,6 +310,9 @@ func (bc *BlockChain) SetHead(head uint64) error {
|
||||||
if err := WriteHeadFastBlockHash(bc.db, bc.currentFastBlock.Hash()); err != nil {
|
if err := WriteHeadFastBlockHash(bc.db, bc.currentFastBlock.Hash()); err != nil {
|
||||||
log.Crit("Failed to reset head fast block", "err", err)
|
log.Crit("Failed to reset head fast block", "err", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bc.chainStats.Update(bc.currentBlock, bc.currentFastBlock, bc.GetTd(bc.currentBlock.Hash(), bc.currentBlock.NumberU64()))
|
||||||
|
|
||||||
return bc.loadLastState()
|
return bc.loadLastState()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -322,6 +330,8 @@ func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error {
|
||||||
// If all checks out, manually set the head block
|
// If all checks out, manually set the head block
|
||||||
bc.mu.Lock()
|
bc.mu.Lock()
|
||||||
bc.currentBlock = block
|
bc.currentBlock = block
|
||||||
|
bc.chainStats.SetNumber(block.Number().Uint64())
|
||||||
|
bc.chainStats.SetTotalDifficulty(bc.GetTd(block.Hash(), block.NumberU64()))
|
||||||
bc.mu.Unlock()
|
bc.mu.Unlock()
|
||||||
|
|
||||||
log.Info("Committed new head block", "number", block.Number(), "hash", hash)
|
log.Info("Committed new head block", "number", block.Number(), "hash", hash)
|
||||||
|
|
@ -421,6 +431,8 @@ func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error {
|
||||||
bc.hc.SetCurrentHeader(bc.genesisBlock.Header())
|
bc.hc.SetCurrentHeader(bc.genesisBlock.Header())
|
||||||
bc.currentFastBlock = bc.genesisBlock
|
bc.currentFastBlock = bc.genesisBlock
|
||||||
|
|
||||||
|
bc.chainStats.Update(bc.currentBlock, bc.currentFastBlock, bc.genesisBlock.Difficulty())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -499,6 +511,7 @@ func (bc *BlockChain) insert(block *types.Block) {
|
||||||
}
|
}
|
||||||
bc.currentFastBlock = block
|
bc.currentFastBlock = block
|
||||||
}
|
}
|
||||||
|
bc.chainStats.Update(bc.currentBlock, bc.currentFastBlock, bc.GetTd(block.Hash(), block.NumberU64()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Genesis retrieves the chain's genesis block.
|
// Genesis retrieves the chain's genesis block.
|
||||||
|
|
@ -693,6 +706,24 @@ func (bc *BlockChain) procFutureBlocks() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stats returns the chainstats which can be queried non-blocking for info about difficulty and numbers
|
||||||
|
// These are provided on a best-effort, and it's theoretically possible that two consecutive calls to
|
||||||
|
// number and difficulty return number for X and difficulty for Y, if the stats is updated between the calls
|
||||||
|
func (bc *BlockChain) Stats() *chainstats.Chainstats {
|
||||||
|
return bc.chainStats
|
||||||
|
}
|
||||||
|
func (bc *BlockChain) CurrentNumber() uint64 {
|
||||||
|
return bc.chainStats.GetNumber()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bc *BlockChain) CurrentFastNumber() uint64 {
|
||||||
|
return bc.chainStats.GetFastNumber()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bc *BlockChain) CurrentTD() *big.Int {
|
||||||
|
return bc.chainStats.GetTotalDifficulty()
|
||||||
|
}
|
||||||
|
|
||||||
// WriteStatus status of write
|
// WriteStatus status of write
|
||||||
type WriteStatus byte
|
type WriteStatus byte
|
||||||
|
|
||||||
|
|
@ -724,6 +755,7 @@ func (bc *BlockChain) Rollback(chain []common.Hash) {
|
||||||
WriteHeadBlockHash(bc.db, bc.currentBlock.Hash())
|
WriteHeadBlockHash(bc.db, bc.currentBlock.Hash())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bc.chainStats.Update(bc.currentBlock, bc.currentFastBlock, bc.GetTd(bc.currentBlock.Hash(), bc.currentBlock.NumberU64()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetReceiptsData computes all the non-consensus fields of the receipts
|
// SetReceiptsData computes all the non-consensus fields of the receipts
|
||||||
|
|
@ -835,6 +867,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
|
||||||
log.Crit("Failed to update head fast block hash", "err", err)
|
log.Crit("Failed to update head fast block hash", "err", err)
|
||||||
}
|
}
|
||||||
bc.currentFastBlock = head
|
bc.currentFastBlock = head
|
||||||
|
bc.chainStats.SetFastNumber(bc.currentFastBlock.NumberU64())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bc.mu.Unlock()
|
bc.mu.Unlock()
|
||||||
|
|
|
||||||
|
|
@ -193,6 +193,15 @@ type BlockChain interface {
|
||||||
|
|
||||||
// InsertReceiptChain inserts a batch of receipts into the local chain.
|
// InsertReceiptChain inserts a batch of receipts into the local chain.
|
||||||
InsertReceiptChain(types.Blocks, []types.Receipts) (int, error)
|
InsertReceiptChain(types.Blocks, []types.Receipts) (int, error)
|
||||||
|
|
||||||
|
// CurrentNumber retrieves number of the current head block
|
||||||
|
CurrentNumber() uint64
|
||||||
|
|
||||||
|
// CurrentNumber retrieves number of the current head fast block
|
||||||
|
CurrentFastNumber() uint64
|
||||||
|
|
||||||
|
// CurrentTD retrives the total difficulty of the current head block
|
||||||
|
CurrentTD() *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new downloader to fetch hashes and blocks from remote peers.
|
// New creates a new downloader to fetch hashes and blocks from remote peers.
|
||||||
|
|
@ -583,9 +592,9 @@ func (d *Downloader) findAncestor(p *peerConnection, height uint64) (uint64, err
|
||||||
floor, ceil := int64(-1), d.lightchain.CurrentHeader().Number.Uint64()
|
floor, ceil := int64(-1), d.lightchain.CurrentHeader().Number.Uint64()
|
||||||
|
|
||||||
if d.mode == FullSync {
|
if d.mode == FullSync {
|
||||||
ceil = d.blockchain.CurrentBlock().NumberU64()
|
ceil = d.blockchain.CurrentNumber()
|
||||||
} else if d.mode == FastSync {
|
} else if d.mode == FastSync {
|
||||||
ceil = d.blockchain.CurrentFastBlock().NumberU64()
|
ceil = d.blockchain.CurrentFastNumber()
|
||||||
}
|
}
|
||||||
if ceil >= MaxForkAncestry {
|
if ceil >= MaxForkAncestry {
|
||||||
floor = int64(ceil - MaxForkAncestry)
|
floor = int64(ceil - MaxForkAncestry)
|
||||||
|
|
@ -1156,16 +1165,16 @@ func (d *Downloader) processHeaders(origin uint64, pivot uint64, td *big.Int) er
|
||||||
for i, header := range rollback {
|
for i, header := range rollback {
|
||||||
hashes[i] = header.Hash()
|
hashes[i] = header.Hash()
|
||||||
}
|
}
|
||||||
lastHeader, lastFastBlock, lastBlock := d.lightchain.CurrentHeader().Number, common.Big0, common.Big0
|
lastHeader, lastFastBlock, lastBlock := d.lightchain.CurrentHeader().Number, uint64(0), uint64(0)
|
||||||
if d.mode != LightSync {
|
if d.mode != LightSync {
|
||||||
lastFastBlock = d.blockchain.CurrentFastBlock().Number()
|
lastFastBlock = d.blockchain.CurrentFastNumber()
|
||||||
lastBlock = d.blockchain.CurrentBlock().Number()
|
lastBlock = d.blockchain.CurrentNumber()
|
||||||
}
|
}
|
||||||
d.lightchain.Rollback(hashes)
|
d.lightchain.Rollback(hashes)
|
||||||
curFastBlock, curBlock := common.Big0, common.Big0
|
curFastBlock, curBlock := uint64(0), uint64(0)
|
||||||
if d.mode != LightSync {
|
if d.mode != LightSync {
|
||||||
curFastBlock = d.blockchain.CurrentFastBlock().Number()
|
curFastBlock = d.blockchain.CurrentFastNumber()
|
||||||
curBlock = d.blockchain.CurrentBlock().Number()
|
curBlock = d.blockchain.CurrentNumber()
|
||||||
}
|
}
|
||||||
log.Warn("Rolled back headers", "count", len(hashes),
|
log.Warn("Rolled back headers", "count", len(hashes),
|
||||||
"header", fmt.Sprintf("%d->%d", lastHeader, d.lightchain.CurrentHeader().Number),
|
"header", fmt.Sprintf("%d->%d", lastHeader, d.lightchain.CurrentHeader().Number),
|
||||||
|
|
@ -1205,8 +1214,7 @@ func (d *Downloader) processHeaders(origin uint64, pivot uint64, td *big.Int) er
|
||||||
// L: Request new headers up from 11 (R's TD was higher, it must have something)
|
// L: Request new headers up from 11 (R's TD was higher, it must have something)
|
||||||
// R: Nothing to give
|
// R: Nothing to give
|
||||||
if d.mode != LightSync {
|
if d.mode != LightSync {
|
||||||
head := d.blockchain.CurrentBlock()
|
if !gotHeaders && td.Cmp(d.blockchain.CurrentTD()) > 0 {
|
||||||
if !gotHeaders && td.Cmp(d.blockchain.GetTd(head.Hash(), head.NumberU64())) > 0 {
|
|
||||||
return errStallingPeer
|
return errStallingPeer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -282,6 +282,18 @@ func (dl *downloadTester) CurrentFastBlock() *types.Block {
|
||||||
}
|
}
|
||||||
return dl.genesis
|
return dl.genesis
|
||||||
}
|
}
|
||||||
|
func (dl *downloadTester) CurrentNumber() uint64 {
|
||||||
|
return dl.CurrentBlock().NumberU64()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dl *downloadTester) CurrentFastNumber() uint64 {
|
||||||
|
return dl.CurrentFastBlock().NumberU64()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dl *downloadTester) CurrentTD() *big.Int {
|
||||||
|
cur := dl.CurrentBlock()
|
||||||
|
return dl.GetTd(cur.Hash(), cur.NumberU64())
|
||||||
|
}
|
||||||
|
|
||||||
// FastSyncCommitHead manually sets the head block to a given hash.
|
// FastSyncCommitHead manually sets the head block to a given hash.
|
||||||
func (dl *downloadTester) FastSyncCommitHead(hash common.Hash) error {
|
func (dl *downloadTester) FastSyncCommitHead(hash common.Hash) error {
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, ne
|
||||||
quitSync: make(chan struct{}),
|
quitSync: make(chan struct{}),
|
||||||
}
|
}
|
||||||
// Figure out whether to allow fast sync or not
|
// Figure out whether to allow fast sync or not
|
||||||
if mode == downloader.FastSync && blockchain.CurrentBlock().NumberU64() > 0 {
|
if mode == downloader.FastSync && blockchain.Stats().GetNumber() > 0 {
|
||||||
log.Warn("Blockchain not empty, fast sync disabled")
|
log.Warn("Blockchain not empty, fast sync disabled")
|
||||||
mode = downloader.FullSync
|
mode = downloader.FullSync
|
||||||
}
|
}
|
||||||
|
|
@ -165,7 +165,7 @@ func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, ne
|
||||||
return engine.VerifyHeader(blockchain, header, true)
|
return engine.VerifyHeader(blockchain, header, true)
|
||||||
}
|
}
|
||||||
heighter := func() uint64 {
|
heighter := func() uint64 {
|
||||||
return blockchain.CurrentBlock().NumberU64()
|
return blockchain.Stats().GetNumber()
|
||||||
}
|
}
|
||||||
inserter := func(blocks types.Blocks) (int, error) {
|
inserter := func(blocks types.Blocks) (int, error) {
|
||||||
// If fast sync is running, deny importing weird blocks
|
// If fast sync is running, deny importing weird blocks
|
||||||
|
|
@ -647,8 +647,8 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
// Schedule a sync if above ours. Note, this will not fire a sync for a gap of
|
// Schedule a sync if above ours. Note, this will not fire a sync for a gap of
|
||||||
// a singe block (as the true TD is below the propagated block), however this
|
// a singe block (as the true TD is below the propagated block), however this
|
||||||
// scenario should easily be covered by the fetcher.
|
// scenario should easily be covered by the fetcher.
|
||||||
currentBlock := pm.blockchain.CurrentBlock()
|
currentTd := pm.blockchain.Stats().GetTotalDifficulty()
|
||||||
if trueTD.Cmp(pm.blockchain.GetTd(currentBlock.Hash(), currentBlock.NumberU64())) > 0 {
|
if trueTD.Cmp(currentTd) > 0 {
|
||||||
go pm.synchronise(p)
|
go pm.synchronise(p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -167,8 +167,7 @@ func (pm *ProtocolManager) synchronise(peer *peer) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Make sure the peer's TD is higher than our own
|
// Make sure the peer's TD is higher than our own
|
||||||
currentBlock := pm.blockchain.CurrentBlock()
|
currentNumber, currentFastNumber, td := pm.blockchain.Stats().Get()
|
||||||
td := pm.blockchain.GetTd(currentBlock.Hash(), currentBlock.NumberU64())
|
|
||||||
|
|
||||||
pHead, pTd := peer.Head()
|
pHead, pTd := peer.Head()
|
||||||
if pTd.Cmp(td) <= 0 {
|
if pTd.Cmp(td) <= 0 {
|
||||||
|
|
@ -179,7 +178,7 @@ func (pm *ProtocolManager) synchronise(peer *peer) {
|
||||||
if atomic.LoadUint32(&pm.fastSync) == 1 {
|
if atomic.LoadUint32(&pm.fastSync) == 1 {
|
||||||
// Fast sync was explicitly requested, and explicitly granted
|
// Fast sync was explicitly requested, and explicitly granted
|
||||||
mode = downloader.FastSync
|
mode = downloader.FastSync
|
||||||
} else if currentBlock.NumberU64() == 0 && pm.blockchain.CurrentFastBlock().NumberU64() > 0 {
|
} else if currentNumber == 0 && currentFastNumber > 0 {
|
||||||
// The database seems empty as the current block is the genesis. Yet the fast
|
// The database seems empty as the current block is the genesis. Yet the fast
|
||||||
// block is ahead, so fast sync was enabled for this node at a certain point.
|
// block is ahead, so fast sync was enabled for this node at a certain point.
|
||||||
// The only scenario where this can happen is if the user manually (or via a
|
// The only scenario where this can happen is if the user manually (or via a
|
||||||
|
|
@ -197,13 +196,13 @@ func (pm *ProtocolManager) synchronise(peer *peer) {
|
||||||
atomic.StoreUint32(&pm.fastSync, 0)
|
atomic.StoreUint32(&pm.fastSync, 0)
|
||||||
}
|
}
|
||||||
atomic.StoreUint32(&pm.acceptTxs, 1) // Mark initial sync done
|
atomic.StoreUint32(&pm.acceptTxs, 1) // Mark initial sync done
|
||||||
if head := pm.blockchain.CurrentBlock(); head.NumberU64() > 0 {
|
if pm.blockchain.Stats().GetNumber() > 0 {
|
||||||
// We've completed a sync cycle, notify all peers of new state. This path is
|
// We've completed a sync cycle, notify all peers of new state. This path is
|
||||||
// essential in star-topology networks where a gateway node needs to notify
|
// essential in star-topology networks where a gateway node needs to notify
|
||||||
// all its out-of-date peers of the availability of a new block. This failure
|
// all its out-of-date peers of the availability of a new block. This failure
|
||||||
// scenario will most often crop up in private and hackathon networks with
|
// scenario will most often crop up in private and hackathon networks with
|
||||||
// degenerate connectivity, but it should be healthy for the mainnet too to
|
// degenerate connectivity, but it should be healthy for the mainnet too to
|
||||||
// more reliably update peers or the local TD state.
|
// more reliably update peers or the local TD state.
|
||||||
go pm.BroadcastBlock(head, false)
|
go pm.BroadcastBlock(pm.blockchain.CurrentBlock(), false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue