core: moved mutex locks in insert blocks to start of function

Insert blocks will no longer allow processing of multiple chains at the
same time. The block lock has been moved to start of the function.
This commit is contained in:
obscuren 2015-04-28 17:26:29 +02:00
parent 04a09b7e2d
commit a4b79f1dac

View File

@ -496,6 +496,9 @@ func (self *ChainManager) procFutureBlocks() {
} }
func (self *ChainManager) InsertChain(chain types.Blocks) error { func (self *ChainManager) InsertChain(chain types.Blocks) error {
self.mu.Lock()
defer self.mu.Unlock()
// A queued approach to delivering events. This is generally faster than direct delivery and requires much less mutex acquiring. // A queued approach to delivering events. This is generally faster than direct delivery and requires much less mutex acquiring.
var ( var (
queue = make([]interface{}, len(chain)) queue = make([]interface{}, len(chain))
@ -543,55 +546,51 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
block.Td = new(big.Int).Set(CalculateTD(block, self.GetBlock(block.ParentHash()))) block.Td = new(big.Int).Set(CalculateTD(block, self.GetBlock(block.ParentHash())))
self.mu.Lock() cblock := self.currentBlock
{ // Write block to database. Eventually we'll have to improve on this and throw away blocks that are
cblock := self.currentBlock // not in the canonical chain.
// Write block to database. Eventually we'll have to improve on this and throw away blocks that are self.write(block)
// not in the canonical chain. // Compare the TD of the last known block in the canonical chain to make sure it's greater.
self.write(block) // At this point it's possible that a different chain (fork) becomes the new canonical chain.
// Compare the TD of the last known block in the canonical chain to make sure it's greater. if block.Td.Cmp(self.td) > 0 {
// At this point it's possible that a different chain (fork) becomes the new canonical chain. //if block.Header().Number.Cmp(new(big.Int).Add(cblock.Header().Number, common.Big1)) < 0 {
if block.Td.Cmp(self.td) > 0 { if block.Number().Cmp(cblock.Number()) <= 0 {
//if block.Header().Number.Cmp(new(big.Int).Add(cblock.Header().Number, common.Big1)) < 0 { chash := cblock.Hash()
if block.Number().Cmp(cblock.Number()) <= 0 { hash := block.Hash()
chash := cblock.Hash()
hash := block.Hash()
if glog.V(logger.Info) { if glog.V(logger.Info) {
glog.Infof("Split detected. New head #%v (%x) TD=%v, was #%v (%x) TD=%v\n", block.Header().Number, hash[:4], block.Td, cblock.Header().Number, chash[:4], self.td) glog.Infof("Split detected. New head #%v (%x) TD=%v, was #%v (%x) TD=%v\n", block.Header().Number, hash[:4], block.Td, cblock.Header().Number, chash[:4], self.td)
}
// during split we merge two different chains and create the new canonical chain
self.merge(self.getBlockByNumber(block.NumberU64()), block)
queue[i] = ChainSplitEvent{block, logs}
queueEvent.splitCount++
} }
// during split we merge two different chains and create the new canonical chain
self.merge(self.getBlockByNumber(block.NumberU64()), block)
self.setTotalDifficulty(block.Td) queue[i] = ChainSplitEvent{block, logs}
self.insert(block) queueEvent.splitCount++
jsonlogger.LogJson(&logger.EthChainNewHead{
BlockHash: block.Hash().Hex(),
BlockNumber: block.Number(),
ChainHeadHash: cblock.Hash().Hex(),
BlockPrevHash: block.ParentHash().Hex(),
})
self.setTransState(state.New(block.Root(), self.stateDb))
self.txState.SetState(state.New(block.Root(), self.stateDb))
queue[i] = ChainEvent{block, logs}
queueEvent.canonicalCount++
if glog.V(logger.Debug) {
glog.Infof("inserted block #%d (%d TXs %d UNCs) (%x...)\n", block.Number(), len(block.Transactions()), len(block.Uncles()), block.Hash().Bytes()[0:4])
}
} else {
queue[i] = ChainSideEvent{block, logs}
queueEvent.sideCount++
} }
self.setTotalDifficulty(block.Td)
self.insert(block)
jsonlogger.LogJson(&logger.EthChainNewHead{
BlockHash: block.Hash().Hex(),
BlockNumber: block.Number(),
ChainHeadHash: cblock.Hash().Hex(),
BlockPrevHash: block.ParentHash().Hex(),
})
self.setTransState(state.New(block.Root(), self.stateDb))
self.txState.SetState(state.New(block.Root(), self.stateDb))
queue[i] = ChainEvent{block, logs}
queueEvent.canonicalCount++
if glog.V(logger.Debug) {
glog.Infof("inserted block #%d (%d TXs %d UNCs) (%x...)\n", block.Number(), len(block.Transactions()), len(block.Uncles()), block.Hash().Bytes()[0:4])
}
} else {
queue[i] = ChainSideEvent{block, logs}
queueEvent.sideCount++
} }
self.mu.Unlock()
stats.processed++ stats.processed++