diff --git a/src/llmq/context.cpp b/src/llmq/context.cpp index 6470afc1a8d693..81053583224b1b 100644 --- a/src/llmq/context.cpp +++ b/src/llmq/context.cpp @@ -46,7 +46,7 @@ void LLMQContext::Create(CEvoDB& evo_db, CTxMemPool& mempool, CConnman& connman, dkg_debugman = std::make_unique(); llmq::quorumBlockProcessor = std::make_unique(evo_db, connman, peerman); qdkgsman = std::make_unique(connman, *bls_worker, *dkg_debugman, *llmq::quorumBlockProcessor, sporkman, peerman, unit_tests, wipe); - llmq::quorumManager = std::make_unique(evo_db, connman, *bls_worker, *llmq::quorumBlockProcessor, *qdkgsman, ::masternodeSync, peerman); + llmq::quorumManager = std::make_unique(evo_db, connman, *bls_worker, *llmq::quorumBlockProcessor, *qdkgsman, ::masternodeSync, peerman, unit_tests, wipe); sigman = std::make_unique(connman, *llmq::quorumManager, peerman, unit_tests, wipe); shareman = std::make_unique(connman, *llmq::quorumManager, *sigman, peerman); llmq::chainLocksHandler = std::make_unique(mempool, connman, sporkman, *sigman, *shareman, *llmq::quorumManager, *::masternodeSync, peerman); diff --git a/src/llmq/quorums.cpp b/src/llmq/quorums.cpp index f15533efcc0e11..cc03ae0de54589 100644 --- a/src/llmq/quorums.cpp +++ b/src/llmq/quorums.cpp @@ -156,7 +156,7 @@ int CQuorum::GetMemberIndex(const uint256& proTxHash) const return -1; } -void CQuorum::WriteContributions(CEvoDB& evoDb) const +void CQuorum::WriteContributions(const std::unique_ptr& db) const { uint256 dbKey = MakeQuorumKey(*this); @@ -167,19 +167,19 @@ void CQuorum::WriteContributions(CEvoDB& evoDb) const for (auto& pubkey : *quorumVvec) { s << CBLSPublicKeyVersionWrapper(pubkey, false); } - evoDb.GetRawDB().Write(std::make_pair(DB_QUORUM_QUORUM_VVEC, dbKey), s); + db->Write(std::make_pair(DB_QUORUM_QUORUM_VVEC, dbKey), s); } if (skShare.IsValid()) { - evoDb.GetRawDB().Write(std::make_pair(DB_QUORUM_SK_SHARE, dbKey), skShare); + db->Write(std::make_pair(DB_QUORUM_SK_SHARE, dbKey), skShare); } } -bool CQuorum::ReadContributions(CEvoDB& evoDb) +bool CQuorum::ReadContributions(const std::unique_ptr& db) { uint256 dbKey = MakeQuorumKey(*this); CDataStream s(SER_DISK, CLIENT_VERSION); - if (!evoDb.GetRawDB().ReadDataStream(std::make_pair(DB_QUORUM_QUORUM_VVEC, dbKey), s)) { + if (!db->ReadDataStream(std::make_pair(DB_QUORUM_QUORUM_VVEC, dbKey), s)) { return false; } @@ -196,16 +196,16 @@ bool CQuorum::ReadContributions(CEvoDB& evoDb) quorumVvec = std::make_shared(std::move(qv)); // We ignore the return value here as it is ok if this fails. If it fails, it usually means that we are not a // member of the quorum but observed the whole DKG process to have the quorum verification vector. - evoDb.GetRawDB().Read(std::make_pair(DB_QUORUM_SK_SHARE, dbKey), skShare); + db->Read(std::make_pair(DB_QUORUM_SK_SHARE, dbKey), skShare); return true; } CQuorumManager::CQuorumManager(CEvoDB& _evoDb, CConnman& _connman, CBLSWorker& _blsWorker, CQuorumBlockProcessor& _quorumBlockProcessor, CDKGSessionManager& _dkgManager, const std::unique_ptr& mn_sync, - const std::unique_ptr& peerman) : - m_evoDb(_evoDb), + const std::unique_ptr& peerman, bool unit_tests, bool wipe) : connman(_connman), + db(std::make_unique(unit_tests ? "" : (GetDataDir() / "llmq/quorumdb"), 1 << 20, unit_tests, wipe)), blsWorker(_blsWorker), dkgManager(_dkgManager), quorumBlockProcessor(_quorumBlockProcessor), @@ -216,6 +216,7 @@ CQuorumManager::CQuorumManager(CEvoDB& _evoDb, CConnman& _connman, CBLSWorker& _ utils::InitQuorumsCache(scanQuorumsCache); quorumThreadInterrupt.reset(); + EraseOldQuorumDB(_evoDb); } void CQuorumManager::Start() @@ -397,11 +398,11 @@ CQuorumPtr CQuorumManager::BuildQuorumFromCommitment(const Consensus::LLMQType l quorum->Init(std::move(qc), pQuorumBaseBlockIndex, minedBlockHash, members); bool hasValidVvec = false; - if (quorum->ReadContributions(m_evoDb)) { + if (WITH_LOCK(cs_db, return quorum->ReadContributions(db))) { hasValidVvec = true; } else { if (BuildQuorumContributions(quorum->qc, quorum)) { - quorum->WriteContributions(m_evoDb); + WITH_LOCK(cs_db, quorum->WriteContributions(db)); hasValidVvec = true; } else { 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()); @@ -823,7 +824,7 @@ void CQuorumManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, C return; } } - pQuorum->WriteContributions(m_evoDb); + WITH_LOCK(cs_db, pQuorum->WriteContributions(db)); return; } } @@ -1031,7 +1032,26 @@ void CQuorumManager::CleanupOldQuorumData(const CBlockIndex* pIndex) const } LOCK(cs_db); - DataCleanupHelper(evoDb.GetRawDB(), dbKeys); + DataCleanupHelper(*db, dbKeys); + + LogPrint(BCLog::LLMQ, "CQuorumManager::%d -- done\n", __func__); +} + +void CQuorumManager::EraseOldQuorumDB(CEvoDB& evoDb) const +{ + // NOTE: We do not migrate old data here because we have no idea + // which bls scheme was used to store it originally. This is ok + // cause the data can be re-requested from other nodes, see + // TriggerQuorumDataRecoveryThreads. + + LOCK(cs_db); + + if (!db->IsEmpty()) return; + + LogPrint(BCLog::LLMQ, "CQuorumManager::%d -- start\n", __func__); + + DataCleanupHelper(evoDb.GetRawDB(), {}); + evoDb.CommitRootTransaction(); LogPrint(BCLog::LLMQ, "CQuorumManager::%d -- done\n", __func__); } diff --git a/src/llmq/quorums.h b/src/llmq/quorums.h index c290d9cf45ba62..defbe94e57095e 100644 --- a/src/llmq/quorums.h +++ b/src/llmq/quorums.h @@ -199,8 +199,8 @@ class CQuorum CBLSSecretKey GetSkShare() const; private: - void WriteContributions(CEvoDB& evoDb) const; - bool ReadContributions(CEvoDB& evoDb); + void WriteContributions(const std::unique_ptr& db) const; + bool ReadContributions(const std::unique_ptr& db); }; /** @@ -212,7 +212,9 @@ class CQuorum class CQuorumManager { private: - CEvoDB& m_evoDb; + mutable Mutex cs_db; + std::unique_ptr db GUARDED_BY(cs_db) {nullptr}; + CConnman& connman; CBLSWorker& blsWorker; CDKGSessionManager& dkgManager; @@ -232,7 +234,7 @@ class CQuorumManager public: CQuorumManager(CEvoDB& _evoDb, CConnman& _connman, CBLSWorker& _blsWorker, CQuorumBlockProcessor& _quorumBlockProcessor, CDKGSessionManager& _dkgManager, const std::unique_ptr& mnSync, - const std::unique_ptr& peerman); + const std::unique_ptr& peerman, bool unit_tests, bool wipe); ~CQuorumManager() { Stop(); }; void Start(); @@ -272,6 +274,7 @@ class CQuorumManager void StartQuorumDataRecoveryThread(const CQuorumCPtr pQuorum, const CBlockIndex* pIndex, uint16_t nDataMask) const; void CleanupOldQuorumData(const CBlockIndex* pIndex) const; + void EraseOldQuorumDB(CEvoDB& evoDb) const; }; extern std::unique_ptr quorumManager;