Skip to content

Commit

Permalink
Merge pull request #5282 from PastaPastaPasta/backport/bump-to-19-rc9
Browse files Browse the repository at this point in the history
[v19.x] backport: rc9 backports and version bump
  • Loading branch information
UdjinM6 committed Mar 30, 2023
2 parents d06c771 + 26873b0 commit af25e48
Show file tree
Hide file tree
Showing 12 changed files with 108 additions and 21 deletions.
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ AC_PREREQ([2.69])
define(_CLIENT_VERSION_MAJOR, 19)
define(_CLIENT_VERSION_MINOR, 0)
define(_CLIENT_VERSION_BUILD, 0)
define(_CLIENT_VERSION_RC, 8)
define(_CLIENT_VERSION_RC, 9)
define(_CLIENT_VERSION_IS_RELEASE, false)
define(_COPYRIGHT_YEAR, 2023)
define(_COPYRIGHT_HOLDERS,[The %s developers])
Expand Down
5 changes: 5 additions & 0 deletions doc/release-notes-5273.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Added RPCs
--------

- `cleardiscouraged` clears all the already discouraged peers.

10 changes: 10 additions & 0 deletions src/banman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,16 @@ void BanMan::ClearBanned()
if (m_client_interface) m_client_interface->BannedListChanged();
}

void BanMan::ClearDiscouraged()
{
{
LOCK(m_cs_banned);
m_discouraged.reset();
m_is_dirty = true;
}
if (m_client_interface) m_client_interface->BannedListChanged();
}

