mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 04:22:55 +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
08aa10c8cb
commit
f4b91c08a6
@ -631,13 +631,29 @@ void CQuorumManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, C
|
|||||||
CQuorumDataRequest request;
|
CQuorumDataRequest request;
|
||||||
vRecv >> 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)) {
|
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);
|
request.SetError(nError);
|
||||||
CDataStream ssResponse(SER_NETWORK, pfrom.GetSendVersion(), request, body);
|
CDataStream ssResponse(SER_NETWORK, pfrom.GetSendVersion(), request, body);
|
||||||
connman.PushMessage(&pfrom, CNetMsgMaker(pfrom.GetSendVersion()).Make(NetMsgType::QDATA, ssResponse));
|
connman.PushMessage(&pfrom, CNetMsgMaker(pfrom.GetSendVersion()).Make(NetMsgType::QDATA, ssResponse));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool request_limit_exceeded(false);
|
||||||
{
|
{
|
||||||
LOCK2(cs_main, cs_data_requests);
|
LOCK2(cs_main, cs_data_requests);
|
||||||
CQuorumDataRequestKey key;
|
CQuorumDataRequestKey key;
|
||||||
@ -651,24 +667,24 @@ void CQuorumManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, C
|
|||||||
} else if (it->second.IsExpired()) {
|
} else if (it->second.IsExpired()) {
|
||||||
it->second = request;
|
it->second = request;
|
||||||
} else {
|
} else {
|
||||||
errorHandler("Request limit exceeded", 25);
|
request_limit_exceeded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GetLLMQParams(request.GetLLMQType()).has_value()) {
|
if (!GetLLMQParams(request.GetLLMQType()).has_value()) {
|
||||||
sendQDATA(CQuorumDataRequest::Errors::QUORUM_TYPE_INVALID);
|
sendQDATA(CQuorumDataRequest::Errors::QUORUM_TYPE_INVALID, request_limit_exceeded);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CBlockIndex* pQuorumBaseBlockIndex = WITH_LOCK(cs_main, return LookupBlockIndex(request.GetQuorumHash()));
|
const CBlockIndex* pQuorumBaseBlockIndex = WITH_LOCK(cs_main, return LookupBlockIndex(request.GetQuorumHash()));
|
||||||
if (pQuorumBaseBlockIndex == nullptr) {
|
if (pQuorumBaseBlockIndex == nullptr) {
|
||||||
sendQDATA(CQuorumDataRequest::Errors::QUORUM_BLOCK_NOT_FOUND);
|
sendQDATA(CQuorumDataRequest::Errors::QUORUM_BLOCK_NOT_FOUND, request_limit_exceeded);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CQuorumCPtr pQuorum = GetQuorum(request.GetLLMQType(), pQuorumBaseBlockIndex);
|
const CQuorumCPtr pQuorum = GetQuorum(request.GetLLMQType(), pQuorumBaseBlockIndex);
|
||||||
if (pQuorum == nullptr) {
|
if (pQuorum == nullptr) {
|
||||||
sendQDATA(CQuorumDataRequest::Errors::QUORUM_NOT_FOUND);
|
sendQDATA(CQuorumDataRequest::Errors::QUORUM_NOT_FOUND, request_limit_exceeded);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -677,7 +693,7 @@ void CQuorumManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, C
|
|||||||
// Check if request wants QUORUM_VERIFICATION_VECTOR data
|
// Check if request wants QUORUM_VERIFICATION_VECTOR data
|
||||||
if (request.GetDataMask() & CQuorumDataRequest::QUORUM_VERIFICATION_VECTOR) {
|
if (request.GetDataMask() & CQuorumDataRequest::QUORUM_VERIFICATION_VECTOR) {
|
||||||
if (!pQuorum->HasVerificationVector()) {
|
if (!pQuorum->HasVerificationVector()) {
|
||||||
sendQDATA(CQuorumDataRequest::Errors::QUORUM_VERIFICATION_VECTOR_MISSING);
|
sendQDATA(CQuorumDataRequest::Errors::QUORUM_VERIFICATION_VECTOR_MISSING, request_limit_exceeded);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -689,20 +705,20 @@ void CQuorumManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, C
|
|||||||
|
|
||||||
int memberIdx = pQuorum->GetMemberIndex(request.GetProTxHash());
|
int memberIdx = pQuorum->GetMemberIndex(request.GetProTxHash());
|
||||||
if (memberIdx == -1) {
|
if (memberIdx == -1) {
|
||||||
sendQDATA(CQuorumDataRequest::Errors::MASTERNODE_IS_NO_MEMBER);
|
sendQDATA(CQuorumDataRequest::Errors::MASTERNODE_IS_NO_MEMBER, request_limit_exceeded);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<CBLSIESEncryptedObject<CBLSSecretKey>> vecEncrypted;
|
std::vector<CBLSIESEncryptedObject<CBLSSecretKey>> vecEncrypted;
|
||||||
if (!dkgManager.GetEncryptedContributions(request.GetLLMQType(), pQuorumBaseBlockIndex, pQuorum->qc->validMembers, request.GetProTxHash(), 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssResponseData << vecEncrypted;
|
ssResponseData << vecEncrypted;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendQDATA(CQuorumDataRequest::Errors::NONE, ssResponseData);
|
sendQDATA(CQuorumDataRequest::Errors::NONE, request_limit_exceeded, ssResponseData);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user