Skip to content

Commit

Permalink
Move SelectQuorumForSigning into CSigningManager and make it height b…
Browse files Browse the repository at this point in the history
…ased
  • Loading branch information
codablock committed Jan 28, 2019
1 parent 4026ea2 commit cf33efc
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 35 deletions.
29 changes: 0 additions & 29 deletions src/llmq/quorums.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,35 +333,6 @@ std::vector<CQuorumCPtr> 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<std::pair<uint256, size_t>> 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);
Expand Down
2 changes: 0 additions & 2 deletions src/llmq/quorums.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,6 @@ class CQuorumManager
CQuorumCPtr GetNewestQuorum(Consensus::LLMQType llmqType);
std::vector<CQuorumCPtr> ScanQuorums(Consensus::LLMQType llmqType, size_t maxCount);
std::vector<CQuorumCPtr> 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);
Expand Down
44 changes: 41 additions & 3 deletions src/llmq/quorums_signing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<std::pair<uint256, size_t>> 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;
}
Expand Down
4 changes: 3 additions & 1 deletion src/llmq/quorums_signing.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,10 @@ class CSigningManager
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;
Expand Down

0 comments on commit cf33efc

Please sign in to comment.