mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 19:42:46 +01:00
Merge pull request #4921 from PastaPastaPasta/v18.x-rc9
[v18.x] rc9 backports
This commit is contained in:
commit
fa12c9685c
@ -2,7 +2,7 @@ AC_PREREQ([2.69])
|
||||
define(_CLIENT_VERSION_MAJOR, 18)
|
||||
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, 2022)
|
||||
define(_COPYRIGHT_HOLDERS,[The %s developers])
|
||||
|
@ -732,6 +732,8 @@ std::optional<std::vector<CFinalCommitment>> CQuorumBlockProcessor::GetMineableC
|
||||
break;
|
||||
}
|
||||
|
||||
if (HasMinedCommitment(llmqParams.type, quorumHash)) continue;
|
||||
|
||||
LOCK(minableCommitmentsCs);
|
||||
|
||||
auto k = std::make_pair(llmqParams.type, quorumHash);
|
||||
|
@ -472,10 +472,9 @@ void CDKGSession::VerifyConnectionAndMinProtoVersions() const
|
||||
logger.Batch("%s does not have min proto version %d (has %d)", m->dmn->proTxHash.ToString(), MIN_MASTERNODE_PROTO_VERSION, it->second);
|
||||
}
|
||||
|
||||
auto lastOutbound = mmetaman.GetMetaInfo(m->dmn->proTxHash)->GetLastOutboundSuccess();
|
||||
if (GetAdjustedTime() - lastOutbound > 60 * 60) {
|
||||
if (mmetaman.GetMetaInfo(m->dmn->proTxHash)->OutboundFailedTooManyTimes()) {
|
||||
m->badConnection = true;
|
||||
logger.Batch("%s no outbound connection since %d seconds", m->dmn->proTxHash.ToString(), GetAdjustedTime() - lastOutbound);
|
||||
logger.Batch("%s failed to connect to it too many times", m->dmn->proTxHash.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -243,7 +243,7 @@ void CQuorumManager::UpdatedBlockTip(const CBlockIndex* pindexNew, bool fInitial
|
||||
}
|
||||
|
||||
for (auto& params : Params().GetConsensus().llmqs) {
|
||||
EnsureQuorumConnections(params, pindexNew);
|
||||
CheckQuorumConnections(params, pindexNew);
|
||||
}
|
||||
|
||||
{
|
||||
@ -262,7 +262,7 @@ void CQuorumManager::UpdatedBlockTip(const CBlockIndex* pindexNew, bool fInitial
|
||||
TriggerQuorumDataRecoveryThreads(pindexNew);
|
||||
}
|
||||
|
||||
void CQuorumManager::EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, const CBlockIndex* pindexNew) const
|
||||
void CQuorumManager::CheckQuorumConnections(const Consensus::LLMQParams& llmqParams, const CBlockIndex* pindexNew) const
|
||||
{
|
||||
auto lastQuorums = ScanQuorums(llmqParams.type, pindexNew, (size_t)llmqParams.keepOldConnections);
|
||||
|
||||
@ -289,11 +289,36 @@ void CQuorumManager::EnsureQuorumConnections(const Consensus::LLMQParams& llmqPa
|
||||
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- llmqType[%d] h[%d] keeping mn quorum connections for quorum: [%d:%s]\n", __func__, int(llmqParams.type), pindexNew->nHeight, curDkgHeight, curDkgBlock.ToString());
|
||||
}
|
||||
|
||||
const auto myProTxHash = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash);
|
||||
bool isISType = llmqParams.type == Params().GetConsensus().llmqTypeInstantSend ||
|
||||
llmqParams.type == Params().GetConsensus().llmqTypeDIP0024InstantSend;
|
||||
|
||||
bool watchOtherISQuorums = isISType && !myProTxHash.IsNull() &&
|
||||
ranges::any_of(lastQuorums, [&myProTxHash](const auto& old_quorum){
|
||||
return old_quorum->IsMember(myProTxHash);
|
||||
});
|
||||
|
||||
for (const auto& quorum : lastQuorums) {
|
||||
if (CLLMQUtils::EnsureQuorumConnections(llmqParams, quorum->m_quorum_base_block_index, WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash))) {
|
||||
if (CLLMQUtils::EnsureQuorumConnections(llmqParams, quorum->m_quorum_base_block_index, myProTxHash)) {
|
||||
if (connmanQuorumsToDelete.erase(quorum->qc->quorumHash) > 0) {
|
||||
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- llmqType[%d] h[%d] keeping mn quorum connections for quorum: [%d:%s]\n", __func__, int(llmqParams.type), pindexNew->nHeight, quorum->m_quorum_base_block_index->nHeight, quorum->m_quorum_base_block_index->GetBlockHash().ToString());
|
||||
}
|
||||
} else if (watchOtherISQuorums && !quorum->IsMember(myProTxHash)) {
|
||||
std::set<uint256> connections;
|
||||
const auto& cindexes = CLLMQUtils::CalcDeterministicWatchConnections(llmqParams.type, quorum->m_quorum_base_block_index, quorum->members.size(), 1);
|
||||
for (auto idx : cindexes) {
|
||||
connections.emplace(quorum->members[idx]->proTxHash);
|
||||
}
|
||||
if (!connections.empty()) {
|
||||
if (!g_connman->HasMasternodeQuorumNodes(llmqParams.type, quorum->m_quorum_base_block_index->GetBlockHash())) {
|
||||
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- llmqType[%d] h[%d] adding mn inter-quorum connections for quorum: [%d:%s]\n", __func__, int(llmqParams.type), pindexNew->nHeight, quorum->m_quorum_base_block_index->nHeight, quorum->m_quorum_base_block_index->GetBlockHash().ToString());
|
||||
g_connman->SetMasternodeQuorumNodes(llmqParams.type, quorum->m_quorum_base_block_index->GetBlockHash(), connections);
|
||||
g_connman->SetMasternodeQuorumRelayMembers(llmqParams.type, quorum->m_quorum_base_block_index->GetBlockHash(), connections);
|
||||
}
|
||||
if (connmanQuorumsToDelete.erase(quorum->qc->quorumHash) > 0) {
|
||||
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- llmqType[%d] h[%d] keeping mn inter-quorum connections for quorum: [%d:%s]\n", __func__, int(llmqParams.type), pindexNew->nHeight, quorum->m_quorum_base_block_index->nHeight, quorum->m_quorum_base_block_index->GetBlockHash().ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const auto& quorumHash : connmanQuorumsToDelete) {
|
||||
|
@ -224,7 +224,7 @@ public:
|
||||
|
||||
private:
|
||||
// all private methods here are cs_main-free
|
||||
void EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, const CBlockIndex *pindexNew) const;
|
||||
void CheckQuorumConnections(const Consensus::LLMQParams& llmqParams, const CBlockIndex *pindexNew) const;
|
||||
|
||||
CQuorumPtr BuildQuorumFromCommitment(Consensus::LLMQType llmqType, const CBlockIndex* pQuorumBaseBlockIndex) const EXCLUSIVE_LOCKS_REQUIRED(quorumsCacheCs);
|
||||
bool BuildQuorumContributions(const CFinalCommitmentPtr& fqc, const std::shared_ptr<CQuorum>& quorum) const;
|
||||
|
@ -701,13 +701,24 @@ std::set<size_t> CLLMQUtils::CalcDeterministicWatchConnections(Consensus::LLMQTy
|
||||
|
||||
bool CLLMQUtils::EnsureQuorumConnections(const Consensus::LLMQParams& llmqParams, const CBlockIndex* pQuorumBaseBlockIndex, const uint256& myProTxHash)
|
||||
{
|
||||
if (!fMasternodeMode && !CLLMQUtils::IsWatchQuorumsEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto members = GetAllQuorumMembers(llmqParams.type, pQuorumBaseBlockIndex);
|
||||
if (members.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isMember = std::find_if(members.begin(), members.end(), [&](const auto& dmn) { return dmn->proTxHash == myProTxHash; }) != members.end();
|
||||
|
||||
if (!isMember && !CLLMQUtils::IsWatchQuorumsEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LogPrint(BCLog::NET_NETCONN, "CLLMQUtils::%s -- isMember=%d for quorum %s:\n",
|
||||
__func__, isMember, pQuorumBaseBlockIndex->GetBlockHash().ToString());
|
||||
|
||||
std::set<uint256> connections;
|
||||
std::set<uint256> relayMembers;
|
||||
if (isMember) {
|
||||
|
@ -2478,8 +2478,7 @@ void CConnman::ThreadOpenMasternodeConnections()
|
||||
LogPrint(BCLog::NET_NETCONN, "CConnman::%s -- connection failed for masternode %s, service=%s\n", __func__, connectToDmn->proTxHash.ToString(), connectToDmn->pdmnState->addr.ToString(false));
|
||||
// Will take a few consequent failed attempts to PoSe-punish a MN.
|
||||
if (mmetaman.GetMetaInfo(connectToDmn->proTxHash)->OutboundFailedTooManyTimes()) {
|
||||
LogPrint(BCLog::NET_NETCONN, "CConnman::%s -- failed to connect to masternode %s too many times, resetting outbound success time\n", __func__, connectToDmn->proTxHash.ToString());
|
||||
mmetaman.GetMetaInfo(connectToDmn->proTxHash)->SetLastOutboundSuccess(0);
|
||||
LogPrint(BCLog::NET_NETCONN, "CConnman::%s -- failed to connect to masternode %s too many times\n", __func__, connectToDmn->proTxHash.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3362,6 +3361,9 @@ size_t CConnman::GetNodeCount(NumConnections flags)
|
||||
if (pnode->fDisconnect) {
|
||||
continue;
|
||||
}
|
||||
if ((flags & CONNECTIONS_VERIFIED) && pnode->GetVerifiedProRegTxHash().IsNull()) {
|
||||
continue;
|
||||
}
|
||||
if (flags & (pnode->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT)) {
|
||||
nNum++;
|
||||
}
|
||||
|
@ -142,6 +142,9 @@ public:
|
||||
CONNECTIONS_IN = (1U << 0),
|
||||
CONNECTIONS_OUT = (1U << 1),
|
||||
CONNECTIONS_ALL = (CONNECTIONS_IN | CONNECTIONS_OUT),
|
||||
CONNECTIONS_VERIFIED = (1U << 2),
|
||||
CONNECTIONS_VERIFIED_IN = (CONNECTIONS_VERIFIED | CONNECTIONS_IN),
|
||||
CONNECTIONS_VERIFIED_OUT = (CONNECTIONS_VERIFIED | CONNECTIONS_OUT),
|
||||
};
|
||||
|
||||
enum SocketEventsMode {
|
||||
|
@ -494,7 +494,12 @@ static UniValue getnetworkinfo(const JSONRPCRequest& request)
|
||||
" ],\n"
|
||||
" \"localrelay\" : true|false, (boolean) true if transaction relay is requested from peers\n"
|
||||
" \"timeoffset\" : xxxxx, (numeric) the time offset\n"
|
||||
" \"connections\" : xxxxx, (numeric) the number of connections\n"
|
||||
" \"connections\" : xxxxx, (numeric) the number of inbound and outbound connections\n"
|
||||
" \"inboundconnections\" : xxxxx, (numeric) the number of inbound connections\n"
|
||||
" \"outboundconnections\" : xxxxx, (numeric) the number of outbound connections\n"
|
||||
" \"mnconnections\" : xxxxx, (numeric) the number of verified mn connections\n"
|
||||
" \"inboundmnconnections\" : xxxxx, (numeric) the number of inbound verified mn connections\n"
|
||||
" \"outboundmnconnections\" : xxxxx, (numeric) the number of outbound verified mn connections\n"
|
||||
" \"networkactive\" : true|false, (boolean) whether p2p networking is enabled\n"
|
||||
" \"socketevents\" : \"xxx/\", (string) the socket events mode, either kqueue, epoll, poll or select\n"
|
||||
" \"networks\" : [ (json array) information per network\n"
|
||||
@ -542,6 +547,11 @@ static UniValue getnetworkinfo(const JSONRPCRequest& request)
|
||||
if (g_connman) {
|
||||
obj.pushKV("networkactive", g_connman->GetNetworkActive());
|
||||
obj.pushKV("connections", (int)g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL));
|
||||
obj.pushKV("inboundconnections", (int)g_connman->GetNodeCount(CConnman::CONNECTIONS_IN));
|
||||
obj.pushKV("outboundconnections", (int)g_connman->GetNodeCount(CConnman::CONNECTIONS_OUT));
|
||||
obj.pushKV("mnconnections", (int)g_connman->GetNodeCount(CConnman::CONNECTIONS_VERIFIED));
|
||||
obj.pushKV("inboundmnconnections", (int)g_connman->GetNodeCount(CConnman::CONNECTIONS_VERIFIED_IN));
|
||||
obj.pushKV("outboundmnconnections", (int)g_connman->GetNodeCount(CConnman::CONNECTIONS_VERIFIED_OUT));
|
||||
std::string strSocketEvents;
|
||||
switch (g_connman->GetSocketEventsMode()) {
|
||||
case CConnman::SOCKETEVENTS_SELECT:
|
||||
|
@ -69,6 +69,20 @@ class LLMQConnections(DashTestFramework):
|
||||
|
||||
self.check_reconnects(4)
|
||||
|
||||
self.log.info("check that inter-quorum masternode conections are added")
|
||||
added = False
|
||||
for mn in self.mninfo:
|
||||
if len(mn.node.quorum("memberof", mn.proTxHash)) > 0:
|
||||
try:
|
||||
with mn.node.assert_debug_log(['adding mn inter-quorum connections']):
|
||||
self.mine_quorum()
|
||||
added = True
|
||||
except:
|
||||
pass # it's ok to not add connections sometimes
|
||||
if added:
|
||||
break
|
||||
assert added # no way we added none
|
||||
|
||||
def check_reconnects(self, expected_connection_count):
|
||||
self.log.info("disable and re-enable networking on all masternodes")
|
||||
for mn in self.mninfo:
|
||||
|
@ -66,7 +66,7 @@ class LLMQSimplePoSeTest(DashTestFramework):
|
||||
def isolate_mn(self, mn):
|
||||
mn.node.setnetworkactive(False)
|
||||
wait_until(lambda: mn.node.getconnectioncount() == 0)
|
||||
return True
|
||||
return True, True
|
||||
|
||||
def close_mn_port(self, mn):
|
||||
self.stop_node(mn.node.index)
|
||||
@ -77,14 +77,14 @@ class LLMQSimplePoSeTest(DashTestFramework):
|
||||
if mn2 is not mn:
|
||||
connect_nodes(mn.node, mn2.node.index)
|
||||
self.reset_probe_timeouts()
|
||||
return False
|
||||
return False, False
|
||||
|
||||
def force_old_mn_proto(self, mn):
|
||||
self.stop_node(mn.node.index)
|
||||
self.start_masternode(mn, ["-pushversion=70216"])
|
||||
connect_nodes(mn.node, 0)
|
||||
self.reset_probe_timeouts()
|
||||
return False
|
||||
return False, True
|
||||
|
||||
def test_no_banning(self, expected_connections=None):
|
||||
for i in range(3):
|
||||
@ -98,15 +98,20 @@ class LLMQSimplePoSeTest(DashTestFramework):
|
||||
expected_contributors = len(mninfos_online)
|
||||
for i in range(2):
|
||||
mn = mninfos_valid.pop()
|
||||
went_offline = invalidate_proc(mn)
|
||||
went_offline, instant_ban = invalidate_proc(mn)
|
||||
if went_offline:
|
||||
mninfos_online.remove(mn)
|
||||
expected_contributors -= 1
|
||||
|
||||
t = time.time()
|
||||
while (not self.check_banned(mn)) and (time.time() - t) < 120:
|
||||
self.reset_probe_timeouts()
|
||||
self.mine_quorum(expected_connections=expected_connections, expected_members=expected_contributors, expected_contributions=expected_contributors, expected_complaints=expected_contributors-1, expected_commitments=expected_contributors, mninfos_online=mninfos_online, mninfos_valid=mninfos_valid)
|
||||
# NOTE: Min PoSe penalty is 100 (see CDeterministicMNList::CalcMaxPoSePenalty()),
|
||||
# so nodes are PoSe-banned in the same DKG they misbehave without being PoSe-punished first.
|
||||
if not instant_ban:
|
||||
# it's ok to miss probes/quorum connections up to 5 times
|
||||
for i in range(5):
|
||||
self.reset_probe_timeouts()
|
||||
self.mine_quorum(expected_connections=expected_connections, expected_members=expected_contributors, expected_contributions=expected_contributors, expected_complaints=0, expected_commitments=expected_contributors, mninfos_online=mninfos_online, mninfos_valid=mninfos_valid)
|
||||
self.reset_probe_timeouts()
|
||||
self.mine_quorum(expected_connections=expected_connections, expected_members=expected_contributors, expected_contributions=expected_contributors, expected_complaints=expected_contributors-1, expected_commitments=expected_contributors, mninfos_online=mninfos_online, mninfos_valid=mninfos_valid)
|
||||
|
||||
assert self.check_banned(mn)
|
||||
|
||||
@ -144,7 +149,7 @@ class LLMQSimplePoSeTest(DashTestFramework):
|
||||
|
||||
def reset_probe_timeouts(self):
|
||||
# Make sure all masternodes will reconnect/re-probe
|
||||
self.bump_mocktime(50 * 60 + 1)
|
||||
self.bump_mocktime(10 * 60 + 1)
|
||||
# Sleep a couple of seconds to let mn sync tick to happen
|
||||
time.sleep(2)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user