Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: A set of qdata/qwatch related fixes #5745

Merged
merged 7 commits into from
Jan 10, 2024
13 changes: 13 additions & 0 deletions src/llmq/dkgsessionmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,21 @@ void CDKGSessionManager::ProcessMessage(CNode& pfrom, const CQuorumManager& quor
}

if (msg_type == NetMsgType::QWATCH) {
if (!fMasternodeMode) {
// non-masternodes should never receive this
m_peerman->Misbehaving(pfrom.GetId(), 10);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a notice: refactored in #5782 - one of these 2 PR should be changed after other is merged

return;
}
pfrom.qwatch = true;
return;
}

if ((!fMasternodeMode && !utils::IsWatchQuorumsEnabled())) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

potentially conflict with #5790 - one of PR to edit; depends which one get merge first.

// regular non-watching nodes should never receive any of these
m_peerman->Misbehaving(pfrom.GetId(), 10);
return;
}

if (vRecv.empty()) {
m_peerman->Misbehaving(pfrom.GetId(), 100);
return;
Expand Down Expand Up @@ -429,13 +440,15 @@ bool CDKGSessionManager::GetEncryptedContributions(Consensus::LLMQType llmqType,
}
}
if (nRequestedMemberIdx == std::numeric_limits<size_t>::max()) {
LogPrint(BCLog::LLMQ, "CDKGSessionManager::%s -- not a member, nProTxHash=%s\n", __func__, nProTxHash.ToString());
return false;
}

