From b97c2c550949d2808afa8d2c86a2c1cfd0cfbb57 Mon Sep 17 00:00:00 2001 From: Zsolt Felfoldi Date: Tue, 7 Mar 2017 17:45:05 +0100 Subject: [PATCH] core: moved header validation before chain mutex lock --- core/blockchain.go | 7 ++++++- core/headerchain.go | 13 +++++++++---- light/lightchain.go | 7 ++++++- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 207c21a659..a57832df02 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1313,6 +1313,11 @@ Error: %v // of the header retrieval mechanisms already need to verify nonces, as well as // because nonces can be verified sparsely, not needing to check each. func (self *BlockChain) 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() @@ -1328,7 +1333,7 @@ func (self *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) return err } - return self.hc.InsertHeaderChain(chain, checkFreq, whFunc) + return self.hc.InsertHeaderChain(chain, whFunc, start) } // writeHeader writes a header into the local chain, given that its parent is diff --git a/core/headerchain.go b/core/headerchain.go index a3d6220877..57da9771b1 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -219,7 +219,8 @@ type WhCallback func(*types.Header) error // should be done or not. The reason behind the optional check is because some // of the header retrieval mechanisms already need to verfy nonces, as well as // because nonces can be verified sparsely, not needing to check each. -func (hc *HeaderChain) InsertHeaderChain(chain []*types.Header, checkFreq int, writeHeader WhCallback) (int, error) { + +func (hc *HeaderChain) ValidateHeaderChain(chain []*types.Header, checkFreq int) (int, error) { // Do a sanity check that the provided chain is actually ordered and linked for i := 1; i < len(chain); i++ { if chain[i].Number.Uint64() != chain[i-1].Number.Uint64()+1 || chain[i].ParentHash != chain[i-1].Hash() { @@ -231,9 +232,6 @@ func (hc *HeaderChain) InsertHeaderChain(chain []*types.Header, checkFreq int, w chain[i-1].Hash().Bytes()[:4], i, chain[i].Number, chain[i].Hash().Bytes()[:4], chain[i].ParentHash[:4]) } } - // Collect some import statistics to report on - stats := struct{ processed, ignored int }{} - start := time.Now() // Generate the list of headers that should be POW verified verify := make([]bool, len(chain)) @@ -309,6 +307,13 @@ func (hc *HeaderChain) InsertHeaderChain(chain []*types.Header, checkFreq int, w } } } + + return 0, nil +} + +func (hc *HeaderChain) InsertHeaderChain(chain []*types.Header, writeHeader WhCallback, start time.Time) (int, error) { + // Collect some import statistics to report on + stats := struct{ processed, ignored int }{} // All headers passed verification, import them into the database for i, header := range chain { // Short circuit insertion if shutting down diff --git a/light/lightchain.go b/light/lightchain.go index 4370dc0fcc..9f7aabb90c 100644 --- a/light/lightchain.go +++ b/light/lightchain.go @@ -369,6 +369,11 @@ 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() @@ -397,7 +402,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 }