Skip to content

Commit

Permalink
Merge pull request #18 from The-Yerbas-Endeavor/v3.1.2.6
Browse files Browse the repository at this point in the history
V3.1.2.6
  • Loading branch information
The-Yerbas-Endeavor committed Apr 2, 2023
2 parents 6dc04b0 + 53e2301 commit 518409b
Show file tree
Hide file tree
Showing 12 changed files with 110 additions and 7 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
push:
branches:
- main
- v3.1.1*
- v3.1.2*
- dev
pull_request:
branches:
Expand Down Expand Up @@ -37,7 +37,7 @@ jobs:
id: selected-version
shell: bash
run: |
if [[ "$GITHUB_EVENT_NAME" == "pull_request" ]] || [[ "$GITHUB_REF" == *dev ]] || [[ "$GITHUB_REF" == *v3.1.1* ]]; then
if [[ "$GITHUB_EVENT_NAME" == "pull_request" ]] || [[ "$GITHUB_REF" == *dev ]] || [[ "$GITHUB_REF" == *v3.1.2* ]]; then
version=${{ steps.versions.outputs.snapshot-version }}
elif [[ "$GITHUB_EVENT_NAME" != "pull_request" ]] && [[ "$GITHUB_REF" == "refs/heads/main" ]]; then
version=${{ steps.versions.outputs.release-version }}
Expand Down
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"xlocinfo": "cpp",
"xstring": "cpp",
"xtree": "cpp",
"xutility": "cpp"
"xutility": "cpp",
"limits": "cpp"
}
}
4 changes: 2 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N)
AC_PREREQ([2.60])
define(_CLIENT_VERSION_MAJOR, 3)
define(_CLIENT_VERSION_MINOR, 1)
define(_CLIENT_VERSION_REVISION, 1)
define(_CLIENT_VERSION_BUILD, 5)
define(_CLIENT_VERSION_REVISION, 2)
define(_CLIENT_VERSION_BUILD, 6)
define(_CLIENT_VERSION_IS_RELEASE, true)
define(_COPYRIGHT_YEAR, 2023)
define(_COPYRIGHT_HOLDERS,[The %s developers])
Expand Down
6 changes: 6 additions & 0 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,8 @@ void CNode::copyStats(CNodeStats &stats)
X(nRecvBytes);
}
X(fWhitelisted);
X(nProcessedAddrs);
X(nRatelimitedAddrs);

// It is common for nodes with good ping times to suddenly become lagged,
// due to a new block arriving or other large transfer.
Expand Down Expand Up @@ -3188,6 +3190,10 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
fGetAddr = false;
nNextLocalAddrSend = 0;
nNextAddrSend = 0;
nAddrTokenBucket = 1; // initialize to 1 to allow self-announcement
nAddrTokenTimestamp = GetTimeMicros();
nProcessedAddrs = 0;
nRatelimitedAddrs = 0;
nNextInvSend = 0;
fRelayTxes = false;
fSentAddr = false;
Expand Down
10 changes: 10 additions & 0 deletions src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,8 @@ class CNodeStats
CAddress addrBind;
// In case this is a verified MN, this value is the proTx of the MN
uint256 verifiedProRegTxHash;
uint64_t nProcessedAddrs;
uint64_t nRatelimitedAddrs;
};


Expand Down Expand Up @@ -835,6 +837,14 @@ class CNode
int64_t nNextAddrSend;
int64_t nNextLocalAddrSend;

/** Number of addresses that can be processed from this peer. */
double nAddrTokenBucket;
/** When nAddrTokenBucket was last updated, in microseconds */
int64_t nAddrTokenTimestamp;

std::atomic<uint64_t> nProcessedAddrs;
std::atomic<uint64_t> nRatelimitedAddrs;

