tip: 269
title: Optimize the performance of block processing
author: kayle.liu <[email protected]>
status: Fnial
type: Standards Track
category: Core
created: 2021-05-21
This TIP is to optimize the block processing speed.
Through the performance analysis of the block processing, it was found that the slower execution time of payStandbyWitness in the block processing is due to the fact that more queries and deserialization operations are taken up by the sorting operation of the witness in the processing block.
Nearly 1/3 of the block processing speed is consumed in the block reward method time (payStandbyWitness). Optimize the block processing speed, you can improve the block processing speed, reduce the number of queries to the database, the number of queries to the database in the execution of the payStandbyWitness method, reduce to once, can reduce the use of the system on performance.
`---[387.867829ms] org.tron.core.db.Manager:processBlock()
+---[0.265525ms] org.tron.consensus.Consensus:validBlock() #1396
+---[0.003094ms] org.tron.core.ChainBaseManager:getBalanceTraceStore() #1400
+---[0.004708ms] org.tron.core.store.BalanceTraceStore:initCurrentBlockBalanceTrace() #95
+---[0.002026ms] org.tron.core.ChainBaseManager:getDynamicPropertiesStore() #1403
+---[0.007791ms] org.tron.core.store.DynamicPropertiesStore:saveBlockEnergyUsage() #95
+---[94.568061ms] org.tron.core.db.Manager:preValidateTransactionSign() #1407
+---[0.019178ms] org.tron.core.capsule.TransactionRetCapsule:<init>() #1414
+---[0.021173ms] org.tron.common.zksnark.MerkleContainer:resetCurrentMerkleTree() #1417
+---[0.040949ms] org.tron.core.db.accountstate.callback.AccountStateCallBack:preExecute() #1418
+---[0.002595ms] org.tron.core.capsule.BlockCapsule:getTransactions() #1419
+---[min=0.001298ms,max=0.013595ms,total=0.289364ms,count=146] org.tron.core.capsule.BlockCapsule:getNum() #1420
+---[min=0.001379ms,max=0.014655ms,total=0.29639ms,count=146] org.tron.core.capsule.TransactionCapsule:setBlockNum() #95
+---[min=0.001424ms,max=0.005147ms,total=0.245214ms,count=146] org.tron.core.db.accountstate.callback.AccountStateCallBack:preExeTrans() #1424
+---[min=0.155521ms,max=9.70466ms,total=187.607083ms,count=146] org.tron.core.db.Manager:processTransaction() #1425
+---[min=0.00161ms,max=0.007481ms,total=0.344484ms,count=146] org.tron.core.capsule.TransactionCapsule:getInstance() #1426
+---[min=0.001784ms,max=0.022878ms,total=0.346678ms,count=146] org.tron.core.db.Manager:isMultiSignTransaction() #95
+---[min=0.001444ms,max=0.01404ms,total=0.316956ms,count=146] org.tron.core.db.accountstate.callback.AccountStateCallBack:exeTransFinish() #1429
+---[min=0.001993ms,max=0.047268ms,total=0.485732ms,count=146] org.tron.core.capsule.TransactionRetCapsule:addTransactionInfo() #1431
+---[0.003836ms] org.tron.core.db.accountstate.callback.AccountStateCallBack:executePushFinish() #1434
+---[0.002098ms] org.tron.core.db.accountstate.callback.AccountStateCallBack:exceptionFinish() #1436
+---[0.202892ms] org.slf4j.Logger:info() #1438
+---[0.00192ms] org.tron.core.capsule.BlockCapsule:getNum() #1439
+---[4.939971ms] org.tron.common.zksnark.MerkleContainer:saveCurrentMerkleTreeAsBestMerkleTree() #95
+---[0.003103ms] org.tron.core.capsule.BlockCapsule:setResult() #1440
+---[0.004572ms] org.tron.core.db.Manager:getDynamicPropertiesStore() #1441
+---[0.037116ms] org.tron.core.store.DynamicPropertiesStore:getAllowAdaptiveEnergy() #95
+---[82.440979ms] org.tron.core.db.Manager:payReward() #1448
+---[0.003923ms] org.tron.core.ChainBaseManager:getDynamicPropertiesStore() #1450
+---[0.027954ms] org.tron.core.store.DynamicPropertiesStore:getNextMaintenanceTime() #95
+---[0.004259ms] org.tron.core.capsule.BlockCapsule:getTimeStamp() #1451
before optimizing
private void sortWitness(List<ByteString> list) {
list.sort(
Comparator.comparingLong(
(ByteString b) -> getWitnessByAddress(b).getVoteCount())
.reversed()
.thenComparing(
Comparator.comparingInt(ByteString::hashCode).reversed()
)
);
}
getWitnessByAddress(b) This method makes more than 4,000 calls to the query, and the main performance consumption is in this method.
- avoid querying in the comparison, the witness list will be obtained by a single query
- the maintenance period already has in-order witness can be obtained through DynamicPropertiesStore
Simplify witness queries To get the ordered witness list from dynamicPropertiesStore, you don't need to query the database iteratively, you can get the witness list in just one query.
This can reduce the database query and the deserialization operation needed after the query, after verification, the optimized payStandbyWitness processing time
`---[267.667815ms] org.tron.core.db.Manager:processBlock()
+---[0.628656ms] org.tron.consensus.Consensus:validBlock() #1396
+---[0.011494ms] org.tron.core.ChainBaseManager:getBalanceTraceStore() #1400
+---[0.017455ms] org.tron.core.store.BalanceTraceStore:initCurrentBlockBalanceTrace() #95
+---[0.004957ms] org.tron.core.ChainBaseManager:getDynamicPropertiesStore() #1403
+---[0.2191ms] org.tron.core.store.DynamicPropertiesStore:saveBlockEnergyUsage() #95
+---[85.907494ms] org.tron.core.db.Manager:preValidateTransactionSign() #1407
+---[0.03864ms] org.tron.core.capsule.TransactionRetCapsule:<init>() #1414
+---[0.031466ms] org.tron.common.zksnark.MerkleContainer:resetCurrentMerkleTree() #1417
+---[0.064555ms] org.tron.core.db.accountstate.callback.AccountStateCallBack:preExecute() #1418
+---[0.00469ms] org.tron.core.capsule.BlockCapsule:getTransactions() #1419
+---[min=0.001408ms,max=0.003854ms,total=0.231615ms,count=129] org.tron.core.capsule.BlockCapsule:getNum() #1420
+---[min=0.001363ms,max=0.01463ms,total=0.233787ms,count=129] org.tron.core.capsule.TransactionCapsule:setBlockNum() #95
+---[min=0.001391ms,max=0.013911ms,total=0.226157ms,count=129] org.tron.core.db.accountstate.callback.AccountStateCallBack:preExeTrans() #1424
+---[min=0.179635ms,max=14.21825ms,total=125.068821ms,count=129] org.tron.core.db.Manager:processTransaction() #1425
+---[min=0.001543ms,max=0.003416ms,total=0.259153ms,count=129] org.tron.core.capsule.TransactionCapsule:getInstance() #1426
+---[min=0.00164ms,max=0.029365ms,total=0.342206ms,count=129] org.tron.core.db.Manager:isMultiSignTransaction() #95
+---[min=0.001482ms,max=0.006611ms,total=0.261829ms,count=129] org.tron.core.db.accountstate.callback.AccountStateCallBack:exeTransFinish() #1429
+---[min=0.002065ms,max=0.034937ms,total=0.410742ms,count=129] org.tron.core.capsule.TransactionRetCapsule:addTransactionInfo() #1431
+---[0.012483ms] org.tron.core.db.accountstate.callback.AccountStateCallBack:executePushFinish() #1434
+---[0.004099ms] org.tron.core.db.accountstate.callback.AccountStateCallBack:exceptionFinish() #1436
+---[0.243828ms] org.slf4j.Logger:info() #1438
+---[0.001956ms] org.tron.core.capsule.BlockCapsule:getNum() #1439
+---[5.168033ms] org.tron.common.zksnark.MerkleContainer:saveCurrentMerkleTreeAsBestMerkleTree() #95
+---[0.009408ms] org.tron.core.capsule.BlockCapsule:setResult() #1440
+---[0.005415ms] org.tron.core.db.Manager:getDynamicPropertiesStore() #1441
+---[0.047165ms] org.tron.core.store.DynamicPropertiesStore:getAllowAdaptiveEnergy() #95
+---[42.898613ms] org.tron.core.db.Manager:payReward() #1448
+---[0.00315ms] org.tron.core.ChainBaseManager:getDynamicPropertiesStore() #1450
+---[0.025559ms] org.tron.core.store.DynamicPropertiesStore:getNextMaintenanceTime() #95
+---[0.007094ms] org.tron.core.capsule.BlockCapsule:getTimeStamp() #1451
+---[0.933923ms] org.tron.consensus.Consensus:applyBlock() #1456
+---[0.856817ms] org.tron.core.db.Manager:updateTransHashCache() #1460
+---[0.03403ms] org.tron.core.db.Manager:updateRecentBlock() #1461
+---[0.391325ms] org.tron.core.db.Manager:updateDynamicProperties() #1462
+---[0.003306ms] org.tron.core.ChainBaseManager:getBalanceTraceStore() #1464
`---[0.007784ms] org.tron.core.store.BalanceTraceStore:resetCurrentBlockTrace() #95