for (const auto i : irange::range(members.size())) {
if (validMembers[i]) {
CBLSIESMultiRecipientObjects<CBLSSecretKey> encryptedContributions;
if (!db->Read(std::make_tuple(DB_ENC_CONTRIB, llmqType, pQuorumBaseBlockIndex->GetBlockHash(), members[i]->proTxHash), encryptedContributions)) {
LogPrint(BCLog::LLMQ, "CDKGSessionManager::%s -- can't read from db, nProTxHash=%s\n", __func__, nProTxHash.ToString());
return false;
}
vecRet.emplace_back(encryptedContributions.Get(nRequestedMemberIdx));
Expand Down
24 changes: 12 additions & 12 deletions src/llmq/quorums.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ void CQuorumManager::Stop()

void CQuorumManager::TriggerQuorumDataRecoveryThreads(const CBlockIndex* pIndex) const
{
if (!fMasternodeMode || !utils::QuorumDataRecoveryEnabled() || pIndex == nullptr) {
if ((!fMasternodeMode && !utils::IsWatchQuorumsEnabled()) || !utils::QuorumDataRecoveryEnabled() || pIndex == nullptr) {
return;
}

Expand Down Expand Up @@ -274,15 +274,13 @@ void CQuorumManager::TriggerQuorumDataRecoveryThreads(const CBlockIndex* pIndex)

void CQuorumManager::UpdatedBlockTip(const CBlockIndex* pindexNew, bool fInitialDownload) const
{
if (!m_mn_sync->IsBlockchainSynced()) {
return;
}
if (!m_mn_sync->IsBlockchainSynced()) return;

for (const auto& params : Params().GetConsensus().llmqs) {
CheckQuorumConnections(params, pindexNew);
}

{
if (fMasternodeMode || utils::IsWatchQuorumsEnabled()) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see many check "fMasternodeMode || utils::IsWatchQuorumsEnabled()" - maybe move a boolean flag fMasternodeMode inside IsWatchQuorumsEnabled such as:

bool IsWatchQuorumsEnabled()
{       
    static bool fIsWatchQuroumsEnabled = gArgs.GetBoolArg("-watchquorums", DEFAULT_WATCH_QUORUMS);
    return fIsWatchQuroumsEnabled ||fMasternodeMode ;
}

// Cleanup expired data requests
LOCK(cs_data_requests);
auto it = mapQuorumDataRequests.begin();
Expand All @@ -301,6 +299,8 @@ void CQuorumManager::UpdatedBlockTip(const CBlockIndex* pindexNew, bool fInitial

void CQuorumManager::CheckQuorumConnections(const Consensus::LLMQParams& llmqParams, const CBlockIndex* pindexNew) const
{
if (!fMasternodeMode && !utils::IsWatchQuorumsEnabled()) return;

auto lastQuorums = ScanQuorums(llmqParams.type, pindexNew, (size_t)llmqParams.keepOldConnections);

auto connmanQuorumsToDelete = connman.GetMasternodeQuorums(llmqParams.type);
Expand Down Expand Up @@ -452,8 +452,8 @@ bool CQuorumManager::RequestQuorumData(CNode* pfrom, Consensus::LLMQType llmqTyp
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- Version must be %d or greater.\n", __func__, LLMQ_DATA_MESSAGES_VERSION);
return false;
}
if (pfrom->GetVerifiedProRegTxHash().IsNull() && !pfrom->qwatch) {
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- pfrom is neither a verified masternode nor a qwatch connection\n", __func__);
if (pfrom->GetVerifiedProRegTxHash().IsNull()) {
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- pfrom is not a verified masternode\n", __func__);
return false;
}
if (!GetLLMQParams(llmqType).has_value()) {
Expand All @@ -472,8 +472,8 @@ bool CQuorumManager::RequestQuorumData(CNode* pfrom, Consensus::LLMQType llmqTyp
LOCK(cs_data_requests);
const CQuorumDataRequestKey key(pfrom->GetVerifiedProRegTxHash(), true, pQuorumBaseBlockIndex->GetBlockHash(), llmqType);
const CQuorumDataRequest request(llmqType, pQuorumBaseBlockIndex->GetBlockHash(), nDataMask, proTxHash);
auto [old_pair, exists] = mapQuorumDataRequests.emplace(key, request);
if (!exists) {
auto [old_pair, inserted] = mapQuorumDataRequests.emplace(key, request);
if (!inserted) {
if (old_pair->second.IsExpired(/*add_bias=*/true)) {
old_pair->second = request;
} else {
Expand Down Expand Up @@ -719,8 +719,8 @@ void CQuorumManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, C
}

if (msg_type == NetMsgType::QDATA) {
if ((!fMasternodeMode && !utils::IsWatchQuorumsEnabled()) || (pfrom.GetVerifiedProRegTxHash().IsNull() && !pfrom.qwatch)) {
errorHandler("Not a verified masternode or a qwatch connection");
if ((!fMasternodeMode && !utils::IsWatchQuorumsEnabled()) || pfrom.GetVerifiedProRegTxHash().IsNull()) {
errorHandler("Not a verified masternode and -watchquorums is not enabled");
return;
}

Expand Down Expand Up @@ -1011,7 +1011,7 @@ void CQuorumManager::StartCleanupOldQuorumDataThread(const CBlockIndex* pIndex)
// window and it's better to have more room so we pick next cycle.
// dkgMiningWindowStart for small quorums is 10 i.e. a safe block to start
// these calculations is at height 576 + 24 * 2 + 10 = 576 + 58.
if (!fMasternodeMode || pIndex == nullptr || (pIndex->nHeight % 576 != 58)) {
if ((!fMasternodeMode && !utils::IsWatchQuorumsEnabled()) || pIndex == nullptr || (pIndex->nHeight % 576 != 58)) {
return;
}

Expand Down
7 changes: 7 additions & 0 deletions test/functional/p2p_quorum_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ def test_basics():
"and does bump our score")
p2p_node0.test_qgetdata(qgetdata_all, response_expected=False)
wait_for_banscore(node0, id_p2p_node0, 10)
self.log.info("Check that normal node bumps our score for qwatch")
p2p_node0.send_message(msg_qwatch())
wait_for_banscore(node0, id_p2p_node0, 20)
# The masternode should not respond to qgetdata for non-masternode connections
self.log.info("Check that masternode doesn't respond to "
"non-masternode connection and does bump our score")
Expand Down Expand Up @@ -383,6 +386,10 @@ def test_watchquorums():
p2p_node0.wait_for_qmessage("qgetdata")
p2p_node0.send_message(p2p_mn2.get_qdata())
wait_for_banscore(node0, id_p2p_node0, (1 - len(extra_args)) * 10)
# Non-masternodes should bump peer's score for qwatch no matter
# whether they (non-masternodes) are watching or not.
p2p_node0.send_message(msg_qwatch())
wait_for_banscore(node0, id_p2p_node0, (1 - len(extra_args)) * 10 + 10)
node0.disconnect_p2ps()
mn2.node.disconnect_p2ps()

Expand Down
Loading