Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bitcoin 0.12 misc P2P/Net PRs #4994

Merged
merged 9 commits into from Feb 19, 2021
1 change: 1 addition & 0 deletions src/Makefile.test.include
Expand Up @@ -71,6 +71,7 @@ BITCOIN_TESTS =\
test/getarg_tests.cpp \
test/hash_tests.cpp \
test/key_tests.cpp \
test/limitedmap_tests.cpp \
test/dbwrapper_tests.cpp \
test/main_tests.cpp \
test/mempool_tests.cpp \
Expand Down
25 changes: 15 additions & 10 deletions src/init.cpp
Expand Up @@ -917,16 +917,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
return InitError(err.value());
}

// Make sure enough file descriptors are available
int nBind = std::max((int)mapArgs.count("-bind") + (int)mapArgs.count("-whitebind"), 1);
nMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS);
nMaxConnections = std::max(std::min(nMaxConnections, FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS), 0);
int nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS);
if (nFD < MIN_CORE_FILEDESCRIPTORS)
return InitError(_("Not enough file descriptors available."));
if (nFD - MIN_CORE_FILEDESCRIPTORS < nMaxConnections)
nMaxConnections = nFD - MIN_CORE_FILEDESCRIPTORS;

// if using block pruning, then disable txindex
if (GetArg("-prune", 0)) {
if (GetBoolArg("-txindex", DEFAULT_TXINDEX))
Expand All @@ -937,6 +927,21 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
}
#endif
}

// Make sure enough file descriptors are available
int nBind = std::max((int)mapArgs.count("-bind") + (int)mapArgs.count("-whitebind"), 1);
int nUserMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS);
nMaxConnections = std::max(nUserMaxConnections, 0);

// Trim requested connection counts, to fit into system limitations
nMaxConnections = std::max(std::min(nMaxConnections, FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS), 0);
int nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS);
if (nFD < MIN_CORE_FILEDESCRIPTORS)
return InitError(_("Not enough file descriptors available."));
nMaxConnections = std::min(nFD - MIN_CORE_FILEDESCRIPTORS, nMaxConnections);

if (nMaxConnections < nUserMaxConnections)
InitWarning(strprintf(_("Reducing -maxconnections from %d to %d, because of system limitations."), nUserMaxConnections, nMaxConnections));

// ensure that the user has not disabled checkpoints when requesting to
// skip transaction verification in initial block download.
Expand Down
19 changes: 11 additions & 8 deletions src/limitedmap.h
Expand Up @@ -27,7 +27,11 @@ class limitedmap
size_type nMaxSize;

