Merge pull request #3368 from codablock/pr_fmasternode

Don't relay anything to inbound/outbound fMasternode connections
This commit is contained in:
Alexander Block 2020-03-24 17:40:51 +01:00 committed by GitHub
commit 8211ff0a8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 50 additions and 16 deletions

View File

@ -713,7 +713,7 @@ void CSigningManager::ProcessRecoveredSig(NodeId nodeId, const CRecoveredSig& re
CInv inv(MSG_QUORUM_RECOVERED_SIG, recoveredSig.GetHash());
g_connman->ForEachNode([&](CNode* pnode) {
if (pnode->nVersion >= LLMQS_PROTO_VERSION && pnode->fSendRecSigs) {
if (pnode->nVersion >= LLMQS_PROTO_VERSION && pnode->fSendRecSigs && !pnode->fMasternode) {
pnode->PushInventory(inv);
}
});

View File

@ -39,7 +39,7 @@ void CMasternodeUtils::ProcessMasternodeConnections(CConnman& connman)
}
connman.ForEachNode(CConnman::AllNodes, [&](CNode* pnode) {
if (pnode->fMasternode && !connman.IsMasternodeQuorumNode(pnode)) {
if (!pnode->fInbound && pnode->fMasternode && !connman.IsMasternodeQuorumNode(pnode)) {
#ifdef ENABLE_WALLET
bool fFound = false;
for (const auto& dmn : vecDmns) {

View File

@ -761,6 +761,7 @@ void CNode::copyStats(CNodeStats &stats)
LOCK(cs_mnauth);
X(verifiedProRegTxHash);
}
X(fMasternode);
}
#undef X
@ -2947,22 +2948,26 @@ void CConnman::RelayTransaction(const CTransaction& tx)
LOCK(cs_vNodes);
for (CNode* pnode : vNodes)
{
if (pnode->fMasternode)
continue;
pnode->PushInventory(inv);
}
}
void CConnman::RelayInv(CInv &inv, const int minProtoVersion) {
void CConnman::RelayInv(CInv &inv, const int minProtoVersion, bool fAllowMasternodeConnections) {
LOCK(cs_vNodes);
for (const auto& pnode : vNodes)
if(pnode->nVersion >= minProtoVersion)
pnode->PushInventory(inv);
for (const auto& pnode : vNodes) {
if (pnode->nVersion < minProtoVersion || (pnode->fMasternode && !fAllowMasternodeConnections))
continue;
pnode->PushInventory(inv);
}
}
void CConnman::RelayInvFiltered(CInv &inv, const CTransaction& relatedTx, const int minProtoVersion)
void CConnman::RelayInvFiltered(CInv &inv, const CTransaction& relatedTx, const int minProtoVersion, bool fAllowMasternodeConnections)
{
LOCK(cs_vNodes);
for (const auto& pnode : vNodes) {
if(pnode->nVersion < minProtoVersion)
if (pnode->nVersion < minProtoVersion || (pnode->fMasternode && !fAllowMasternodeConnections))
continue;
{
LOCK(pnode->cs_filter);
@ -2973,11 +2978,12 @@ void CConnman::RelayInvFiltered(CInv &inv, const CTransaction& relatedTx, const
}
}
void CConnman::RelayInvFiltered(CInv &inv, const uint256& relatedTxHash, const int minProtoVersion)
void CConnman::RelayInvFiltered(CInv &inv, const uint256& relatedTxHash, const int minProtoVersion, bool fAllowMasternodeConnections)
{
LOCK(cs_vNodes);
for (const auto& pnode : vNodes) {
if(pnode->nVersion < minProtoVersion) continue;
if (pnode->nVersion < minProtoVersion || (pnode->fMasternode && !fAllowMasternodeConnections))
continue;
{
LOCK(pnode->cs_filter);
if(pnode->pfilter && !pnode->pfilter->contains(relatedTxHash)) continue;

View File

@ -353,10 +353,10 @@ public:
void ReleaseNodeVector(const std::vector<CNode*>& vecNodes);
void RelayTransaction(const CTransaction& tx);
void RelayInv(CInv &inv, const int minProtoVersion = MIN_PEER_PROTO_VERSION);
void RelayInvFiltered(CInv &inv, const CTransaction &relatedTx, const int minProtoVersion = MIN_PEER_PROTO_VERSION);
void RelayInv(CInv &inv, const int minProtoVersion = MIN_PEER_PROTO_VERSION, bool fAllowMasternodeConnections = false);
void RelayInvFiltered(CInv &inv, const CTransaction &relatedTx, const int minProtoVersion = MIN_PEER_PROTO_VERSION, bool fAllowMasternodeConnections = false);
// This overload will not update node filters, so use it only for the cases when other messages will update related transaction data in filters
void RelayInvFiltered(CInv &inv, const uint256 &relatedTxHash, const int minProtoVersion = MIN_PEER_PROTO_VERSION);
void RelayInvFiltered(CInv &inv, const uint256 &relatedTxHash, const int minProtoVersion = MIN_PEER_PROTO_VERSION, bool fAllowMasternodeConnections = false);
void RemoveAskFor(const uint256& hash);
// Addrman functions
@ -707,6 +707,7 @@ public:
CAddress addrBind;
// In case this is a verified MN, this value is the proTx of the MN
uint256 verifiedProRegTxHash;
bool fMasternode;
};

View File

@ -321,7 +321,7 @@ void PushNodeVersion(CNode *pnode, CConnman* connman, int64_t nTime)
}
connman->PushMessage(pnode, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::VERSION, PROTOCOL_VERSION, (uint64_t)nLocalNodeServices, nTime, addrYou, addrMe,
nonce, strSubVersion, nNodeStartingHeight, ::fRelayTxes, mnauthChallenge));
nonce, strSubVersion, nNodeStartingHeight, ::fRelayTxes, mnauthChallenge, pnode->fMasternode));
if (fLogIPs) {
LogPrint(BCLog::NET, "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nNodeStartingHeight, addrMe.ToString(), addrYou.ToString(), nodeid);
@ -955,6 +955,7 @@ void PeerLogicValidation::UpdatedBlockTip(const CBlockIndex *pindexNew, const CB
}
// Relay inventory, but don't relay old inventory during initial block download.
connman->ForEachNode([nNewHeight, &vHashes](CNode* pnode) {
if (pnode->fMasternode) return;
if (nNewHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 0)) {
for (const uint256& hash : reverse_iterate(vHashes)) {
pnode->PushBlockHash(hash);
@ -1870,6 +1871,21 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
LOCK(pfrom->cs_mnauth);
vRecv >> pfrom->receivedMNAuthChallenge;
}
if (!vRecv.empty()) {
bool fOtherMasternode = false;
vRecv >> fOtherMasternode;
if (pfrom->fInbound) {
pfrom->fMasternode = fOtherMasternode;
if (fOtherMasternode) {
LogPrint(BCLog::NET, "peer=%d is an inbound masternode connection, not relaying anything to it\n", pfrom->GetId());
if (!fMasternodeMode) {
LogPrint(BCLog::NET, "but we're not a masternode, disconnecting\n");
pfrom->fDisconnect = true;
return true;
}
}
}
}
// Disconnect if we connected to ourself
if (pfrom->fInbound && !connman->CheckIncomingNonce(nNonce))
{
@ -2309,7 +2325,9 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
LogPrint(BCLog::NET, " getblocks stopping, pruned or too old block at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
break;
}
pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
if (!pfrom->fMasternode) {
pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
}
if (--nLimit <= 0)
{
// When this block is requested, we'll send an inv that'll
@ -3606,7 +3624,7 @@ bool PeerLogicValidation::SendMessages(CNode* pto, std::atomic<bool>& interruptM
if (pindexBestHeader == nullptr)
pindexBestHeader = chainActive.Tip();
bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->fClient && !pto->fOneShot); // Download if this is a nice peer, or we have no nice peers and this one might do.
if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex) {
if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex && !pto->fMasternode) {
// Only actively request headers from a single peer, unless we're close to end of initial download.
if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - nMaxTipAge) {
state.fSyncStarted = true;

View File

@ -97,6 +97,7 @@ UniValue getpeerinfo(const JSONRPCRequest& request)
" \"subver\": \"/Dash Core:x.x.x/\", (string) The string version\n"
" \"inbound\": true|false, (boolean) Inbound (true) or Outbound (false)\n"
" \"addnode\": true|false, (boolean) Whether connection was due to addnode/-connect or if it was an automatic/inbound connection\n"
" \"masternode\": true|false, (boolean) Whether connection was due to masternode connection attempt\n"
" \"startingheight\": n, (numeric) The starting height (block) of the peer\n"
" \"banscore\": n, (numeric) The ban score\n"
" \"synced_headers\": n, (numeric) The last header we have in common with this peer\n"
@ -164,6 +165,7 @@ UniValue getpeerinfo(const JSONRPCRequest& request)
obj.push_back(Pair("subver", stats.cleanSubVer));
obj.push_back(Pair("inbound", stats.fInbound));
obj.push_back(Pair("addnode", stats.m_manual_connection));
obj.push_back(Pair("masternode", stats.fMasternode));
obj.push_back(Pair("startingheight", stats.nStartingHeight));
if (fStateStats) {
obj.push_back(Pair("banscore", statestats.nMisbehavior));

View File

@ -23,6 +23,13 @@ class LLMQChainLocksTest(DashTestFramework):
def run_test(self):
# Connect all nodes to node1 so that we always have the whole network connected
# Otherwise only masternode connections will be established between nodes, which won't propagate TXs/blocks
# Usually node0 is the one that does this, but in this test we isolate it multiple times
for i in range(len(self.nodes)):
if i != 1:
connect_nodes(self.nodes[i], 1)
self.log.info("Wait for dip0008 activation")
while self.nodes[0].getblockchaininfo()["bip9_softforks"]["dip0008"]["status"] != "active":