From 88ee7a372e194b3b31f5245fcef6f53d66212e8c Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Thu, 15 Dec 2016 20:27:24 +0400 Subject: [PATCH] better local address discovery for active mn (#1203) * Make local address discovery more robust in CActiveMasternode * parameter interaction: -masternode=1 -> setting -listen=1 * slightly postpone first run to give net thread a chance to connect to some peers * make sure local address detected in CActiveMasternode::ManageStateInitial is valid * Simplified address detection logic --- src/activemasternode.cpp | 39 ++++++++++++++++++++++++++++++++++++--- src/darksend.cpp | 4 ++-- src/init.cpp | 6 ++++++ src/masternode.cpp | 7 ++++++- src/masternode.h | 1 + 5 files changed, 51 insertions(+), 6 deletions(-) diff --git a/src/activemasternode.cpp b/src/activemasternode.cpp index e539e61fc..1dc241f05 100644 --- a/src/activemasternode.cpp +++ b/src/activemasternode.cpp @@ -127,10 +127,43 @@ bool CActiveMasternode::SendMasternodePing() void CActiveMasternode::ManageStateInitial() { LogPrint("masternode", "CActiveMasternode::ManageStateInitial -- status = %s, type = %s, pinger enabled = %d\n", GetStatus(), GetTypeString(), fPingerEnabled); + // Check that our local network configuration is correct - if(!GetLocal(service)) { + if (!fListen) { + // listen option is probably overwritten by smth else, no good nState = ACTIVE_MASTERNODE_NOT_CAPABLE; - strNotCapableReason = "Can't detect external address. Please consider using the externalip configuration option if problem persists."; + strNotCapableReason = "Masternode must accept connections from outside. Make sure listen configuration option is not overwritten by some another parameter."; + LogPrintf("CActiveMasternode::ManageStateInitial -- %s: %s\n", GetStateString(), strNotCapableReason); + return; + } + + bool fFoundLocal = false; + { + LOCK(cs_vNodes); + + // First try to find whatever local address is specified by externalip option + fFoundLocal = GetLocal(service) && CMasternode::IsValidNetAddr(service); + if(!fFoundLocal) { + // nothing and no live connections, can't do anything for now + if (vNodes.empty()) { + nState = ACTIVE_MASTERNODE_NOT_CAPABLE; + strNotCapableReason = "Can't detect valid external address. Will retry when there are some connections available."; + LogPrintf("CActiveMasternode::ManageStateInitial -- %s: %s\n", GetStateString(), strNotCapableReason); + return; + } + // We have some peers, let's try to find our local address from one of them + BOOST_FOREACH(CNode* pnode, vNodes) { + if (pnode->fSuccessfullyConnected && pnode->addr.IsIPv4()) { + fFoundLocal = GetLocal(service, &pnode->addr) && CMasternode::IsValidNetAddr(service); + if(fFoundLocal) break; + } + } + } + } + + if(!fFoundLocal) { + nState = ACTIVE_MASTERNODE_NOT_CAPABLE; + strNotCapableReason = "Can't detect valid external address. Please consider using the externalip configuration option if problem persists. Make sure to use IPv4 address only."; LogPrintf("CActiveMasternode::ManageStateInitial -- %s: %s\n", GetStateString(), strNotCapableReason); return; } @@ -150,7 +183,7 @@ void CActiveMasternode::ManageStateInitial() return; } - LogPrintf("CActiveMasternode::ManageState -- Checking inbound connection to '%s'\n", service.ToString()); + LogPrintf("CActiveMasternode::ManageStateInitial -- Checking inbound connection to '%s'\n", service.ToString()); if(!ConnectNode((CAddress)service, NULL, true)) { nState = ACTIVE_MASTERNODE_NOT_CAPABLE; diff --git a/src/darksend.cpp b/src/darksend.cpp index d26c73646..124d943ef 100644 --- a/src/darksend.cpp +++ b/src/darksend.cpp @@ -2479,8 +2479,8 @@ void ThreadCheckDarkSendPool() nTick++; // check if we should activate or ping every few minutes, - // start right after sync is considered to be done - if(nTick % MASTERNODE_MIN_MNP_SECONDS == 1) + // slightly postpone first run to give net thread a chance to connect to some peers + if(nTick % MASTERNODE_MIN_MNP_SECONDS == 15) activeMasternode.ManageState(); mnodeman.Check(); diff --git a/src/init.cpp b/src/init.cpp index 094259a2f..9633df7d0 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -797,6 +797,12 @@ void InitParameterInteraction() LogPrintf("%s: parameter interaction: -whitebind set -> setting -listen=1\n", __func__); } + if (GetBoolArg("-masternode", false)) { + // masternodes must accept connections from outside + if (SoftSetBoolArg("-listen", true)) + LogPrintf("%s: parameter interaction: -masternode=1 -> setting -listen=1\n", __func__); + } + if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0) { // when only connecting to trusted nodes, do not seed via DNS, or listen by default if (SoftSetBoolArg("-dnsseed", false)) diff --git a/src/masternode.cpp b/src/masternode.cpp index ca1aa6355..1f865aff1 100644 --- a/src/masternode.cpp +++ b/src/masternode.cpp @@ -273,11 +273,16 @@ void CMasternode::Check(bool fForce) } bool CMasternode::IsValidNetAddr() +{ + return IsValidNetAddr(addr); +} + +bool CMasternode::IsValidNetAddr(CService addrIn) { // TODO: regtest is fine with any addresses for now, // should probably be a bit smarter if one day we start to implement tests for this return Params().NetworkIDString() == CBaseChainParams::REGTEST || - (addr.IsIPv4() && IsReachable(addr) && addr.IsRoutable()); + (addrIn.IsIPv4() && IsReachable(addrIn) && addrIn.IsRoutable()); } masternode_info_t CMasternode::GetInfo() diff --git a/src/masternode.h b/src/masternode.h index dde471ebd..c4b655dde 100644 --- a/src/masternode.h +++ b/src/masternode.h @@ -274,6 +274,7 @@ public: } bool IsValidNetAddr(); + static bool IsValidNetAddr(CService addrIn); void IncreasePoSeBanScore() { if(nPoSeBanScore < MASTERNODE_POSE_BAN_MAX_SCORE) nPoSeBanScore++; } void DecreasePoSeBanScore() { if(nPoSeBanScore > -MASTERNODE_POSE_BAN_MAX_SCORE) nPoSeBanScore--; }