core: simplify component flushing in storeBlock

Instead of flushing everything to `cache` and then to `bc.dao`, wrap `bc.dao`
directly for block/tx data and AERs and then flush to it. Block/transactions
are usually processed more quickly than other components, so they easily end
up in `cache` where they directly affect Seek performance for any executing
transaction.

Simple as it is this change improves voter NEO transfer benchmark with 1000
accounts by more than 25%, from ~18500 TPS to ~23500 TPS. It doesn't affect
much other cases.
This commit is contained in:
Roman Khimov 2021-09-22 13:38:53 +03:00
parent b66bc33cf9
commit c009356b73

View file

@ -904,6 +904,8 @@ func (bc *Blockchain) GetStateSyncModule() blockchainer.StateSync {
func (bc *Blockchain) storeBlock(block *block.Block, txpool *mempool.Pool) error { func (bc *Blockchain) storeBlock(block *block.Block, txpool *mempool.Pool) error {
var ( var (
cache = bc.dao.GetWrapped() cache = bc.dao.GetWrapped()
blockCache = bc.dao.GetWrapped()
aerCache = bc.dao.GetWrapped()
appExecResults = make([]*state.AppExecResult, 0, 2+len(block.Transactions)) appExecResults = make([]*state.AppExecResult, 0, 2+len(block.Transactions))
aerchan = make(chan *state.AppExecResult, len(block.Transactions)/8) // Tested 8 and 4 with no practical difference, but feel free to test more and tune. aerchan = make(chan *state.AppExecResult, len(block.Transactions)/8) // Tested 8 and 4 with no practical difference, but feel free to test more and tune.
aerdone = make(chan error) aerdone = make(chan error)
@ -911,7 +913,7 @@ func (bc *Blockchain) storeBlock(block *block.Block, txpool *mempool.Pool) error
) )
go func() { go func() {
var ( var (
kvcache = cache.GetWrapped() kvcache = blockCache
writeBuf = io.NewBufBinWriter() writeBuf = io.NewBufBinWriter()
) )
if err := kvcache.StoreAsBlock(block, writeBuf); err != nil { if err := kvcache.StoreAsBlock(block, writeBuf); err != nil {
@ -960,15 +962,11 @@ func (bc *Blockchain) storeBlock(block *block.Block, txpool *mempool.Pool) error
writeBuf.Reset() writeBuf.Reset()
} }
} }
_, err := kvcache.Persist()
if err != nil {
blockdone <- err
}
close(blockdone) close(blockdone)
}() }()
go func() { go func() {
var ( var (
kvcache = cache.GetWrapped() kvcache = aerCache
writeBuf = io.NewBufBinWriter() writeBuf = io.NewBufBinWriter()
err error err error
appendBlock bool appendBlock bool
@ -1010,11 +1008,6 @@ func (bc *Blockchain) storeBlock(block *block.Block, txpool *mempool.Pool) error
return return
} }
} }
_, err = kvcache.Persist()
if err != nil {
aerdone <- err
}
close(aerdone) close(aerdone)
}() }()
aer, err := bc.runPersist(bc.contracts.GetPersistScript(), block, cache, trigger.OnPersist) aer, err := bc.runPersist(bc.contracts.GetPersistScript(), block, cache, trigger.OnPersist)
@ -1129,6 +1122,16 @@ func (bc *Blockchain) storeBlock(block *block.Block, txpool *mempool.Pool) error
} }
bc.lock.Lock() bc.lock.Lock()
_, err = blockCache.Persist()
if err != nil {
bc.lock.Unlock()
return err
}
_, err = aerCache.Persist()
if err != nil {
bc.lock.Unlock()
return err
}
_, err = cache.Persist() _, err = cache.Persist()
if err != nil { if err != nil {
bc.lock.Unlock() bc.lock.Unlock()