diff options
Diffstat (limited to 'light/lightchain.go')
-rw-r--r-- | light/lightchain.go | 56 |
1 files changed, 21 insertions, 35 deletions
diff --git a/light/lightchain.go b/light/lightchain.go index 4370dc0fc..e8fd0ba5e 100644 --- a/light/lightchain.go +++ b/light/lightchain.go @@ -17,21 +17,22 @@ package light import ( + "context" "math/big" "sync" "sync/atomic" + "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/pow" "github.com/ethereum/go-ethereum/rlp" "github.com/hashicorp/golang-lru" - "golang.org/x/net/context" ) var ( @@ -63,14 +64,13 @@ type LightChain struct { procInterrupt int32 // interrupt signaler for block processing wg sync.WaitGroup - pow pow.PoW - validator core.HeaderValidator + engine consensus.Engine } // NewLightChain returns a fully initialised light chain using information // available in the database. It initialises the default Ethereum header // validator. -func NewLightChain(odr OdrBackend, config *params.ChainConfig, pow pow.PoW, mux *event.TypeMux) (*LightChain, error) { +func NewLightChain(odr OdrBackend, config *params.ChainConfig, engine consensus.Engine, mux *event.TypeMux) (*LightChain, error) { bodyCache, _ := lru.New(bodyCacheLimit) bodyRLPCache, _ := lru.New(bodyCacheLimit) blockCache, _ := lru.New(blockCacheLimit) @@ -83,25 +83,17 @@ func NewLightChain(odr OdrBackend, config *params.ChainConfig, pow pow.PoW, mux bodyCache: bodyCache, bodyRLPCache: bodyRLPCache, blockCache: blockCache, - pow: pow, + engine: engine, } - var err error - bc.hc, err = core.NewHeaderChain(odr.Database(), config, bc.Validator, bc.getProcInterrupt) - bc.SetValidator(core.NewHeaderValidator(config, bc.hc, pow)) + bc.hc, err = core.NewHeaderChain(odr.Database(), config, bc.engine, bc.getProcInterrupt) if err != nil { return nil, err } - bc.genesisBlock, _ = bc.GetBlockByNumber(NoOdr, 0) if bc.genesisBlock == nil { - bc.genesisBlock, err = core.WriteDefaultGenesisBlock(odr.Database()) - if err != nil { - return nil, err - } - log.Warn("Wrote default ethereum genesis block") + return nil, core.ErrNoGenesis } - if bc.genesisBlock.Hash() == params.MainNetGenesisHash { // add trusted CHT WriteTrustedCht(bc.chainDb, TrustedCht{Number: 805, Root: common.HexToHash("85e4286fe0a730390245c49de8476977afdae0eb5530b277f62a52b12313d50f")}) @@ -148,9 +140,6 @@ func (self *LightChain) loadLastState() error { headerTd := self.GetTd(header.Hash(), header.Number.Uint64()) log.Info("Loaded most recent local header", "number", header.Number, "hash", header.Hash(), "td", headerTd) - // Try to be smart and issue a pow verification for the head to pre-generate caches - go self.pow.Verify(types.NewBlockWithHeader(header)) - return nil } @@ -191,20 +180,6 @@ func (self *LightChain) Status() (td *big.Int, currentBlock common.Hash, genesis return self.GetTd(hash, header.Number.Uint64()), hash, self.genesisBlock.Hash() } -// SetValidator sets the validator which is used to validate incoming headers. -func (self *LightChain) SetValidator(validator core.HeaderValidator) { - self.procmu.Lock() - defer self.procmu.Unlock() - self.validator = validator -} - -// Validator returns the current header validator. -func (self *LightChain) Validator() core.HeaderValidator { - self.procmu.RLock() - defer self.procmu.RUnlock() - return self.validator -} - // State returns a new mutable state based on the current HEAD block. func (self *LightChain) State() *LightState { return NewLightState(StateTrieID(self.hc.CurrentHeader()), self.odr) @@ -238,6 +213,9 @@ func (bc *LightChain) ResetWithGenesisBlock(genesis *types.Block) { // Accessors +// Engine retrieves the light chain's consensus engine. +func (bc *LightChain) Engine() consensus.Engine { return bc.engine } + // Genesis returns the genesis block func (bc *LightChain) Genesis() *types.Block { return bc.genesisBlock @@ -369,9 +347,17 @@ func (self *LightChain) postChainEvents(events []interface{}) { // In the case of a light chain, InsertHeaderChain also creates and posts light // chain events when necessary. func (self *LightChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) { + start := time.Now() + if i, err := self.hc.ValidateHeaderChain(chain, checkFreq); err != nil { + return i, err + } + // Make sure only one thread manipulates the chain at once self.chainmu.Lock() - defer self.chainmu.Unlock() + defer func() { + self.chainmu.Unlock() + time.Sleep(time.Millisecond * 10) // ugly hack; do not hog chain lock in case syncing is CPU-limited by validation + }() self.wg.Add(1) defer self.wg.Done() @@ -397,7 +383,7 @@ func (self *LightChain) InsertHeaderChain(chain []*types.Header, checkFreq int) } return err } - i, err := self.hc.InsertHeaderChain(chain, checkFreq, whFunc) + i, err := self.hc.InsertHeaderChain(chain, whFunc, start) go self.postChainEvents(events) return i, err } |