diff --git a/src/addrman.cpp b/src/addrman.cpp index 52d36cd145..e0b1e3270a 100644 --- a/src/addrman.cpp +++ b/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(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(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 &vAddr, const CNetAddr& source, int64_t nTimePenalty) +bool AddrManImpl::Add_(const std::vector& vAddr, const CNetAddr& source, std::chrono::seconds time_penalty) { int added{0}; for (std::vector::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 &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 AddrManImpl::Select_(bool new_only, std::optional network) const +std::pair AddrManImpl::Select_(bool new_only, std::optional network) const { AssertLockHeld(cs); @@ -780,7 +783,7 @@ std::pair AddrManImpl::Select_(bool new_only, std::optional 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 addresses; for (unsigned int n = 0; n < vRandom.size(); n++) { if (addresses.size() >= nNodes) @@ -843,7 +846,7 @@ std::vector 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 AddrManImpl::SelectTriedCollision_() +std::pair AddrManImpl::SelectTriedCollision_() { AssertLockHeld(cs); @@ -976,7 +980,7 @@ std::pair 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 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(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 net, std::optional in_new) return ret; } -bool AddrManImpl::Add(const std::vector& vAddr, const CNetAddr& source, int64_t nTimePenalty) +bool AddrManImpl::Add(const std::vector& 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 AddrManImpl::SelectTriedCollision() +std::pair AddrManImpl::SelectTriedCollision() { LOCK(cs); Check(); @@ -1193,7 +1200,7 @@ std::pair AddrManImpl::SelectTriedCollision() return ret; } -std::pair AddrManImpl::Select(bool new_only, std::optional network) const +std::pair AddrManImpl::Select(bool new_only, std::optional network) const { LOCK(cs); Check(); @@ -1211,11 +1218,11 @@ std::vector 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 net, std::optional in_new) con return m_impl->Size(net, in_new); } -bool AddrMan::Add(const std::vector& vAddr, const CNetAddr& source, int64_t nTimePenalty) +bool AddrMan::Add(const std::vector& 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 AddrMan::SelectTriedCollision() +std::pair AddrMan::SelectTriedCollision() { return m_impl->SelectTriedCollision(); } -std::pair AddrMan::Select(bool new_only, std::optional network) const +std::pair AddrMan::Select(bool new_only, std::optional network) const { return m_impl->Select(new_only, network); } @@ -1313,9 +1320,9 @@ std::vector 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) diff --git a/src/addrman.h b/src/addrman.h index b432e6afb4..111b38f153 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -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& vAddr, const CNetAddr& source, int64_t nTimePenalty = 0); + bool Add(const std::vector& 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 SelectTriedCollision(); + std::pair 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 Select(bool new_only = false, std::optional network = std::nullopt) const; + std::pair Select(bool new_only = false, std::optional 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); diff --git a/src/addrman_impl.h b/src/addrman_impl.h index a1bf2991f9..825f33567f 100644 --- a/src/addrman_impl.h +++ b/src/addrman_impl.h @@ -11,7 +11,9 @@ #include #include #include +#include #include +#include #include #include @@ -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>(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 net, std::optional in_new) const EXCLUSIVE_LOCKS_REQUIRED(!cs); - bool Add(const std::vector& vAddr, const CNetAddr& source, int64_t nTimePenalty) + bool Add(const std::vector& 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 SelectTriedCollision() EXCLUSIVE_LOCKS_REQUIRED(!cs); + std::pair SelectTriedCollision() EXCLUSIVE_LOCKS_REQUIRED(!cs); - std::pair Select(bool new_only, std::optional network) const + std::pair Select(bool new_only, std::optional network) const EXCLUSIVE_LOCKS_REQUIRED(!cs); std::vector GetAddr(size_t max_addresses, size_t max_pct, std::optional 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 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 &vAddr, const CNetAddr& source, int64_t nTimePenalty) EXCLUSIVE_LOCKS_REQUIRED(cs); + bool Add_(const std::vector& 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 Select_(bool new_only, std::optional network) const EXCLUSIVE_LOCKS_REQUIRED(cs); + std::pair Select_(bool new_only, std::optional network) const EXCLUSIVE_LOCKS_REQUIRED(cs); /** Helper to generalize looking up an addrman entry from either table. * @@ -262,7 +264,7 @@ private: std::vector GetAddr_(size_t max_addresses, size_t max_pct, std::optional 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 SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs); + std::pair SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs); std::optional FindAddressEntry_(const CAddress& addr) EXCLUSIVE_LOCKS_REQUIRED(cs); diff --git a/src/bench/addrman.cpp b/src/bench/addrman.cpp index aaaf671014..94cf6fe702 100644 --- a/src/bench/addrman.cpp +++ b/src/bench/addrman.cpp @@ -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(); const CNetAddr source{LookupHost("252.2.2.2", false).value()}; addrman.Add({i2p_address}, source); diff --git a/src/net.cpp b/src/net.cpp index f3e0455390..8965f784c3 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -232,7 +232,7 @@ static std::vector ConvertSeeds(const std::vector &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 vSeedsOut; FastRandomContext rng; CDataStream s(vSeedsIn, SER_NETWORK, PROTOCOL_VERSION | ADDRV2_FORMAT); @@ -240,7 +240,7 @@ static std::vector ConvertSeeds(const std::vector &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() - 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(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(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() - 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 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 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 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 diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 88b37aa8e7..1830729924 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -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 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()}; @@ -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 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); } diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index 6e7b646eff..ea4bce94d6 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include diff --git a/src/protocol.h b/src/protocol.h index 9d294b82e1..7da040e0df 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -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>(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(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}; diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index ecb1441ee6..922edef604 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -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(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)) { diff --git a/src/serialize.h b/src/serialize.h index 14e56baef4..c8b57ad482 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -704,6 +704,29 @@ struct CompactSizeFormatter } }; +template +struct ChronoFormatter { + template + 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 + 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 +using LossyChronoFormatter = ChronoFormatter; + template struct LimitedStringFormatter { diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index 1e2e3a8b6c..78d6ec9feb 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -309,7 +309,7 @@ BOOST_AUTO_TEST_CASE(addrman_new_multiplicity) { auto addrman = std::make_unique(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 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 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); } diff --git a/src/test/fuzz/addrman.cpp b/src/test/fuzz/addrman.cpp index 0de69455c7..32e5787273 100644 --- a/src/test/fuzz/addrman.cpp +++ b/src/test/fuzz/addrman.cpp @@ -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()); } // 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(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(lhs), lhs.source, lhs.nLastSuccess, lhs.nAttempts, lhs.nRefCount, lhs.fInTried) == - std::tie(static_cast(rhs), rhs.source, rhs.nLastSuccess, rhs.nAttempts, rhs.nRefCount, rhs.fInTried); + return std::tie(static_cast(lhs), lhs.source, lhs.m_last_success, lhs.nAttempts, lhs.nRefCount, lhs.fInTried) == + std::tie(static_cast(rhs), rhs.source, rhs.m_last_success, rhs.nAttempts, rhs.nRefCount, rhs.fInTried); }; using Addresses = std::unordered_set; @@ -279,25 +279,25 @@ FUZZ_TARGET_INIT(addrman, initialize_addrman) } const std::optional opt_net_addr = ConsumeDeserializable(fuzzed_data_provider); if (opt_net_addr) { - addr_man.Add(addresses, *opt_net_addr, fuzzed_data_provider.ConsumeIntegralInRange(0, 100000000)); + addr_man.Add(addresses, *opt_net_addr, std::chrono::seconds{ConsumeTime(fuzzed_data_provider, 0, 100000000)}); } }, [&] { const std::optional opt_service = ConsumeDeserializable(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 opt_service = ConsumeDeserializable(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 opt_service = ConsumeDeserializable(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)}}); } }, [&] { diff --git a/src/test/fuzz/util.cpp b/src/test/fuzz/util.cpp index bd55d99f97..c23151cc50 100644 --- a/src/test/fuzz/util.cpp +++ b/src/test/fuzz/util.cpp @@ -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()}}}; +} + FILE* FuzzedFileProvider::open() { SetFuzzedErrNo(m_fuzzed_data_provider); diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h index f93ee3719c..43864a5453 100644 --- a/src/test/fuzz/util.h +++ b/src/test/fuzz/util.h @@ -307,10 +307,7 @@ inline CService ConsumeService(FuzzedDataProvider& fuzzed_data_provider) noexcep return {ConsumeNetAddr(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral()}; } -inline CAddress ConsumeAddress(FuzzedDataProvider& fuzzed_data_provider) noexcept -{ - return {ConsumeService(fuzzed_data_provider), ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS), fuzzed_data_provider.ConsumeIntegral()}; -} +CAddress ConsumeAddress(FuzzedDataProvider& fuzzed_data_provider) noexcept; template auto ConsumeNode(FuzzedDataProvider& fuzzed_data_provider, const std::optional& node_id_in = std::nullopt) noexcept diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index d9fe06d759..ffaac9144d 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -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 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(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. diff --git a/src/timedata.h b/src/timedata.h index 902b4dc0f8..8c036f1c1a 100644 --- a/src/timedata.h +++ b/src/timedata.h @@ -5,9 +5,12 @@ #ifndef BITCOIN_TIMEDATA_H #define BITCOIN_TIMEDATA_H +#include + #include -#include -#include +#include +#include +#include #include 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() + std::chrono::seconds{GetTimeOffset()}; } void AddTimeData(const CNetAddr& ip, int64_t nTime); /** diff --git a/src/util/time.h b/src/util/time.h index 19d3cbc347..306a1ae3f2 100644 --- a/src/util/time.h +++ b/src/util/time.h @@ -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; using SecondsDouble = std::chrono::duration; /**