core: improve and fix locking in storeBlock

Getting batch, updating Prometheus metrics and pushing events doesn't require
any locking: batch is a local cache batch that no one outside cares about,
Prometheus metrics are not critical to be in perfect sync and events are
asynchronous anyway.

Native contracts also don't require any locks and they should be processed
before dumping storage changes.
This commit is contained in:
Roman Khimov 2020-05-12 17:45:17 +03:00
parent bef14977a2
commit 44ae9086b6

View file

@ -802,12 +802,6 @@ func (bc *Blockchain) storeBlock(block *block.Block) error {
} }
} }
} }
bc.lock.Lock()
defer bc.lock.Unlock()
if bc.config.SaveStorageBatch {
bc.lastBatch = cache.DAO.GetBatch()
}
for i := range bc.contracts.Contracts { for i := range bc.contracts.Contracts {
systemInterop := bc.newInteropContext(trigger.Application, cache, block, nil) systemInterop := bc.newInteropContext(trigger.Application, cache, block, nil)
@ -816,14 +810,22 @@ func (bc *Blockchain) storeBlock(block *block.Block) error {
} }
} }
if bc.config.SaveStorageBatch {
bc.lastBatch = cache.DAO.GetBatch()
}
bc.lock.Lock()
_, err := cache.Persist() _, err := cache.Persist()
if err != nil { if err != nil {
bc.lock.Unlock()
return err return err
} }
bc.topBlock.Store(block) bc.topBlock.Store(block)
atomic.StoreUint32(&bc.blockHeight, block.Index) atomic.StoreUint32(&bc.blockHeight, block.Index)
updateBlockHeightMetric(block.Index)
bc.memPool.RemoveStale(bc.isTxStillRelevant, bc) bc.memPool.RemoveStale(bc.isTxStillRelevant, bc)
bc.lock.Unlock()
updateBlockHeightMetric(block.Index)
// Genesis block is stored when Blockchain is not yet running, so there // Genesis block is stored when Blockchain is not yet running, so there
// is no one to read this event. And it doesn't make much sense as event // is no one to read this event. And it doesn't make much sense as event
// anyway. // anyway.