Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ BITCOIN_TESTS =\
test/llmq_commitment_tests.cpp \
test/llmq_hash_tests.cpp \
test/llmq_params_tests.cpp \
test/llmq_signing_shares_tests.cpp \
test/llmq_snapshot_tests.cpp \
test/llmq_utils_tests.cpp \
test/logging_tests.cpp \
Expand Down
30 changes: 14 additions & 16 deletions src/llmq/signing_shares.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,8 +424,9 @@ bool CSigSharesManager::ProcessMessageBatchedSigShares(const CNode& pfrom, const
return true;
}

if (bool ban{false}; !PreVerifyBatchedSigShares(m_mn_activeman, qman, sessionInfo, batchedSigShares, ban)) {
return !ban;
auto verifyResult = PreVerifyBatchedSigShares(m_mn_activeman, qman, sessionInfo, batchedSigShares);
if (!verifyResult.IsSuccess()) {
return !verifyResult.should_ban;
}

std::vector<CSigShare> sigSharesToProcess;
Expand Down Expand Up @@ -522,46 +523,43 @@ void CSigSharesManager::ProcessMessageSigShare(NodeId fromId, const CSigShare& s
sigShare.GetSignHash().ToString(), sigShare.getId().ToString(), sigShare.getMsgHash().ToString(), sigShare.getQuorumMember(), fromId);
}

bool CSigSharesManager::PreVerifyBatchedSigShares(const CActiveMasternodeManager& mn_activeman, const CQuorumManager& quorum_manager,
const CSigSharesNodeState::SessionInfo& session, const CBatchedSigShares& batchedSigShares, bool& retBan)
PreVerifyBatchedResult CSigSharesManager::PreVerifyBatchedSigShares(const CActiveMasternodeManager& mn_activeman,
const CQuorumManager& quorum_manager,
const CSigSharesNodeState::SessionInfo& session,
const CBatchedSigShares& batchedSigShares)
{
retBan = false;

if (!IsQuorumActive(session.llmqType, quorum_manager, session.quorum->qc->quorumHash)) {
// quorum is too old
return false;
return {PreVerifyResult::QuorumTooOld, false};
}
if (!session.quorum->IsMember(mn_activeman.GetProTxHash())) {
// we're not a member so we can't verify it (we actually shouldn't have received it)
return false;
return {PreVerifyResult::NotAMember, false};
}
if (!session.quorum->HasVerificationVector()) {
// TODO we should allow to ask other nodes for the quorum vvec if we missed it in the DKG
LogPrint(BCLog::LLMQ_SIGS, "CSigSharesManager::%s -- we don't have the quorum vvec for %s, no verification possible.\n", __func__,
session.quorumHash.ToString());
return false;
return {PreVerifyResult::MissingVerificationVector, false};
}

std::unordered_set<uint16_t> dupMembers;

for (const auto& [quorumMember, _] : batchedSigShares.sigShares) {
if (!dupMembers.emplace(quorumMember).second) {
retBan = true;
return false;
return {PreVerifyResult::DuplicateMember, true};
}

if (quorumMember >= session.quorum->members.size()) {
LogPrint(BCLog::LLMQ_SIGS, "CSigSharesManager::%s -- quorumMember out of bounds\n", __func__);
retBan = true;
return false;
return {PreVerifyResult::QuorumMemberOutOfBounds, true};
}
if (!session.quorum->qc->validMembers[quorumMember]) {
LogPrint(BCLog::LLMQ_SIGS, "CSigSharesManager::%s -- quorumMember not valid\n", __func__);
retBan = true;
return false;
return {PreVerifyResult::QuorumMemberNotValid, true};
}
}
return true;
return {PreVerifyResult::Success, false};
}

bool CSigSharesManager::CollectPendingSigSharesToVerify(
Expand Down
27 changes: 23 additions & 4 deletions src/llmq/signing_shares.h
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,23 @@ class CSignedSession
int attempt{0};
};

enum class PreVerifyResult {
Success,
QuorumTooOld,
NotAMember,
MissingVerificationVector,
DuplicateMember,
QuorumMemberOutOfBounds,
QuorumMemberNotValid
};

struct PreVerifyBatchedResult {
PreVerifyResult result;
bool should_ban;

[[nodiscard]] bool IsSuccess() const { return result == PreVerifyResult::Success; }
};

class CSigSharesManager : public CRecoveredSigsListener
{
private:
Expand Down Expand Up @@ -447,6 +464,12 @@ class CSigSharesManager : public CRecoveredSigsListener

void NotifyRecoveredSig(const std::shared_ptr<const CRecoveredSig>& sig) const;

static bool VerifySigSharesInv(Consensus::LLMQType llmqType, const CSigSharesInv& inv);
static PreVerifyBatchedResult PreVerifyBatchedSigShares(const CActiveMasternodeManager& mn_activeman,
const CQuorumManager& quorum_manager,
const CSigSharesNodeState::SessionInfo& session,
const CBatchedSigShares& batchedSigShares);

private:
// all of these return false when the currently processed message should be aborted (as each message actually contains multiple messages)
bool ProcessMessageSigSesAnn(const CNode& pfrom, const CSigSesAnn& ann);
Expand All @@ -455,10 +478,6 @@ class CSigSharesManager : public CRecoveredSigsListener
bool ProcessMessageBatchedSigShares(const CNode& pfrom, const CBatchedSigShares& batchedSigShares);
void ProcessMessageSigShare(NodeId fromId, const CSigShare& sigShare);

static bool VerifySigSharesInv(Consensus::LLMQType llmqType, const CSigSharesInv& inv);
static bool PreVerifyBatchedSigShares(const CActiveMasternodeManager& mn_activeman, const CQuorumManager& quorum_manager,
const CSigSharesNodeState::SessionInfo& session, const CBatchedSigShares& batchedSigShares, bool& retBan);

bool CollectPendingSigSharesToVerify(
size_t maxUniqueSessions, std::unordered_map<NodeId, std::vector<CSigShare>>& retSigShares,
std::unordered_map<std::pair<Consensus::LLMQType, uint256>, CQuorumCPtr, StaticSaltedHasher>& retQuorums);
Expand Down
Loading
Loading