mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 20:12:57 +01:00
fix(net): Do not punish nodes when Quorum data are missing. (#5272)
## Issue being fixed or feature implemented Currently, we store internally the nodes that already requested `QGETDATA` for the same Quorum. If data for the same Quorum is requested twice from the same `proRegTx`, then the requester is P2P misbehaved. ## What was done? Some data like `VerificationVector` and `EncryptedContributions` are not instantly available. This PR does not misbehave nodes for requesting data that weren't available when asked. ## How Has This Been Tested? ## Breaking Changes ## Checklist: - [x] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation **For repository code-owners and collaborators only** - [x] I have assigned this pull request to a milestone
This commit is contained in:
parent
38c1ee7509
commit
bcb65a217d
@ -630,13 +630,29 @@ void CQuorumManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, C
|
||||
CQuorumDataRequest request;
|
||||
vRecv >> request;
|
||||
|
||||
auto sendQDATA = [&](CQuorumDataRequest::Errors nError = CQuorumDataRequest::Errors::UNDEFINED,
|
||||
auto sendQDATA = [&](CQuorumDataRequest::Errors nError,
|
||||
bool request_limit_exceeded,
|
||||
const CDataStream& body = CDataStream(SER_NETWORK, PROTOCOL_VERSION)) {
|
||||
switch (nError) {
|
||||
case (CQuorumDataRequest::Errors::NONE):
|
||||
case (CQuorumDataRequest::Errors::QUORUM_TYPE_INVALID):
|
||||
case (CQuorumDataRequest::Errors::QUORUM_BLOCK_NOT_FOUND):
|
||||
case (CQuorumDataRequest::Errors::QUORUM_NOT_FOUND):
|
||||
case (CQuorumDataRequest::Errors::MASTERNODE_IS_NO_MEMBER):
|
||||
case (CQuorumDataRequest::Errors::UNDEFINED):
|
||||
if (request_limit_exceeded) errorHandler("Request limit exceeded", 25);
|
||||
break;
|
||||
case (CQuorumDataRequest::Errors::QUORUM_VERIFICATION_VECTOR_MISSING):
|
||||
case (CQuorumDataRequest::Errors::ENCRYPTED_CONTRIBUTIONS_MISSING):
|
||||
// Do not punish limit exceed if we don't have the requested data
|
||||
break;
|
||||
}
|
||||
request.SetError(nError);
|
||||
CDataStream ssResponse(SER_NETWORK, pfrom.GetSendVersion(), request, body);
|
||||
connman.PushMessage(&pfrom, CNetMsgMaker(pfrom.GetSendVersion()).Make(NetMsgType::QDATA, ssResponse));
|
||||
};
|
||||
|
||||
bool request_limit_exceeded(false);
|
||||
{
|
||||
LOCK2(cs_main, cs_data_requests);
|
||||
CQuorumDataRequestKey key;
|
||||
@ -650,24 +666,24 @@ void CQuorumManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, C
|
||||
} else if (it->second.IsExpired()) {
|
||||
it->second = request;
|
||||
} else {
|
||||
errorHandler("Request limit exceeded", 25);
|
||||
request_limit_exceeded = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!GetLLMQParams(request.GetLLMQType()).has_value()) {
|
||||
sendQDATA(CQuorumDataRequest::Errors::QUORUM_TYPE_INVALID);
|
||||
sendQDATA(CQuorumDataRequest::Errors::QUORUM_TYPE_INVALID, request_limit_exceeded);
|
||||
return;
|
||||
}
|
||||
|
||||
const CBlockIndex* pQuorumBaseBlockIndex = WITH_LOCK(cs_main, return LookupBlockIndex(request.GetQuorumHash()));
|
||||
if (pQuorumBaseBlockIndex == nullptr) {
|
||||
sendQDATA(CQuorumDataRequest::Errors::QUORUM_BLOCK_NOT_FOUND);
|
||||
sendQDATA(CQuorumDataRequest::Errors::QUORUM_BLOCK_NOT_FOUND, request_limit_exceeded);
|
||||
return;
|
||||
}
|
||||
|
||||
const CQuorumCPtr pQuorum = GetQuorum(request.GetLLMQType(), pQuorumBaseBlockIndex);
|
||||
if (pQuorum == nullptr) {
|
||||
sendQDATA(CQuorumDataRequest::Errors::QUORUM_NOT_FOUND);
|
||||
sendQDATA(CQuorumDataRequest::Errors::QUORUM_NOT_FOUND, request_limit_exceeded);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -676,7 +692,7 @@ void CQuorumManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, C
|
||||
// Check if request wants QUORUM_VERIFICATION_VECTOR data
|
||||
if (request.GetDataMask() & CQuorumDataRequest::QUORUM_VERIFICATION_VECTOR) {
|
||||
if (!pQuorum->HasVerificationVector()) {
|
||||
sendQDATA(CQuorumDataRequest::Errors::QUORUM_VERIFICATION_VECTOR_MISSING);
|
||||
sendQDATA(CQuorumDataRequest::Errors::QUORUM_VERIFICATION_VECTOR_MISSING, request_limit_exceeded);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -688,20 +704,20 @@ void CQuorumManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, C
|
||||
|
||||
int memberIdx = pQuorum->GetMemberIndex(request.GetProTxHash());
|
||||
if (memberIdx == -1) {
|
||||
sendQDATA(CQuorumDataRequest::Errors::MASTERNODE_IS_NO_MEMBER);
|
||||
sendQDATA(CQuorumDataRequest::Errors::MASTERNODE_IS_NO_MEMBER, request_limit_exceeded);
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<CBLSIESEncryptedObject<CBLSSecretKey>> vecEncrypted;
|
||||
if (!dkgManager.GetEncryptedContributions(request.GetLLMQType(), pQuorumBaseBlockIndex, pQuorum->qc->validMembers, request.GetProTxHash(), vecEncrypted)) {
|
||||
sendQDATA(CQuorumDataRequest::Errors::ENCRYPTED_CONTRIBUTIONS_MISSING);
|
||||
sendQDATA(CQuorumDataRequest::Errors::ENCRYPTED_CONTRIBUTIONS_MISSING, request_limit_exceeded);
|
||||
return;
|
||||
}
|
||||
|
||||
ssResponseData << vecEncrypted;
|
||||
}
|
||||
|
||||
sendQDATA(CQuorumDataRequest::Errors::NONE, ssResponseData);
|
||||
sendQDATA(CQuorumDataRequest::Errors::NONE, request_limit_exceeded, ssResponseData);
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user