aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeffrey Wilcke <jeffrey@ethereum.org>2015-05-17 23:54:16 +0800
committerJeffrey Wilcke <jeffrey@ethereum.org>2015-05-17 23:54:16 +0800
commit443d0248436f653bc2d56653dd52b8abbe408f60 (patch)
treec6e47b04770c322a0023b19ba5d1b2aa0dfac877
parent426c70ac0b6f0051e4e618c1eff231a6bed8e6ee (diff)
parent27782bbadec13482311754457e6e913fab076f8a (diff)
downloadgo-tangerine-443d0248436f653bc2d56653dd52b8abbe408f60.tar.gz
go-tangerine-443d0248436f653bc2d56653dd52b8abbe408f60.tar.zst
go-tangerine-443d0248436f653bc2d56653dd52b8abbe408f60.zip
Merge pull request #1021 from obscuren/global_chain_lock
core: global chain insert lock
-rw-r--r--core/chain_manager.go87
1 files changed, 43 insertions, 44 deletions
diff --git a/core/chain_manager.go b/core/chain_manager.go
index 2e8eb927d..62e518ca0 100644
--- a/core/chain_manager.go
+++ b/core/chain_manager.go
@@ -83,8 +83,9 @@ type ChainManager struct {
eventMux *event.TypeMux
genesisBlock *types.Block
// Last known total difficulty
- mu sync.RWMutex
- tsmu sync.RWMutex
+ mu sync.RWMutex
+ chainmu sync.RWMutex
+ tsmu sync.RWMutex
td *big.Int
currentBlock *types.Block
@@ -518,6 +519,9 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
self.wg.Add(1)
defer self.wg.Done()
+ self.chainmu.Lock()
+ defer self.chainmu.Unlock()
+
// A queued approach to delivering events. This is generally faster than direct delivery and requires much less mutex acquiring.
var (
queue = make([]interface{}, len(chain))
@@ -542,7 +546,6 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
continue
}
- block.Td = new(big.Int)
// Do not penelise on future block. We'll need a block queue eventually that will queue
// future block for future use
if err == BlockFutureErr {
@@ -568,54 +571,50 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
return i, err
}
- self.mu.Lock()
- {
- cblock := self.currentBlock
- // Write block to database. Eventually we'll have to improve on this and throw away blocks that are
- // not in the canonical chain.
- self.write(block)
- // Compare the TD of the last known block in the canonical chain to make sure it's greater.
- // At this point it's possible that a different chain (fork) becomes the new canonical chain.
- if block.Td.Cmp(self.td) > 0 {
- // chain fork
- if block.ParentHash() != cblock.Hash() {
- // during split we merge two different chains and create the new canonical chain
- self.merge(cblock, block)
-
- queue[i] = ChainSplitEvent{block, logs}
- queueEvent.splitCount++
- }
-
- self.setTotalDifficulty(block.Td)
- self.insert(block)
+ cblock := self.currentBlock
+ // Write block to database. Eventually we'll have to improve on this and throw away blocks that are
+ // not in the canonical chain.
+ self.write(block)
+ // Compare the TD of the last known block in the canonical chain to make sure it's greater.
+ // At this point it's possible that a different chain (fork) becomes the new canonical chain.
+ if block.Td.Cmp(self.td) > 0 {
+ // chain fork
+ if block.ParentHash() != cblock.Hash() {
+ // during split we merge two different chains and create the new canonical chain
+ self.merge(cblock, block)
+
+ queue[i] = ChainSplitEvent{block, logs}
+ queueEvent.splitCount++
+ }
- jsonlogger.LogJson(&logger.EthChainNewHead{
- BlockHash: block.Hash().Hex(),
- BlockNumber: block.Number(),
- ChainHeadHash: cblock.Hash().Hex(),
- BlockPrevHash: block.ParentHash().Hex(),
- })
+ self.setTotalDifficulty(block.Td)
+ self.insert(block)
- self.setTransState(state.New(block.Root(), self.stateDb))
- self.txState.SetState(state.New(block.Root(), self.stateDb))
+ jsonlogger.LogJson(&logger.EthChainNewHead{
+ BlockHash: block.Hash().Hex(),
+ BlockNumber: block.Number(),
+ ChainHeadHash: cblock.Hash().Hex(),
+ BlockPrevHash: block.ParentHash().Hex(),
+ })
- queue[i] = ChainEvent{block, block.Hash(), logs}
- queueEvent.canonicalCount++
+ self.setTransState(state.New(block.Root(), self.stateDb))
+ self.txState.SetState(state.New(block.Root(), self.stateDb))
- if glog.V(logger.Debug) {
- glog.Infof("[%v] inserted block #%d (%d TXs %d UNCs) (%x...)\n", time.Now().UnixNano(), block.Number(), len(block.Transactions()), len(block.Uncles()), block.Hash().Bytes()[0:4])
- }
- } else {
- if glog.V(logger.Detail) {
- glog.Infof("inserted forked block #%d (TD=%v) (%d TXs %d UNCs) (%x...)\n", block.Number(), block.Difficulty(), len(block.Transactions()), len(block.Uncles()), block.Hash().Bytes()[0:4])
- }
+ queue[i] = ChainEvent{block, block.Hash(), logs}
+ queueEvent.canonicalCount++
- queue[i] = ChainSideEvent{block, logs}
- queueEvent.sideCount++
+ if glog.V(logger.Debug) {
+ glog.Infof("[%v] inserted block #%d (%d TXs %d UNCs) (%x...)\n", time.Now().UnixNano(), block.Number(), len(block.Transactions()), len(block.Uncles()), block.Hash().Bytes()[0:4])
}
- self.futureBlocks.Delete(block.Hash())
+ } else {
+ if glog.V(logger.Detail) {
+ glog.Infof("inserted forked block #%d (TD=%v) (%d TXs %d UNCs) (%x...)\n", block.Number(), block.Difficulty(), len(block.Transactions()), len(block.Uncles()), block.Hash().Bytes()[0:4])
+ }
+
+ queue[i] = ChainSideEvent{block, logs}
+ queueEvent.sideCount++
}
- self.mu.Unlock()
+ self.futureBlocks.Delete(block.Hash())
stats.processed++