bool BanMan::IsDiscouraged(const CNetAddr& net_addr)
{
LOCK(m_cs_banned);
Expand Down
1 change: 1 addition & 0 deletions src/banman.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class BanMan
void Ban(const CSubNet& sub_net, int64_t ban_time_offset = 0, bool since_unix_epoch = false);
void Discourage(const CNetAddr& net_addr);
void ClearBanned();
void ClearDiscouraged();

//! Return whether net_addr is banned
bool IsBanned(const CNetAddr& net_addr);
Expand Down
26 changes: 23 additions & 3 deletions src/evo/deterministicmns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,15 +218,35 @@ std::vector<CDeterministicMNCPtr> CDeterministicMNList::GetProjectedMNPayees(int
if (nCount < 0 ) {
return {};
}
nCount = std::min(nCount, int(GetValidMNsCount()));
nCount = std::min(nCount, int(GetValidWeightedMNsCount()));

std::vector<CDeterministicMNCPtr> result;
result.reserve(nCount);

auto remaining_hpmn_payments = 0;
CDeterministicMNCPtr hpmn_to_be_skipped = nullptr;
ForEachMNShared(true, [&](const CDeterministicMNCPtr& dmn) {
result.emplace_back(dmn);
if (dmn->pdmnState->nLastPaidHeight == nHeight) {
// We found the last MN Payee.
// If the last payee is a HPMN, we need to check its consecutive payments and pay him again if needed
if (dmn->nType == MnType::HighPerformance && dmn->pdmnState->nConsecutivePayments < dmn_types::HighPerformance.voting_weight) {
remaining_hpmn_payments = dmn_types::HighPerformance.voting_weight - dmn->pdmnState->nConsecutivePayments;
for ([[maybe_unused]] auto _ : irange::range(remaining_hpmn_payments)) {
result.emplace_back(dmn);
hpmn_to_be_skipped = dmn;
}
}
}
return;
});

ForEachMNShared(true, [&](const CDeterministicMNCPtr& dmn) {
if (dmn == hpmn_to_be_skipped) return;
for ([[maybe_unused]] auto _ : irange::range(GetMnType(dmn->nType).voting_weight)) {
result.emplace_back(dmn);
}
});
std::sort(result.begin(), result.end(), [&](const CDeterministicMNCPtr& a, const CDeterministicMNCPtr& b) {
std::sort(result.begin() + remaining_hpmn_payments, result.end(), [&](const CDeterministicMNCPtr& a, const CDeterministicMNCPtr& b) {
return CompareByLastPaid(a.get(), b.get());
});

Expand Down
9 changes: 9 additions & 0 deletions src/evo/deterministicmns.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include <immer/map.hpp>

#include <numeric>
#include <unordered_map>
#include <utility>

Expand Down Expand Up @@ -241,6 +242,14 @@ class CDeterministicMNList
return ranges::count_if(mnMap, [](const auto& p) { return p.second->nType == MnType::HighPerformance && IsMNValid(*p.second); });
}

[[nodiscard]] size_t GetValidWeightedMNsCount() const
{
return std::accumulate(mnMap.begin(), mnMap.end(), 0, [](auto res, const auto& p) {
if (!IsMNValid(*p.second)) return res;
return res + GetMnType(p.second->nType).voting_weight;
});
}

/**
* Execute a callback on all masternodes in the mnList. This will pass a reference
* of each masternode to the callback function. This should be preferred over ForEachMNShared.
Expand Down
1 change: 1 addition & 0 deletions src/evo/mnauth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ void CMNAuth::ProcessMessage(CNode& peer, CConnman& connman, std::string_view ms
if (!mnauth.sig.IsValid()) {
LOCK(cs_main);
Misbehaving(peer.GetId(), 100, "invalid mnauth signature");
LogPrint(BCLog::NET_NETCONN, "CMNAuth::ProcessMessage -- invalid mnauth for protx=%s with sig=%s\n", mnauth.proRegTxHash.ToString(), mnauth.sig.ToString());
return;
}

Expand Down
44 changes: 31 additions & 13 deletions src/llmq/quorums.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ void CQuorumManager::UpdatedBlockTip(const CBlockIndex* pindexNew, bool fInitial
LOCK(cs_data_requests);
auto it = mapQuorumDataRequests.begin();
while (it != mapQuorumDataRequests.end()) {
if (it->second.IsExpired()) {
if (it->second.IsExpired(/*add_bias=*/true)) {
it = mapQuorumDataRequests.erase(it);
} else {
++it;
Expand Down Expand Up @@ -474,10 +474,12 @@ bool CQuorumManager::RequestQuorumData(CNode* pfrom, Consensus::LLMQType llmqTyp
key.quorumHash = pQuorumBaseBlockIndex->GetBlockHash();
key.llmqType = llmqType;
auto it = mapQuorumDataRequests.emplace(key, CQuorumDataRequest(llmqType, pQuorumBaseBlockIndex->GetBlockHash(), nDataMask, proTxHash));
if (!it.second && !it.first->second.IsExpired()) {
if (!it.second && !it.first->second.IsExpired(/*add_bias=*/true)) {
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- Already requested\n", __func__);
return false;
}
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- sending QGETDATA quorumHash[%s] llmqType[%d] proRegTx[%s]\n", __func__, key.quorumHash.ToString(),
ToUnderlying(key.llmqType), key.proRegTx.ToString());

CNetMsgMaker msgMaker(pfrom->GetSendVersion());
connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::QGETDATA, it.first->second));
Expand Down Expand Up @@ -630,13 +632,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;
Expand All @@ -647,27 +665,27 @@ void CQuorumManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, C
auto it = mapQuorumDataRequests.find(key);
if (it == mapQuorumDataRequests.end()) {
it = mapQuorumDataRequests.emplace(key, request).first;
} else if (it->second.IsExpired()) {
} else if (it->second.IsExpired(/*add_bias=*/false)) {
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;
}

Expand All @@ -676,7 +694,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;
}

Expand All @@ -688,20 +706,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;
}