public:
limitedmap(size_type nMaxSizeIn = 0) { nMaxSize = nMaxSizeIn; }
limitedmap(size_type nMaxSizeIn)
{
assert(nMaxSizeIn > 0);
nMaxSize = nMaxSizeIn;
}
const_iterator begin() const { return map.begin(); }
const_iterator end() const { return map.end(); }
size_type size() const { return map.size(); }
Expand All @@ -38,13 +42,12 @@ class limitedmap
{
std::pair<iterator, bool> ret = map.insert(x);
if (ret.second) {
if (nMaxSize && map.size() == nMaxSize) {
if (map.size() > nMaxSize) {
map.erase(rmap.begin()->second);
rmap.erase(rmap.begin());
}
rmap.insert(make_pair(x.second, ret.first));
}
return;
}
void erase(const key_type& k)
{
Expand Down Expand Up @@ -81,11 +84,11 @@ class limitedmap
size_type max_size() const { return nMaxSize; }
size_type max_size(size_type s)
{
if (s)
while (map.size() > s) {
map.erase(rmap.begin()->second);
rmap.erase(rmap.begin());
}
assert(s > 0);
while (map.size() > s) {
map.erase(rmap.begin()->second);
rmap.erase(rmap.begin());
}
nMaxSize = s;
return nMaxSize;
}
Expand Down
23 changes: 19 additions & 4 deletions src/main.cpp
Expand Up @@ -6059,10 +6059,10 @@ bool static ProcessMessage(const CChainParams& chainparams, CNode* pfrom, string
vRecv >> locator >> hashStop;

LOCK(cs_main);

if (IsInitialBlockDownload(chainparams.GetConsensus()))
if (IsInitialBlockDownload(chainparams.GetConsensus()) && !pfrom->fWhitelisted) {
LogPrint("net", "Ignoring getheaders from peer=%d because node is in initial block download\n", pfrom->id);
return true;

}
CBlockIndex* pindex = NULL;
if (locator.IsNull())
{
Expand Down Expand Up @@ -6354,6 +6354,12 @@ bool static ProcessMessage(const CChainParams& chainparams, CNode* pfrom, string
else if (strCommand == "mempool")
{
int currentHeight = GetHeight();
if (CNode::OutboundTargetReached(chainparams.GetConsensus().PoWTargetSpacing(currentHeight), false) && !pfrom->fWhitelisted)
{
LogPrint("net", "mempool request with bandwidth limit reached, disconnect peer=%d\n", pfrom->GetId());
pfrom->fDisconnect = true;
return true;
}

LOCK2(cs_main, pfrom->cs_filter);

Expand Down Expand Up @@ -6831,7 +6837,16 @@ bool SendMessages(const Consensus::Params& params, CNode* pto, bool fSendTrickle
if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetTime() - 24 * 60 * 60) {
state.fSyncStarted = true;
nSyncStarted++;
CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader;
const CBlockIndex *pindexStart = pindexBestHeader;
/* If possible, start at the block preceding the currently
best known header. This ensures that we always get a
non-empty list of headers back as long as the peer
is up-to-date. With a non-empty response, we can initialise
the peer's known best block. This wouldn't be possible
if we requested starting at pindexBestHeader and
got back an empty response. */
if (pindexStart->pprev)
pindexStart = pindexStart->pprev;
LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->id, pto->nStartingHeight);
pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256());
}
Expand Down
1 change: 1 addition & 0 deletions src/net.h
Expand Up @@ -156,6 +156,7 @@ extern bool fListen;
extern uint64_t nLocalServices;
extern uint64_t nLocalHostNonce;
extern CAddrMan addrman;

/** Maximum number of connections to simultaneously allow (aka connection slots) */
extern int nMaxConnections;

Expand Down
101 changes: 101 additions & 0 deletions src/test/limitedmap_tests.cpp
@@ -0,0 +1,101 @@
// Copyright (c) 2012-2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "limitedmap.h"

#include "test/test_bitcoin.h"

#include <boost/test/unit_test.hpp>

BOOST_FIXTURE_TEST_SUITE(limitedmap_tests, BasicTestingSetup)

BOOST_AUTO_TEST_CASE(limitedmap_test)
{
// create a limitedmap capped at 10 items
limitedmap<int, int> map(10);

// check that the max size is 10
BOOST_CHECK(map.max_size() == 10);

// check that it's empty
BOOST_CHECK(map.size() == 0);

// insert (-1, -1)
map.insert(std::pair<int, int>(-1, -1));

// make sure that the size is updated
BOOST_CHECK(map.size() == 1);

// make sure that the new items is in the map
BOOST_CHECK(map.count(-1) == 1);

// insert 10 new items
for (int i = 0; i < 10; i++) {
map.insert(std::pair<int, int>(i, i + 1));
}

// make sure that the map now contains 10 items...
BOOST_CHECK(map.size() == 10);

// ...and that the first item has been discarded
BOOST_CHECK(map.count(-1) == 0);

// iterate over the map, both with an index and an iterator
limitedmap<int, int>::const_iterator it = map.begin();
for (int i = 0; i < 10; i++) {
// make sure the item is present
BOOST_CHECK(map.count(i) == 1);

// use the iterator to check for the expected key adn value
BOOST_CHECK(it->first == i);
BOOST_CHECK(it->second == i + 1);

// use find to check for the value
BOOST_CHECK(map.find(i)->second == i + 1);

// update and recheck
map.update(it, i + 2);
BOOST_CHECK(map.find(i)->second == i + 2);

it++;
}

// check that we've exhausted the iterator
BOOST_CHECK(it == map.end());

// resize the map to 5 items
map.max_size(5);

// check that the max size and size are now 5
BOOST_CHECK(map.max_size() == 5);
BOOST_CHECK(map.size() == 5);

// check that items less than 5 have been discarded
// and items greater than 5 are retained
for (int i = 0; i < 10; i++) {
if (i < 5) {
BOOST_CHECK(map.count(i) == 0);
} else {
BOOST_CHECK(map.count(i) == 1);
}
}

// erase some items not in the map
for (int i = 100; i < 1000; i += 100) {
map.erase(i);
}

// check that the size is unaffected
BOOST_CHECK(map.size() == 5);

// erase the remaining elements
for (int i = 5; i < 10; i++) {
map.erase(i);
}

// check that the map is now empty
BOOST_CHECK(map.empty());
}

BOOST_AUTO_TEST_SUITE_END()
9 changes: 4 additions & 5 deletions src/timedata.cpp
Expand Up @@ -38,7 +38,7 @@ int64_t CTimeWarning::AddTimeData(const CNetAddr& ip, int64_t nTime, int64_t now
return nTimeOffset;
}

LogPrintf("Added time data, samples %d, offset %+d (%+d minutes)\n", setKnown.size(), nTimeOffset, nTimeOffset/60);
LogPrint("net","added time data, samples %d, offset %+d (%+d minutes)\n", setKnown.size(), nTimeOffset, nTimeOffset/60);

if (nPeersBehind + nPeersAhead < TIMEDATA_WARNING_SAMPLES) {
if (nTimeOffset < -TIMEDATA_WARNING_THRESHOLD) {
Expand All @@ -58,14 +58,13 @@ void CTimeWarning::Warn(size_t peersAhead, size_t peersBehind)
{
std::string strMessage;
if (peersBehind >= TIMEDATA_WARNING_MAJORITY) {
strMessage = _("Warning: Your computer's date and time may be ahead of the rest of the network! If your clock is wrong Zcash will not work properly.");
strMessage = _("Your computer's date and time may be ahead of the rest of the network! If your clock is wrong Zcash will not work properly.");
} else if (peersAhead >= TIMEDATA_WARNING_MAJORITY) {
strMessage = _("Warning: Your computer's date and time may be behind the rest of the network! If your clock is wrong Zcash will not work properly.");
strMessage = _("Your computer's date and time may be behind the rest of the network! If your clock is wrong Zcash will not work properly.");
} else {
strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Zcash will not work properly.");
strMessage = _("Please check that your computer's date and time are correct! If your clock is wrong Zcash will not work properly.");
}
SetMiscWarning(strMessage, GetTime());
LogPrintf("*** %s\n", strMessage);
uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING);
}