Skip to content

Commit 9ba7375

Browse files
committed
Merge bitcoin/bitcoin#24697: refactor address relay time
fa64dd6 refactor: Use type-safe std::chrono for addrman time (MarcoFalke) fa2ae37 Add type-safe AdjustedTime() getter to timedata (MarcoFalke) fa5103a Add ChronoFormatter to serialize (MarcoFalke) fa253d3 util: Add HoursDouble (MarcoFalke) fa21fc6 scripted-diff: Rename addrman time symbols (MarcoFalke) fa9284c refactor: Remove not needed std::max (MacroFake) Pull request description: Those refactors are overlapping with, but otherwise largely unrelated to #24662. ACKs for top commit: naumenkogs: utACK fa64dd6 dergoegge: Code review ACK fa64dd6 Tree-SHA512: a50625e78036e7220a11997e6d9b6c6b317cb38ce02b1835fb41cbee2d8bfb1faf29b29d8990be78d6b5e15e9a9d8dec33bf25fa439b47610ef708950969724b
2 parents 687aba8 + fa64dd6 commit 9ba7375

17 files changed

+207
-167
lines changed

src/addrman.cpp

Lines changed: 78 additions & 71 deletions
Large diffs are not rendered by default.

src/addrman.h

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <protocol.h>
1212
#include <streams.h>
1313
#include <timedata.h>
14+
#include <util/time.h>
1415

1516
#include <cstdint>
1617
#include <memory>
@@ -107,23 +108,23 @@ class AddrMan
107108
*
108109
* @param[in] vAddr Address records to attempt to add.
109110
* @param[in] source The address of the node that sent us these addr records.
110-
* @param[in] nTimePenalty A "time penalty" to apply to the address record's nTime. If a peer
111+
* @param[in] time_penalty A "time penalty" to apply to the address record's nTime. If a peer
111112
* sends us an address record with nTime=n, then we'll add it to our
112-
* addrman with nTime=(n - nTimePenalty).
113+
* addrman with nTime=(n - time_penalty).
113114
* @return true if at least one address is successfully added. */
114-
bool Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, int64_t nTimePenalty = 0);
115+
bool Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, std::chrono::seconds time_penalty = 0s);
115116

116117
/**
117118
* Mark an address record as accessible and attempt to move it to addrman's tried table.
118119
*
119120
* @param[in] addr Address record to attempt to move to tried table.
120-
* @param[in] nTime The time that we were last connected to this peer.
121+
* @param[in] time The time that we were last connected to this peer.
121122
* @return true if the address is successfully moved from the new table to the tried table.
122123
*/
123-
bool Good(const CService& addr, int64_t nTime = GetAdjustedTime());
124+
bool Good(const CService& addr, NodeSeconds time = AdjustedTime());
124125

125126
//! Mark an entry as connection attempted to.
126-
void Attempt(const CService& addr, bool fCountFailure, int64_t nTime = GetAdjustedTime());
127+
void Attempt(const CService& addr, bool fCountFailure, NodeSeconds time = AdjustedTime());
127128

128129
//! See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
129130
void ResolveCollisions();
@@ -133,18 +134,18 @@ class AddrMan
133134
* attempting to evict.
134135
*
135136
* @return CAddress The record for the selected tried peer.
136-
* int64_t The last time we attempted to connect to that peer.
137+
* seconds The last time we attempted to connect to that peer.
137138
*/
138-
std::pair<CAddress, int64_t> SelectTriedCollision();
139+
std::pair<CAddress, NodeSeconds> SelectTriedCollision();
139140

140141
/**
141142
* Choose an address to connect to.
142143
*
143144
* @param[in] newOnly Whether to only select addresses from the new table.
144145
* @return CAddress The record for the selected peer.
145-
* int64_t The last time we attempted to connect to that peer.
146+
* seconds The last time we attempted to connect to that peer.
146147
*/
147-
std::pair<CAddress, int64_t> Select(bool newOnly = false) const;
148+
std::pair<CAddress, NodeSeconds> Select(bool newOnly = false) const;
148149

149150
/**
150151
* Return all or many randomly selected addresses, optionally by network.
@@ -166,9 +167,9 @@ class AddrMan
166167
* not leak information about currently connected peers.
167168
*
168169
* @param[in] addr The address of the peer we were connected to
169-
* @param[in] nTime The time that we were last connected to this peer
170+
* @param[in] time The time that we were last connected to this peer
170171
*/
171-
void Connected(const CService& addr, int64_t nTime = GetAdjustedTime());
172+
void Connected(const CService& addr, NodeSeconds time = AdjustedTime());
172173

