Skip to content

Commit 13e3dd9

Browse files
Merge #5481: feat: Split quorum contrib data out of evodb
ad35c1a apply suggestions (UdjinM6) 600dcf3 refactor: make clang-format happy (UdjinM6) da9b8e0 feat: Split quorum contribution db out of evodb (UdjinM6) Pull request description: ## Issue being fixed or feature implemented Quorum data is not stored on-chain, it's a temporary data produced during dkg and should not be a part of evodb. ## What was done? Use new db in `llmq/` to store quorum data, migrate old data to it. ## How Has This Been Tested? Run tests, run a node on testnet ## Breaking Changes n/a ## Checklist: - [x] I have performed a self-review of my own code - [ ] 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)_ ACKs for top commit: knst: utACK ad35c1a PastaPastaPasta: utACK ad35c1a Tree-SHA512: b394a53815897f02ec28776c948a32c258ad7f0d9b78fbfd509146a92c8af53e7577d503bc62ae53c40f88aab2c30160fec09f45f0d3447ba64c05c0887676eb
2 parents 89a7c60 + ad35c1a commit 13e3dd9

File tree

3 files changed

+101
-24
lines changed

3 files changed

+101
-24
lines changed

src/llmq/context.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,20 @@
1818
#include <llmq/signing_shares.h>
1919

2020
LLMQContext::LLMQContext(CChainState& chainstate, CConnman& connman, CDeterministicMNManager& dmnman, CEvoDB& evo_db,
21-
CMasternodeMetaMan& mn_metaman, CMNHFManager& mnhfman, CSporkManager& sporkman, CTxMemPool& mempool,
22-
const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync,
23-
const std::unique_ptr<PeerManager>& peerman, bool unit_tests, bool wipe) :
21+
CMasternodeMetaMan& mn_metaman, CMNHFManager& mnhfman, CSporkManager& sporkman,
22+
CTxMemPool& mempool, const CActiveMasternodeManager* const mn_activeman,
23+
const CMasternodeSync& mn_sync, const std::unique_ptr<PeerManager>& peerman, bool unit_tests,
24+
bool wipe) :
2425
is_masternode{mn_activeman != nullptr},
2526
bls_worker{std::make_shared<CBLSWorker>()},
2627
dkg_debugman{std::make_unique<llmq::CDKGDebugManager>()},
2728
quorum_block_processor{std::make_unique<llmq::CQuorumBlockProcessor>(chainstate, dmnman, evo_db, peerman)},
28-
qdkgsman{std::make_unique<llmq::CDKGSessionManager>(*bls_worker, chainstate, connman, dmnman, *dkg_debugman, mn_metaman, *quorum_block_processor, mn_activeman, sporkman, peerman, unit_tests, wipe)},
29-
qman{std::make_unique<llmq::CQuorumManager>(*bls_worker, chainstate, connman, dmnman, *qdkgsman, evo_db, *quorum_block_processor, mn_activeman, mn_sync, sporkman)},
29+
qdkgsman{std::make_unique<llmq::CDKGSessionManager>(*bls_worker, chainstate, connman, dmnman, *dkg_debugman,
30+
mn_metaman, *quorum_block_processor, mn_activeman, sporkman,
31+
peerman, unit_tests, wipe)},
32+
qman{std::make_unique<llmq::CQuorumManager>(*bls_worker, chainstate, connman, dmnman, *qdkgsman, evo_db,
33+
*quorum_block_processor, mn_activeman, mn_sync, sporkman, unit_tests,
34+
wipe)},
3035
sigman{std::make_unique<llmq::CSigningManager>(connman, mn_activeman, chainstate, *qman, peerman, unit_tests, wipe)},
3136
shareman{std::make_unique<llmq::CSigSharesManager>(connman, *sigman, mn_activeman, *qman, sporkman, peerman)},
3237
clhandler{[&]() -> llmq::CChainLocksHandler* const {
@@ -39,7 +44,8 @@ LLMQContext::LLMQContext(CChainState& chainstate, CConnman& connman, CDeterminis
3944
llmq::quorumInstantSendManager = std::make_unique<llmq::CInstantSendManager>(*llmq::chainLocksHandler, chainstate, connman, *qman, *sigman, *shareman, sporkman, mempool, mn_sync, peerman, is_masternode, unit_tests, wipe);
4045
return llmq::quorumInstantSendManager.get();
4146
}()},
42-
ehfSignalsHandler{std::make_unique<llmq::CEHFSignalsHandler>(chainstate, mnhfman, *sigman, *shareman, mempool, *qman, sporkman, peerman)}
47+
ehfSignalsHandler{std::make_unique<llmq::CEHFSignalsHandler>(chainstate, mnhfman, *sigman, *shareman, mempool,
48+
*qman, sporkman, peerman)}
4349
{
4450
// NOTE: we use this only to wipe the old db, do NOT use it for anything else
4551
// TODO: remove it in some future version

src/llmq/quorums.cpp

Lines changed: 81 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ int CQuorum::GetMemberIndex(const uint256& proTxHash) const
164164
return -1;
165165
}
166166

167-
void CQuorum::WriteContributions(CEvoDB& evoDb) const
167+
void CQuorum::WriteContributions(CDBWrapper& db) const
168168
{
169169
uint256 dbKey = MakeQuorumKey(*this);
170170

@@ -175,19 +175,19 @@ void CQuorum::WriteContributions(CEvoDB& evoDb) const
175175
for (auto& pubkey : *quorumVvec) {
176176
s << CBLSPublicKeyVersionWrapper(pubkey, false);
177177
}
178-
evoDb.GetRawDB().Write(std::make_pair(DB_QUORUM_QUORUM_VVEC, dbKey), s);
178+
db.Write(std::make_pair(DB_QUORUM_QUORUM_VVEC, dbKey), s);
179179
}
180180
if (skShare.IsValid()) {
181-
evoDb.GetRawDB().Write(std::make_pair(DB_QUORUM_SK_SHARE, dbKey), skShare);
181+
db.Write(std::make_pair(DB_QUORUM_SK_SHARE, dbKey), skShare);
182182
}
183183
}
184184

