Skip to content

Commit 4092abc

Browse files
UdjinM6PastaPastaPasta
authored andcommitted
fix: Improve quorum data caching and cleanup (dashpay#5731)
## Issue being fixed or feature implemented ## What was done? ## How Has This Been Tested? ## Breaking Changes ## Checklist: - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [ ] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ --------- Co-authored-by: PastaPastaPasta <[email protected]>
1 parent 96d4a30 commit 4092abc

File tree

5 files changed

+67
-31
lines changed

5 files changed

+67
-31
lines changed

src/llmq/params.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,13 @@ struct LLMQParams {
104104
// For rotated quorums it should be equal to 2 x active quorums set.
105105
int keepOldConnections;
106106

107+
// The number of quorums for which we should keep keys. Usually it's equal to keepOldConnections.
108+
// Unlike for other quorum types we want to keep data (secret key shares and vvec)
109+
// for Platform quorums for much longer because Platform can be restarted and
110+
// it must be able to re-sign stuff.
111+
112+
int keepOldKeys;
113+
107114
// How many members should we try to send all sigShares to before we give up.
108115
int recoveryMembers;
109116
};
@@ -138,6 +145,7 @@ static constexpr std::array<LLMQParams, 14> available_llmqs = {
138145
.signingActiveQuorumCount = 2, // just a few ones to allow easier testing
139146

140147
.keepOldConnections = 3,
148+
.keepOldKeys = 3,
141149
.recoveryMembers = 3,
142150
},
143151

@@ -163,6 +171,7 @@ static constexpr std::array<LLMQParams, 14> available_llmqs = {
163171
.signingActiveQuorumCount = 2, // just a few ones to allow easier testing
164172

165173
.keepOldConnections = 3,
174+
.keepOldKeys = 3,
166175
.recoveryMembers = 3,
167176
},
168177

@@ -188,6 +197,7 @@ static constexpr std::array<LLMQParams, 14> available_llmqs = {
188197
.signingActiveQuorumCount = 2, // just a few ones to allow easier testing
189198

190199
.keepOldConnections = 3,
200+
.keepOldKeys = 3,
191201
.recoveryMembers = 3,
192202
},
193203

@@ -213,6 +223,7 @@ static constexpr std::array<LLMQParams, 14> available_llmqs = {
213223
.signingActiveQuorumCount = 2, // just a few ones to allow easier testing
214224

215225
.keepOldConnections = 4,
226+
.keepOldKeys = 4,
216227
.recoveryMembers = 3,
217228
},
218229

@@ -238,6 +249,7 @@ static constexpr std::array<LLMQParams, 14> available_llmqs = {
238249
.signingActiveQuorumCount = 2, // just a few ones to allow easier testing
239250

240251
.keepOldConnections = 4,
252+
.keepOldKeys = 24 * 30 * 2, // 2 months of quorums
241253
.recoveryMembers = 3,
242254
},
243255

@@ -263,6 +275,7 @@ static constexpr std::array<LLMQParams, 14> available_llmqs = {
263275
.signingActiveQuorumCount = 4, // just a few ones to allow easier testing
264276

265277
.keepOldConnections = 5,
278+
.keepOldKeys = 5,
266279
.recoveryMembers = 6,
267280
},
268281

@@ -288,6 +301,7 @@ static constexpr std::array<LLMQParams, 14> available_llmqs = {
288301
.signingActiveQuorumCount = 2, // just a few ones to allow easier testing
289302

290303
.keepOldConnections = 4,
304+
.keepOldKeys = 4,
291305
.recoveryMembers = 4,
292306
},
293307

@@ -313,6 +327,7 @@ static constexpr std::array<LLMQParams, 14> available_llmqs = {
313327
.signingActiveQuorumCount = 4, // just a few ones to allow easier testing
314328

315329
.keepOldConnections = 5,
330+
.keepOldKeys = 24 * 30 * 2, // 2 months of quorums
316331
.recoveryMembers = 6,
317332
},
318333

@@ -338,6 +353,7 @@ static constexpr std::array<LLMQParams, 14> available_llmqs = {
338353

339354
.signingActiveQuorumCount = 24, // a full day worth of LLMQs
340355
.keepOldConnections = 25,
356+
.keepOldKeys = 25,
341357
.recoveryMembers = 25,
342358
},
343359

@@ -363,6 +379,7 @@ static constexpr std::array<LLMQParams, 14> available_llmqs = {
363379

364380
.signingActiveQuorumCount = 32,
365381
.keepOldConnections = 64,
382+
.keepOldKeys = 64,
366383
.recoveryMembers = 25,
367384
},
368385

@@ -389,6 +406,7 @@ static constexpr std::array<LLMQParams, 14> available_llmqs = {
389406
.signingActiveQuorumCount = 4, // two days worth of LLMQs
390407

391408
.keepOldConnections = 5,
409+
.keepOldKeys = 5,
392410
.recoveryMembers = 100,
393411
},
394412

@@ -416,6 +434,7 @@ static constexpr std::array<LLMQParams, 14> available_llmqs = {
416434
.signingActiveQuorumCount = 4, // four days worth of LLMQs
417435

418436
.keepOldConnections = 5,
437+
.keepOldKeys = 5,
419438
.recoveryMembers = 100,
420439
},
421440

@@ -443,6 +462,7 @@ static constexpr std::array<LLMQParams, 14> available_llmqs = {
443462
.signingActiveQuorumCount = 24, // a full day worth of LLMQs
444463

445464
.keepOldConnections = 25,
465+
.keepOldKeys = 24 * 30 * 2, // 2 months of quorums
446466
.recoveryMembers = 50,
447467
},
448468

@@ -470,6 +490,7 @@ static constexpr std::array<LLMQParams, 14> available_llmqs = {
470490
.signingActiveQuorumCount = 24, // a full day worth of LLMQs
471491

472492
.keepOldConnections = 25,
493+
.keepOldKeys = 24 * 30 * 2, // 2 months of quorums
473494
.recoveryMembers = 12,
474495
},
475496

src/llmq/quorums.cpp

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,8 @@ CQuorumManager::CQuorumManager(CBLSWorker& _blsWorker, CChainState& chainstate,
200200
m_mn_sync(mn_sync),
201201
m_peerman(peerman)
202202
{
203-
utils::InitQuorumsCache(mapQuorumsCache);
204-
utils::InitQuorumsCache(scanQuorumsCache);
203+
utils::InitQuorumsCache(mapQuorumsCache, false);
204+
utils::InitQuorumsCache(scanQuorumsCache, false);
205205

206206
quorumThreadInterrupt.reset();
207207
}
@@ -296,7 +296,7 @@ void CQuorumManager::UpdatedBlockTip(const CBlockIndex* pindexNew, bool fInitial
296296
}
297297

298298
TriggerQuorumDataRecoveryThreads(pindexNew);
299-
CleanupOldQuorumData(pindexNew);
299+
StartCleanupOldQuorumDataThread(pindexNew);
300300
}
301301

302302
void CQuorumManager::CheckQuorumConnections(const Consensus::LLMQParams& llmqParams, const CBlockIndex* pindexNew) const
@@ -956,7 +956,7 @@ void CQuorumManager::StartQuorumDataRecoveryThread(const CQuorumCPtr pQuorum, co
956956
});
957957
}
958958