173174
//! Update an entry's service bits.
174175
void SetServices(const CService& addr, ServiceFlags nServices);

src/addrman_impl.h

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
#include <protocol.h>
1212
#include <serialize.h>
1313
#include <sync.h>
14+
#include <timedata.h>
1415
#include <uint256.h>
16+
#include <util/time.h>
1517

1618
#include <cstdint>
1719
#include <optional>
@@ -38,16 +40,16 @@ class AddrInfo : public CAddress
3840
{
3941
public:
4042
//! last try whatsoever by us (memory only)
41-
int64_t nLastTry{0};
43+
NodeSeconds m_last_try{0s};
4244

4345
//! last counted attempt (memory only)
44-
int64_t nLastCountAttempt{0};
46+
NodeSeconds m_last_count_attempt{0s};
4547

4648
//! where knowledge about this address first came from
4749
CNetAddr source;
4850

4951
//! last successful connection by us
50-
int64_t nLastSuccess{0};
52+
NodeSeconds m_last_success{0s};
5153

5254
//! connection attempts since last successful attempt
5355
int nAttempts{0};
@@ -64,7 +66,7 @@ class AddrInfo : public CAddress
6466
SERIALIZE_METHODS(AddrInfo, obj)
6567
{
6668
READWRITEAS(CAddress, obj);
67-
READWRITE(obj.source, obj.nLastSuccess, obj.nAttempts);
69+
READWRITE(obj.source, Using<ChronoFormatter<int64_t>>(obj.m_last_success), obj.nAttempts);
6870
}
6971

7072
AddrInfo(const CAddress &addrIn, const CNetAddr &addrSource) : CAddress(addrIn), source(addrSource)
@@ -91,10 +93,10 @@ class AddrInfo : public CAddress
9193
int GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const;
9294

9395
//! Determine whether the statistics about this entry are bad enough so that it can just be deleted
94-
bool IsTerrible(int64_t nNow = GetAdjustedTime()) const;
96+
bool IsTerrible(NodeSeconds now = AdjustedTime()) const;
9597

9698
//! Calculate the relative chance this entry should be given when selecting nodes to connect to
97-
double GetChance(int64_t nNow = GetAdjustedTime()) const;
99+
double GetChance(NodeSeconds now = AdjustedTime()) const;
98100
};
99101

100102
class AddrManImpl
@@ -112,26 +114,26 @@ class AddrManImpl
112114

113115
size_t size() const EXCLUSIVE_LOCKS_REQUIRED(!cs);
114116

115-
bool Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, int64_t nTimePenalty)
117+
bool Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, std::chrono::seconds time_penalty)
116118
EXCLUSIVE_LOCKS_REQUIRED(!cs);
117119

118-
bool Good(const CService& addr, int64_t nTime)
120+
bool Good(const CService& addr, NodeSeconds time)
119121
EXCLUSIVE_LOCKS_REQUIRED(!cs);
120122

121-
void Attempt(const CService& addr, bool fCountFailure, int64_t nTime)
123+
void Attempt(const CService& addr, bool fCountFailure, NodeSeconds time)
122124
EXCLUSIVE_LOCKS_REQUIRED(!cs);
123125

124126
void ResolveCollisions() EXCLUSIVE_LOCKS_REQUIRED(!cs);
125127

126-
std::pair<CAddress, int64_t> SelectTriedCollision() EXCLUSIVE_LOCKS_REQUIRED(!cs);
128+
std::pair<CAddress, NodeSeconds> SelectTriedCollision() EXCLUSIVE_LOCKS_REQUIRED(!cs);
127129

128-
std::pair<CAddress, int64_t> Select(bool newOnly) const
130+
std::pair<CAddress, NodeSeconds> Select(bool newOnly) const
129131
EXCLUSIVE_LOCKS_REQUIRED(!cs);
130132

131133
std::vector<CAddress> GetAddr(size_t max_addresses, size_t max_pct, std::optional<Network> network) const
132134
EXCLUSIVE_LOCKS_REQUIRED(!cs);
133135

134-
void Connected(const CService& addr, int64_t nTime)
136+
void Connected(const CService& addr, NodeSeconds time)
135137
EXCLUSIVE_LOCKS_REQUIRED(!cs);
136138

137139
void SetServices(const CService& addr, ServiceFlags nServices)
@@ -202,7 +204,7 @@ class AddrManImpl
202204
int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE] GUARDED_BY(cs);
203205

