core, light: remove procInterrupt from HeaderChain, LightChain

Verifying headers isn't that slow and the tiny benefit of quitting
earlier doesn't justify passing around a callback to wrap an atomic
field.
This commit is contained in:
Felix Lange 2017-05-30 10:45:16 +02:00
parent cb809c03da
commit d93440c987
3 changed files with 12 additions and 44 deletions

View file

@ -139,7 +139,7 @@ func NewBlockChain(chainDb ethdb.Database, config *params.ChainConfig, engine co
bc.SetProcessor(NewStateProcessor(config, bc, engine)) bc.SetProcessor(NewStateProcessor(config, bc, engine))
var err error var err error
bc.hc, err = NewHeaderChain(chainDb, config, engine, bc.getProcInterrupt) bc.hc, err = NewHeaderChain(chainDb, config, engine)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -168,10 +168,6 @@ func NewBlockChain(chainDb ethdb.Database, config *params.ChainConfig, engine co
return bc, nil return bc, nil
} }
func (bc *BlockChain) getProcInterrupt() bool {
return atomic.LoadInt32(&bc.procInterrupt) == 1
}
// loadLastState loads the last known chain state from the database. This method // loadLastState loads the last known chain state from the database. This method
// assumes that the chain manager mutex is held. // assumes that the chain manager mutex is held.
func (bc *BlockChain) loadLastState() error { func (bc *BlockChain) loadLastState() error {

View file

@ -18,7 +18,6 @@ package core
import ( import (
crand "crypto/rand" crand "crypto/rand"
"errors"
"fmt" "fmt"
"math" "math"
"math/big" "math/big"
@ -58,17 +57,14 @@ type HeaderChain struct {
tdCache *lru.Cache // Cache for the most recent block total difficulties tdCache *lru.Cache // Cache for the most recent block total difficulties
numberCache *lru.Cache // Cache for the most recent block numbers numberCache *lru.Cache // Cache for the most recent block numbers
procInterrupt func() bool
rand *mrand.Rand rand *mrand.Rand
engine consensus.Engine engine consensus.Engine
} }
// NewHeaderChain creates a new HeaderChain structure. // NewHeaderChain creates a new HeaderChain structure.
// getValidator should return the parent's validator // getValidator should return the parent's validator
// procInterrupt points to the parent's interrupt semaphore
// wg points to the parent's shutdown wait group // wg points to the parent's shutdown wait group
func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine consensus.Engine, procInterrupt func() bool) (*HeaderChain, error) { func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine consensus.Engine) (*HeaderChain, error) {
headerCache, _ := lru.New(headerCacheLimit) headerCache, _ := lru.New(headerCacheLimit)
tdCache, _ := lru.New(tdCacheLimit) tdCache, _ := lru.New(tdCacheLimit)
numberCache, _ := lru.New(numberCacheLimit) numberCache, _ := lru.New(numberCacheLimit)
@ -80,14 +76,13 @@ func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine c
} }
hc := &HeaderChain{ hc := &HeaderChain{
config: config, config: config,
chainDb: chainDb, chainDb: chainDb,
headerCache: headerCache, headerCache: headerCache,
tdCache: tdCache, tdCache: tdCache,
numberCache: numberCache, numberCache: numberCache,
procInterrupt: procInterrupt, rand: mrand.New(mrand.NewSource(seed.Int64())),
rand: mrand.New(mrand.NewSource(seed.Int64())), engine: engine,
engine: engine,
} }
hc.genesisHeader = hc.GetHeaderByNumber(0) hc.genesisHeader = hc.GetHeaderByNumber(0)
@ -230,11 +225,6 @@ func (hc *HeaderChain) ValidateHeaderChain(chain []*types.Header, checkFreq int)
// Iterate over the headers and ensure they all check out // Iterate over the headers and ensure they all check out
for i, header := range chain { for i, header := range chain {
// If the chain is terminating, stop processing blocks
if hc.procInterrupt() {
log.Debug("Premature abort during headers verification")
return 0, errors.New("aborted")
}
// If the header is a banned one, straight out abort // If the header is a banned one, straight out abort
if BadHashes[header.Hash()] { if BadHashes[header.Hash()] {
return i, ErrBlacklistedHash return i, ErrBlacklistedHash
@ -261,11 +251,6 @@ func (hc *HeaderChain) InsertHeaderChain(chain []*types.Header, writeHeader WhCa
stats := struct{ processed, ignored int }{} stats := struct{ processed, ignored int }{}
// All headers passed verification, import them into the database // All headers passed verification, import them into the database
for i, header := range chain { for i, header := range chain {
// Short circuit insertion if shutting down
if hc.procInterrupt() {
log.Debug("Premature abort during headers import")
return i, errors.New("aborted")
}
// If the header's already known, skip it, otherwise store // If the header's already known, skip it, otherwise store
if hc.GetHeader(header.Hash(), header.Number.Uint64()) != nil { if hc.GetHeader(header.Hash(), header.Number.Uint64()) != nil {
stats.ignored++ stats.ignored++

View file

@ -20,7 +20,6 @@ import (
"context" "context"
"math/big" "math/big"
"sync" "sync"
"sync/atomic"
"time" "time"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -60,9 +59,7 @@ type LightChain struct {
quit chan struct{} quit chan struct{}
running int32 // running must be called automically running int32 // running must be called automically
// procInterrupt must be atomically called wg sync.WaitGroup
procInterrupt int32 // interrupt signaler for block processing
wg sync.WaitGroup
engine consensus.Engine engine consensus.Engine
} }
@ -86,7 +83,7 @@ func NewLightChain(odr OdrBackend, config *params.ChainConfig, engine consensus.
engine: engine, engine: engine,
} }
var err error var err error
bc.hc, err = core.NewHeaderChain(odr.Database(), config, bc.engine, bc.getProcInterrupt) bc.hc, err = core.NewHeaderChain(odr.Database(), config, bc.engine)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -114,10 +111,6 @@ func NewLightChain(odr OdrBackend, config *params.ChainConfig, engine consensus.
return bc, nil return bc, nil
} }
func (self *LightChain) getProcInterrupt() bool {
return atomic.LoadInt32(&self.procInterrupt) == 1
}
// Odr returns the ODR backend of the chain // Odr returns the ODR backend of the chain
func (self *LightChain) Odr() OdrBackend { func (self *LightChain) Odr() OdrBackend {
return self.odr return self.odr
@ -293,15 +286,9 @@ func (self *LightChain) GetBlockByNumber(ctx context.Context, number uint64) (*t
return self.GetBlock(ctx, hash, number) return self.GetBlock(ctx, hash, number)
} }
// Stop stops the blockchain service. If any imports are currently in progress // Stop stops the blockchain service.
// it will abort them using the procInterrupt.
func (bc *LightChain) Stop() { func (bc *LightChain) Stop() {
if !atomic.CompareAndSwapInt32(&bc.running, 0, 1) {
return
}
close(bc.quit) close(bc.quit)
atomic.StoreInt32(&bc.procInterrupt, 1)
bc.wg.Wait() bc.wg.Wait()
log.Info("Blockchain manager stopped") log.Info("Blockchain manager stopped")
} }