959-
static void DataCleanupHelper(CDBWrapper& db, std::set<uint256> skip_list)
959+
static void DataCleanupHelper(CDBWrapper& db, std::set<uint256> skip_list, bool compact = false)
960960
{
961961
const auto prefixes = {DB_QUORUM_QUORUM_VVEC, DB_QUORUM_SK_SHARE};
962962

@@ -990,39 +990,54 @@ static void DataCleanupHelper(CDBWrapper& db, std::set<uint256> skip_list)
990990

991991
db.WriteBatch(batch);
992992

993-
LogPrint(BCLog::LLMQ, "CQuorumManager::%d -- %s removed %d\n", __func__, prefix, count);
993+
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- %s removed %d\n", __func__, prefix, count);
994994
}
995995

996996
pcursor.reset();
997-
db.CompactFull();
997+
998+
if (compact) {
999+
// Avoid using this on regular cleanups, use on db migrations only
1000+
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- compact start\n", __func__);
1001+
db.CompactFull();
1002+
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- compact end\n", __func__);
1003+
}
9981004
}
9991005

1000-
void CQuorumManager::CleanupOldQuorumData(const CBlockIndex* pIndex) const
1006+
void CQuorumManager::StartCleanupOldQuorumDataThread(const CBlockIndex* pIndex) const
10011007
{
1002-
if (!fMasternodeMode || pIndex == nullptr || (pIndex->nHeight % 576 != 0)) {
1008+
// Note: this function is CPU heavy and we don't want it to be running during DKGs.
1009+
// The largest dkgMiningWindowStart for a related quorum type is 42 (LLMQ_60_75).
1010+
// At the same time most quorums use dkgInterval = 24 so the next DKG for them
1011+
// (after block 576 + 42) will start at block 576 + 24 * 2. That's only a 6 blocks
1012+
// window and it's better to have more room so we pick next cycle.
1013+
// dkgMiningWindowStart for small quorums is 10 i.e. a safe block to start
1014+
// these calculations is at height 576 + 24 * 2 + 10 = 576 + 58.
1015+
if (!fMasternodeMode || pIndex == nullptr || (pIndex->nHeight % 576 != 58)) {
10031016
return;
10041017
}
10051018

1006-
std::set<uint256> dbKeysToSkip;
1019+
cxxtimer::Timer t(/*start=*/ true);
1020+
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- start\n", __func__);
10071021

1008-
LogPrint(BCLog::LLMQ, "CQuorumManager::%d -- start\n", __func__);
1009-
// Platform quorums in all networks are created every 24 blocks (~1h).
1010-
// Unlike for other quorum types we want to keep data (secret key shares and vvec)
1011-
// for Platform quorums for at least 2 months because Platform can be restarted and
1012-
// it must be able to re-sign stuff. During a month, 24 * 30 quorums are created.
1013-
constexpr auto numPlatformQuorumsDataToKeep = 24 * 30 * 2;
1022+
// do not block the caller thread
1023+
workerPool.push([pIndex, t, this](int threadId) {
1024+
std::set<uint256> dbKeysToSkip;
10141025

1015-
for (const auto& params : Params().GetConsensus().llmqs) {
1016-
auto nQuorumsToKeep = params.type == Params().GetConsensus().llmqTypePlatform ? numPlatformQuorumsDataToKeep : params.keepOldConnections;
1017-
const auto vecQuorums = ScanQuorums(params.type, pIndex, nQuorumsToKeep);
1018-
for (const auto& pQuorum : vecQuorums) {
1019-
dbKeysToSkip.insert(MakeQuorumKey(*pQuorum));
1026+
for (const auto& params : Params().GetConsensus().llmqs) {
1027+
if (quorumThreadInterrupt) {
1028+
break;
1029+
}
1030+
for (const auto& pQuorum : ScanQuorums(params.type, pIndex, params.keepOldKeys)) {
1031+
dbKeysToSkip.insert(MakeQuorumKey(*pQuorum));
1032+
}
10201033
}
1021-
}
10221034

1023-
DataCleanupHelper(m_evoDb.GetRawDB(), dbKeysToSkip);
1035+
if (!quorumThreadInterrupt) {
1036+
DataCleanupHelper(m_evoDb.GetRawDB(), dbKeysToSkip);
1037+
}
10241038

1025-
LogPrint(BCLog::LLMQ, "CQuorumManager::%d -- done\n", __func__);
1039+
LogPrint(BCLog::LLMQ, "CQuorumManager::StartCleanupOldQuorumDataThread -- done. time=%d\n", t.count());
1040+
});
10261041
}
10271042

10281043
} // namespace llmq

src/llmq/quorums.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ class CQuorumManager
277277
void StartCachePopulatorThread(const CQuorumCPtr pQuorum) const;
278278
void StartQuorumDataRecoveryThread(const CQuorumCPtr pQuorum, const CBlockIndex* pIndex, uint16_t nDataMask) const;
279279

280-
void CleanupOldQuorumData(const CBlockIndex* pIndex) const;
280+
void StartCleanupOldQuorumDataThread(const CBlockIndex* pIndex) const;
281281
};
282282