204206
//! last time Good was called (memory only). Initially set to 1 so that "never" is strictly worse.
205-
int64_t nLastGood GUARDED_BY(cs){1};
207+
NodeSeconds m_last_good GUARDED_BY(cs){1s};
206208

207209
//! Holds addrs inserted into tried table that collide with existing entries. Test-before-evict discipline used to resolve these collisions.
208210
std::set<int> m_tried_collisions;
@@ -233,25 +235,25 @@ class AddrManImpl
233235

234236
/** Attempt to add a single address to addrman's new table.
235237
* @see AddrMan::Add() for parameters. */
236-
bool AddSingle(const CAddress& addr, const CNetAddr& source, int64_t nTimePenalty) EXCLUSIVE_LOCKS_REQUIRED(cs);
238+
bool AddSingle(const CAddress& addr, const CNetAddr& source, std::chrono::seconds time_penalty) EXCLUSIVE_LOCKS_REQUIRED(cs);
237239

238-
bool Good_(const CService& addr, bool test_before_evict, int64_t time) EXCLUSIVE_LOCKS_REQUIRED(cs);
240+
bool Good_(const CService& addr, bool test_before_evict, NodeSeconds time) EXCLUSIVE_LOCKS_REQUIRED(cs);
239241

240-
bool Add_(const std::vector<CAddress> &vAddr, const CNetAddr& source, int64_t nTimePenalty) EXCLUSIVE_LOCKS_REQUIRED(cs);
242+
bool Add_(const std::vector<CAddress>& vAddr, const CNetAddr& source, std::chrono::seconds time_penalty) EXCLUSIVE_LOCKS_REQUIRED(cs);
241243

242-
void Attempt_(const CService& addr, bool fCountFailure, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs);
244+
void Attempt_(const CService& addr, bool fCountFailure, NodeSeconds time) EXCLUSIVE_LOCKS_REQUIRED(cs);
243245

244-
std::pair<CAddress, int64_t> Select_(bool newOnly) const EXCLUSIVE_LOCKS_REQUIRED(cs);
246+
std::pair<CAddress, NodeSeconds> Select_(bool newOnly) const EXCLUSIVE_LOCKS_REQUIRED(cs);
245247

246248
std::vector<CAddress> GetAddr_(size_t max_addresses, size_t max_pct, std::optional<Network> network) const EXCLUSIVE_LOCKS_REQUIRED(cs);
247249

248-
void Connected_(const CService& addr, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs);
250+
void Connected_(const CService& addr, NodeSeconds time) EXCLUSIVE_LOCKS_REQUIRED(cs);
249251

250252
void SetServices_(const CService& addr, ServiceFlags nServices) EXCLUSIVE_LOCKS_REQUIRED(cs);
251253

252254
void ResolveCollisions_() EXCLUSIVE_LOCKS_REQUIRED(cs);
253255

254-
std::pair<CAddress, int64_t> SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs);
256+
std::pair<CAddress, NodeSeconds> SelectTriedCollision_() EXCLUSIVE_LOCKS_REQUIRED(cs);
255257

256258
std::optional<AddressPosition> FindAddressEntry_(const CAddress& addr) EXCLUSIVE_LOCKS_REQUIRED(cs);
257259

src/bench/addrman.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ static void CreateAddresses()
4343

4444
CAddress ret(CService(addr, port), NODE_NETWORK);
4545

46-
ret.nTime = GetAdjustedTime();
46+
ret.nTime = AdjustedTime();
4747

4848
return ret;
4949
};

src/net.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -187,15 +187,15 @@ static std::vector<CAddress> ConvertSeeds(const std::vector<uint8_t> &vSeedsIn)
187187
// it'll get a pile of addresses with newer timestamps.
188188
// Seed nodes are given a random 'last seen time' of between one and two
189189
// weeks ago.
190-
const int64_t nOneWeek = 7*24*60*60;
190+
const auto one_week{7 * 24h};
191191
std::vector<CAddress> vSeedsOut;
192192
FastRandomContext rng;
193193
CDataStream s(vSeedsIn, SER_NETWORK, PROTOCOL_VERSION | ADDRV2_FORMAT);
194194
while (!s.eof()) {
195195
CService endpoint;
196196
s >> endpoint;
197197
CAddress addr{endpoint, GetDesirableServiceFlags(NODE_NONE)};
198-
addr.nTime = GetTime() - rng.randrange(nOneWeek) - nOneWeek;
198+
addr.nTime = rng.rand_uniform_delay(Now<NodeSeconds>() - one_week, -one_week);
199199
LogPrint(BCLog::NET, "Added hardcoded seed: %s\n", addr.ToString());
200200
vSeedsOut.push_back(addr);
201201
}
@@ -452,10 +452,9 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
452452
}
453453
}
454454

