llmq: Store encrypted DKG contributitons (#3948)

* llmq: Add CDKGSessionManager::WriteEncryptedContributions

Allows to store each member's encrypted contributions of the DKG.

* llmq: Store each member's contributions in the llmq database

* llmq: Add CDKGSessionManager::GetEncryptedContributions

I decided to don't cache here since its probably very unlikely this is called twice in a short period with what we have planed for it so far. We can add caching if the requirement for it changes at some point?
This commit is contained in:
dustinface 2021-01-22 16:11:06 +01:00 committed by GitHub
parent e197f976e1
commit ec1281c7ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 1 deletions

View File

@ -97,6 +97,7 @@ bool CDKGSession::Init(const CBlockIndex* _pindexQuorum, const std::vector<CDete
memberIds.resize(members.size()); memberIds.resize(members.size());
receivedVvecs.resize(members.size()); receivedVvecs.resize(members.size());
receivedSkContributions.resize(members.size()); receivedSkContributions.resize(members.size());
vecEncryptedContributions.resize(members.size());
for (size_t i = 0; i < mns.size(); i++) { for (size_t i = 0; i < mns.size(); i++) {
members[i] = std::make_unique<CDKGMember>(mns[i], i); members[i] = std::make_unique<CDKGMember>(mns[i], i);
@ -343,6 +344,7 @@ void CDKGSession::ReceiveMessage(const CDKGContribution& qc, bool& retBan)
bool verifyPending = false; bool verifyPending = false;
receivedSkContributions[member->idx] = skContribution; receivedSkContributions[member->idx] = skContribution;
vecEncryptedContributions[member->idx] = qc.contributions;
pendingContributionVerifications.emplace_back(member->idx); pendingContributionVerifications.emplace_back(member->idx);
if (pendingContributionVerifications.size() >= 32) { if (pendingContributionVerifications.size() >= 32) {
verifyPending = true; verifyPending = true;
@ -383,6 +385,9 @@ void CDKGSession::VerifyPendingContributions()
memberIndexes.emplace_back(idx); memberIndexes.emplace_back(idx);
vvecs.emplace_back(receivedVvecs[idx]); vvecs.emplace_back(receivedVvecs[idx]);
skContributions.emplace_back(receivedSkContributions[idx]); skContributions.emplace_back(receivedSkContributions[idx]);
// Write here to definitely store one contribution for each member no matter if
// our share is valid or not, could be that others are still correct
dkgManager.WriteEncryptedContributions(params.type, pindexQuorum, m->dmn->proTxHash, *vecEncryptedContributions[idx]);
} }
auto result = blsWorker.VerifyContributionShares(myId, vvecs, skContributions); auto result = blsWorker.VerifyContributionShares(myId, vvecs, skContributions);

View File

@ -262,6 +262,8 @@ private:
std::vector<BLSVerificationVectorPtr> receivedVvecs; std::vector<BLSVerificationVectorPtr> receivedVvecs;
// these are not necessarily verified yet. Only trust in what was written to the DB // these are not necessarily verified yet. Only trust in what was written to the DB
BLSSecretKeyVector receivedSkContributions; BLSSecretKeyVector receivedSkContributions;
/// Contains the received unverified/encrypted DKG contributions
std::vector<std::shared_ptr<CBLSIESMultiRecipientObjects<CBLSSecretKey>>> vecEncryptedContributions;
uint256 myProTxHash; uint256 myProTxHash;
CBLSId myId; CBLSId myId;

View File

@ -18,6 +18,7 @@ CDKGSessionManager* quorumDKGSessionManager;
static const std::string DB_VVEC = "qdkg_V"; static const std::string DB_VVEC = "qdkg_V";
static const std::string DB_SKCONTRIB = "qdkg_S"; static const std::string DB_SKCONTRIB = "qdkg_S";
static const std::string DB_ENC_CONTRIB = "qdkg_E";
CDKGSessionManager::CDKGSessionManager(CDBWrapper& _llmqDb, CBLSWorker& _blsWorker) : CDKGSessionManager::CDKGSessionManager(CDBWrapper& _llmqDb, CBLSWorker& _blsWorker) :
llmqDb(_llmqDb), llmqDb(_llmqDb),
@ -204,6 +205,11 @@ void CDKGSessionManager::WriteVerifiedSkContribution(Consensus::LLMQType llmqTyp
llmqDb.Write(std::make_tuple(DB_SKCONTRIB, llmqType, pindexQuorum->GetBlockHash(), proTxHash), skContribution); llmqDb.Write(std::make_tuple(DB_SKCONTRIB, llmqType, pindexQuorum->GetBlockHash(), proTxHash), skContribution);
} }
void CDKGSessionManager::WriteEncryptedContributions(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const uint256& proTxHash, const CBLSIESMultiRecipientObjects<CBLSSecretKey>& contributions)
{
llmqDb.Write(std::make_tuple(DB_ENC_CONTRIB, llmqType, pindexQuorum->GetBlockHash(), proTxHash), contributions);
}
bool CDKGSessionManager::GetVerifiedContributions(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const std::vector<bool>& validMembers, std::vector<uint16_t>& memberIndexesRet, std::vector<BLSVerificationVectorPtr>& vvecsRet, BLSSecretKeyVector& skContributionsRet) bool CDKGSessionManager::GetVerifiedContributions(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const std::vector<bool>& validMembers, std::vector<uint16_t>& memberIndexesRet, std::vector<BLSVerificationVectorPtr>& vvecsRet, BLSSecretKeyVector& skContributionsRet)
{ {
LOCK(contributionsCacheCs); LOCK(contributionsCacheCs);
@ -239,6 +245,36 @@ bool CDKGSessionManager::GetVerifiedContributions(Consensus::LLMQType llmqType,
return true; return true;
} }
bool CDKGSessionManager::GetEncryptedContributions(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const std::vector<bool>& validMembers, const uint256& nProTxHash, std::vector<CBLSIESEncryptedObject<CBLSSecretKey>>& vecRet)
{
auto members = CLLMQUtils::GetAllQuorumMembers(llmqType, pindexQuorum);
vecRet.clear();
vecRet.reserve(members.size());
size_t nRequestedMemberIdx{std::numeric_limits<size_t>::max()};
for (size_t i = 0; i < members.size(); i++) {
if (members[i]->proTxHash == nProTxHash) {
nRequestedMemberIdx = i;
break;
}
}
if (nRequestedMemberIdx == std::numeric_limits<size_t>::max()) {
return false;
}
for (size_t i = 0; i < members.size(); i++) {
if (validMembers[i]) {
CBLSIESMultiRecipientObjects<CBLSSecretKey> encryptedContributions;
if (!llmqDb.Read(std::make_tuple(DB_ENC_CONTRIB, llmqType, pindexQuorum->GetBlockHash(), members[i]->proTxHash), encryptedContributions)) {
return false;
}
vecRet.emplace_back(encryptedContributions.Get(nRequestedMemberIdx));
}
}
return true;
}
void CDKGSessionManager::CleanupCache() void CDKGSessionManager::CleanupCache()
{ {
LOCK(contributionsCacheCs); LOCK(contributionsCacheCs);

View File

@ -61,10 +61,14 @@ public:
bool GetJustification(const uint256& hash, CDKGJustification& ret) const; bool GetJustification(const uint256& hash, CDKGJustification& ret) const;
bool GetPrematureCommitment(const uint256& hash, CDKGPrematureCommitment& ret) const; bool GetPrematureCommitment(const uint256& hash, CDKGPrematureCommitment& ret) const;
// Verified contributions are written while in the DKG // Contributions are written while in the DKG
void WriteVerifiedVvecContribution(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const uint256& proTxHash, const BLSVerificationVectorPtr& vvec); void WriteVerifiedVvecContribution(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const uint256& proTxHash, const BLSVerificationVectorPtr& vvec);
void WriteVerifiedSkContribution(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const uint256& proTxHash, const CBLSSecretKey& skContribution); void WriteVerifiedSkContribution(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const uint256& proTxHash, const CBLSSecretKey& skContribution);
bool GetVerifiedContributions(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const std::vector<bool>& validMembers, std::vector<uint16_t>& memberIndexesRet, std::vector<BLSVerificationVectorPtr>& vvecsRet, BLSSecretKeyVector& skContributionsRet); bool GetVerifiedContributions(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const std::vector<bool>& validMembers, std::vector<uint16_t>& memberIndexesRet, std::vector<BLSVerificationVectorPtr>& vvecsRet, BLSSecretKeyVector& skContributionsRet);
/// Write encrypted (unverified) DKG contributions for the member with the given proTxHash to the llmqDb
void WriteEncryptedContributions(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const uint256& proTxHash, const CBLSIESMultiRecipientObjects<CBLSSecretKey>& contributions);
/// Read encrypted (unverified) DKG contributions for the member with the given proTxHash from the llmqDb
bool GetEncryptedContributions(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const std::vector<bool>& validMembers, const uint256& proTxHash, std::vector<CBLSIESEncryptedObject<CBLSSecretKey>>& vecRet);
private: private:
void CleanupCache(); void CleanupCache();