Skip to content

Commit d4f4173

Browse files
committed
perf: parse CCbTx once during block validation (merkle roots and CL)
It combines calls CheckCbTxMerkleRoots and CheckCbTxBestChainlock
1 parent 09aa42e commit d4f4173

File tree

3 files changed

+43
-46
lines changed

3 files changed

+43
-46
lines changed

src/evo/cbtx.cpp

Lines changed: 11 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -59,31 +59,15 @@ bool CheckCbTx(const CTransaction& tx, const CBlockIndex* pindexPrev, TxValidati
5959
}
6060

6161
// This can only be done after the block has been fully processed, as otherwise we won't have the finished MN list
62-
bool CheckCbTxMerkleRoots(const CBlock& block, const CBlockIndex* pindex,
62+
bool CheckCbTxMerkleRoots(const CBlock& block, const CCbTx& cbTx, const CBlockIndex* pindex,
6363
const llmq::CQuorumBlockProcessor& quorum_block_processor, CSimplifiedMNList&& sml,
6464
BlockValidationState& state)
6565
{
66-
if (block.vtx[0]->nType != TRANSACTION_COINBASE) {
67-
return true;
68-
}
69-
70-
static int64_t nTimePayload = 0;
71-
72-
int64_t nTime1 = GetTimeMicros();
73-
74-
const auto opt_cbTx = GetTxPayload<CCbTx>(*block.vtx[0]);
75-
if (!opt_cbTx) {
76-
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cbtx-payload");
77-
}
78-
auto cbTx = *opt_cbTx;
79-
80-
int64_t nTime2 = GetTimeMicros(); nTimePayload += nTime2 - nTime1;
81-
LogPrint(BCLog::BENCHMARK, " - GetTxPayload: %.2fms [%.2fs]\n", 0.001 * (nTime2 - nTime1), nTimePayload * 0.000001);
82-
8366
if (pindex) {
8467
static int64_t nTimeMerkleMNL = 0;
8568
static int64_t nTimeMerkleQuorum = 0;
8669

70+
int64_t nTime1 = GetTimeMicros();
8771
uint256 calculatedMerkleRoot;
8872
if (!CalcCbTxMerkleRootMNList(calculatedMerkleRoot, std::move(sml), state)) {
8973
// pass the state returned by the function above
@@ -93,8 +77,10 @@ bool CheckCbTxMerkleRoots(const CBlock& block, const CBlockIndex* pindex,
9377
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cbtx-mnmerkleroot");
9478
}
9579

96-
int64_t nTime3 = GetTimeMicros(); nTimeMerkleMNL += nTime3 - nTime2;
97-
LogPrint(BCLog::BENCHMARK, " - CalcCbTxMerkleRootMNList: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeMerkleMNL * 0.000001);
80+
int64_t nTime2 = GetTimeMicros();
81+
nTimeMerkleMNL += nTime2 - nTime1;
82+
LogPrint(BCLog::BENCHMARK, " - CalcCbTxMerkleRootMNList: %.2fms [%.2fs]\n", 0.001 * (nTime2 - nTime1),
83+
nTimeMerkleMNL * 0.000001);
9884

9985
if (cbTx.nVersion >= CCbTx::Version::MERKLE_ROOT_QUORUMS) {
10086
if (!CalcCbTxMerkleRootQuorums(block, pindex->pprev, quorum_block_processor, calculatedMerkleRoot, state)) {
@@ -106,9 +92,10 @@ bool CheckCbTxMerkleRoots(const CBlock& block, const CBlockIndex* pindex,
10692
}
10793
}
10894

109-
int64_t nTime4 = GetTimeMicros(); nTimeMerkleQuorum += nTime4 - nTime3;
110-
LogPrint(BCLog::BENCHMARK, " - CalcCbTxMerkleRootQuorums: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeMerkleQuorum * 0.000001);
111-
95+
int64_t nTime3 = GetTimeMicros();
96+
nTimeMerkleQuorum += nTime3 - nTime2;
97+
LogPrint(BCLog::BENCHMARK, " - CalcCbTxMerkleRootQuorums: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2),
98+
nTimeMerkleQuorum * 0.000001);
11299
}
113100

114101
return true;
@@ -314,19 +301,9 @@ bool CalcCbTxMerkleRootQuorums(const CBlock& block, const CBlockIndex* pindexPre
314301
return true;
315302
}
316303

317-
bool CheckCbTxBestChainlock(const CBlock& block, const CBlockIndex* pindex,
304+
bool CheckCbTxBestChainlock(const CCbTx& cbTx, const CBlockIndex* pindex,
318305
const llmq::CChainLocksHandler& chainlock_handler, BlockValidationState& state)
319306
{
320-
if (block.vtx[0]->nType != TRANSACTION_COINBASE) {
321-
return true;
322-
}
323-
324-
const auto opt_cbTx = GetTxPayload<CCbTx>(*block.vtx[0]);
325-
if (!opt_cbTx) {
326-
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cbtx-payload");
327-
}
328-
const auto& cbTx = *opt_cbTx;
329-
330307
if (cbTx.nVersion < CCbTx::Version::CLSIG_AND_BALANCE) {
331308
return true;
332309
}

src/evo/cbtx.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,15 @@ template<> struct is_serializable_enum<CCbTx::Version> : std::true_type {};
6666

6767
bool CheckCbTx(const CTransaction& tx, const CBlockIndex* pindexPrev, TxValidationState& state);
6868

69-
bool CheckCbTxMerkleRoots(const CBlock& block, const CBlockIndex* pindex,
69+
bool CheckCbTxMerkleRoots(const CBlock& block, const CCbTx& cbTx, const CBlockIndex* pindex,
7070
const llmq::CQuorumBlockProcessor& quorum_block_processor, CSimplifiedMNList&& sml,
7171
BlockValidationState& state);
7272
bool CalcCbTxMerkleRootMNList(uint256& merkleRootRet, CSimplifiedMNList&& sml, BlockValidationState& state);
7373
bool CalcCbTxMerkleRootQuorums(const CBlock& block, const CBlockIndex* pindexPrev,
7474
const llmq::CQuorumBlockProcessor& quorum_block_processor, uint256& merkleRootRet,
7575
BlockValidationState& state);
7676

77-
bool CheckCbTxBestChainlock(const CBlock& block, const CBlockIndex* pindexPrev,
77+
bool CheckCbTxBestChainlock(const CCbTx& cbTx, const CBlockIndex* pindexPrev,
7878
const llmq::CChainLocksHandler& chainlock_handler, BlockValidationState& state);
7979
bool CalcCbTxBestChainlock(const llmq::CChainLocksHandler& chainlock_handler, const CBlockIndex* pindexPrev,
8080
uint32_t& bestCLHeightDiff, CBLSSignature& bestCLSignature);

src/evo/specialtxman.cpp

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -193,18 +193,38 @@ bool CSpecialTxProcessor::ProcessSpecialTxsInBlock(const CBlock& block, const CB
193193
nTimeDMN += nTime4 - nTime3;
194194
LogPrint(BCLog::BENCHMARK, " - m_dmnman: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeDMN * 0.000001);
195195

196-
if (fCheckCbTxMerkleRoots && !CheckCbTxMerkleRoots(block, pindex, m_qblockman, CSimplifiedMNList(mn_list), state)) {
197-
// pass the state returned by the function above
198-
return false;
199-
}
196+
int64_t nTime5{nTime4};
200197

201-
int64_t nTime5 = GetTimeMicros();
202-
nTimeMerkle += nTime5 - nTime4;
203-
LogPrint(BCLog::BENCHMARK, " - CheckCbTxMerkleRoots: %.2fms [%.2fs]\n", 0.001 * (nTime5 - nTime4), nTimeMerkle * 0.000001);
198+
if (fCheckCbTxMerkleRoots && block.vtx[0]->nType == TRANSACTION_COINBASE) {
199+
int64_t nTime1_cbtx = GetTimeMicros();
204200

205-
if (fCheckCbTxMerkleRoots && !CheckCbTxBestChainlock(block, pindex, m_clhandler, state)) {
206-
// pass the state returned by the function above
207-
return false;
201+
const auto opt_cbTx = GetTxPayload<CCbTx>(*block.vtx[0]);
202+
if (!opt_cbTx) {
203+
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cbtx-payload");
204+
}
205+
static int64_t nTimePayload = 0;
206+
207+
int64_t nTime2_cbtx = GetTimeMicros();
208+
nTimePayload += nTime2_cbtx - nTime1_cbtx;
209+
LogPrint(BCLog::BENCHMARK, " - GetTxPayload: %.2fms [%.2fs]\n",
210+
0.001 * (nTime2_cbtx - nTime1_cbtx), nTimePayload * 0.000001);
211+
212+
if (!CheckCbTxMerkleRoots(block, *opt_cbTx, pindex, m_qblockman, CSimplifiedMNList(mn_list), state)) {
213+
// pass the state returned by the function above
214+
return false;
215+
}
216+
217+
nTime5 = GetTimeMicros();
218+
nTimeMerkle += nTime5 - nTime4;
219+
220+
LogPrint(BCLog::BENCHMARK, " - CheckCbTxMerkleRoots: %.2fms [%.2fs]\n", 0.001 * (nTime5 - nTime4),
221+
nTimeMerkle * 0.000001);
222+
223+
224+
if (!CheckCbTxBestChainlock(*opt_cbTx, pindex, m_clhandler, state)) {
225+
// pass the state returned by the function above
226+
return false;
227+
}
208228
}
209229

210230
int64_t nTime6 = GetTimeMicros();

0 commit comments

Comments
 (0)