aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/init.cpp18
-rw-r--r--src/main.cpp10
-rw-r--r--src/main.h6
-rw-r--r--src/net.cpp18
4 files changed, 33 insertions, 19 deletions
diff --git a/src/init.cpp b/src/init.cpp
index c962a5f82d..71a9eae861 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -389,7 +389,8 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-whitebind=<addr>", _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6"));
strUsage += HelpMessageOpt("-whitelist=<netmask>", _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") +
" " + _("Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway"));
- strUsage += HelpMessageOpt("-whitelistalwaysrelay", strprintf(_("Always relay transactions received from whitelisted peers (default: %d)"), DEFAULT_WHITELISTALWAYSRELAY));
+ strUsage += HelpMessageOpt("-whitelistrelay", strprintf(_("Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d)"), DEFAULT_WHITELISTRELAY));
+ strUsage += HelpMessageOpt("-whitelistforcerelay", strprintf(_("Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d)"), DEFAULT_WHITELISTFORCERELAY));
strUsage += HelpMessageOpt("-maxuploadtarget=<n>", strprintf(_("Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)"), DEFAULT_MAX_UPLOAD_TARGET));
#ifdef ENABLE_WALLET
@@ -751,15 +752,21 @@ void InitParameterInteraction()
LogPrintf("%s: parameter interaction: -zapwallettxes=<mode> -> setting -rescan=1\n", __func__);
}
- // disable walletbroadcast and whitelistalwaysrelay in blocksonly mode
+ // disable walletbroadcast and whitelistrelay in blocksonly mode
if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) {
- if (SoftSetBoolArg("-whitelistalwaysrelay", false))
- LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -whitelistalwaysrelay=0\n", __func__);
+ if (SoftSetBoolArg("-whitelistrelay", false))
+ LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -whitelistrelay=0\n", __func__);
#ifdef ENABLE_WALLET
if (SoftSetBoolArg("-walletbroadcast", false))
LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -walletbroadcast=0\n", __func__);
#endif
}
+
+ // Forcing relay from whitelisted hosts implies we will accept relays from them in the first place.
+ if (GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) {
+ if (SoftSetBoolArg("-whitelistrelay", true))
+ LogPrintf("%s: parameter interaction: -whitelistforcerelay=1 -> setting -whitelistrelay=1\n", __func__);
+ }
}
void InitLogging()
@@ -886,6 +893,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
if (GetBoolArg("-benchmark", false))
InitWarning(_("Unsupported argument -benchmark ignored, use -debug=bench."));
+ if (GetBoolArg("-whitelistalwaysrelay", false))
+ InitWarning(_("Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay."));
+
// Checkmempool and checkblockindex default to true in regtest mode
int ratio = std::min<int>(std::max<int>(GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000);
if (ratio != 0) {
diff --git a/src/main.cpp b/src/main.cpp
index 265d784900..359167961b 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -4497,8 +4497,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
bool fBlocksOnly = GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY);
- // Allow whitelisted peers to send data other than blocks in blocks only mode if whitelistalwaysrelay is true
- if (pfrom->fWhitelisted && GetBoolArg("-whitelistalwaysrelay", DEFAULT_WHITELISTALWAYSRELAY))
+ // Allow whitelisted peers to send data other than blocks in blocks only mode if whitelistrelay is true
+ if (pfrom->fWhitelisted && GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY))
fBlocksOnly = false;
LOCK(cs_main);
@@ -4677,8 +4677,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
else if (strCommand == NetMsgType::TX)
{
// Stop processing the transaction early if
- // We are in blocks only mode and peer is either not whitelisted or whitelistalwaysrelay is off
- if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && (!pfrom->fWhitelisted || !GetBoolArg("-whitelistalwaysrelay", DEFAULT_WHITELISTALWAYSRELAY)))
+ // We are in blocks only mode and peer is either not whitelisted or whitelistrelay is off
+ if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && (!pfrom->fWhitelisted || !GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY)))
{
LogPrint("net", "transaction sent in violation of protocol peer=%d\n", pfrom->id);
return true;
@@ -4778,7 +4778,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
assert(recentRejects);
recentRejects->insert(tx.GetHash());
- if (pfrom->fWhitelisted && GetBoolArg("-whitelistalwaysrelay", DEFAULT_WHITELISTALWAYSRELAY)) {
+ if (pfrom->fWhitelisted && GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) {
// Always relay transactions received from whitelisted peers, even
// if they were already in the mempool or rejected from it due
// to policy, allowing the node to function as a gateway for
diff --git a/src/main.h b/src/main.h
index 17ac550cf7..9fd97d2126 100644
--- a/src/main.h
+++ b/src/main.h
@@ -42,8 +42,10 @@ struct CNodeStateStats;
/** Default for accepting alerts from the P2P network. */
static const bool DEFAULT_ALERTS = true;
-/** Default for DEFAULT_WHITELISTALWAYSRELAY. */
-static const bool DEFAULT_WHITELISTALWAYSRELAY = true;
+/** Default for DEFAULT_WHITELISTRELAY. */
+static const bool DEFAULT_WHITELISTRELAY = true;
+/** Default for DEFAULT_WHITELISTFORCERELAY. */
+static const bool DEFAULT_WHITELISTFORCERELAY = true;
/** Default for -minrelaytxfee, minimum relay fee for transactions */
static const unsigned int DEFAULT_MIN_RELAY_TX_FEE = 1000;
/** Default for -maxorphantx, maximum number of orphan transactions kept in memory */
diff --git a/src/net.cpp b/src/net.cpp
index 8abfc4b430..2f60cfa1ca 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -884,8 +884,6 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) {
continue;
if (node->fDisconnect)
continue;
- if (node->addr.IsLocal())
- continue;
vEvictionCandidates.push_back(CNodeRef(node));
}
}
@@ -916,15 +914,20 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) {
if (vEvictionCandidates.empty()) return false;
- // Identify the network group with the most connections
+ // Identify the network group with the most connections and youngest member.
+ // (vEvictionCandidates is already sorted by reverse connect time)
std::vector<unsigned char> naMostConnections;
unsigned int nMostConnections = 0;
+ int64_t nMostConnectionsTime = 0;
std::map<std::vector<unsigned char>, std::vector<CNodeRef> > mapAddrCounts;
BOOST_FOREACH(const CNodeRef &node, vEvictionCandidates) {
mapAddrCounts[node->addr.GetGroup()].push_back(node);
+ int64_t grouptime = mapAddrCounts[node->addr.GetGroup()][0]->nTimeConnected;
+ size_t groupsize = mapAddrCounts[node->addr.GetGroup()].size();
- if (mapAddrCounts[node->addr.GetGroup()].size() > nMostConnections) {
- nMostConnections = mapAddrCounts[node->addr.GetGroup()].size();
+ if (groupsize > nMostConnections || (groupsize == nMostConnections && grouptime > nMostConnectionsTime)) {
+ nMostConnections = groupsize;
+ nMostConnectionsTime = grouptime;
naMostConnections = node->addr.GetGroup();
}
}
@@ -932,14 +935,13 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) {
// Reduce to the network group with the most connections
vEvictionCandidates = mapAddrCounts[naMostConnections];
- // Do not disconnect peers if there is only 1 connection from their network group
+ // Do not disconnect peers if there is only one unprotected connection from their network group.
if (vEvictionCandidates.size() <= 1)
// unless we prefer the new connection (for whitelisted peers)
if (!fPreferNewConnection)
return false;
- // Disconnect the most recent connection from the network group with the most connections
- std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected);
+ // Disconnect from the network group with the most connections
vEvictionCandidates[0]->fDisconnect = true;
return true;