// inventory based relay
CRollingBloomFilter filterInventoryKnown;
// Set of transaction ids we still have to announce.
Expand Down
40 changes: 40 additions & 0 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1937,6 +1937,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
{
connman->PushMessage(pfrom, CNetMsgMaker(nSendVersion).Make(NetMsgType::GETADDR));
pfrom->fGetAddr = true;

// When requesting a getaddr, accept an additional MAX_ADDR_TO_SEND addresses in response
// (bypassing the MAX_ADDR_PROCESSING_TOKEN_BUCKET limit).
pfrom->nAddrTokenBucket += MAX_ADDR_TO_SEND;
}
connman->MarkAddressGood(pfrom->addr);
}
Expand Down Expand Up @@ -2062,11 +2066,40 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
std::vector<CAddress> vAddrOk;
int64_t nNow = GetAdjustedTime();
int64_t nSince = nNow - 10 * 60;

// track rate limiting within this message
uint64_t nProcessedAddrs = 0;
uint64_t nRatelimitedAddrs = 0;

// Update/increment addr rate limiting bucket.
const uint64_t nCurrentTime = GetMockableTimeMicros();
if (pfrom->nAddrTokenBucket < MAX_ADDR_PROCESSING_TOKEN_BUCKET) {
const uint64_t nTimeElapsed = std::max(nCurrentTime - pfrom->nAddrTokenTimestamp, uint64_t(0));
const double nIncrement = nTimeElapsed * MAX_ADDR_RATE_PER_SECOND / 1e6;
pfrom->nAddrTokenBucket = std::min<double>(pfrom->nAddrTokenBucket + nIncrement, MAX_ADDR_PROCESSING_TOKEN_BUCKET);
}
pfrom->nAddrTokenTimestamp = nCurrentTime;

// Randomize entries before processing, to prevent an attacker to
// determine which entries will make it through the rate limit
Shuffle(vAddr.begin(), vAddr.end(), FastRandomContext());

for (CAddress& addr : vAddr)
{
if (interruptMsgProc)
return true;

// apply rate limiting
if (!pfrom->fWhitelisted) {
if (pfrom->nAddrTokenBucket < 1.0) {
nRatelimitedAddrs++;
continue;
}
pfrom->nAddrTokenBucket -= 1.0;
}

nProcessedAddrs++;

// We only bother storing full nodes, though this may include
// things which we would not make an outbound connection to, in
// part because we may make feeler connections to them.
Expand All @@ -2085,6 +2118,13 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
if (fReachable)
vAddrOk.push_back(addr);
}

pfrom->nProcessedAddrs += nProcessedAddrs;
pfrom->nRatelimitedAddrs += nRatelimitedAddrs;

LogPrint(BCLog::NET, "Received addr: %u addresses (%u processed, %u rate-limited) peer=%d\n",
vAddr.size(), nProcessedAddrs, nRatelimitedAddrs, pfrom->GetId());

connman->AddNewAddresses(vAddrOk, pfrom->addr, 2 * 60 * 60);
if (vAddr.size() < 1000)
pfrom->fGetAddr = false;
Expand Down
9 changes: 9 additions & 0 deletions src/net_processing.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ static const int64_t ORPHAN_TX_EXPIRE_INTERVAL = 5 * 60;
/** Default number of orphan+recently-replaced txn to keep around for block reconstruction */
static const unsigned int DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN = 100;

/** The maximum rate of address records we're willing to process on average.
* Is bypassed for whitelisted connections. */
static constexpr double MAX_ADDR_RATE_PER_SECOND{0.1};

/** The soft limit of the address processing token bucket (the regular MAX_ADDR_RATE_PER_SECOND
* based increments won't go above this, but the MAX_ADDR_TO_SEND increment following GETADDR
* is exempt from this limit. */
static constexpr size_t MAX_ADDR_PROCESSING_TOKEN_BUCKET{MAX_ADDR_TO_SEND};

