From f3f4c16c352ef99e01f8cab5634c9fe483695ba3 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Wed, 7 Feb 2024 21:34:54 +0300 Subject: [PATCH] fix: Store BLSVerificationVector on disk using basic bls scheme (#5480) ## Issue being fixed or feature implemented Shouldn't change the way data is stored on mainnet/testnet nodes since they use basic bls scheme anyway now. For devnets/regtest (which activate v19 again and again) this patch should fix potential issues reading pre-fork data right after the fork. ## What was done? Pls see individual commits ## 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)_ --- src/llmq/dkgsessionmgr.cpp | 22 ++++++++++++++++++---- src/llmq/quorums.cpp | 25 +++++++++++++++++++------ 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/llmq/dkgsessionmgr.cpp b/src/llmq/dkgsessionmgr.cpp index 2f94a4dc54..a8b14f4b38 100644 --- a/src/llmq/dkgsessionmgr.cpp +++ b/src/llmq/dkgsessionmgr.cpp @@ -378,7 +378,12 @@ bool CDKGSessionManager::GetPrematureCommitment(const uint256& hash, CDKGPrematu void CDKGSessionManager::WriteVerifiedVvecContribution(Consensus::LLMQType llmqType, const CBlockIndex* pQuorumBaseBlockIndex, const uint256& proTxHash, const BLSVerificationVectorPtr& vvec) { - db->Write(std::make_tuple(DB_VVEC, llmqType, pQuorumBaseBlockIndex->GetBlockHash(), proTxHash), *vvec); + CDataStream s(SER_DISK, CLIENT_VERSION); + WriteCompactSize(s, vvec->size()); + for (auto& pubkey : *vvec) { + s << CBLSPublicKeyVersionWrapper(pubkey, false); + } + db->Write(std::make_tuple(DB_VVEC, llmqType, pQuorumBaseBlockIndex->GetBlockHash(), proTxHash), s); } void CDKGSessionManager::WriteVerifiedSkContribution(Consensus::LLMQType llmqType, const CBlockIndex* pQuorumBaseBlockIndex, const uint256& proTxHash, const CBLSSecretKey& skContribution) @@ -408,11 +413,20 @@ bool CDKGSessionManager::GetVerifiedContributions(Consensus::LLMQType llmqType, ContributionsCacheKey cacheKey = {llmqType, pQuorumBaseBlockIndex->GetBlockHash(), proTxHash}; auto it = contributionsCache.find(cacheKey); if (it == contributionsCache.end()) { - auto vvecPtr = std::make_shared>(); - CBLSSecretKey skContribution; - if (!db->Read(std::make_tuple(DB_VVEC, llmqType, pQuorumBaseBlockIndex->GetBlockHash(), proTxHash), *vvecPtr)) { + CDataStream s(SER_DISK, CLIENT_VERSION); + if (!db->ReadDataStream(std::make_tuple(DB_VVEC, llmqType, pQuorumBaseBlockIndex->GetBlockHash(), proTxHash), s)) { return false; } + size_t vvec_size = ReadCompactSize(s); + CBLSPublicKey pubkey; + std::vector qv; + for ([[maybe_unused]] size_t _ : irange::range(vvec_size)) { + s >> CBLSPublicKeyVersionWrapper(pubkey, false); + qv.emplace_back(pubkey); + } + auto vvecPtr = std::make_shared>(std::move(qv)); + + CBLSSecretKey skContribution; db->Read(std::make_tuple(DB_SKCONTRIB, llmqType, pQuorumBaseBlockIndex->GetBlockHash(), proTxHash), skContribution); it = contributionsCache.emplace(cacheKey, ContributionsCacheEntry{GetTimeMillis(), vvecPtr, skContribution}).first; diff --git a/src/llmq/quorums.cpp b/src/llmq/quorums.cpp index edf8ad384d..b9e83704bb 100644 --- a/src/llmq/quorums.cpp +++ b/src/llmq/quorums.cpp @@ -164,7 +164,12 @@ void CQuorum::WriteContributions(CEvoDB& evoDb) const LOCK(cs); if (HasVerificationVector()) { - evoDb.GetRawDB().Write(std::make_pair(DB_QUORUM_QUORUM_VVEC, dbKey), *quorumVvec); + CDataStream s(SER_DISK, CLIENT_VERSION); + WriteCompactSize(s, quorumVvec->size()); + for (auto& pubkey : *quorumVvec) { + s << CBLSPublicKeyVersionWrapper(pubkey, false); + } + evoDb.GetRawDB().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); @@ -174,17 +179,25 @@ void CQuorum::WriteContributions(CEvoDB& evoDb) const bool CQuorum::ReadContributions(CEvoDB& evoDb) { uint256 dbKey = MakeQuorumKey(*this); + CDataStream s(SER_DISK, CLIENT_VERSION); - std::vector qv; - if (evoDb.Read(std::make_pair(DB_QUORUM_QUORUM_VVEC, dbKey), qv)) { - WITH_LOCK(cs, quorumVvec = std::make_shared>(std::move(qv))); - } else { + if (!evoDb.GetRawDB().ReadDataStream(std::make_pair(DB_QUORUM_QUORUM_VVEC, dbKey), s)) { return false; } + size_t vvec_size = ReadCompactSize(s); + CBLSPublicKey pubkey; + std::vector qv; + for ([[maybe_unused]] size_t _ : irange::range(vvec_size)) { + s >> CBLSPublicKeyVersionWrapper(pubkey, false); + qv.emplace_back(pubkey); + } + + LOCK(cs); + 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. - WITH_LOCK(cs, evoDb.Read(std::make_pair(DB_QUORUM_SK_SHARE, dbKey), skShare)); + evoDb.GetRawDB().Read(std::make_pair(DB_QUORUM_SK_SHARE, dbKey), skShare); return true; }