185-
bool CQuorum::ReadContributions(CEvoDB& evoDb)
185+
bool CQuorum::ReadContributions(const CDBWrapper& db)
186186
{
187187
uint256 dbKey = MakeQuorumKey(*this);
188188
CDataStream s(SER_DISK, CLIENT_VERSION);
189189

190-
if (!evoDb.GetRawDB().ReadDataStream(std::make_pair(DB_QUORUM_QUORUM_VVEC, dbKey), s)) {
190+
if (!db.ReadDataStream(std::make_pair(DB_QUORUM_QUORUM_VVEC, dbKey), s)) {
191191
return false;
192192
}
193193

@@ -203,27 +203,31 @@ bool CQuorum::ReadContributions(CEvoDB& evoDb)
203203
quorumVvec = std::make_shared<std::vector<CBLSPublicKey>>(std::move(qv));
204204
// We ignore the return value here as it is ok if this fails. If it fails, it usually means that we are not a
205205
// member of the quorum but observed the whole DKG process to have the quorum verification vector.
206-
evoDb.GetRawDB().Read(std::make_pair(DB_QUORUM_SK_SHARE, dbKey), skShare);
206+
db.Read(std::make_pair(DB_QUORUM_SK_SHARE, dbKey), skShare);
207207

208208
return true;
209209
}
210210

211-
CQuorumManager::CQuorumManager(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDeterministicMNManager& dmnman,
212-
CDKGSessionManager& _dkgManager, CEvoDB& _evoDb, CQuorumBlockProcessor& _quorumBlockProcessor,
213-
const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync, const CSporkManager& sporkman) :
211+
CQuorumManager::CQuorumManager(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman,
212+
CDeterministicMNManager& dmnman, CDKGSessionManager& _dkgManager, CEvoDB& _evoDb,
213+
CQuorumBlockProcessor& _quorumBlockProcessor,
214+
const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync,
215+
const CSporkManager& sporkman, bool unit_tests, bool wipe) :
216+
db(std::make_unique<CDBWrapper>(unit_tests ? "" : (gArgs.GetDataDirNet() / "llmq" / "quorumdb"), 1 << 20,
217+
unit_tests, wipe)),
214218
blsWorker(_blsWorker),
215219
m_chainstate(chainstate),
216220
connman(_connman),
217221
m_dmnman(dmnman),
218222
dkgManager(_dkgManager),
219-
m_evoDb(_evoDb),
220223
quorumBlockProcessor(_quorumBlockProcessor),
221224
m_mn_activeman(mn_activeman),
222225
m_mn_sync(mn_sync),
223226
m_sporkman(sporkman)
224227
{
225228
utils::InitQuorumsCache(mapQuorumsCache, false);
226229
quorumThreadInterrupt.reset();
230+
MigrateOldQuorumDB(_evoDb);
227231
}
228232

229233
void CQuorumManager::Start()
@@ -404,11 +408,11 @@ CQuorumPtr CQuorumManager::BuildQuorumFromCommitment(const Consensus::LLMQType l
404408
quorum->Init(std::move(qc), pQuorumBaseBlockIndex, minedBlockHash, members);
405409

406410
bool hasValidVvec = false;
407-
if (quorum->ReadContributions(m_evoDb)) {
411+
if (WITH_LOCK(cs_db, return quorum->ReadContributions(*db))) {
408412
hasValidVvec = true;
409413
} else {
410414
if (BuildQuorumContributions(quorum->qc, quorum)) {
411-
quorum->WriteContributions(m_evoDb);
415+
WITH_LOCK(cs_db, quorum->WriteContributions(*db));
412416
hasValidVvec = true;
413417
} else {
414418
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- llmqType[%d] quorumIndex[%d] quorum.ReadContributions and BuildQuorumContributions for quorumHash[%s] failed\n", __func__, ToUnderlying(llmqType), quorum->qc->quorumIndex, quorum->qc->quorumHash.ToString());
@@ -846,7 +850,7 @@ PeerMsgRet CQuorumManager::ProcessMessage(CNode& pfrom, const std::string& msg_t
846850
return errorHandler("Invalid secret key share received");
847851
}
848852
}
849-
pQuorum->WriteContributions(m_evoDb);
853+
WITH_LOCK(cs_db, pQuorum->WriteContributions(*db));
850854
return {};
851855
}
852856
return {};
@@ -1100,13 +1104,76 @@ void CQuorumManager::StartCleanupOldQuorumDataThread(const CBlockIndex* pIndex)
11001104
}
11011105

11021106
if (!quorumThreadInterrupt) {
1103-
DataCleanupHelper(m_evoDb.GetRawDB(), dbKeysToSkip);
1107+
WITH_LOCK(cs_db, DataCleanupHelper(*db, dbKeysToSkip));
11041108
}
11051109

11061110
LogPrint(BCLog::LLMQ, "CQuorumManager::StartCleanupOldQuorumDataThread -- done. time=%d\n", t.count());
11071111
});
11081112
}
11091113