Expand Down Expand Up @@ -902,7 +920,7 @@ void CQuorumManager::StartQuorumDataRecoveryThread(const CQuorumCPtr pQuorum, co
key.quorumHash = pQuorum->qc->quorumHash;
key.llmqType = pQuorum->qc->llmqType;
auto it = mapQuorumDataRequests.find(key);
if (it != mapQuorumDataRequests.end() && !it->second.IsExpired()) {
if (it != mapQuorumDataRequests.end() && !it->second.IsExpired(/*add_bias=*/true)) {
printLog("Already asked");
continue;
}
Expand Down
3 changes: 2 additions & 1 deletion src/llmq/quorums.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ class CQuorumDataRequest
bool fProcessed{false};

static constexpr int64_t EXPIRATION_TIMEOUT{300};
static constexpr int64_t EXPIRATION_BIAS{60};

public:

Expand Down Expand Up @@ -119,7 +120,7 @@ class CQuorumDataRequest
Errors GetError() const { return nError; }
std::string GetErrorString() const;

bool IsExpired() const { return (GetTime() - nTime) >= EXPIRATION_TIMEOUT; }
bool IsExpired(bool add_bias) const { return (GetTime() - nTime) >= (EXPIRATION_TIMEOUT + (add_bias ? EXPIRATION_BIAS : 0)); }
bool IsProcessed() const { return fProcessed; }
void SetProcessed() { fProcessed = true; }

Expand Down
22 changes: 22 additions & 0 deletions src/rpc/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,27 @@ static UniValue clearbanned(const JSONRPCRequest& request)
return NullUniValue;
}

static UniValue cleardiscouraged(const JSONRPCRequest& request)
{
RPCHelpMan{"cleardiscouraged",
"\nClear all discouraged nodes.\n",
{},
RPCResult{RPCResult::Type::NONE, "", ""},
RPCExamples{
HelpExampleCli("cleardiscouraged", "")
+ HelpExampleRpc("cleardiscouraged", "")
},
}.Check(request);
NodeContext& node = EnsureNodeContext(request.context);
if (!node.banman) {
throw JSONRPCError(RPC_DATABASE_ERROR, "Error: Ban database not loaded");
}

node.banman->ClearDiscouraged();

return NullUniValue;
}

static UniValue setnetworkactive(const JSONRPCRequest& request)
{
RPCHelpMan{"setnetworkactive",
Expand Down Expand Up @@ -825,6 +846,7 @@ static const CRPCCommand commands[] =
{ "network", "setban", &setban, {"subnet", "command", "bantime", "absolute"} },
{ "network", "listbanned", &listbanned, {} },
{ "network", "clearbanned", &clearbanned, {} },
{ "network", "cleardiscouraged", &cleardiscouraged, {} },
{ "network", "setnetworkactive", &setnetworkactive, {"state"} },
{ "network", "getnodeaddresses", &getnodeaddresses, {"count"} },
};
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/rpcwallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2482,7 +2482,7 @@ static UniValue getwalletinfo(const JSONRPCRequest& request)
{RPCResult::Type::STR_AMOUNT, "paytxfee", "the transaction fee configuration, set in " + CURRENCY_UNIT + "/kB"},
{RPCResult::Type::STR_HEX, "hdchainid", "the ID of the HD chain"},
{RPCResult::Type::STR, "hdaccountcount", "how many accounts of the HD chain are in this wallet"},
{RPCResult::Type::ARR, "", "",
{RPCResult::Type::ARR, "hdaccounts", "",
{
{RPCResult::Type::OBJ, "", "",
{
Expand Down
4 changes: 2 additions & 2 deletions test/functional/test_framework/test_framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -980,8 +980,8 @@ def set_dash_test_params(self, num_nodes, masterodes_count, extra_args=None, fas

# This is nRequestTimeout in dash-q-recovery thread
self.quorum_data_thread_request_timeout_seconds = 10
# This is EXPIRATION_TIMEOUT in CQuorumDataRequest
self.quorum_data_request_expiration_timeout = 300
# This is EXPIRATION_TIMEOUT + EXPIRATION_BIAS in CQuorumDataRequest
self.quorum_data_request_expiration_timeout = 360

def set_dash_dip8_activation(self, activate_after_block):
self.dip8_activation_height = activate_after_block
Expand Down

0 comments on commit af25e48

Please sign in to comment.