From cf33efc9e15254f2fc5cdc8399dc0a1ef10e38f6 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Thu, 24 Jan 2019 14:11:14 +0100 Subject: [PATCH] Move SelectQuorumForSigning into CSigningManager and make it height based --- src/llmq/quorums.cpp | 29 ------------------------ src/llmq/quorums.h | 2 -- src/llmq/quorums_signing.cpp | 44 +++++++++++++++++++++++++++++++++--- src/llmq/quorums_signing.h | 4 +++- 4 files changed, 44 insertions(+), 35 deletions(-) diff --git a/src/llmq/quorums.cpp b/src/llmq/quorums.cpp index 8859c0616..4622e50aa 100644 --- a/src/llmq/quorums.cpp +++ b/src/llmq/quorums.cpp @@ -333,35 +333,6 @@ std::vector CQuorumManager::ScanQuorums(Consensus::LLMQType llmqTyp return result; } -CQuorumCPtr CQuorumManager::SelectQuorum(Consensus::LLMQType llmqType, const uint256& selectionHash) -{ - LOCK(cs_main); - return SelectQuorum(llmqType, chainActive.Tip()->GetBlockHash(), selectionHash); -} - -CQuorumCPtr CQuorumManager::SelectQuorum(Consensus::LLMQType llmqType, const uint256& startBlock, const uint256& selectionHash) -{ - auto& llmqParams = Params().GetConsensus().llmqs.at(llmqType); - size_t poolSize = (size_t)llmqParams.signingActiveQuorumCount; - - auto quorums = ScanQuorums(llmqType, startBlock, poolSize); - if (quorums.empty()) { - return nullptr; - } - - std::vector> scores; - scores.reserve(quorums.size()); - for (size_t i = 0; i < quorums.size(); i++) { - CHashWriter h(SER_NETWORK, 0); - h << (uint8_t)llmqType; - h << quorums[i]->quorumHash; - h << selectionHash; - scores.emplace_back(h.GetHash(), i); - } - std::sort(scores.begin(), scores.end()); - return quorums[scores.front().second]; -} - CQuorumCPtr CQuorumManager::GetQuorum(Consensus::LLMQType llmqType, const uint256& quorumHash) { AssertLockHeld(cs_main); diff --git a/src/llmq/quorums.h b/src/llmq/quorums.h index 0fcd6022d..ff2f962a0 100644 --- a/src/llmq/quorums.h +++ b/src/llmq/quorums.h @@ -99,8 +99,6 @@ public: CQuorumCPtr GetNewestQuorum(Consensus::LLMQType llmqType); std::vector ScanQuorums(Consensus::LLMQType llmqType, size_t maxCount); std::vector ScanQuorums(Consensus::LLMQType llmqType, const uint256& startBlock, size_t maxCount); - CQuorumCPtr SelectQuorum(Consensus::LLMQType llmqType, const uint256& selectionHash); - CQuorumCPtr SelectQuorum(Consensus::LLMQType llmqType, const uint256& startBlock, const uint256& selectionHash); private: void EnsureQuorumConnections(Consensus::LLMQType llmqType, const CBlockIndex *pindexNew); diff --git a/src/llmq/quorums_signing.cpp b/src/llmq/quorums_signing.cpp index 08b18f59c..0d0ed6553 100644 --- a/src/llmq/quorums_signing.cpp +++ b/src/llmq/quorums_signing.cpp @@ -496,12 +496,18 @@ bool CSigningManager::AsyncSignIfMember(Consensus::LLMQType llmqType, const uint db.WriteVoteForId(llmqType, id, msgHash); } + int tipHeight; + { + LOCK(cs_main); + tipHeight = chainActive.Height(); + } + // This might end up giving different results on different members // This might happen when we are on the brink of confirming a new quorum // This gives a slight risk of not getting enough shares to recover a signature // But at least it shouldn't be possible to get conflicting recovered signatures // TODO fix this by re-signing when the next block arrives, but only when that block results in a change of the quorum list and no recovered signature has been created in the mean time - CQuorumCPtr quorum = quorumManager->SelectQuorum(llmqType, id); + CQuorumCPtr quorum = SelectQuorumForSigning(llmqType, tipHeight, id); if (!quorum) { LogPrintf("CSigningManager::%s -- failed to select quorum. id=%s, msgHash=%s\n", __func__, id.ToString(), msgHash.ToString()); return false; @@ -548,11 +554,43 @@ bool CSigningManager::IsConflicting(Consensus::LLMQType llmqType, const uint256& return false; } -bool CSigningManager::VerifyRecoveredSig(Consensus::LLMQType llmqType, const uint256& signedAtTip, const uint256& id, const uint256& msgHash, const CBLSSignature& sig) +CQuorumCPtr CSigningManager::SelectQuorumForSigning(Consensus::LLMQType llmqType, int signHeight, const uint256& selectionHash) +{ + auto& llmqParams = Params().GetConsensus().llmqs.at(llmqType); + size_t poolSize = (size_t)llmqParams.signingActiveQuorumCount; + + uint256 startBlock; + { + LOCK(cs_main); + if (signHeight > chainActive.Height()) { + return nullptr; + } + startBlock = chainActive[signHeight]->GetBlockHash(); + } + + auto quorums = quorumManager->ScanQuorums(llmqType, startBlock, poolSize); + if (quorums.empty()) { + return nullptr; + } + + std::vector> scores; + scores.reserve(quorums.size()); + for (size_t i = 0; i < quorums.size(); i++) { + CHashWriter h(SER_NETWORK, 0); + h << (uint8_t)llmqType; + h << quorums[i]->quorumHash; + h << selectionHash; + scores.emplace_back(h.GetHash(), i); + } + std::sort(scores.begin(), scores.end()); + return quorums[scores.front().second]; +} + +bool CSigningManager::VerifyRecoveredSig(Consensus::LLMQType llmqType, int signedAtHeight, const uint256& id, const uint256& msgHash, const CBLSSignature& sig) { auto& llmqParams = Params().GetConsensus().llmqs.at(Params().GetConsensus().llmqTypeForChainLocks); - auto quorum = quorumManager->SelectQuorum(llmqParams.type, signedAtTip, id); + auto quorum = SelectQuorumForSigning(llmqParams.type, signedAtHeight, id); if (!quorum) { return false; } diff --git a/src/llmq/quorums_signing.h b/src/llmq/quorums_signing.h index e1c4178e1..842703d6a 100644 --- a/src/llmq/quorums_signing.h +++ b/src/llmq/quorums_signing.h @@ -147,8 +147,10 @@ public: bool HasRecoveredSigForSession(const uint256& signHash); bool IsConflicting(Consensus::LLMQType llmqType, const uint256& id, const uint256& msgHash); + CQuorumCPtr SelectQuorumForSigning(Consensus::LLMQType llmqType, int signHeight, const uint256& selectionHash); + // Verifies a recovered sig that was signed while the chain tip was at signedAtTip - bool VerifyRecoveredSig(Consensus::LLMQType llmqType, const uint256& signedAtTip, const uint256& id, const uint256& msgHash, const CBLSSignature& sig); + bool VerifyRecoveredSig(Consensus::LLMQType llmqType, int signedAtHeight, const uint256& id, const uint256& msgHash, const CBLSSignature& sig); }; extern CSigningManager* quorumSigningManager;