mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 19:42:46 +01:00
merge bitcoin#24697: refactor address relay time
This commit is contained in:
parent
730cdf241a
commit
bc3ec30144
151
src/addrman.cpp
151
src/addrman.cpp
@ -29,19 +29,19 @@ static constexpr uint32_t ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP{64};
|
||||
/** Maximum number of times an address can occur in the new table */
|
||||
static constexpr int32_t ADDRMAN_NEW_BUCKETS_PER_ADDRESS{8};
|
||||
/** How old addresses can maximally be */
|
||||
static constexpr int64_t ADDRMAN_HORIZON_DAYS{30};
|
||||
static constexpr auto ADDRMAN_HORIZON{30 * 24h};
|
||||
/** After how many failed attempts we give up on a new node */
|
||||
static constexpr int32_t ADDRMAN_RETRIES{3};
|
||||
/** How many successive failures are allowed ... */
|
||||
static constexpr int32_t ADDRMAN_MAX_FAILURES{10};
|
||||
/** ... in at least this many days */
|
||||
static constexpr int64_t ADDRMAN_MIN_FAIL_DAYS{7};
|
||||
/** ... in at least this duration */
|
||||
static constexpr auto ADDRMAN_MIN_FAIL{7 * 24h};
|
||||
/** How recent a successful connection should be before we allow an address to be evicted from tried */
|
||||
static constexpr int64_t ADDRMAN_REPLACEMENT_HOURS{4};
|
||||
static constexpr auto ADDRMAN_REPLACEMENT{4h};
|
||||
/** The maximum number of tried addr collisions to store */
|
||||
static constexpr size_t ADDRMAN_SET_TRIED_COLLISION_SIZE{10};
|
||||
/** The maximum time we'll spend trying to resolve a tried table collision, in seconds */
|
||||
static constexpr int64_t ADDRMAN_TEST_WINDOW{40*60}; // 40 minutes
|
||||
/** The maximum time we'll spend trying to resolve a tried table collision */
|
||||
static constexpr auto ADDRMAN_TEST_WINDOW{40min};
|
||||
|
||||
int AddrInfo::GetTriedBucket(const uint256& nKey, const NetGroupManager& netgroupman) const
|
||||
{
|
||||
@ -64,36 +64,39 @@ int AddrInfo::GetBucketPosition(const uint256& nKey, bool fNew, int bucket) cons
|
||||
return hash1 % ADDRMAN_BUCKET_SIZE;
|
||||
}
|
||||
|
||||
bool AddrInfo::IsTerrible(int64_t nNow) const
|
||||
bool AddrInfo::IsTerrible(NodeSeconds now) const
|
||||
{
|
||||
if (nNow - nLastTry <= 60) { // never remove things tried in the last minute
|
||||
if (now - m_last_try <= 1min) { // never remove things tried in the last minute
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nTime > nNow + 10 * 60) // came in a flying DeLorean
|
||||
return true;
|
||||
|
||||
if (nNow - nTime > ADDRMAN_HORIZON_DAYS * 24 * 60 * 60) { // not seen in recent history
|
||||
if (nTime > now + 10min) { // came in a flying DeLorean
|
||||
return true;
|
||||
}
|
||||
|
||||
if (nLastSuccess == 0 && nAttempts >= ADDRMAN_RETRIES) // tried N times and never a success
|
||||
if (now - nTime > ADDRMAN_HORIZON) { // not seen in recent history
|
||||
return true;
|
||||
}
|
||||
|
||||
if (nNow - nLastSuccess > ADDRMAN_MIN_FAIL_DAYS * 24 * 60 * 60 && nAttempts >= ADDRMAN_MAX_FAILURES) // N successive failures in the last week
|
||||
if (TicksSinceEpoch<std::chrono::seconds>(m_last_success) == 0 && nAttempts >= ADDRMAN_RETRIES) { // tried N times and never a success
|
||||
return true;
|
||||
}
|
||||
|
||||
if (now - m_last_success > ADDRMAN_MIN_FAIL && nAttempts >= ADDRMAN_MAX_FAILURES) { // N successive failures in the last week
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
double AddrInfo::GetChance(int64_t nNow) const
|
||||
double AddrInfo::GetChance(NodeSeconds now) const
|
||||
{
|
||||
double fChance = 1.0;
|
||||
int64_t nSinceLastTry = std::max<int64_t>(nNow - nLastTry, 0);
|
||||
|
||||
// deprioritize very recent attempts away
|
||||
if (nSinceLastTry < 60 * 10)
|
||||
if (now - m_last_try < 10min) {
|
||||
fChance *= 0.01;
|
||||
}
|
||||
|
||||
// deprioritize 66% after each failed attempt, but at most 1/28th to avoid the search taking forever or overly penalizing outages.
|
||||
fChance *= pow(0.66, std::min(nAttempts, 8));
|
||||
@ -547,7 +550,7 @@ void AddrManImpl::MakeTried(AddrInfo& info, int nId)
|
||||
m_network_counts[info.GetNetwork()].n_tried++;
|
||||
}
|
||||
|
||||
bool AddrManImpl::AddSingle(const CAddress& addr, const CNetAddr& source, int64_t nTimePenalty)
|
||||
bool AddrManImpl::AddSingle(const CAddress& addr, const CNetAddr& source, std::chrono::seconds time_penalty)
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
@ -559,15 +562,15 @@ bool AddrManImpl::AddSingle(const CAddress& addr, const CNetAddr& source, int64_
|
||||
|
||||
// Do not set a penalty for a source's self-announcement
|
||||
if (addr == source) {
|
||||
nTimePenalty = 0;
|
||||
time_penalty = 0s;
|
||||
}
|
||||
|
||||
if (pinfo) {
|
||||
// periodically update nTime
|
||||
bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
|
||||
int64_t nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
|
||||
if (pinfo->nTime < addr.nTime - nUpdateInterval - nTimePenalty) {
|
||||
pinfo->nTime = std::max((int64_t)0, addr.nTime - nTimePenalty);
|
||||
const bool currently_online{AdjustedTime() - addr.nTime < 24h};
|
||||
const auto update_interval{currently_online ? 1h : 24h};
|
||||
if (pinfo->nTime < addr.nTime - update_interval - time_penalty) {
|
||||
pinfo->nTime = std::max(NodeSeconds{0s}, addr.nTime - time_penalty);
|
||||
}
|
||||
|
||||
// add services
|
||||
@ -593,7 +596,7 @@ bool AddrManImpl::AddSingle(const CAddress& addr, const CNetAddr& source, int64_
|
||||
}
|
||||
} else {
|
||||
pinfo = Create(addr, source, &nId);
|
||||
pinfo->nTime = std::max((int64_t)0, (int64_t)pinfo->nTime - nTimePenalty);
|
||||
pinfo->nTime = std::max(NodeSeconds{0s}, pinfo->nTime - time_penalty);
|
||||
}
|
||||
|
||||
int nUBucket = pinfo->GetNewBucket(nKey, source, m_netgroupman);
|
||||
@ -622,13 +625,13 @@ bool AddrManImpl::AddSingle(const CAddress& addr, const CNetAddr& source, int64_
|
||||
return fInsert;
|
||||
}
|
||||
|
||||
bool AddrManImpl::Good_(const CService& addr, bool test_before_evict, int64_t nTime)
|
||||
bool AddrManImpl::Good_(const CService& addr, bool test_before_evict, NodeSeconds time)
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
int nId;
|
||||
|
||||
nLastGood = nTime;
|
||||
m_last_good = time;
|
||||
|
||||
AddrInfo* pinfo = Find(addr, &nId);
|
||||
|
||||
@ -638,8 +641,8 @@ bool AddrManImpl::Good_(const CService& addr, bool test_before_evict, int64_t nT
|
||||
AddrInfo& info = *pinfo;
|
||||
|
||||
// update info
|
||||
info.nLastSuccess = nTime;
|
||||
info.nLastTry = nTime;
|
||||
info.m_last_success = time;
|
||||
info.m_last_try = time;
|
||||
info.nAttempts = 0;
|
||||
// nTime is not updated here, to avoid leaking information about
|
||||
// currently-connected peers.
|
||||
@ -680,11 +683,11 @@ bool AddrManImpl::Good_(const CService& addr, bool test_before_evict, int64_t nT
|
||||
}
|
||||
}
|
||||
|
||||
bool AddrManImpl::Add_(const std::vector<CAddress> &vAddr, const CNetAddr& source, int64_t nTimePenalty)
|
||||
bool AddrManImpl::Add_(const std::vector<CAddress>& vAddr, const CNetAddr& source, std::chrono::seconds time_penalty)
|
||||
{
|
||||
int added{0};
|
||||
for (std::vector<CAddress>::const_iterator it = vAddr.begin(); it != vAddr.end(); it++) {
|
||||
added += AddSingle(*it, source, nTimePenalty) ? 1 : 0;
|
||||
added += AddSingle(*it, source, time_penalty) ? 1 : 0;
|
||||
}
|
||||
if (added > 0) {
|
||||
LogPrint(BCLog::ADDRMAN, "Added %i addresses (of %i) from %s: %i tried, %i new\n", added, vAddr.size(), source.ToStringAddr(), nTried, nNew);
|
||||
@ -692,7 +695,7 @@ bool AddrManImpl::Add_(const std::vector<CAddress> &vAddr, const CNetAddr& sourc
|
||||
return added > 0;
|
||||
}
|
||||
|
||||
void AddrManImpl::Attempt_(const CService& addr, bool fCountFailure, int64_t nTime)
|
||||
void AddrManImpl::Attempt_(const CService& addr, bool fCountFailure, NodeSeconds time)
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
@ -705,14 +708,14 @@ void AddrManImpl::Attempt_(const CService& addr, bool fCountFailure, int64_t nTi
|
||||
AddrInfo& info = *pinfo;
|
||||
|
||||
// update info
|
||||
info.nLastTry = nTime;
|
||||
if (fCountFailure && info.nLastCountAttempt < nLastGood) {
|
||||
info.nLastCountAttempt = nTime;
|
||||
info.m_last_try = time;
|
||||
if (fCountFailure && info.m_last_count_attempt < m_last_good) {
|
||||
info.m_last_count_attempt = time;
|
||||
info.nAttempts++;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<CAddress, int64_t> AddrManImpl::Select_(bool new_only, std::optional<Network> network) const
|
||||
std::pair<CAddress, NodeSeconds> AddrManImpl::Select_(bool new_only, std::optional<Network> network) const
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
@ -780,7 +783,7 @@ std::pair<CAddress, int64_t> AddrManImpl::Select_(bool new_only, std::optional<N
|
||||
// With probability GetChance() * chance_factor, return the entry.
|
||||
if (insecure_rand.randbits(30) < chance_factor * info.GetChance() * (1 << 30)) {
|
||||
LogPrint(BCLog::ADDRMAN, "Selected %s from %s\n", info.ToStringAddrPort(), search_tried ? "tried" : "new");
|
||||
return {info, info.nLastTry};
|
||||
return {info, info.m_last_try};
|
||||
}
|
||||
|
||||
// Otherwise start over with a (likely) different bucket, and increased chance factor.
|
||||
@ -818,7 +821,7 @@ std::vector<CAddress> AddrManImpl::GetAddr_(size_t max_addresses, size_t max_pct
|
||||
}
|
||||
|
||||
// gather a list of random nodes, skipping those of low quality
|
||||
const int64_t now{GetAdjustedTime()};
|
||||
const auto now{AdjustedTime()};
|
||||
std::vector<CAddress> addresses;
|
||||
for (unsigned int n = 0; n < vRandom.size(); n++) {
|
||||
if (addresses.size() >= nNodes)
|
||||
@ -843,7 +846,7 @@ std::vector<CAddress> AddrManImpl::GetAddr_(size_t max_addresses, size_t max_pct
|
||||
return addresses;
|
||||
}
|
||||
|
||||
void AddrManImpl::Connected_(const CService& addr, int64_t nTime)
|
||||
void AddrManImpl::Connected_(const CService& addr, NodeSeconds time)
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
@ -856,9 +859,10 @@ void AddrManImpl::Connected_(const CService& addr, int64_t nTime)
|
||||
AddrInfo& info = *pinfo;
|
||||
|
||||
// update info
|
||||
int64_t nUpdateInterval = 20 * 60;
|
||||
if (nTime - info.nTime > nUpdateInterval)
|
||||
info.nTime = nTime;
|
||||
const auto update_interval{20min};
|
||||
if (time - info.nTime > update_interval) {
|
||||
info.nTime = time;
|
||||
}
|
||||
}
|
||||
|
||||
void AddrManImpl::SetServices_(const CService& addr, ServiceFlags nServices)
|
||||
@ -914,22 +918,22 @@ void AddrManImpl::ResolveCollisions_()
|
||||
int id_old = vvTried[tried_bucket][tried_bucket_pos];
|
||||
AddrInfo& info_old = mapInfo[id_old];
|
||||
|
||||
const auto current_time{GetAdjustedTime()};
|
||||
const auto current_time{AdjustedTime()};
|
||||
|
||||
// Has successfully connected in last X hours
|
||||
if (current_time - info_old.nLastSuccess < ADDRMAN_REPLACEMENT_HOURS*(60*60)) {
|
||||
if (current_time - info_old.m_last_success < ADDRMAN_REPLACEMENT) {
|
||||
erase_collision = true;
|
||||
} else if (current_time - info_old.nLastTry < ADDRMAN_REPLACEMENT_HOURS*(60*60)) { // attempted to connect and failed in last X hours
|
||||
} else if (current_time - info_old.m_last_try < ADDRMAN_REPLACEMENT) { // attempted to connect and failed in last X hours
|
||||
|
||||
// Give address at least 60 seconds to successfully connect
|
||||
if (current_time - info_old.nLastTry > 60) {
|
||||
if (current_time - info_old.m_last_try > 60s) {
|
||||
LogPrint(BCLog::ADDRMAN, "Replacing %s with %s in tried table\n", info_old.ToStringAddrPort(), info_new.ToStringAddrPort());
|
||||
|
||||
// Replaces an existing address already in the tried table with the new address
|
||||
Good_(info_new, false, current_time);
|
||||
erase_collision = true;
|
||||
}
|
||||
} else if (current_time - info_new.nLastSuccess > ADDRMAN_TEST_WINDOW) {
|
||||
} else if (current_time - info_new.m_last_success > ADDRMAN_TEST_WINDOW) {
|
||||
// If the collision hasn't resolved in some reasonable amount of time,
|
||||
// just evict the old entry -- we must not be able to
|
||||
// connect to it for some reason.
|
||||
@ -938,7 +942,7 @@ void AddrManImpl::ResolveCollisions_()
|
||||
erase_collision = true;
|
||||
}
|
||||
} else { // Collision is not actually a collision anymore
|
||||
Good_(info_new, false, GetAdjustedTime());
|
||||
Good_(info_new, false, AdjustedTime());
|
||||
erase_collision = true;
|
||||
}
|
||||
}
|
||||
@ -951,7 +955,7 @@ void AddrManImpl::ResolveCollisions_()
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<CAddress, int64_t> AddrManImpl::SelectTriedCollision_()
|
||||
std::pair<CAddress, NodeSeconds> AddrManImpl::SelectTriedCollision_()
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
|
||||
@ -976,7 +980,7 @@ std::pair<CAddress, int64_t> AddrManImpl::SelectTriedCollision_()
|
||||
int tried_bucket_pos = newInfo.GetBucketPosition(nKey, false, tried_bucket);
|
||||
|
||||
const AddrInfo& info_old = mapInfo[vvTried[tried_bucket][tried_bucket_pos]];
|
||||
return {info_old, info_old.nLastTry};
|
||||
return {info_old, info_old.m_last_try};
|
||||
}
|
||||
|
||||
std::optional<AddressPosition> AddrManImpl::FindAddressEntry_(const CAddress& addr)
|
||||
@ -1057,8 +1061,9 @@ int AddrManImpl::CheckAddrman() const
|
||||
int n = entry.first;
|
||||
const AddrInfo& info = entry.second;
|
||||
if (info.fInTried) {
|
||||
if (!info.nLastSuccess)
|
||||
if (!TicksSinceEpoch<std::chrono::seconds>(info.m_last_success)) {
|
||||
return -1;
|
||||
}
|
||||
if (info.nRefCount)
|
||||
return -2;
|
||||
setTried.insert(n);
|
||||
@ -1077,10 +1082,12 @@ int AddrManImpl::CheckAddrman() const
|
||||
}
|
||||
if (info.nRandomPos < 0 || (size_t)info.nRandomPos >= vRandom.size() || vRandom[info.nRandomPos] != n)
|
||||
return -14;
|
||||
if (info.nLastTry < 0)
|
||||
if (info.m_last_try < NodeSeconds{0s}) {
|
||||
return -6;
|
||||
if (info.nLastSuccess < 0)
|
||||
}
|
||||
if (info.m_last_success < NodeSeconds{0s}) {
|
||||
return -8;
|
||||
}
|
||||
}
|
||||
|
||||
if (setTried.size() != (size_t)nTried)
|
||||
@ -1150,29 +1157,29 @@ size_t AddrManImpl::Size(std::optional<Network> net, std::optional<bool> in_new)
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool AddrManImpl::Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, int64_t nTimePenalty)
|
||||
bool AddrManImpl::Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, std::chrono::seconds time_penalty)
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
auto ret = Add_(vAddr, source, nTimePenalty);
|
||||
auto ret = Add_(vAddr, source, time_penalty);
|
||||
Check();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool AddrManImpl::Good(const CService& addr, int64_t nTime)
|
||||
bool AddrManImpl::Good(const CService& addr, NodeSeconds time)
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
auto ret = Good_(addr, /*test_before_evict=*/true, nTime);
|
||||
auto ret = Good_(addr, /*test_before_evict=*/true, time);
|
||||
Check();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AddrManImpl::Attempt(const CService& addr, bool fCountFailure, int64_t nTime)
|
||||
void AddrManImpl::Attempt(const CService& addr, bool fCountFailure, NodeSeconds time)
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
Attempt_(addr, fCountFailure, nTime);
|
||||
Attempt_(addr, fCountFailure, time);
|
||||
Check();
|
||||
}
|
||||
|
||||
@ -1184,7 +1191,7 @@ void AddrManImpl::ResolveCollisions()
|
||||
Check();
|
||||
}
|
||||
|
||||
std::pair<CAddress, int64_t> AddrManImpl::SelectTriedCollision()
|
||||
std::pair<CAddress, NodeSeconds> AddrManImpl::SelectTriedCollision()
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
@ -1193,7 +1200,7 @@ std::pair<CAddress, int64_t> AddrManImpl::SelectTriedCollision()
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::pair<CAddress, int64_t> AddrManImpl::Select(bool new_only, std::optional<Network> network) const
|
||||
std::pair<CAddress, NodeSeconds> AddrManImpl::Select(bool new_only, std::optional<Network> network) const
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
@ -1211,11 +1218,11 @@ std::vector<CAddress> AddrManImpl::GetAddr(size_t max_addresses, size_t max_pct,
|
||||
return addresses;
|
||||
}
|
||||
|
||||
void AddrManImpl::Connected(const CService& addr, int64_t nTime)
|
||||
void AddrManImpl::Connected(const CService& addr, NodeSeconds time)
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
Connected_(addr, nTime);
|
||||
Connected_(addr, time);
|
||||
Check();
|
||||
}
|
||||
|
||||
@ -1278,19 +1285,19 @@ size_t AddrMan::Size(std::optional<Network> net, std::optional<bool> in_new) con
|
||||
return m_impl->Size(net, in_new);
|
||||
}
|
||||
|
||||
bool AddrMan::Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, int64_t nTimePenalty)
|
||||
bool AddrMan::Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, std::chrono::seconds time_penalty)
|
||||
{
|
||||
return m_impl->Add(vAddr, source, nTimePenalty);
|
||||
return m_impl->Add(vAddr, source, time_penalty);
|
||||
}
|
||||
|
||||
bool AddrMan::Good(const CService& addr, int64_t nTime)
|
||||
bool AddrMan::Good(const CService& addr, NodeSeconds time)
|
||||
{
|
||||
return m_impl->Good(addr, nTime);
|
||||
return m_impl->Good(addr, time);
|
||||
}
|
||||
|
||||
void AddrMan::Attempt(const CService& addr, bool fCountFailure, int64_t nTime)
|
||||
void AddrMan::Attempt(const CService& addr, bool fCountFailure, NodeSeconds time)
|
||||
{
|
||||
m_impl->Attempt(addr, fCountFailure, nTime);
|
||||
m_impl->Attempt(addr, fCountFailure, time);
|
||||
}
|
||||
|
||||
void AddrMan::ResolveCollisions()
|
||||
@ -1298,12 +1305,12 @@ void AddrMan::ResolveCollisions()
|
||||
m_impl->ResolveCollisions();
|
||||
}
|
||||
|
||||
std::pair<CAddress, int64_t> AddrMan::SelectTriedCollision()
|
||||
std::pair<CAddress, NodeSeconds> AddrMan::SelectTriedCollision()
|
||||
{
|
||||
return m_impl->SelectTriedCollision();
|
||||
}
|
||||
|
||||
std::pair<CAddress, int64_t> AddrMan::Select(bool new_only, std::optional<Network> network) const
|
||||
std::pair<CAddress, NodeSeconds> AddrMan::Select(bool new_only, std::optional<Network> network) const
|
||||
{
|
||||
return m_impl->Select(new_only, network);
|
||||
}
|
||||
@ -1313,9 +1320,9 @@ std::vector<CAddress> AddrMan::GetAddr(size_t max_addresses, size_t max_pct, std
|
||||
return m_impl->GetAddr(max_addresses, max_pct, network);
|
||||
}
|
||||
|
||||
void AddrMan::Connected(const CService& addr, int64_t nTime)
|
||||
void AddrMan::Connected(const CService& addr, NodeSeconds time)
|
||||
{
|
||||
m_impl->Connected(addr, nTime);
|
||||
m_impl->Connected(addr, time);
|
||||
}
|
||||
|
||||
void AddrMan::SetServices(const CService& addr, ServiceFlags nServices)
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <protocol.h>
|
||||
#include <streams.h>
|
||||
#include <timedata.h>
|
||||
#include <util/time.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
@ -124,23 +125,23 @@ public:
|
||||
*
|
||||
* @param[in] vAddr Address records to attempt to add.
|
||||
* @param[in] source The address of the node that sent us these addr records.
|
||||
* @param[in] nTimePenalty A "time penalty" to apply to the address record's nTime. If a peer
|
||||
* @param[in] time_penalty A "time penalty" to apply to the address record's nTime. If a peer
|
||||
* sends us an address record with nTime=n, then we'll add it to our
|
||||
* addrman with nTime=(n - nTimePenalty).
|
||||
* addrman with nTime=(n - time_penalty).
|
||||
* @return true if at least one address is successfully added. */
|
||||
bool Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, int64_t nTimePenalty = 0);
|
||||
bool Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, std::chrono::seconds time_penalty = 0s);
|
||||
|
||||
/**
|
||||
* Mark an address record as accessible and attempt to move it to addrman's tried table.
|
||||
*
|
||||
* @param[in] addr Address record to attempt to move to tried table.
|
||||
* @param[in] nTime The time that we were last connected to this peer.
|
||||
* @param[in] time The time that we were last connected to this peer.
|
||||
* @return true if the address is successfully moved from the new table to the tried table.
|
||||
*/
|
||||
bool Good(const CService& addr, int64_t nTime = GetAdjustedTime());
|
||||
bool Good(const CService& addr, NodeSeconds time = AdjustedTime());
|
||||
|
||||
//! Mark an entry as connection attempted to.
|
||||
void Attempt(const CService& addr, bool fCountFailure, int64_t nTime = GetAdjustedTime());
|
||||
void Attempt(const CService& addr, bool fCountFailure, NodeSeconds time = AdjustedTime());
|
||||
|
||||
//! See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
|
||||
void ResolveCollisions();
|
||||
@ -150,9 +151,9 @@ public:
|
||||
* attempting to evict.
|
||||
*
|
||||
* @return CAddress The record for the selected tried peer.
|
||||
* int64_t The last time we attempted to connect to that peer.
|
||||
* seconds The last time we attempted to connect to that peer.
|
||||
*/
|
||||
std::pair<CAddress, int64_t> SelectTriedCollision();
|
||||
std::pair<CAddress, NodeSeconds> SelectTriedCollision();
|
||||
|
||||
/**
|
||||
* Choose an address to connect to.
|
||||
@ -164,9 +165,9 @@ public:
|
||||
* @param[in] network Select only addresses of this network (nullopt = all). Passing a network may
|
||||
* slow down the search.
|
||||
* @return CAddress The record for the selected peer.
|
||||
* int64_t The last time we attempted to connect to that peer.
|
||||
* seconds The last time we attempted to connect to that peer.
|
||||
*/
|
||||
std::pair<CAddress, int64_t> Select(bool new_only = false, std::optional<Network> network = std::nullopt) const;
|
||||
std::pair<CAddress, NodeSeconds> Select(bool new_only = false, std::optional<Network> network = std::nullopt) const;
|
||||
|
||||
/**
|
||||
* Return all or many randomly selected addresses, optionally by network.
|
||||
@ -188,9 +189,9 @@ public:
|
||||
* not leak information about currently connected peers.
|
||||
*
|
||||
* @param[in] addr The address of the peer we were connected to
|
||||
* @param[in] nTime The time that we were last connected to this peer
|
||||
* @param[in] time The time that we were last connected to this peer
|
||||
*/
|
||||
void Connected(const CService& addr, int64_t nTime = GetAdjustedTime());
|
||||
void Connected(const CService& addr, NodeSeconds time = AdjustedTime());
|
||||
|
||||
//! Update an entry's service bits.
|
||||
void SetServices(const CService& addr, ServiceFlags nServices);
|
||||
|
@ -11,7 +11,9 @@
|
||||
#include <protocol.h>
|
||||
#include <serialize.h>
|
||||
#include <sync.h>
|
||||
#include <timedata.h>
|
||||
#include <uint256.h>
|
||||
#include <util/time.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
@ -38,16 +40,16 @@ class AddrInfo : public CAddress
|
||||
{
|
||||
public:
|
||||
//! last try whatsoever by us (memory only)
|
||||
int64_t nLastTry{0};
|
||||
NodeSeconds m_last_try{0s};
|
||||
|
||||
//! last counted attempt (memory only)
|
||||
int64_t nLastCountAttempt{0};
|
||||
NodeSeconds m_last_count_attempt{0s};
|
||||
|
||||
//! where knowledge about this address first came from
|
||||
CNetAddr source;
|
||||
|
||||
//! last successful connection by us
|
||||
int64_t nLastSuccess{0};
|
||||
NodeSeconds m_last_success{0s};
|
||||
|
||||
//! connection attempts since last successful attempt
|
||||
int nAttempts{0};
|
||||
@ -64,7 +66,7 @@ public:
|
||||
SERIALIZE_METHODS(AddrInfo, obj)
|
||||
{
|
||||
READWRITEAS(CAddress, obj);
|
||||
READWRITE(obj.source, obj.nLastSuccess, obj.nAttempts);
|
||||
READWRITE(obj.source, Using<ChronoFormatter<int64_t>>(obj.m_last_success), obj.nAttempts);
|
||||
}
|
||||
|
||||
AddrInfo(const CAddress &addrIn, const CNetAddr &addrSource) : CAddress(addrIn), source(addrSource)
|
||||
@ -91,10 +93,10 @@ public:
|
||||
int GetBucketPosition(const uint256 &nKey, bool fNew, int bucket) const;
|
||||
|
||||
//! Determine whether the statistics about this entry are bad enough so that it can just be deleted
|
||||
bool IsTerrible(int64_t nNow = GetAdjustedTime()) const;
|
||||
bool IsTerrible(NodeSeconds now = AdjustedTime()) const;
|
||||
|
||||
//! Calculate the relative chance this entry should be given when selecting nodes to connect to
|
||||
double GetChance(int64_t nNow = GetAdjustedTime()) const;
|
||||
double GetChance(NodeSeconds now = AdjustedTime()) const;
|
||||
};
|
||||
|
||||
class AddrManImpl
|
||||
@ -112,26 +114,26 @@ public:
|
||||
|
||||
size_t Size(std::optional<Network> net, std::optional<bool> in_new) const EXCLUSIVE_LOCKS_REQUIRED(!cs);
|
||||
|
||||
bool Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, int64_t nTimePenalty)
|
||||
bool Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, std::chrono::seconds time_penalty)
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!cs);
|
||||
|
||||
bool Good(const CService& addr, int64_t nTime)
|
||||
bool Good(const CService& addr, NodeSeconds time)
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!cs);
|
||||
|
||||
void Attempt(const CService& addr, bool fCountFailure, int64_t nTime)
|
||||
void Attempt(const CService& addr, bool fCountFailure, NodeSeconds time)
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!cs);
|
||||
|
||||
void ResolveCollisions() EXCLUSIVE_LOCKS_REQUIRED(!cs);
|
||||
|
||||
std::pair<CAddress, int64_t> SelectTriedCollision() EXCLUSIVE_LOCKS_REQUIRED(!cs);
|
||||
std::pair<CAddress, NodeSeconds> SelectTriedCollision() EXCLUSIVE_LOCKS_REQUIRED(!cs);
|
||||
|
||||
std::pair<CAddress, int64_t> Select(bool new_only, std::optional<Network> network) const
|
||||
std::pair<CAddress, NodeSeconds> Select(bool new_only, std::optional<Network> network) const
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!cs);
|
||||
|
||||
std::vector<CAddress> GetAddr(size_t max_addresses, size_t max_pct, std::optional<Network> network) const
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!cs);
|
||||
|
||||
void Connected(const CService& addr, int64_t nTime)
|
||||
void Connected(const CService& addr, NodeSeconds time)
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!cs);
|
||||
|
||||
void SetServices(const CService& addr, ServiceFlags nServices)
|
||||
@ -205,7 +207,7 @@ private:
|
||||
int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE] GUARDED_BY(cs);
|
||||
|
||||
//! last time Good was called (memory only). Initially set to 1 so that "never" is strictly worse.
|
||||
int64_t nLastGood GUARDED_BY(cs){1};
|
||||
NodeSeconds m_last_good GUARDED_BY(cs){1s};
|
||||
|
||||
//! Holds addrs inserted into tried table that collide with existing entries. Test-before-evict discipline used to resolve these collisions.
|
||||
std::set<int> m_tried_collisions;
|
||||
@ -244,15 +246,15 @@ private:
|
||||
|
||||
/** Attempt to add a single address to addrman's new table.
|
||||
* @see AddrMan::Add() for parameters. */
|
||||
bool AddSingle(const CAddress& addr, const CNetAddr& source, int64_t nTimePenalty) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
bool AddSingle(const CAddress& addr, const CNetAddr& source, std::chrono::seconds time_penalty) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
bool Good_(const CService& addr, bool test_before_evict, int64_t time) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
bool Good_(const CService& addr, bool test_before_evict, NodeSeconds time) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
bool Add_(const std::vector<CAddress> &vAddr, const CNetAddr& source, int64_t nTimePenalty) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
bool Add_(const std::vector<CAddress>& vAddr, const CNetAddr& source, std::chrono::seconds time_penalty) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
void Attempt_(const CService& addr, bool fCountFailure, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
void Attempt_(const CService& addr, bool fCountFailure, NodeSeconds time) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
std::pair<CAddress, int64_t> Select_(bool new_only, std::optional<Network> network) const EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
std::pair<CAddress, NodeSeconds> Select_(bool new_only, std::optional<Network> network) const EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
/** Helper to generalize looking up an addrman entry from either table.
|
||||
*
|
||||
@ -262,7 +264,7 @@ private:
|
||||
|
||||
std::vector<CAddress> GetAddr_(size_t max_addresses, size_t max_pct, std::optional<Network> network) const EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
void Connected_(const CService& addr, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
void Connected_(const CService& addr, NodeSeconds time) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
void SetServices_(const CService& addr, ServiceFlags nServices) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
@ -270,7 +272,7 @@ private:
|
||||
|
||||
void ResolveCollisions_() EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
std::pair<CAddress, int64_t> SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
std::pair<CAddress, NodeSeconds> SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
std::optional<AddressPosition> FindAddressEntry_(const CAddress& addr) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
|
||||
|
@ -42,7 +42,7 @@ static void CreateAddresses()
|
||||
|
||||
CAddress ret(CService(addr, port), NODE_NETWORK);
|
||||
|
||||
ret.nTime = GetAdjustedTime();
|
||||
ret.nTime = AdjustedTime();
|
||||
|
||||
return ret;
|
||||
};
|
||||
@ -118,7 +118,7 @@ static void AddrManSelectByNetwork(benchmark::Bench& bench)
|
||||
CService i2p_service;
|
||||
i2p_service.SetSpecial("udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.i2p");
|
||||
CAddress i2p_address(i2p_service, NODE_NONE);
|
||||
i2p_address.nTime = GetAdjustedTime();
|
||||
i2p_address.nTime = Now<NodeSeconds>();
|
||||
const CNetAddr source{LookupHost("252.2.2.2", false).value()};
|
||||
addrman.Add({i2p_address}, source);
|
||||
|
||||
|
18
src/net.cpp
18
src/net.cpp
@ -232,7 +232,7 @@ static std::vector<CAddress> ConvertSeeds(const std::vector<uint8_t> &vSeedsIn)
|
||||
// it'll get a pile of addresses with newer timestamps.
|
||||
// Seed nodes are given a random 'last seen time' of between one and two
|
||||
// weeks ago.
|
||||
const int64_t nOneWeek = 7*24*60*60;
|
||||
const auto one_week{7 * 24h};
|
||||
std::vector<CAddress> vSeedsOut;
|
||||
FastRandomContext rng;
|
||||
CDataStream s(vSeedsIn, SER_NETWORK, PROTOCOL_VERSION | ADDRV2_FORMAT);
|
||||
@ -240,7 +240,7 @@ static std::vector<CAddress> ConvertSeeds(const std::vector<uint8_t> &vSeedsIn)
|
||||
CService endpoint;
|
||||
s >> endpoint;
|
||||
CAddress addr{endpoint, GetDesirableServiceFlags(NODE_NONE)};
|
||||
addr.nTime = GetTime() - rng.randrange(nOneWeek) - nOneWeek;
|
||||
addr.nTime = rng.rand_uniform_delay(Now<NodeSeconds>() - one_week, -one_week);
|
||||
LogPrint(BCLog::NET, "Added hardcoded seed: %s\n", addr.ToStringAddrPort());
|
||||
vSeedsOut.push_back(addr);
|
||||
}
|
||||
@ -512,11 +512,11 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
|
||||
LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "trying %s connection %s lastseen=%.1fhrs\n",
|
||||
use_v2transport ? "v2" : "v1",
|
||||
pszDest ? pszDest : addrConnect.ToStringAddrPort(),
|
||||
pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
|
||||
Ticks<HoursDouble>(pszDest ? 0h : AdjustedTime() - addrConnect.nTime));
|
||||
} else {
|
||||
LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "trying %s connection lastseen=%.1fhrs\n",
|
||||
use_v2transport ? "v2" : "v1",
|
||||
pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
|
||||
Ticks<HoursDouble>(pszDest ? 0h : AdjustedTime() - addrConnect.nTime));
|
||||
}
|
||||
|
||||
// Resolve
|
||||
@ -3080,9 +3080,8 @@ void CConnman::ThreadDNSAddressSeed()
|
||||
const auto addresses{LookupHost(host, nMaxIPs, true)};
|
||||
if (!addresses.empty()) {
|
||||
for (const CNetAddr& ip : addresses) {
|
||||
int nOneDay = 24*3600;
|
||||
CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()), requiredServiceBits);
|
||||
addr.nTime = GetTime() - 3*nOneDay - rng.randrange(4*nOneDay); // use a random age between 3 and 7 days old
|
||||
addr.nTime = rng.rand_uniform_delay(Now<NodeSeconds>() - 3 * 24h, -4 * 24h); // use a random age between 3 and 7 days old
|
||||
vAdd.push_back(addr);
|
||||
found++;
|
||||
}
|
||||
@ -3451,7 +3450,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, CDe
|
||||
|
||||
auto mnList = dmnman.GetListAtChainTip();
|
||||
|
||||
int64_t nANow = GetAdjustedTime();
|
||||
const auto nANow{AdjustedTime()};
|
||||
int nTries = 0;
|
||||
while (!interruptNet)
|
||||
{
|
||||
@ -3474,7 +3473,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, CDe
|
||||
break;
|
||||
|
||||
CAddress addr;
|
||||
int64_t addr_last_try{0};
|
||||
NodeSeconds addr_last_try{0s};
|
||||
|
||||
if (fFeeler) {
|
||||
// First, try to get a tried table collision address. This returns
|
||||
@ -3530,8 +3529,9 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, CDe
|
||||
if (onion_only && !addr.IsTor()) continue;
|
||||
|
||||
// only consider very recently tried nodes after 30 failed attempts
|
||||
if (nANow - addr_last_try < 600 && nTries < 30)
|
||||
if (nANow - addr_last_try < 10min && nTries < 30) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// for non-feelers, require all the services we'll want,
|
||||
// for feelers, only require they be a full node (only because most
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <reverse_iterator.h>
|
||||
#include <scheduler.h>
|
||||
#include <streams.h>
|
||||
#include <timedata.h>
|
||||
#include <tinyformat.h>
|
||||
#include <index/txindex.h>
|
||||
#include <txmempool.h>
|
||||
@ -3695,7 +3696,7 @@ void PeerManagerImpl::ProcessMessage(
|
||||
// indicate to the peer that we will participate in addr relay.
|
||||
if (fListen && !m_chainman.ActiveChainstate().IsInitialBlockDownload())
|
||||
{
|
||||
CAddress addr{GetLocalAddress(pfrom), peer->m_our_services, (uint32_t)GetAdjustedTime()};
|
||||
CAddress addr{GetLocalAddress(pfrom), peer->m_our_services, AdjustedTime()};
|
||||
FastRandomContext insecure_rand;
|
||||
if (addr.IsRoutable())
|
||||
{
|
||||
@ -3982,8 +3983,7 @@ void PeerManagerImpl::ProcessMessage(
|
||||
|
||||
// Store the new addresses
|
||||
std::vector<CAddress> vAddrOk;
|
||||
int64_t nNow = GetAdjustedTime();
|
||||
int64_t nSince = nNow - 10 * 60;
|
||||
const auto current_a_time{AdjustedTime()};
|
||||
|
||||
// Update/increment addr rate limiting bucket.
|
||||
const auto current_time{GetTime<std::chrono::microseconds>()};
|
||||
@ -4019,8 +4019,9 @@ void PeerManagerImpl::ProcessMessage(
|
||||
if (!MayHaveUsefulAddressDB(addr.nServices) && !HasAllDesirableServiceFlags(addr.nServices))
|
||||
continue;
|
||||
|
||||
if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
|
||||
addr.nTime = nNow - 5 * 24 * 60 * 60;
|
||||
if (addr.nTime <= NodeSeconds{100000000s} || addr.nTime > current_a_time + 10min) {
|
||||
addr.nTime = current_a_time - 5 * 24h;
|
||||
}
|
||||
AddAddressKnown(*peer, addr);
|
||||
if (m_banman && (m_banman->IsDiscouraged(addr) || m_banman->IsBanned(addr))) {
|
||||
// Do not process banned/discouraged addresses beyond remembering we received them
|
||||
@ -4028,7 +4029,7 @@ void PeerManagerImpl::ProcessMessage(
|
||||
}
|
||||
++num_proc;
|
||||
bool fReachable = IsReachable(addr);
|
||||
if (addr.nTime > nSince && !peer->m_getaddr_sent && vAddr.size() <= 10 && addr.IsRoutable()) {
|
||||
if (addr.nTime > current_a_time - 10min && !peer->m_getaddr_sent && vAddr.size() <= 10 && addr.IsRoutable()) {
|
||||
// Relay to a limited number of other nodes
|
||||
RelayAddress(pfrom.GetId(), addr, fReachable);
|
||||
}
|
||||
@ -4041,7 +4042,7 @@ void PeerManagerImpl::ProcessMessage(
|
||||
LogPrint(BCLog::NET, "Received addr: %u addresses (%u processed, %u rate-limited) from peer=%d\n",
|
||||
vAddr.size(), num_proc, num_rate_limit, pfrom.GetId());
|
||||
|
||||
m_addrman.Add(vAddrOk, pfrom.addr, 2 * 60 * 60);
|
||||
m_addrman.Add(vAddrOk, pfrom.addr, 2h);
|
||||
if (vAddr.size() < 1000) peer->m_getaddr_sent = false;
|
||||
|
||||
// AddrFetch: Require multiple addresses to avoid disconnecting on self-announcements
|
||||
@ -5667,7 +5668,7 @@ void PeerManagerImpl::MaybeSendAddr(CNode& node, Peer& peer, std::chrono::micros
|
||||
peer.m_addr_known->reset();
|
||||
}
|
||||
if (std::optional<CService> local_service = GetLocalAddrForPeer(node)) {
|
||||
CAddress local_addr{*local_service, peer.m_our_services, (uint32_t)GetAdjustedTime()};
|
||||
CAddress local_addr{*local_service, peer.m_our_services, AdjustedTime()};
|
||||
FastRandomContext insecure_rand;
|
||||
PushAddress(peer, local_addr, insecure_rand);
|
||||
}
|
||||
|
@ -43,7 +43,6 @@
|
||||
#include <shutdown.h>
|
||||
#include <support/allocators/secure.h>
|
||||
#include <sync.h>
|
||||
#include <timedata.h>
|
||||
#include <txmempool.h>
|
||||
#include <uint256.h>
|
||||
#include <util/check.h>
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <streams.h>
|
||||
#include <uint256.h>
|
||||
#include <util/expected.h>
|
||||
#include <util/time.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
@ -397,7 +398,7 @@ static inline bool MayHaveUsefulAddressDB(ServiceFlags services)
|
||||
/** A CService with information about it as peer */
|
||||
class CAddress : public CService
|
||||
{
|
||||
static constexpr uint32_t TIME_INIT{100000000};
|
||||
static constexpr std::chrono::seconds TIME_INIT{100000000};
|
||||
|
||||
/** Historically, CAddress disk serialization stored the CLIENT_VERSION, optionally OR'ed with
|
||||
* the ADDRV2_FORMAT flag to indicate V2 serialization. The first field has since been
|
||||
@ -427,7 +428,7 @@ class CAddress : public CService
|
||||
public:
|
||||
CAddress() : CService{} {};
|
||||
explicit CAddress(CService ipIn, ServiceFlags nServicesIn) : CService{ipIn}, nServices{nServicesIn} {};
|
||||
CAddress(CService ipIn, ServiceFlags nServicesIn, uint32_t nTimeIn) : CService{ipIn}, nTime{nTimeIn}, nServices{nServicesIn} {};
|
||||
CAddress(CService ipIn, ServiceFlags nServicesIn, NodeSeconds time) : CService{ipIn}, nTime{time}, nServices{nServicesIn} {};
|
||||
|
||||
SERIALIZE_METHODS(CAddress, obj)
|
||||
{
|
||||
@ -460,7 +461,7 @@ public:
|
||||
use_v2 = s.GetVersion() & ADDRV2_FORMAT;
|
||||
}
|
||||
|
||||
READWRITE(obj.nTime);
|
||||
READWRITE(Using<LossyChronoFormatter<uint32_t>>(obj.nTime));
|
||||
// nServices is serialized as CompactSize in V2; as uint64_t in V1.
|
||||
if (use_v2) {
|
||||
uint64_t services_tmp;
|
||||
@ -475,8 +476,8 @@ public:
|
||||
SerReadWriteMany(os, ser_action, ReadWriteAsHelper<CService>(obj));
|
||||
}
|
||||
|
||||
//! Always included in serialization.
|
||||
uint32_t nTime{TIME_INIT};
|
||||
//! Always included in serialization. The behavior is unspecified if the value is not representable as uint32_t.
|
||||
NodeSeconds nTime{TIME_INIT};
|
||||
//! Serialized as uint64_t in V1, and as CompactSize in V2.
|
||||
ServiceFlags nServices{NODE_NONE};
|
||||
|
||||
|
@ -966,7 +966,7 @@ static RPCHelpMan getnodeaddresses()
|
||||
|
||||
for (const CAddress& addr : vAddr) {
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.pushKV("time", (int)addr.nTime);
|
||||
obj.pushKV("time", int64_t{TicksSinceEpoch<std::chrono::seconds>(addr.nTime)});
|
||||
obj.pushKV("services", (uint64_t)addr.nServices);
|
||||
obj.pushKV("address", addr.ToStringAddr());
|
||||
obj.pushKV("port", addr.GetPort());
|
||||
@ -1015,7 +1015,7 @@ static RPCHelpMan addpeeraddress()
|
||||
|
||||
if (net_addr.has_value()) {
|
||||
CAddress address{{net_addr.value(), port}, ServiceFlags{NODE_NETWORK}};
|
||||
address.nTime = GetAdjustedTime();
|
||||
address.nTime = AdjustedTime();
|
||||
// The source address is set equal to the address. This is equivalent to the peer
|
||||
// announcing itself.
|
||||
if (node.addrman->Add({address}, address)) {
|
||||
|
@ -704,6 +704,29 @@ struct CompactSizeFormatter
|
||||
}
|
||||
};
|
||||
|
||||
template <typename U, bool LOSSY = false>
|
||||
struct ChronoFormatter {
|
||||
template <typename Stream, typename Tp>
|
||||
void Unser(Stream& s, Tp& tp)
|
||||
{
|
||||
U u;
|
||||
s >> u;
|
||||
// Lossy deserialization does not make sense, so force Wnarrowing
|
||||
tp = Tp{typename Tp::duration{typename Tp::duration::rep{u}}};
|
||||
}
|
||||
template <typename Stream, typename Tp>
|
||||
void Ser(Stream& s, Tp tp)
|
||||
{
|
||||
if constexpr (LOSSY) {
|
||||
s << U(tp.time_since_epoch().count());
|
||||
} else {
|
||||
s << U{tp.time_since_epoch().count()};
|
||||
}
|
||||
}
|
||||
};
|
||||
template <typename U>
|
||||
using LossyChronoFormatter = ChronoFormatter<U, true>;
|
||||
|
||||
template<size_t Limit>
|
||||
struct LimitedStringFormatter
|
||||
{
|
||||
|
@ -309,7 +309,7 @@ BOOST_AUTO_TEST_CASE(addrman_new_multiplicity)
|
||||
{
|
||||
auto addrman = std::make_unique<AddrMan>(EMPTY_NETGROUPMAN, DETERMINISTIC, GetCheckRatio(m_node));
|
||||
CAddress addr{CAddress(ResolveService("253.3.3.3", 8333), NODE_NONE)};
|
||||
int64_t start_time{GetAdjustedTime()};
|
||||
const auto start_time{AdjustedTime()};
|
||||
addr.nTime = start_time;
|
||||
|
||||
// test that multiplicity stays at 1 if nTime doesn't increase
|
||||
@ -328,7 +328,7 @@ BOOST_AUTO_TEST_CASE(addrman_new_multiplicity)
|
||||
for (unsigned int i = 1; i < 400; ++i) {
|
||||
std::string addr_ip{ToString(i % 256) + "." + ToString(i >> 8 % 256) + ".1.1"};
|
||||
CNetAddr source{ResolveIP(addr_ip)};
|
||||
addr.nTime = start_time + i;
|
||||
addr.nTime = start_time + std::chrono::seconds{i};
|
||||
addrman->Add({addr}, source);
|
||||
}
|
||||
AddressPosition addr_pos_multi = addrman->FindAddressEntry(addr).value();
|
||||
@ -379,15 +379,15 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr)
|
||||
BOOST_CHECK_EQUAL(vAddr1.size(), 0U);
|
||||
|
||||
CAddress addr1 = CAddress(ResolveService("250.250.2.1", 8333), NODE_NONE);
|
||||
addr1.nTime = GetAdjustedTime(); // Set time so isTerrible = false
|
||||
addr1.nTime = AdjustedTime(); // Set time so isTerrible = false
|
||||
CAddress addr2 = CAddress(ResolveService("250.251.2.2", 9999), NODE_NONE);
|
||||
addr2.nTime = GetAdjustedTime();
|
||||
addr2.nTime = AdjustedTime();
|
||||
CAddress addr3 = CAddress(ResolveService("251.252.2.3", 8333), NODE_NONE);
|
||||
addr3.nTime = GetAdjustedTime();
|
||||
addr3.nTime = AdjustedTime();
|
||||
CAddress addr4 = CAddress(ResolveService("252.253.3.4", 8333), NODE_NONE);
|
||||
addr4.nTime = GetAdjustedTime();
|
||||
addr4.nTime = AdjustedTime();
|
||||
CAddress addr5 = CAddress(ResolveService("252.254.4.5", 8333), NODE_NONE);
|
||||
addr5.nTime = GetAdjustedTime();
|
||||
addr5.nTime = AdjustedTime();
|
||||
CNetAddr source1 = ResolveIP("250.1.2.1");
|
||||
CNetAddr source2 = ResolveIP("250.2.3.3");
|
||||
|
||||
@ -413,7 +413,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr)
|
||||
CAddress addr = CAddress(ResolveService(strAddr), NODE_NONE);
|
||||
|
||||
// Ensure that for all addrs in addrman, isTerrible == false.
|
||||
addr.nTime = GetAdjustedTime();
|
||||
addr.nTime = AdjustedTime();
|
||||
addrman->Add({addr}, ResolveIP(strAddr));
|
||||
if (i % 8 == 0)
|
||||
addrman->Good(addr);
|
||||
@ -905,8 +905,8 @@ BOOST_AUTO_TEST_CASE(addrman_evictionworks)
|
||||
|
||||
// Ensure test of address fails, so that it is evicted.
|
||||
// Update entry in tried by setting last good connection in the deep past.
|
||||
BOOST_CHECK(!addrman->Good(info, /*nTime=*/1));
|
||||
addrman->Attempt(info, /*fCountFailure=*/false, /*nTime=*/GetAdjustedTime() - 61);
|
||||
BOOST_CHECK(!addrman->Good(info, NodeSeconds{1s}));
|
||||
addrman->Attempt(info, /*fCountFailure=*/false, AdjustedTime() - 61s);
|
||||
|
||||
// Should swap 36 for 19.
|
||||
addrman->ResolveCollisions();
|
||||
@ -1053,7 +1053,7 @@ BOOST_AUTO_TEST_CASE(addrman_update_address)
|
||||
CNetAddr source{ResolveIP("252.2.2.2")};
|
||||
CAddress addr{CAddress(ResolveService("250.1.1.1", 8333), NODE_NONE)};
|
||||
|
||||
int64_t start_time{GetAdjustedTime() - 10000};
|
||||
const auto start_time{AdjustedTime() - 10000s};
|
||||
addr.nTime = start_time;
|
||||
BOOST_CHECK(addrman->Add({addr}, source));
|
||||
BOOST_CHECK_EQUAL(addrman->Size(), 1U);
|
||||
@ -1065,7 +1065,7 @@ BOOST_AUTO_TEST_CASE(addrman_update_address)
|
||||
addrman->SetServices(addr_diff_port, NODE_NETWORK_LIMITED);
|
||||
std::vector<CAddress> vAddr1{addrman->GetAddr(/*max_addresses=*/0, /*max_pct=*/0, /*network=*/std::nullopt)};
|
||||
BOOST_CHECK_EQUAL(vAddr1.size(), 1U);
|
||||
BOOST_CHECK_EQUAL(vAddr1.at(0).nTime, start_time);
|
||||
BOOST_CHECK(vAddr1.at(0).nTime == start_time);
|
||||
BOOST_CHECK_EQUAL(vAddr1.at(0).nServices, NODE_NONE);
|
||||
|
||||
// Updating an addrman entry with the correct port is successful
|
||||
@ -1073,7 +1073,7 @@ BOOST_AUTO_TEST_CASE(addrman_update_address)
|
||||
addrman->SetServices(addr, NODE_NETWORK_LIMITED);
|
||||
std::vector<CAddress> vAddr2 = addrman->GetAddr(/*max_addresses=*/0, /*max_pct=*/0, /*network=*/std::nullopt);
|
||||
BOOST_CHECK_EQUAL(vAddr2.size(), 1U);
|
||||
BOOST_CHECK(vAddr2.at(0).nTime >= start_time + 10000);
|
||||
BOOST_CHECK(vAddr2.at(0).nTime >= start_time + 10000s);
|
||||
BOOST_CHECK_EQUAL(vAddr2.at(0).nServices, NODE_NETWORK_LIMITED);
|
||||
}
|
||||
|
||||
|
@ -114,11 +114,11 @@ void FillAddrman(AddrMan& addrman, FuzzedDataProvider& fuzzed_data_provider)
|
||||
|
||||
for (size_t j = 0; j < num_addresses; ++j) {
|
||||
const auto addr = CAddress{CService{RandAddr(fuzzed_data_provider, fast_random_context), 8333}, NODE_NETWORK};
|
||||
const auto time_penalty = fast_random_context.randrange(100000001);
|
||||
const std::chrono::seconds time_penalty{fast_random_context.randrange(100000001)};
|
||||
addrman.Add({addr}, source, time_penalty);
|
||||
|
||||
if (n > 0 && addrman.Size() % n == 0) {
|
||||
addrman.Good(addr, GetTime());
|
||||
addrman.Good(addr, Now<NodeSeconds>());
|
||||
}
|
||||
|
||||
// Add 10% of the addresses from more than one source.
|
||||
@ -162,7 +162,7 @@ public:
|
||||
CSipHasher hasher(0, 0);
|
||||
auto addr_key = a.GetKey();
|
||||
auto source_key = a.source.GetAddrBytes();
|
||||
hasher.Write(a.nLastSuccess);
|
||||
hasher.Write(TicksSinceEpoch<std::chrono::seconds>(a.m_last_success));
|
||||
hasher.Write(a.nAttempts);
|
||||
hasher.Write(a.nRefCount);
|
||||
hasher.Write(a.fInTried);
|
||||
@ -176,8 +176,8 @@ public:
|
||||
};
|
||||
|
||||
auto addrinfo_eq = [](const AddrInfo& lhs, const AddrInfo& rhs) {
|
||||
return std::tie(static_cast<const CService&>(lhs), lhs.source, lhs.nLastSuccess, lhs.nAttempts, lhs.nRefCount, lhs.fInTried) ==
|
||||
std::tie(static_cast<const CService&>(rhs), rhs.source, rhs.nLastSuccess, rhs.nAttempts, rhs.nRefCount, rhs.fInTried);
|
||||
return std::tie(static_cast<const CService&>(lhs), lhs.source, lhs.m_last_success, lhs.nAttempts, lhs.nRefCount, lhs.fInTried) ==
|
||||
std::tie(static_cast<const CService&>(rhs), rhs.source, rhs.m_last_success, rhs.nAttempts, rhs.nRefCount, rhs.fInTried);
|
||||
};
|
||||
|
||||
using Addresses = std::unordered_set<AddrInfo, decltype(addrinfo_hasher), decltype(addrinfo_eq)>;
|
||||
@ -279,25 +279,25 @@ FUZZ_TARGET_INIT(addrman, initialize_addrman)
|
||||
}
|
||||
const std::optional<CNetAddr> opt_net_addr = ConsumeDeserializable<CNetAddr>(fuzzed_data_provider);
|
||||
if (opt_net_addr) {
|
||||
addr_man.Add(addresses, *opt_net_addr, fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 100000000));
|
||||
addr_man.Add(addresses, *opt_net_addr, std::chrono::seconds{ConsumeTime(fuzzed_data_provider, 0, 100000000)});
|
||||
}
|
||||
},
|
||||
[&] {
|
||||
const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
|
||||
if (opt_service) {
|
||||
addr_man.Good(*opt_service, ConsumeTime(fuzzed_data_provider));
|
||||
addr_man.Good(*opt_service, NodeSeconds{std::chrono::seconds{ConsumeTime(fuzzed_data_provider)}});
|
||||
}
|
||||
},
|
||||
[&] {
|
||||
const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
|
||||
if (opt_service) {
|
||||
addr_man.Attempt(*opt_service, fuzzed_data_provider.ConsumeBool(), ConsumeTime(fuzzed_data_provider));
|
||||
addr_man.Attempt(*opt_service, fuzzed_data_provider.ConsumeBool(), NodeSeconds{std::chrono::seconds{ConsumeTime(fuzzed_data_provider)}});
|
||||
}
|
||||
},
|
||||
[&] {
|
||||
const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
|
||||
if (opt_service) {
|
||||
addr_man.Connected(*opt_service, ConsumeTime(fuzzed_data_provider));
|
||||
addr_man.Connected(*opt_service, NodeSeconds{std::chrono::seconds{ConsumeTime(fuzzed_data_provider)}});
|
||||
}
|
||||
},
|
||||
[&] {
|
||||
|
@ -390,6 +390,11 @@ bool ContainsSpentInput(const CTransaction& tx, const CCoinsViewCache& inputs) n
|
||||
return false;
|
||||
}
|
||||
|
||||
CAddress ConsumeAddress(FuzzedDataProvider& fuzzed_data_provider) noexcept
|
||||
{
|
||||
return {ConsumeService(fuzzed_data_provider), ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS), NodeSeconds{std::chrono::seconds{fuzzed_data_provider.ConsumeIntegral<uint32_t>()}}};
|
||||
}
|
||||
|
||||
FILE* FuzzedFileProvider::open()
|
||||
{
|
||||
SetFuzzedErrNo(m_fuzzed_data_provider);
|
||||
|
@ -307,10 +307,7 @@ inline CService ConsumeService(FuzzedDataProvider& fuzzed_data_provider) noexcep
|
||||
return {ConsumeNetAddr(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<uint16_t>()};
|
||||
}
|
||||
|
||||
inline CAddress ConsumeAddress(FuzzedDataProvider& fuzzed_data_provider) noexcept
|
||||
{
|
||||
return {ConsumeService(fuzzed_data_provider), ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS), fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
|
||||
}
|
||||
CAddress ConsumeAddress(FuzzedDataProvider& fuzzed_data_provider) noexcept;
|
||||
|
||||
template <bool ReturnUniquePtr = false>
|
||||
auto ConsumeNode(FuzzedDataProvider& fuzzed_data_provider, const std::optional<NodeId>& node_id_in = std::nullopt) noexcept
|
||||
|
@ -337,21 +337,21 @@ BOOST_AUTO_TEST_CASE(netbase_getgroup)
|
||||
// try a few edge cases for port, service flags and time.
|
||||
|
||||
static const std::vector<CAddress> fixture_addresses({
|
||||
CAddress(
|
||||
CAddress{
|
||||
CService(CNetAddr(in6_addr(IN6ADDR_LOOPBACK_INIT)), 0 /* port */),
|
||||
NODE_NONE,
|
||||
0x4966bc61U /* Fri Jan 9 02:54:25 UTC 2009 */
|
||||
),
|
||||
CAddress(
|
||||
NodeSeconds{0x4966bc61s}, /* Fri Jan 9 02:54:25 UTC 2009 */
|
||||
},
|
||||
CAddress{
|
||||
CService(CNetAddr(in6_addr(IN6ADDR_LOOPBACK_INIT)), 0x00f1 /* port */),
|
||||
NODE_NETWORK,
|
||||
0x83766279U /* Tue Nov 22 11:22:33 UTC 2039 */
|
||||
),
|
||||
CAddress(
|
||||
NodeSeconds{0x83766279s}, /* Tue Nov 22 11:22:33 UTC 2039 */
|
||||
},
|
||||
CAddress{
|
||||
CService(CNetAddr(in6_addr(IN6ADDR_LOOPBACK_INIT)), 0xf1f2 /* port */),
|
||||
static_cast<ServiceFlags>(NODE_NETWORK_LIMITED),
|
||||
0xffffffffU /* Sun Feb 7 06:28:15 UTC 2106 */
|
||||
)
|
||||
NodeSeconds{0xffffffffs}, /* Sun Feb 7 06:28:15 UTC 2106 */
|
||||
},
|
||||
});
|
||||
|
||||
// fixture_addresses should equal to this when serialized in V1 format.
|
||||
|
@ -5,9 +5,12 @@
|
||||
#ifndef BITCOIN_TIMEDATA_H
|
||||
#define BITCOIN_TIMEDATA_H
|
||||
|
||||
#include <util/time.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <cassert>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
static const int64_t DEFAULT_MAX_TIME_ADJUSTMENT = 70 * 60;
|
||||
@ -73,6 +76,7 @@ public:
|
||||
/** Functions to keep track of adjusted P2P time */
|
||||
int64_t GetTimeOffset();
|
||||
int64_t GetAdjustedTime();
|
||||
inline NodeSeconds AdjustedTime() { return Now<NodeSeconds>() + std::chrono::seconds{GetTimeOffset()}; }
|
||||
void AddTimeData(const CNetAddr& ip, int64_t nTime);
|
||||
|
||||
/**
|
||||
|
@ -55,6 +55,7 @@ constexpr int64_t count_seconds(std::chrono::seconds t) { return t.count(); }
|
||||
constexpr int64_t count_milliseconds(std::chrono::milliseconds t) { return t.count(); }
|
||||
constexpr int64_t count_microseconds(std::chrono::microseconds t) { return t.count(); }
|
||||
|
||||
using HoursDouble = std::chrono::duration<double, std::chrono::hours::period>;
|
||||
using SecondsDouble = std::chrono::duration<double, std::chrono::seconds::period>;
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user