core, light: get rid of the dual mutexes, hard to reason with
This commit is contained in:
@ -57,7 +57,6 @@ type LightChain struct {
|
||||
scope event.SubscriptionScope
|
||||
genesisBlock *types.Block
|
||||
|
||||
mu sync.RWMutex
|
||||
chainmu sync.RWMutex
|
||||
|
||||
bodyCache *lru.Cache // Cache for the most recent block bodies
|
||||
@ -165,8 +164,8 @@ func (self *LightChain) loadLastState() error {
|
||||
// SetHead rewinds the local chain to a new head. Everything above the new
|
||||
// head will be deleted and the new one set.
|
||||
func (bc *LightChain) SetHead(head uint64) {
|
||||
bc.mu.Lock()
|
||||
defer bc.mu.Unlock()
|
||||
bc.chainmu.Lock()
|
||||
defer bc.chainmu.Unlock()
|
||||
|
||||
bc.hc.SetHead(head, nil)
|
||||
bc.loadLastState()
|
||||
@ -188,8 +187,8 @@ func (bc *LightChain) ResetWithGenesisBlock(genesis *types.Block) {
|
||||
// Dump the entire block chain and purge the caches
|
||||
bc.SetHead(0)
|
||||
|
||||
bc.mu.Lock()
|
||||
defer bc.mu.Unlock()
|
||||
bc.chainmu.Lock()
|
||||
defer bc.chainmu.Unlock()
|
||||
|
||||
// Prepare the genesis block and reinitialise the chain
|
||||
rawdb.WriteTd(bc.chainDb, genesis.Hash(), genesis.NumberU64(), genesis.Difficulty())
|
||||
@ -315,8 +314,8 @@ func (bc *LightChain) Stop() {
|
||||
// Rollback is designed to remove a chain of links from the database that aren't
|
||||
// certain enough to be valid.
|
||||
func (self *LightChain) Rollback(chain []common.Hash) {
|
||||
self.mu.Lock()
|
||||
defer self.mu.Unlock()
|
||||
self.chainmu.Lock()
|
||||
defer self.chainmu.Unlock()
|
||||
|
||||
for i := len(chain) - 1; i >= 0; i-- {
|
||||
hash := chain[i]
|
||||
@ -362,19 +361,13 @@ func (self *LightChain) InsertHeaderChain(chain []*types.Header, checkFreq int)
|
||||
|
||||
// Make sure only one thread manipulates the chain at once
|
||||
self.chainmu.Lock()
|
||||
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
|
||||
}()
|
||||
defer self.chainmu.Unlock()
|
||||
|
||||
self.wg.Add(1)
|
||||
defer self.wg.Done()
|
||||
|
||||
var events []interface{}
|
||||
whFunc := func(header *types.Header) error {
|
||||
self.mu.Lock()
|
||||
defer self.mu.Unlock()
|
||||
|
||||
status, err := self.hc.WriteHeader(header)
|
||||
|
||||
switch status {
|
||||
@ -441,8 +434,8 @@ func (self *LightChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []c
|
||||
//
|
||||
// Note: ancestor == 0 returns the same block, 1 returns its parent and so on.
|
||||
func (bc *LightChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) {
|
||||
bc.chainmu.Lock()
|
||||
defer bc.chainmu.Unlock()
|
||||
bc.chainmu.RLock()
|
||||
defer bc.chainmu.RUnlock()
|
||||
|
||||
return bc.hc.GetAncestor(hash, number, ancestor, maxNonCanonical)
|
||||
}
|
||||
@ -483,8 +476,8 @@ func (self *LightChain) SyncCht(ctx context.Context) bool {
|
||||
}
|
||||
// Retrieve the latest useful header and update to it
|
||||
if header, err := GetHeaderByNumber(ctx, self.odr, latest); header != nil && err == nil {
|
||||
self.mu.Lock()
|
||||
defer self.mu.Unlock()
|
||||
self.chainmu.Lock()
|
||||
defer self.chainmu.Unlock()
|
||||
|
||||
// Ensure the chain didn't move past the latest block while retrieving it
|
||||
if self.hc.CurrentHeader().Number.Uint64() < header.Number.Uint64() {
|
||||
|
@ -122,10 +122,10 @@ func testHeaderChainImport(chain []*types.Header, lightchain *LightChain) error
|
||||
return err
|
||||
}
|
||||
// Manually insert the header into the database, but don't reorganize (allows subsequent testing)
|
||||
lightchain.mu.Lock()
|
||||
lightchain.chainmu.Lock()
|
||||
rawdb.WriteTd(lightchain.chainDb, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, lightchain.GetTdByHash(header.ParentHash)))
|
||||
rawdb.WriteHeader(lightchain.chainDb, header)
|
||||
lightchain.mu.Unlock()
|
||||
lightchain.chainmu.Unlock()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user