eth: improve shutdown synchronization (#20695)
* eth: improve shutdown synchronization Most goroutines started by eth.Ethereum didn't have any shutdown sync at all, which lead to weird error messages when quitting the client. This change improves the clean shutdown path by stopping all internal components in dependency order and waiting for them to actually be stopped before shutdown is considered done. In particular, we now stop everything related to peers before stopping 'resident' parts such as core.BlockChain. * eth: rewrite sync controller * eth: remove sync start debug message * eth: notify chainSyncer about new peers after handshake * eth: move downloader.Cancel call into chainSyncer * eth: make post-sync block broadcast synchronous * eth: add comments * core: change blockchain stop message * eth: change closeBloomHandler channel type
This commit is contained in:
@ -67,9 +67,6 @@ type LesServer interface {
|
||||
type Ethereum struct {
|
||||
config *Config
|
||||
|
||||
// Channel for shutting down the service
|
||||
shutdownChan chan bool
|
||||
|
||||
// Handlers
|
||||
txPool *core.TxPool
|
||||
blockchain *core.BlockChain
|
||||
@ -84,8 +81,9 @@ type Ethereum struct {
|
||||
engine consensus.Engine
|
||||
accountManager *accounts.Manager
|
||||
|
||||
bloomRequests chan chan *bloombits.Retrieval // Channel receiving bloom data retrieval requests
|
||||
bloomIndexer *core.ChainIndexer // Bloom indexer operating during block imports
|
||||
bloomRequests chan chan *bloombits.Retrieval // Channel receiving bloom data retrieval requests
|
||||
bloomIndexer *core.ChainIndexer // Bloom indexer operating during block imports
|
||||
closeBloomHandler chan struct{}
|
||||
|
||||
APIBackend *EthAPIBackend
|
||||
|
||||
@ -145,17 +143,17 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||
log.Info("Initialised chain configuration", "config", chainConfig)
|
||||
|
||||
eth := &Ethereum{
|
||||
config: config,
|
||||
chainDb: chainDb,
|
||||
eventMux: ctx.EventMux,
|
||||
accountManager: ctx.AccountManager,
|
||||
engine: CreateConsensusEngine(ctx, chainConfig, &config.Ethash, config.Miner.Notify, config.Miner.Noverify, chainDb),
|
||||
shutdownChan: make(chan bool),
|
||||
networkID: config.NetworkId,
|
||||
gasPrice: config.Miner.GasPrice,
|
||||
etherbase: config.Miner.Etherbase,
|
||||
bloomRequests: make(chan chan *bloombits.Retrieval),
|
||||
bloomIndexer: NewBloomIndexer(chainDb, params.BloomBitsBlocks, params.BloomConfirms),
|
||||
config: config,
|
||||
chainDb: chainDb,
|
||||
eventMux: ctx.EventMux,
|
||||
accountManager: ctx.AccountManager,
|
||||
engine: CreateConsensusEngine(ctx, chainConfig, &config.Ethash, config.Miner.Notify, config.Miner.Noverify, chainDb),
|
||||
closeBloomHandler: make(chan struct{}),
|
||||
networkID: config.NetworkId,
|
||||
gasPrice: config.Miner.GasPrice,
|
||||
etherbase: config.Miner.Etherbase,
|
||||
bloomRequests: make(chan chan *bloombits.Retrieval),
|
||||
bloomIndexer: NewBloomIndexer(chainDb, params.BloomBitsBlocks, params.BloomConfirms),
|
||||
}
|
||||
|
||||
bcVersion := rawdb.ReadDatabaseVersion(chainDb)
|
||||
@ -557,18 +555,20 @@ func (s *Ethereum) Start(srvr *p2p.Server) error {
|
||||
// Stop implements node.Service, terminating all internal goroutines used by the
|
||||
// Ethereum protocol.
|
||||
func (s *Ethereum) Stop() error {
|
||||
s.bloomIndexer.Close()
|
||||
s.blockchain.Stop()
|
||||
s.engine.Close()
|
||||
// Stop all the peer-related stuff first.
|
||||
s.protocolManager.Stop()
|
||||
if s.lesServer != nil {
|
||||
s.lesServer.Stop()
|
||||
}
|
||||
|
||||
// Then stop everything else.
|
||||
s.bloomIndexer.Close()
|
||||
close(s.closeBloomHandler)
|
||||
s.txPool.Stop()
|
||||
s.miner.Stop()
|
||||
s.eventMux.Stop()
|
||||
|
||||
s.blockchain.Stop()
|
||||
s.engine.Close()
|
||||
s.chainDb.Close()
|
||||
close(s.shutdownChan)
|
||||
s.eventMux.Stop()
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user