mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 19:42:46 +01:00
Merge pull request #4936 from PastaPastaPasta/v18.x-rc10
[V18.x] backport: rc10 backports
This commit is contained in:
commit
1fa81c6a04
@ -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, 9)
|
||||
define(_CLIENT_VERSION_RC, 10)
|
||||
define(_CLIENT_VERSION_IS_RELEASE, false)
|
||||
define(_COPYRIGHT_YEAR, 2022)
|
||||
define(_COPYRIGHT_HOLDERS,[The %s developers])
|
||||
|
@ -32,7 +32,10 @@ static const std::string DB_QUORUM_QUORUM_VVEC = "q_Qqvvec";
|
||||
CQuorumManager* quorumManager;
|
||||
|
||||
CCriticalSection cs_data_requests;
|
||||
static std::unordered_map<std::pair<uint256, bool>, CQuorumDataRequest, StaticSaltedHasher> mapQuorumDataRequests GUARDED_BY(cs_data_requests);
|
||||
//key = <ProTx, bool, quorumHash, llmqType>
|
||||
//TODO: Document purpose of bool
|
||||
using key_t = std::tuple<uint256, bool, uint256, uint8_t>;
|
||||
static std::unordered_map<key_t, CQuorumDataRequest, StaticSaltedHasher> mapQuorumDataRequests GUARDED_BY(cs_data_requests);
|
||||
|
||||
static uint256 MakeQuorumKey(const CQuorum& q)
|
||||
{
|
||||
@ -195,8 +198,7 @@ void CQuorumManager::TriggerQuorumDataRecoveryThreads(const CBlockIndex* pIndex)
|
||||
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- Process block %s\n", __func__, pIndex->GetBlockHash().ToString());
|
||||
|
||||
for (auto& params : Params().GetConsensus().llmqs) {
|
||||
// Process signingActiveQuorumCount + 1 quorums for all available llmqTypes
|
||||
const auto vecQuorums = ScanQuorums(params.type, pIndex, params.signingActiveQuorumCount + 1);
|
||||
const auto vecQuorums = ScanQuorums(params.type, pIndex, params.keepOldConnections);
|
||||
|
||||
// First check if we are member of any quorum of this type
|
||||
auto proTxHash = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.proTxHash);
|
||||
@ -434,7 +436,8 @@ bool CQuorumManager::RequestQuorumData(CNode* pFrom, Consensus::LLMQType llmqTyp
|
||||
}
|
||||
|
||||
LOCK(cs_data_requests);
|
||||
auto key = std::make_pair(pFrom->GetVerifiedProRegTxHash(), true);
|
||||
auto quorumHash = pQuorumBaseBlockIndex->GetBlockHash();
|
||||
auto key = std::make_tuple(pFrom->GetVerifiedProRegTxHash(), true, quorumHash, (uint8_t)llmqType);
|
||||
auto it = mapQuorumDataRequests.emplace(key, CQuorumDataRequest(llmqType, pQuorumBaseBlockIndex->GetBlockHash(), nDataMask, proTxHash));
|
||||
if (!it.second && !it.first->second.IsExpired()) {
|
||||
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- Already requested\n", __func__);
|
||||
@ -585,11 +588,13 @@ void CQuorumManager::ProcessMessage(CNode* pFrom, const std::string& msg_type, C
|
||||
|
||||
{
|
||||
LOCK2(cs_main, cs_data_requests);
|
||||
auto key = std::make_pair(pFrom->GetVerifiedProRegTxHash(), false);
|
||||
auto quorumHash = request.GetQuorumHash();
|
||||
auto llmqType = (uint8_t) request.GetLLMQType();
|
||||
auto key = std::make_tuple(pFrom->GetVerifiedProRegTxHash(), false, quorumHash, llmqType);
|
||||
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()) {
|
||||
it->second = request;
|
||||
} else {
|
||||
errorHandler("Request limit exceeded", 25);
|
||||
@ -658,7 +663,10 @@ void CQuorumManager::ProcessMessage(CNode* pFrom, const std::string& msg_type, C
|
||||
|
||||
{
|
||||
LOCK2(cs_main, cs_data_requests);
|
||||
auto it = mapQuorumDataRequests.find(std::make_pair(pFrom->GetVerifiedProRegTxHash(), true));
|
||||
auto quorumHash = request.GetQuorumHash();
|
||||
auto llmqType = (uint8_t) request.GetLLMQType();
|
||||
auto key = std::make_tuple(pFrom->GetVerifiedProRegTxHash(), true, quorumHash, llmqType);
|
||||
auto it = mapQuorumDataRequests.find(key);
|
||||
if (it == mapQuorumDataRequests.end()) {
|
||||
errorHandler("Not requested");
|
||||
return;
|
||||
@ -830,7 +838,10 @@ void CQuorumManager::StartQuorumDataRecoveryThread(const CQuorumCPtr pQuorum, co
|
||||
pCurrentMemberHash = &vecMemberHashes[(nMyStartOffset + nTries++) % vecMemberHashes.size()];
|
||||
{
|
||||
LOCK(cs_data_requests);
|
||||
auto it = mapQuorumDataRequests.find(std::make_pair(*pCurrentMemberHash, true));
|
||||
auto quorumHash = pQuorum->qc->quorumHash;
|
||||
auto llmqType = (uint8_t)pQuorum->qc->quorumIndex;
|
||||
auto key = std::make_tuple(*pCurrentMemberHash, true, quorumHash, (uint8_t)llmqType);
|
||||
auto it = mapQuorumDataRequests.find(key);
|
||||
if (it != mapQuorumDataRequests.end() && !it->second.IsExpired()) {
|
||||
printLog("Already asked");
|
||||
continue;
|
||||
@ -855,7 +866,10 @@ void CQuorumManager::StartQuorumDataRecoveryThread(const CQuorumCPtr pQuorum, co
|
||||
printLog("Requested");
|
||||
} else {
|
||||
LOCK(cs_data_requests);
|
||||
auto it = mapQuorumDataRequests.find(std::make_pair(verifiedProRegTxHash, true));
|
||||
auto quorumHash = pQuorum->qc->quorumHash;
|
||||
auto llmqType = (uint8_t)pQuorum->qc->quorumIndex;
|
||||
auto key = std::make_tuple(*pCurrentMemberHash, true, quorumHash, (uint8_t)llmqType);
|
||||
auto it = mapQuorumDataRequests.find(key);
|
||||
if (it == mapQuorumDataRequests.end()) {
|
||||
printLog("Failed");
|
||||
pNode->fDisconnect = true;
|
||||
|
@ -798,7 +798,7 @@ bool CLLMQUtils::IsQuorumActive(Consensus::LLMQType llmqType, const uint256& quo
|
||||
// sig shares and recovered sigs are only accepted from recent/active quorums
|
||||
// we allow one more active quorum as specified in consensus, as otherwise there is a small window where things could
|
||||
// fail while we are on the brink of a new quorum
|
||||
auto quorums = quorumManager->ScanQuorums(llmqType, GetLLMQParams(llmqType).signingActiveQuorumCount + 1);
|
||||
auto quorums = quorumManager->ScanQuorums(llmqType, GetLLMQParams(llmqType).keepOldConnections);
|
||||
return ranges::any_of(quorums, [&quorumHash](const auto& q){ return q->qc->quorumHash == quorumHash; });
|
||||
}
|
||||
|
||||
@ -942,7 +942,7 @@ void CLLMQUtils::InitQuorumsCache(CacheType& cache)
|
||||
{
|
||||
for (auto& llmq : Params().GetConsensus().llmqs) {
|
||||
cache.emplace(std::piecewise_construct, std::forward_as_tuple(llmq.type),
|
||||
std::forward_as_tuple(llmq.signingActiveQuorumCount + 1));
|
||||
std::forward_as_tuple(llmq.keepOldConnections));
|
||||
}
|
||||
}
|
||||
template void CLLMQUtils::InitQuorumsCache<std::map<Consensus::LLMQType, unordered_lru_cache<uint256, bool, StaticSaltedHasher>>>(std::map<Consensus::LLMQType, unordered_lru_cache<uint256, bool, StaticSaltedHasher>>& cache);
|
||||
|
@ -61,6 +61,9 @@ void CMasternodeUtils::ProcessMasternodeConnections(CConnman& connman)
|
||||
} else if (GetSystemTimeInSeconds() - pnode->nTimeConnected < 5) {
|
||||
// non-verified, give it some time to verify itself
|
||||
return;
|
||||
} else if (pnode->qwatch) {
|
||||
// keep watching nodes
|
||||
return;
|
||||
}
|
||||
// we're not disconnecting masternode probes for at least a few seconds
|
||||
if (pnode->m_masternode_probe_connection && GetSystemTimeInSeconds() - pnode->nTimeConnected < 5) return;
|
||||
|
19
src/net.cpp
19
src/net.cpp
@ -2379,6 +2379,7 @@ void CConnman::ThreadOpenMasternodeConnections()
|
||||
return;
|
||||
|
||||
int64_t nANow = GetAdjustedTime();
|
||||
constexpr const auto &_func_ = __func__;
|
||||
|
||||
// NOTE: Process only one pending masternode at a time
|
||||
|
||||
@ -2405,6 +2406,22 @@ void CConnman::ThreadOpenMasternodeConnections()
|
||||
continue;
|
||||
}
|
||||
const auto& addr2 = dmn->pdmnState->addr;
|
||||
if (connectedNodes.count(addr2) && !connectedProRegTxHashes.count(proRegTxHash)) {
|
||||
// we probably connected to it before it became a masternode
|
||||
// or maybe we are still waiting for mnauth
|
||||
(void)ForNode(addr2, [&](CNode* pnode) {
|
||||
if (pnode->nTimeFirstMessageReceived != 0 && GetSystemTimeInSeconds() - pnode->nTimeFirstMessageReceived > 5) {
|
||||
// clearly not expecting mnauth to take that long even if it wasn't the first message
|
||||
// we received (as it should normally), disconnect
|
||||
LogPrint(BCLog::NET_NETCONN, "CConnman::%s -- dropping non-mnauth connection to %s, service=%s\n", _func_, proRegTxHash.ToString(), addr2.ToString(false));
|
||||
pnode->fDisconnect = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
// either way - it's not ready, skip it for now
|
||||
continue;
|
||||
}
|
||||
if (!connectedNodes.count(addr2) && !IsMasternodeOrDisconnectRequested(addr2) && !connectedProRegTxHashes.count(proRegTxHash)) {
|
||||
int64_t lastAttempt = mmetaman.GetMetaInfo(dmn->proTxHash)->GetLastOutboundAttempt();
|
||||
// back off trying connecting to an address if we already tried recently
|
||||
@ -3366,6 +3383,8 @@ size_t CConnman::GetNodeCount(NumConnections flags)
|
||||
}
|
||||
if (flags & (pnode->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT)) {
|
||||
nNum++;
|
||||
} else if (flags == CONNECTIONS_VERIFIED) {
|
||||
nNum++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2716,7 +2716,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStrea
|
||||
// Tell our peer that he should send us CoinJoin queue messages
|
||||
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::SENDDSQUEUE, true));
|
||||
|
||||
if (llmq::CLLMQUtils::IsWatchQuorumsEnabled() && !pfrom->m_masternode_connection) {
|
||||
if (llmq::CLLMQUtils::IsWatchQuorumsEnabled() && connman->IsMasternodeQuorumNode(pfrom)) {
|
||||
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QWATCH));
|
||||
}
|
||||
|
||||
@ -2748,7 +2748,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStrea
|
||||
|
||||
if (pfrom->nTimeFirstMessageReceived == 0) {
|
||||
// First message after VERSION/VERACK
|
||||
pfrom->nTimeFirstMessageReceived = GetTimeMicros();
|
||||
pfrom->nTimeFirstMessageReceived = GetSystemTimeInSeconds();
|
||||
pfrom->fFirstMessageIsMNAUTH = msg_type == NetMsgType::MNAUTH;
|
||||
// Note: do not break the flow here
|
||||
|
||||
|
@ -13,6 +13,20 @@
|
||||
|
||||
template<typename T> struct SaltedHasherImpl;
|
||||
|
||||
template<typename N, typename M, typename K, typename Q>
|
||||
struct SaltedHasherImpl<std::tuple<N, M, K, Q>>
|
||||
{
|
||||
static std::size_t CalcHash(const std::tuple<N, M, K, Q>& v, uint64_t k0, uint64_t k1)
|
||||
{
|
||||
CSipHasher c(k0, k1);
|
||||
c.Write((unsigned char*)&std::get<0>(v), sizeof(M));
|
||||
c.Write((unsigned char*)&std::get<1>(v), sizeof(N));
|
||||
c.Write((unsigned char*)&std::get<2>(v), sizeof(K));
|
||||
c.Write((unsigned char*)&std::get<3>(v), sizeof(Q));
|
||||
return c.Finalize();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename N>
|
||||
struct SaltedHasherImpl<std::pair<uint256, N>>
|
||||
{
|
||||
|
@ -7,7 +7,7 @@
|
||||
Tests correspond to code in rpc/net.cpp.
|
||||
"""
|
||||
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.test_framework import DashTestFramework
|
||||
from test_framework.util import (
|
||||
assert_equal,
|
||||
assert_greater_than_or_equal,
|
||||
@ -47,15 +47,9 @@ def assert_net_servicesnames(servicesflag, servicenames):
|
||||
assert "HEADERS_COMPRESSED" in servicenames
|
||||
|
||||
|
||||
class NetTest(BitcoinTestFramework):
|
||||
class NetTest(DashTestFramework):
|
||||
def set_test_params(self):
|
||||
self.setup_clean_chain = True
|
||||
self.num_nodes = 2
|
||||
|
||||
def setup_network(self):
|
||||
self.disable_mocktime()
|
||||
self.setup_nodes()
|
||||
connect_nodes(self.nodes[0], 1)
|
||||
self.set_dash_test_params(3, 1, fast_dip3_enforcement=True)
|
||||
|
||||
def run_test(self):
|
||||
# Wait for one ping/pong to finish so that we can be sure that there is no chatter between nodes for some time
|
||||
@ -76,7 +70,9 @@ class NetTest(BitcoinTestFramework):
|
||||
|
||||
def _test_connection_count(self):
|
||||
# connect_nodes connects each node to the other
|
||||
assert_equal(self.nodes[0].getconnectioncount(), 2)
|
||||
# and node0 was also connected to node2 (a masternode)
|
||||
# during network setup
|
||||
assert_equal(self.nodes[0].getconnectioncount(), 3)
|
||||
|
||||
def _test_getnettotals(self):
|
||||
# getnettotals totalbytesrecv and totalbytessent should be
|
||||
@ -87,7 +83,7 @@ class NetTest(BitcoinTestFramework):
|
||||
net_totals_before = self.nodes[0].getnettotals()
|
||||
peer_info = self.nodes[0].getpeerinfo()
|
||||
net_totals_after = self.nodes[0].getnettotals()
|
||||
assert_equal(len(peer_info), 2)
|
||||
assert_equal(len(peer_info), 3)
|
||||
peers_recv = sum([peer['bytesrecv'] for peer in peer_info])
|
||||
peers_sent = sum([peer['bytessent'] for peer in peer_info])
|
||||
|
||||
@ -110,7 +106,7 @@ class NetTest(BitcoinTestFramework):
|
||||
|
||||
def _test_getnetworkinfo(self):
|
||||
assert_equal(self.nodes[0].getnetworkinfo()['networkactive'], True)
|
||||
assert_equal(self.nodes[0].getnetworkinfo()['connections'], 2)
|
||||
assert_equal(self.nodes[0].getnetworkinfo()['connections'], 3)
|
||||
|
||||
self.nodes[0].setnetworkactive(state=False)
|
||||
assert_equal(self.nodes[0].getnetworkinfo()['networkactive'], False)
|
||||
@ -131,6 +127,17 @@ class NetTest(BitcoinTestFramework):
|
||||
for info in network_info:
|
||||
assert_net_servicesnames(int(info["localservices"], 16), info["localservicesnames"])
|
||||
|
||||
self.log.info('Test extended connections info')
|
||||
connect_nodes(self.nodes[1], 2)
|
||||
self.nodes[1].ping()
|
||||
wait_until(lambda: all(['pingtime' in n for n in self.nodes[1].getpeerinfo()]))
|
||||
assert_equal(self.nodes[1].getnetworkinfo()['connections'], 3)
|
||||
assert_equal(self.nodes[1].getnetworkinfo()['inboundconnections'], 1)
|
||||
assert_equal(self.nodes[1].getnetworkinfo()['outboundconnections'], 2)
|
||||
assert_equal(self.nodes[1].getnetworkinfo()['mnconnections'], 1)
|
||||
assert_equal(self.nodes[1].getnetworkinfo()['inboundmnconnections'], 0)
|
||||
assert_equal(self.nodes[1].getnetworkinfo()['outboundmnconnections'], 1)
|
||||
|
||||
def _test_getaddednodeinfo(self):
|
||||
assert_equal(self.nodes[0].getaddednodeinfo(), [])
|
||||
# add a node (node2) to node0
|
||||
@ -180,7 +187,8 @@ class NetTest(BitcoinTestFramework):
|
||||
node_addresses = self.nodes[0].getnodeaddresses(REQUEST_COUNT)
|
||||
assert_equal(len(node_addresses), REQUEST_COUNT)
|
||||
for a in node_addresses:
|
||||
assert_greater_than(a["time"], 1527811200) # 1st June 2018
|
||||
# see penalty calculations for ADDRs with nTime <= 100000000 in net_processing.cpp
|
||||
assert_equal(a["time"], self.mocktime - 5 * 24 * 60 * 60 - 2 * 60 * 60)
|
||||
assert_equal(a["services"], NODE_NETWORK)
|
||||
assert a["address"] in imported_addrs
|
||||
assert_equal(a["port"], 8333)
|
||||
|
Loading…
Reference in New Issue
Block a user