Skip to content

Commit 5950755

Browse files
committed
Merge pull request #1220 from karalabe/fix-chain-deadlock2
core: fix a lock annoyance and potential deadlock
2 parents 5f341e5 + 4541c22 commit 5950755

File tree

2 files changed

+18
-6
lines changed

2 files changed

+18
-6
lines changed

core/chain_manager.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,9 @@ func (self *ChainManager) Td() *big.Int {
179179
}
180180

181181
func (self *ChainManager) GasLimit() *big.Int {
182-
// return self.currentGasLimit
182+
self.mu.RLock()
183+
defer self.mu.RUnlock()
184+
183185
return self.currentBlock.GasLimit()
184186
}
185187

@@ -376,6 +378,8 @@ func (self *ChainManager) ExportN(w io.Writer, first uint64, last uint64) error
376378
return nil
377379
}
378380

381+
// insert injects a block into the current chain block chain. Note, this function
382+
// assumes that the `mu` mutex is held!
379383
func (bc *ChainManager) insert(block *types.Block) {
380384
key := append(blockNumPre, block.Number().Bytes()...)
381385
bc.blockDb.Put(key, block.Hash().Bytes())
@@ -484,6 +488,8 @@ func (self *ChainManager) GetAncestors(block *types.Block, length int) (blocks [
484488
return
485489
}
486490

491+
// setTotalDifficulty updates the TD of the chain manager. Note, this function
492+
// assumes that the `mu` mutex is held!
487493
func (bc *ChainManager) setTotalDifficulty(td *big.Int) {
488494
bc.td = new(big.Int).Set(td)
489495
}
@@ -540,9 +546,6 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
540546
self.wg.Add(1)
541547
defer self.wg.Done()
542548

543-
self.mu.Lock()
544-
defer self.mu.Unlock()
545-
546549
self.chainmu.Lock()
547550
defer self.chainmu.Unlock()
548551

@@ -625,7 +628,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
625628
cblock := self.currentBlock
626629
// Compare the TD of the last known block in the canonical chain to make sure it's greater.
627630
// At this point it's possible that a different chain (fork) becomes the new canonical chain.
628-
if block.Td.Cmp(self.td) > 0 {
631+
if block.Td.Cmp(self.Td()) > 0 {
629632
// chain fork
630633
if block.ParentHash() != cblock.Hash() {
631634
// during split we merge two different chains and create the new canonical chain
@@ -638,8 +641,10 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
638641
queueEvent.splitCount++
639642
}
640643

644+
self.mu.Lock()
641645
self.setTotalDifficulty(block.Td)
642646
self.insert(block)
647+
self.mu.Unlock()
643648

644649
jsonlogger.LogJson(&logger.EthChainNewHead{
645650
BlockHash: block.Hash().Hex(),
@@ -747,9 +752,11 @@ func (self *ChainManager) merge(oldBlock, newBlock *types.Block) error {
747752
}
748753

749754
// insert blocks. Order does not matter. Last block will be written in ImportChain itself which creates the new head properly
755+
self.mu.Lock()
750756
for _, block := range newChain {
751757
self.insert(block)
752758
}
759+
self.mu.Unlock()
753760

754761
return nil
755762
}

event/filter/filter_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package filter
22

3-
import "testing"
3+
import (
4+
"testing"
5+
"time"
6+
)
47

58
func TestFilters(t *testing.T) {
69
var success bool
@@ -24,6 +27,8 @@ func TestFilters(t *testing.T) {
2427
fm.Notify(Generic{Str1: "hello"}, true)
2528
fm.Stop()
2629

30+
time.Sleep(10 * time.Millisecond) // yield to the notifier
31+
2732
if !success {
2833
t.Error("expected 'hello' to be posted")
2934
}

0 commit comments

Comments
 (0)