455-
/// debug print
456455
LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "trying connection %s lastseen=%.1fhrs\n",
457-
pszDest ? pszDest : addrConnect.ToString(),
458-
pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime) / 3600.0);
456+
pszDest ? pszDest : addrConnect.ToString(),
457+
Ticks<HoursDouble>(pszDest ? 0h : AdjustedTime() - addrConnect.nTime));
459458

460459
// Resolve
461460
const uint16_t default_port{pszDest != nullptr ? Params().GetDefaultPort(pszDest) :
@@ -1469,9 +1468,8 @@ void CConnman::ThreadDNSAddressSeed()
14691468
unsigned int nMaxIPs = 256; // Limits number of IPs learned from a DNS seed
14701469
if (LookupHost(host, vIPs, nMaxIPs, true)) {
14711470
for (const CNetAddr& ip : vIPs) {
1472-
int nOneDay = 24*3600;
14731471
CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()), requiredServiceBits);
1474-
addr.nTime = GetTime() - 3*nOneDay - rng.randrange(4*nOneDay); // use a random age between 3 and 7 days old
1472+
addr.nTime = rng.rand_uniform_delay(Now<NodeSeconds>() - 3 * 24h, -4 * 24h); // use a random age between 3 and 7 days old
14751473
vAdd.push_back(addr);
14761474
found++;
14771475
}
@@ -1737,7 +1735,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
17371735

17381736
addrman.ResolveCollisions();
17391737

