Skip to content

Commit 7bed080

Browse files
committed
perf: cache shared_ptr to SML instead of SML list
Shared_ptr to SML is preserved between multiple CDeterministicMNList and it helps to avoid building SML from a scratch; also it helps to avoid comparision of SML item-by-item.
1 parent 3b4a1a0 commit 7bed080

File tree

7 files changed

+20
-10
lines changed

7 files changed

+20
-10
lines changed

src/evo/cbtx.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
class BlockValidationState;
1515
class CBlock;
1616
class CBlockIndex;
17+
class CDeterministicMNList;
1718
class TxValidationState;
19+
1820
namespace llmq {
1921
class CQuorumBlockProcessor;
2022
}// namespace llmq

src/evo/deterministicmns.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,8 @@ bool CDeterministicMNManager::ProcessBlock(const CBlock& block, gsl::not_null<co
618618
int nHeight = pindex->nHeight;
619619

620620
try {
621+
newList.GetSML(); // to fullfill cache of SML
622+
621623
LOCK(cs);
622624

623625
oldList = GetListForBlockInternal(pindex->pprev);
@@ -633,6 +635,7 @@ bool CDeterministicMNManager::ProcessBlock(const CBlock& block, gsl::not_null<co
633635

634636
diff.nHeight = pindex->nHeight;
635637
mnListDiffsCache.emplace(pindex->GetBlockHash(), diff);
638+
mnListsCache.emplace(newList.GetBlockHash(), newList);
636639
} catch (const std::exception& e) {
637640
LogPrintf("CDeterministicMNManager::%s -- internal error: %s\n", __func__, e.what());
638641
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "failed-dmn-block");
@@ -766,7 +769,10 @@ CDeterministicMNList CDeterministicMNManager::GetListForBlockInternal(gsl::not_n
766769
if (tipIndex) {
767770
// always keep a snapshot for the tip
768771
if (snapshot.GetBlockHash() == tipIndex->GetBlockHash()) {
769-
mnListsCache.emplace(snapshot.GetBlockHash(), snapshot);
772+
auto hash = snapshot.GetBlockHash();
773+
if (mnListsCache.find(hash) == mnListsCache.end()) {
774+
mnListsCache.emplace(snapshot.GetBlockHash(), snapshot);
775+
}
770776
} else {
771777
// keep snapshots for yet alive quorums
772778
if (ranges::any_of(Params().GetConsensus().llmqs,

src/evo/simplifiedmns.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,20 +104,22 @@ bool CSimplifiedMNList::operator==(const CSimplifiedMNList& rhs) const
104104
);
105105
}
106106

107-
bool CalcCbTxMerkleRootMNList(uint256& merkleRootRet, CSimplifiedMNList&& sml, BlockValidationState& state)
107+
bool CalcCbTxMerkleRootMNList(uint256& merkleRootRet, const CDeterministicMNList& mn_list, BlockValidationState& state)
108108
{
109109
try {
110110
static std::atomic<int64_t> nTimeMerkle = 0;
111111

112112
int64_t nTime1 = GetTimeMicros();
113113

114114
static Mutex cached_mutex;
115-
static CSimplifiedMNList smlCached GUARDED_BY(cached_mutex);
115+
static std::shared_ptr<const CSimplifiedMNList> cached_sml GUARDED_BY(cached_mutex){
116+
std::make_shared<const CSimplifiedMNList>()};
116117
static uint256 merkleRootCached GUARDED_BY(cached_mutex);
117118
static bool mutatedCached GUARDED_BY(cached_mutex){false};
118119

120+
std::shared_ptr<const CSimplifiedMNList> sml{mn_list.GetSML()};
119121
LOCK(cached_mutex);
120-
if (sml == smlCached) {
122+
if (sml == cached_sml || *sml == *cached_sml) {
121123
merkleRootRet = merkleRootCached;
122124
if (mutatedCached) {
123125
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "mutated-cached-calc-cb-mnmerkleroot");
@@ -126,14 +128,14 @@ bool CalcCbTxMerkleRootMNList(uint256& merkleRootRet, CSimplifiedMNList&& sml, B
126128
}
127129

128130
bool mutated = false;
129-
merkleRootRet = sml.CalcMerkleRoot(&mutated);
131+
merkleRootRet = sml->CalcMerkleRoot(&mutated);
130132

131133
int64_t nTime2 = GetTimeMicros();
132134
nTimeMerkle += nTime2 - nTime1;
133135
LogPrint(BCLog::BENCHMARK, " - CalcMerkleRoot: %.2fms [%.2fs]\n", 0.001 * (nTime2 - nTime1),
134136
nTimeMerkle * 0.000001);
135137

136-
smlCached = std::move(sml);
138+
cached_sml = sml;
137139
merkleRootCached = merkleRootRet;
138140
mutatedCached = mutated;
139141

src/evo/simplifiedmns.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,6 @@ class CSimplifiedMNList
110110
bool operator==(const CSimplifiedMNList& rhs) const;
111111
};
112112

113-
bool CalcCbTxMerkleRootMNList(uint256& merkleRootRet, CSimplifiedMNList&& sml, BlockValidationState& state);
113+
bool CalcCbTxMerkleRootMNList(uint256& merkleRootRet, const CDeterministicMNList& sml, BlockValidationState& state);
114114

115115
#endif // BITCOIN_EVO_SIMPLIFIEDMNS_H

src/evo/specialtxman.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,7 @@ bool CSpecialTxProcessor::ProcessSpecialTxsInBlock(const CBlock& block, const CB
608608
nTimeDMN * 0.000001);
609609

610610
uint256 calculatedMerkleRoot;
611-
if (!CalcCbTxMerkleRootMNList(calculatedMerkleRoot, CSimplifiedMNList{std::move(mn_list)}, state)) {
611+
if (!CalcCbTxMerkleRootMNList(calculatedMerkleRoot, mn_list, state)) {
612612
// pass the state returned by the function above
613613
return false;
614614
}

src/node/miner.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
291291
if (!m_chain_helper.special_tx->BuildNewListFromBlock(*pblock, pindexPrev, m_chainstate.CoinsTip(), true, state, mn_list)) {
292292
throw std::runtime_error(strprintf("%s: BuildNewListFromBlock failed: %s", __func__, state.ToString()));
293293
}
294-
if (!CalcCbTxMerkleRootMNList(cbTx.merkleRootMNList, CSimplifiedMNList(mn_list), state)) {
294+
if (!CalcCbTxMerkleRootMNList(cbTx.merkleRootMNList, mn_list, state)) {
295295
throw std::runtime_error(strprintf("%s: CalcCbTxMerkleRootMNList failed: %s", __func__, state.ToString()));
296296
}
297297
if (fDIP0008Active_context) {

src/test/util/setup_common.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ CBlock TestChainSetup::CreateBlock(
519519
if (!chainstate.ChainHelper().special_tx->BuildNewListFromBlock(block, chainstate.m_chain.Tip(), chainstate.CoinsTip(), true, state, mn_list)) {
520520
Assert(false);
521521
}
522-
if (!CalcCbTxMerkleRootMNList(cbTx->merkleRootMNList, CSimplifiedMNList(mn_list), state)) {
522+
if (!CalcCbTxMerkleRootMNList(cbTx->merkleRootMNList, mn_list, state)) {
523523
Assert(false);
524524
}
525525
if (!CalcCbTxMerkleRootQuorums(block, chainstate.m_chain.Tip(), *m_node.llmq_ctx->quorum_block_processor, cbTx->merkleRootQuorums, state)) {

0 commit comments

Comments
 (0)