forked from cerc-io/plugeth
Merge pull request #1939 from karalabe/fix-blocked-sync-goroutines
eth: don't block sync goroutines that short circuit
This commit is contained in:
commit
8202bae070
@ -411,11 +411,14 @@ func (self *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error {
|
|||||||
|
|
||||||
// insert injects a new head block into the current block chain. This method
|
// insert injects a new head block into the current block chain. This method
|
||||||
// assumes that the block is indeed a true head. It will also reset the head
|
// assumes that the block is indeed a true head. It will also reset the head
|
||||||
// header and the head fast sync block to this very same block to prevent them
|
// header and the head fast sync block to this very same block if they are older
|
||||||
// from pointing to a possibly old canonical chain (i.e. side chain by now).
|
// or if they are on a different side chain.
|
||||||
//
|
//
|
||||||
// Note, this function assumes that the `mu` mutex is held!
|
// Note, this function assumes that the `mu` mutex is held!
|
||||||
func (bc *BlockChain) insert(block *types.Block) {
|
func (bc *BlockChain) insert(block *types.Block) {
|
||||||
|
// If the block is on a side chain or an unknown one, force other heads onto it too
|
||||||
|
updateHeads := GetCanonicalHash(bc.chainDb, block.NumberU64()) != block.Hash()
|
||||||
|
|
||||||
// Add the block to the canonical chain number scheme and mark as the head
|
// Add the block to the canonical chain number scheme and mark as the head
|
||||||
if err := WriteCanonicalHash(bc.chainDb, block.Hash(), block.NumberU64()); err != nil {
|
if err := WriteCanonicalHash(bc.chainDb, block.Hash(), block.NumberU64()); err != nil {
|
||||||
glog.Fatalf("failed to insert block number: %v", err)
|
glog.Fatalf("failed to insert block number: %v", err)
|
||||||
@ -423,16 +426,20 @@ func (bc *BlockChain) insert(block *types.Block) {
|
|||||||
if err := WriteHeadBlockHash(bc.chainDb, block.Hash()); err != nil {
|
if err := WriteHeadBlockHash(bc.chainDb, block.Hash()); err != nil {
|
||||||
glog.Fatalf("failed to insert head block hash: %v", err)
|
glog.Fatalf("failed to insert head block hash: %v", err)
|
||||||
}
|
}
|
||||||
if err := WriteHeadHeaderHash(bc.chainDb, block.Hash()); err != nil {
|
|
||||||
glog.Fatalf("failed to insert head header hash: %v", err)
|
|
||||||
}
|
|
||||||
if err := WriteHeadFastBlockHash(bc.chainDb, block.Hash()); err != nil {
|
|
||||||
glog.Fatalf("failed to insert head fast block hash: %v", err)
|
|
||||||
}
|
|
||||||
// Update the internal state with the head block
|
|
||||||
bc.currentBlock = block
|
bc.currentBlock = block
|
||||||
bc.currentHeader = block.Header()
|
|
||||||
bc.currentFastBlock = block
|
// If the block is better than out head or is on a different chain, force update heads
|
||||||
|
if updateHeads {
|
||||||
|
if err := WriteHeadHeaderHash(bc.chainDb, block.Hash()); err != nil {
|
||||||
|
glog.Fatalf("failed to insert head header hash: %v", err)
|
||||||
|
}
|
||||||
|
bc.currentHeader = block.Header()
|
||||||
|
|
||||||
|
if err := WriteHeadFastBlockHash(bc.chainDb, block.Hash()); err != nil {
|
||||||
|
glog.Fatalf("failed to insert head fast block hash: %v", err)
|
||||||
|
}
|
||||||
|
bc.currentFastBlock = block
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
|
@ -248,10 +248,11 @@ func (d *Downloader) UnregisterPeer(id string) error {
|
|||||||
|
|
||||||
// Synchronise tries to sync up our local block chain with a remote peer, both
|
// Synchronise tries to sync up our local block chain with a remote peer, both
|
||||||
// adding various sanity checks as well as wrapping it with various log entries.
|
// adding various sanity checks as well as wrapping it with various log entries.
|
||||||
func (d *Downloader) Synchronise(id string, head common.Hash, td *big.Int, mode SyncMode) {
|
func (d *Downloader) Synchronise(id string, head common.Hash, td *big.Int, mode SyncMode) error {
|
||||||
glog.V(logger.Detail).Infof("Attempting synchronisation: %v, head [%x…], TD %v", id, head[:4], td)
|
glog.V(logger.Detail).Infof("Attempting synchronisation: %v, head [%x…], TD %v", id, head[:4], td)
|
||||||
|
|
||||||
switch err := d.synchronise(id, head, td, mode); err {
|
err := d.synchronise(id, head, td, mode)
|
||||||
|
switch err {
|
||||||
case nil:
|
case nil:
|
||||||
glog.V(logger.Detail).Infof("Synchronisation completed")
|
glog.V(logger.Detail).Infof("Synchronisation completed")
|
||||||
|
|
||||||
@ -268,6 +269,7 @@ func (d *Downloader) Synchronise(id string, head common.Hash, td *big.Int, mode
|
|||||||
default:
|
default:
|
||||||
glog.V(logger.Warn).Infof("Synchronisation failed: %v", err)
|
glog.V(logger.Warn).Infof("Synchronisation failed: %v", err)
|
||||||
}
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// synchronise will select the peer and use it for synchronising. If an empty string is given
|
// synchronise will select the peer and use it for synchronising. If an empty string is given
|
||||||
|
@ -170,13 +170,16 @@ func (pm *ProtocolManager) synchronise(peer *peer) {
|
|||||||
if pm.fastSync {
|
if pm.fastSync {
|
||||||
mode = downloader.FastSync
|
mode = downloader.FastSync
|
||||||
}
|
}
|
||||||
pm.downloader.Synchronise(peer.id, peer.Head(), peer.Td(), mode)
|
if err := pm.downloader.Synchronise(peer.id, peer.Head(), peer.Td(), mode); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
// If fast sync was enabled, and we synced up, disable it
|
// If fast sync was enabled, and we synced up, disable it
|
||||||
if pm.fastSync {
|
if pm.fastSync {
|
||||||
|
// Wait until all pending imports finish processing
|
||||||
for pm.downloader.Synchronising() {
|
for pm.downloader.Synchronising() {
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
}
|
}
|
||||||
|
// Disable fast sync if we indeed have something in our chain
|
||||||
if pm.blockchain.CurrentBlock().NumberU64() > 0 {
|
if pm.blockchain.CurrentBlock().NumberU64() > 0 {
|
||||||
glog.V(logger.Info).Infof("fast sync complete, auto disabling")
|
glog.V(logger.Info).Infof("fast sync complete, auto disabling")
|
||||||
pm.fastSync = false
|
pm.fastSync = false
|
||||||
|
Loading…
Reference in New Issue
Block a user