1114+
// TODO: remove in v23
1115+
void CQuorumManager::MigrateOldQuorumDB(CEvoDB& evoDb) const
1116+
{
1117+
LOCK(cs_db);
1118+
if (!db->IsEmpty()) return;
1119+
1120+
const auto prefixes = {DB_QUORUM_QUORUM_VVEC, DB_QUORUM_SK_SHARE};
1121+
1122+
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- start\n", __func__);
1123+
1124+
CDBBatch batch(*db);
1125+
std::unique_ptr<CDBIterator> pcursor(evoDb.GetRawDB().NewIterator());
1126+
1127+
for (const auto& prefix : prefixes) {
1128+
auto start = std::make_tuple(prefix, uint256());
1129+
pcursor->Seek(start);
1130+
1131+
int count{0};
1132+
while (pcursor->Valid()) {
1133+
decltype(start) k;
1134+
CDataStream s(SER_DISK, CLIENT_VERSION);
1135+
CBLSSecretKey sk;
1136+
1137+
if (!pcursor->GetKey(k) || std::get<0>(k) != prefix) {
1138+
break;
1139+
}
1140+
1141+
if (prefix == DB_QUORUM_QUORUM_VVEC) {
1142+
if (!evoDb.GetRawDB().ReadDataStream(k, s)) {
1143+
break;
1144+
}
1145+
batch.Write(k, s);
1146+
}
1147+
if (prefix == DB_QUORUM_SK_SHARE) {
1148+
if (!pcursor->GetValue(sk)) {
1149+
break;
1150+
}
1151+
batch.Write(k, sk);
1152+
}
1153+
1154+
if (batch.SizeEstimate() >= (1 << 24)) {
1155+
db->WriteBatch(batch);
1156+
batch.Clear();
1157+
}
1158+
1159+
++count;
1160+
pcursor->Next();
1161+
}
1162+
1163+
db->WriteBatch(batch);
1164+
1165+
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- %s moved %d\n", __func__, prefix, count);
1166+
}
1167+
1168+
pcursor.reset();
1169+
db->CompactFull();
1170+
1171+
DataCleanupHelper(evoDb.GetRawDB(), {});
1172+
evoDb.CommitRootTransaction();
1173+
1174+
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- done\n", __func__);
1175+
}
1176+
11101177
CQuorumCPtr SelectQuorumForSigning(const Consensus::LLMQParams& llmq_params, const CChain& active_chain, const CQuorumManager& qman,
11111178
const uint256& selectionHash, int signHeight, int signOffset)
11121179
{

src/llmq/quorums.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,8 @@ class CQuorum
217217

218218
private:
219219
bool HasVerificationVectorInternal() const EXCLUSIVE_LOCKS_REQUIRED(cs_vvec_shShare);
220-
void WriteContributions(CEvoDB& evoDb) const;
221-
bool ReadContributions(CEvoDB& evoDb);
220+
void WriteContributions(CDBWrapper& db) const;
221+
bool ReadContributions(const CDBWrapper& db);
222222
};
223223