1740-
int64_t nANow = GetAdjustedTime();
1738+
const auto nANow{AdjustedTime()};
17411739
int nTries = 0;
17421740
while (!interruptNet)
17431741
{
@@ -1760,7 +1758,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
17601758
break;
17611759

17621760
CAddress addr;
1763-
int64_t addr_last_try{0};
1761+
NodeSeconds addr_last_try{0s};
17641762

17651763
if (fFeeler) {
17661764
// First, try to get a tried table collision address. This returns
@@ -1800,8 +1798,9 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
18001798
continue;
18011799

18021800
// only consider very recently tried nodes after 30 failed attempts
1803-
if (nANow - addr_last_try < 600 && nTries < 30)
1801+
if (nANow - addr_last_try < 10min && nTries < 30) {
18041802
continue;
1803+
}
18051804

18061805
// for non-feelers, require all the services we'll want,
18071806
// for feelers, only require they be a full node (only because most

src/net_processing.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <scheduler.h>
3030
#include <streams.h>
3131
#include <sync.h>
32+
#include <timedata.h>
3233
#include <tinyformat.h>
3334
#include <txmempool.h>
3435
#include <txorphanage.h>
@@ -2929,7 +2930,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
29292930
// indicate to the peer that we will participate in addr relay.
29302931
if (fListen && !m_chainman.ActiveChainstate().IsInitialBlockDownload())
29312932
{
2932-
CAddress addr{GetLocalAddress(pfrom.addr), peer->m_our_services, (uint32_t)GetAdjustedTime()};
2933+
CAddress addr{GetLocalAddress(pfrom.addr), peer->m_our_services, AdjustedTime()};
29332934
FastRandomContext insecure_rand;
29342935
if (addr.IsRoutable())
29352936
{
@@ -3134,8 +3135,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
31343135

31353136
// Store the new addresses
31363137
std::vector<CAddress> vAddrOk;
3137-
int64_t nNow = GetAdjustedTime();
3138-
int64_t nSince = nNow - 10 * 60;
3138+
const auto current_a_time{AdjustedTime()};
31393139

31403140
// Update/increment addr rate limiting bucket.
31413141
const auto current_time{GetTime<std::chrono::microseconds>()};
@@ -3171,16 +3171,17 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
31713171
if (!MayHaveUsefulAddressDB(addr.nServices) && !HasAllDesirableServiceFlags(addr.nServices))
31723172
continue;
31733173

3174-
if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
3175-
addr.nTime = nNow - 5 * 24 * 60 * 60;
3174+
if (addr.nTime <= NodeSeconds{100000000s} || addr.nTime > current_a_time + 10min) {
3175+
addr.nTime = current_a_time - 5 * 24h;
3176+
}
31763177
AddAddressKnown(*peer, addr);
31773178
if (m_banman && (m_banman->IsDiscouraged(addr) || m_banman->IsBanned(addr))) {
31783179
// Do not process banned/discouraged addresses beyond remembering we received them
31793180
continue;
31803181
}
31813182
++num_proc;
31823183
bool fReachable = IsReachable(addr);
3183-
if (addr.nTime > nSince && !peer->m_getaddr_sent && vAddr.size() <= 10 && addr.IsRoutable()) {
3184+
if (addr.nTime > current_a_time - 10min && !peer->m_getaddr_sent && vAddr.size() <= 10 && addr.IsRoutable()) {
31843185
// Relay to a limited number of other nodes
31853186
RelayAddress(pfrom.GetId(), addr, fReachable);
31863187
}
@@ -3193,7 +3194,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
31933194
LogPrint(BCLog::NET, "Received addr: %u addresses (%u processed, %u rate-limited) from peer=%d\n",
31943195
vAddr.size(), num_proc, num_rate_limit, pfrom.GetId());
31953196

3196-
m_addrman.Add(vAddrOk, pfrom.addr, 2 * 60 * 60);
3197+
m_addrman.Add(vAddrOk, pfrom.addr, 2h);
31973198
if (vAddr.size() < 1000) peer->m_getaddr_sent = false;
31983199

31993200
// AddrFetch: Require multiple addresses to avoid disconnecting on self-announcements
@@ -4685,7 +4686,7 @@ void PeerManagerImpl::MaybeSendAddr(CNode& node, Peer& peer, std::chrono::micros
46854686
peer.m_addr_known->reset();
46864687
}
46874688
if (std::optional<CService> local_service = GetLocalAddrForPeer(node)) {
4688-
CAddress local_addr{*local_service, peer.m_our_services, (uint32_t)GetAdjustedTime()};
4689+
CAddress local_addr{*local_service, peer.m_our_services, AdjustedTime()};
46894690
FastRandomContext insecure_rand;
46904691
PushAddress(peer, local_addr, insecure_rand);
46914692
}

src/node/interfaces.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
#include <shutdown.h>
3737
#include <support/allocators/secure.h>
3838
#include <sync.h>
39-
#include <timedata.h>
4039
#include <txmempool.h>
4140
#include <uint256.h>
4241
#include <univalue.h>

src/protocol.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <serialize.h>
1212
#include <streams.h>
1313
#include <uint256.h>
14+
#include <util/time.h>
1415

1516
#include <cstdint>
1617
#include <limits>
@@ -352,7 +353,7 @@ static inline bool MayHaveUsefulAddressDB(ServiceFlags services)
352353
/** A CService with information about it as peer */
353354
class CAddress : public CService
354355
{
355-
static constexpr uint32_t TIME_INIT{100000000};
356+
static constexpr std::chrono::seconds TIME_INIT{100000000};
356357

357358
/** Historically, CAddress disk serialization stored the CLIENT_VERSION, optionally OR'ed with
358359
* the ADDRV2_FORMAT flag to indicate V2 serialization. The first field has since been
@@ -382,7 +383,7 @@ class CAddress : public CService
382383
public:
383384
CAddress() : CService{} {};
384385
CAddress(CService ipIn, ServiceFlags nServicesIn) : CService{ipIn}, nServices{nServicesIn} {};
385-
CAddress(CService ipIn, ServiceFlags nServicesIn, uint32_t nTimeIn) : CService{ipIn}, nTime{nTimeIn}, nServices{nServicesIn} {};
386+
CAddress(CService ipIn, ServiceFlags nServicesIn, NodeSeconds time) : CService{ipIn}, nTime{time}, nServices{nServicesIn} {};
386387

387388
SERIALIZE_METHODS(CAddress, obj)
388389
{
@@ -415,7 +416,7 @@ class CAddress : public CService
415416
use_v2 = s.GetVersion() & ADDRV2_FORMAT;
416417
}
417418

418-
READWRITE(obj.nTime);
419+
READWRITE(Using<LossyChronoFormatter<uint32_t>>(obj.nTime));
419420
// nServices is serialized as CompactSize in V2; as uint64_t in V1.
420421
if (use_v2) {
421422
uint64_t services_tmp;
@@ -430,8 +431,8 @@ class CAddress : public CService
430431
SerReadWriteMany(os, ser_action, ReadWriteAsHelper<CService>(obj));
431432
}
432433

433-
//! Always included in serialization.
434-
uint32_t nTime{TIME_INIT};
434+
//! Always included in serialization. The behavior is unspecified if the value is not representable as uint32_t.
435+
NodeSeconds nTime{TIME_INIT};
435436
//! Serialized as uint64_t in V1, and as CompactSize in V2.
436437
ServiceFlags nServices{NODE_NONE};
437438

0 commit comments

Comments
 (0)