/** Headers download timeout expressed in microseconds
* Timeout = base + per_header * (expected number of headers) */
static constexpr int64_t HEADERS_DOWNLOAD_TIMEOUT_BASE = 15 * 60 * 1000000; // 15 minutes
Expand Down
5 changes: 4 additions & 1 deletion src/policy/policy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ CAmount GetDustThreshold(const CTxOut& txout, const CFeeRate& dustRelayFeeIn)

bool IsDust(const CTxOut& txout, const CFeeRate& dustRelayFeeIn)
{
return (txout.nValue < GetDustThreshold(txout, dustRelayFeeIn));
if (txout.scriptPubKey.IsAssetScript())
return false;
else
return (txout.nValue < GetDustThreshold(txout, dustRelayFeeIn));
}

/**
Expand Down
23 changes: 23 additions & 0 deletions src/random.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,29 @@ class FastRandomContext {
bool randbool() { return randbits(1); }
};

/** More efficient than using std::Shuffle on a FastRandomContext.
*
* This is more efficient as std::Shuffle will consume entropy in groups of
* 64 bits at the time and throw away most.
*
* This also works around a bug in libstdc++ std::Shuffle that may cause
* type::operator=(type&&) to be invoked on itself, which the library's
* debug mode detects and panics on. This is a known issue, see
* https://stackoverflow.com/questions/22915325/avoiding-self-assignment-in-stdshuffle
*/
template<typename I, typename R>
void Shuffle(I first, I last, R&& rng)
{
while (first != last) {
size_t j = rng.randrange(last - first);
if (j) {
using std::swap;
swap(*first, *(first + j));
}
++first;
}
}

/* Number of random bytes returned by GetOSRand.
* When changing this constant make sure to change all call sites, and make
* sure that the underlying OS APIs for all platforms support the number.
Expand Down
6 changes: 5 additions & 1 deletion src/rpc/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ UniValue getpeerinfo(const JSONRPCRequest& request)
" n, (numeric) The heights of blocks we're currently asking from this peer\n"
" ...\n"
" ],\n"
" \"addr_processed\": n, (numeric) The total number of addresses processed, excluding those dropped due to rate limiting\n"
" \"addr_rate_limited\": n, (numeric) The total number of addresses dropped due to rate limiting\n"
" \"whitelisted\": true|false, (boolean) Whether the peer is whitelisted\n"
" \"bytessent_per_msg\": {\n"
" \"addr\": n, (numeric) The total bytes sent aggregated by message type\n"
Expand Down Expand Up @@ -176,7 +178,9 @@ UniValue getpeerinfo(const JSONRPCRequest& request)
}
obj.push_back(Pair("inflight", heights));
}
obj.push_back(Pair("whitelisted", stats.fWhitelisted));
obj.pushKV("addr_processed", stats.nProcessedAddrs);
obj.pushKV("addr_rate_limited", stats.nRatelimitedAddrs);
obj.pushKV("whitelisted", stats.fWhitelisted);

UniValue sendPerMsgCmd(UniValue::VOBJ);
for (const mapMsgCmdSize::value_type &i : stats.mapSendBytesPerMsgCmd) {
Expand Down
6 changes: 6 additions & 0 deletions src/utiltime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ int64_t GetTime()
return now;
}

int64_t GetMockableTimeMicros()
{
if (nMockTime) return nMockTime * 1000000;
return GetTimeMicros();
}

void SetMockTime(int64_t nMockTimeIn)
{
nMockTime.store(nMockTimeIn, std::memory_order_relaxed);
Expand Down
1 change: 1 addition & 0 deletions src/utiltime.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
int64_t GetTime();
int64_t GetTimeMillis();
int64_t GetTimeMicros();
int64_t GetMockableTimeMicros();
int64_t GetSystemTimeInSeconds(); // Like GetTime(), but not mockable
void SetMockTime(int64_t nMockTimeIn);
int64_t GetMockTime();
Expand Down

0 comments on commit 518409b

Please sign in to comment.