224224
/**
@@ -230,12 +230,14 @@ class CQuorum
230230
class CQuorumManager
231231
{
232232
private:
233+
mutable Mutex cs_db;
234+
std::unique_ptr<CDBWrapper> db GUARDED_BY(cs_db){nullptr};
235+
233236
CBLSWorker& blsWorker;
234237
CChainState& m_chainstate;
235238
CConnman& connman;
236239
CDeterministicMNManager& m_dmnman;
237240
CDKGSessionManager& dkgManager;
238-
CEvoDB& m_evoDb;
239241
CQuorumBlockProcessor& quorumBlockProcessor;
240242
const CActiveMasternodeManager* const m_mn_activeman;
241243
const CMasternodeSync& m_mn_sync;
@@ -254,7 +256,8 @@ class CQuorumManager
254256
public:
255257
CQuorumManager(CBLSWorker& _blsWorker, CChainState& chainstate, CConnman& _connman, CDeterministicMNManager& dmnman,
256258
CDKGSessionManager& _dkgManager, CEvoDB& _evoDb, CQuorumBlockProcessor& _quorumBlockProcessor,
257-
const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync, const CSporkManager& sporkman);
259+
const CActiveMasternodeManager* const mn_activeman, const CMasternodeSync& mn_sync,
260+
const CSporkManager& sporkman, bool unit_tests, bool wipe);
258261
~CQuorumManager() { Stop(); };
259262

260263
void Start();
@@ -294,6 +297,7 @@ class CQuorumManager
294297
void StartQuorumDataRecoveryThread(const CQuorumCPtr pQuorum, const CBlockIndex* pIndex, uint16_t nDataMask) const;
295298

296299
void StartCleanupOldQuorumDataThread(const CBlockIndex* pIndex) const;
300+
void MigrateOldQuorumDB(CEvoDB& evoDb) const;
297301
};
298302

299303
// when selecting a quorum for signing and verification, we use CQuorumManager::SelectQuorum with this offset as

0 commit comments

Comments
 (0)