283283
extern std::unique_ptr<CQuorumManager> quorumManager;

src/llmq/utils.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,17 +1110,17 @@ std::map<Consensus::LLMQType, QvvecSyncMode> GetEnabledQuorumVvecSyncEntries()
11101110
}
11111111

11121112
template <typename CacheType>
1113-
void InitQuorumsCache(CacheType& cache)
1113+
void InitQuorumsCache(CacheType& cache, bool limit_by_connections)
11141114
{
11151115
for (const auto& llmq : Params().GetConsensus().llmqs) {
11161116
cache.emplace(std::piecewise_construct, std::forward_as_tuple(llmq.type),
1117-
std::forward_as_tuple(llmq.keepOldConnections));
1117+
std::forward_as_tuple(limit_by_connections ? llmq.keepOldConnections : llmq.keepOldKeys));
11181118
}
11191119
}
1120-
template void InitQuorumsCache<std::map<Consensus::LLMQType, unordered_lru_cache<uint256, bool, StaticSaltedHasher>>>(std::map<Consensus::LLMQType, unordered_lru_cache<uint256, bool, StaticSaltedHasher>>& cache);
1121-
template void InitQuorumsCache<std::map<Consensus::LLMQType, unordered_lru_cache<uint256, std::vector<CQuorumCPtr>, StaticSaltedHasher>>>(std::map<Consensus::LLMQType, unordered_lru_cache<uint256, std::vector<CQuorumCPtr>, StaticSaltedHasher>>& cache);
1122-
template void InitQuorumsCache<std::map<Consensus::LLMQType, unordered_lru_cache<uint256, std::shared_ptr<llmq::CQuorum>, StaticSaltedHasher, 0ul, 0ul>, std::less<Consensus::LLMQType>, std::allocator<std::pair<Consensus::LLMQType const, unordered_lru_cache<uint256, std::shared_ptr<llmq::CQuorum>, StaticSaltedHasher, 0ul, 0ul>>>>>(std::map<Consensus::LLMQType, unordered_lru_cache<uint256, std::shared_ptr<llmq::CQuorum>, StaticSaltedHasher, 0ul, 0ul>, std::less<Consensus::LLMQType>, std::allocator<std::pair<Consensus::LLMQType const, unordered_lru_cache<uint256, std::shared_ptr<llmq::CQuorum>, StaticSaltedHasher, 0ul, 0ul>>>>&);
1123-
template void InitQuorumsCache<std::map<Consensus::LLMQType, unordered_lru_cache<uint256, int, StaticSaltedHasher>>>(std::map<Consensus::LLMQType, unordered_lru_cache<uint256, int, StaticSaltedHasher>>& cache);
1120+
template void InitQuorumsCache<std::map<Consensus::LLMQType, unordered_lru_cache<uint256, bool, StaticSaltedHasher>>>(std::map<Consensus::LLMQType, unordered_lru_cache<uint256, bool, StaticSaltedHasher>>& cache, bool limit_by_connections);
1121+
template void InitQuorumsCache<std::map<Consensus::LLMQType, unordered_lru_cache<uint256, std::vector<CQuorumCPtr>, StaticSaltedHasher>>>(std::map<Consensus::LLMQType, unordered_lru_cache<uint256, std::vector<CQuorumCPtr>, StaticSaltedHasher>>& cache, bool limit_by_connections);
1122+
template void InitQuorumsCache<std::map<Consensus::LLMQType, unordered_lru_cache<uint256, std::shared_ptr<llmq::CQuorum>, StaticSaltedHasher, 0ul, 0ul>, std::less<Consensus::LLMQType>, std::allocator<std::pair<Consensus::LLMQType const, unordered_lru_cache<uint256, std::shared_ptr<llmq::CQuorum>, StaticSaltedHasher, 0ul, 0ul>>>>>(std::map<Consensus::LLMQType, unordered_lru_cache<uint256, std::shared_ptr<llmq::CQuorum>, StaticSaltedHasher, 0ul, 0ul>, std::less<Consensus::LLMQType>, std::allocator<std::pair<Consensus::LLMQType const, unordered_lru_cache<uint256, std::shared_ptr<llmq::CQuorum>, StaticSaltedHasher, 0ul, 0ul>>>>&cache, bool limit_by_connections);
1123+
template void InitQuorumsCache<std::map<Consensus::LLMQType, unordered_lru_cache<uint256, int, StaticSaltedHasher>>>(std::map<Consensus::LLMQType, unordered_lru_cache<uint256, int, StaticSaltedHasher>>& cache, bool limit_by_connections);
11241124

11251125
} // namespace utils
11261126

src/llmq/utils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ void IterateNodesRandom(NodesContainer& nodeStates, Continue&& cont, Callback&&
120120
}
121121

122122
template <typename CacheType>
123-
void InitQuorumsCache(CacheType& cache);
123+
void InitQuorumsCache(CacheType& cache, bool limit_by_connections = true);
124124

125125
} // namespace utils
126126

0 commit comments

Comments
 (0)