mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 01:13:45 +00:00
Merge 77c5188219 into c4d21bc8e5
This commit is contained in:
commit
a1d1478322
2 changed files with 43 additions and 15 deletions
|
|
@ -114,7 +114,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
|
||||||
|
currentTd atomic.Value // The total difficulty
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBlockChain returns a fully initialised block chain using information
|
// NewBlockChain returns a fully initialised block chain using information
|
||||||
|
|
@ -140,6 +141,7 @@ func NewBlockChain(chainDb ethdb.Database, config *params.ChainConfig, engine co
|
||||||
vmConfig: vmConfig,
|
vmConfig: vmConfig,
|
||||||
badBlocks: badBlocks,
|
badBlocks: badBlocks,
|
||||||
}
|
}
|
||||||
|
|
||||||
bc.SetValidator(NewBlockValidator(config, bc, engine))
|
bc.SetValidator(NewBlockValidator(config, bc, engine))
|
||||||
bc.SetProcessor(NewStateProcessor(config, bc, engine))
|
bc.SetProcessor(NewStateProcessor(config, bc, engine))
|
||||||
|
|
||||||
|
|
@ -168,6 +170,13 @@ func NewBlockChain(chainDb ethdb.Database, config *params.ChainConfig, engine co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
currentBlock := bc.CurrentBlock()
|
||||||
|
td := big.NewInt(0)
|
||||||
|
if currentBlock != nil {
|
||||||
|
td.Set(bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64()))
|
||||||
|
}
|
||||||
|
bc.currentTd.Store(td)
|
||||||
|
log.Info("Set initial td", "td", td)
|
||||||
// Take ownership of this particular state
|
// Take ownership of this particular state
|
||||||
go bc.update()
|
go bc.update()
|
||||||
return bc, nil
|
return bc, nil
|
||||||
|
|
@ -330,6 +339,13 @@ func (bc *BlockChain) CurrentBlock() *types.Block {
|
||||||
return bc.currentBlock
|
return bc.currentBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CurrentTD returns ( a copy of) the current difficulty. This method does not
|
||||||
|
// use any locks, and the information may be mildly stale, since a new block
|
||||||
|
// insertion may be in progress
|
||||||
|
func (bc *BlockChain) CurrentTd() *big.Int {
|
||||||
|
return new(big.Int).Set(bc.currentTd.Load().(*big.Int))
|
||||||
|
}
|
||||||
|
|
||||||
// CurrentFastBlock retrieves the current fast-sync head block of the canonical
|
// CurrentFastBlock retrieves the current fast-sync head block of the canonical
|
||||||
// chain. The block is retrieved from the blockchain's internal cache.
|
// chain. The block is retrieved from the blockchain's internal cache.
|
||||||
func (bc *BlockChain) CurrentFastBlock() *types.Block {
|
func (bc *BlockChain) CurrentFastBlock() *types.Block {
|
||||||
|
|
@ -858,9 +874,13 @@ func (bc *BlockChain) WriteBlock(block *types.Block) (status WriteStatus, err er
|
||||||
} else {
|
} else {
|
||||||
status = SideStatTy
|
status = SideStatTy
|
||||||
}
|
}
|
||||||
|
//Creating a new bigint here, to be sure not to violate the rule below:
|
||||||
|
// Once Store has been called, a Value must not be copied.
|
||||||
|
if externTd.Cmp(localTd) > 0 {
|
||||||
|
bc.currentTd.Store(new(big.Int).Set(externTd))
|
||||||
|
}
|
||||||
|
|
||||||
bc.futureBlocks.Remove(block.Hash())
|
bc.futureBlocks.Remove(block.Hash())
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
34
eth/sync.go
34
eth/sync.go
|
|
@ -167,44 +167,52 @@ 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()
|
td := pm.blockchain.CurrentTd()
|
||||||
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 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var currentBlock *types.Block
|
||||||
|
|
||||||
// Otherwise try to sync with the downloader
|
// Otherwise try to sync with the downloader
|
||||||
mode := downloader.FullSync
|
mode := downloader.FullSync
|
||||||
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{
|
||||||
// The database seems empty as the current block is the genesis. Yet the fast
|
currentBlock = pm.blockchain.CurrentBlock()
|
||||||
// block is ahead, so fast sync was enabled for this node at a certain point.
|
if currentBlock.NumberU64() == 0 && pm.blockchain.CurrentFastBlock().NumberU64() > 0 {
|
||||||
// The only scenario where this can happen is if the user manually (or via a
|
// The database seems empty as the current block is the genesis. Yet the fast
|
||||||
// bad block) rolled back a fast sync node below the sync point. In this case
|
// block is ahead, so fast sync was enabled for this node at a certain point.
|
||||||
// however it's safe to reenable fast sync.
|
// The only scenario where this can happen is if the user manually (or via a
|
||||||
atomic.StoreUint32(&pm.fastSync, 1)
|
// bad block) rolled back a fast sync node below the sync point. In this case
|
||||||
mode = downloader.FastSync
|
// however it's safe to reenable fast sync.
|
||||||
|
atomic.StoreUint32(&pm.fastSync, 1)
|
||||||
|
mode = downloader.FastSync
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err := pm.downloader.Synchronise(peer.id, pHead, pTd, mode); err != nil {
|
if err := pm.downloader.Synchronise(peer.id, pHead, pTd, mode); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
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 currentBlock == nil{
|
||||||
|
currentBlock = pm.blockchain.CurrentBlock()
|
||||||
|
}
|
||||||
|
if currentBlock.NumberU64() > 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(currentBlock, false)
|
||||||
}
|
}
|
||||||
// If fast sync was enabled, and we synced up, disable it
|
// If fast sync was enabled, and we synced up, disable it
|
||||||
if atomic.LoadUint32(&pm.fastSync) == 1 {
|
if atomic.LoadUint32(&pm.fastSync) == 1 {
|
||||||
// Disable fast sync if we indeed have something in our chain
|
// Disable fast sync if we indeed have something in our chain
|
||||||
if pm.blockchain.CurrentBlock().NumberU64() > 0 {
|
if currentBlock.NumberU64() > 0 {
|
||||||
log.Info("Fast sync complete, auto disabling")
|
log.Info("Fast sync complete, auto disabling")
|
||||||
atomic.StoreUint32(&pm.fastSync, 0)
|
atomic.StoreUint32(&pm.fastSync, 0)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue