Skip to content

Commit a93fec6

Browse files
committed
merge bitcoin#23380: Fix AddrMan::Add() return semantics and logging
1 parent d1a4b14 commit a93fec6

File tree

6 files changed

+95
-82
lines changed

6 files changed

+95
-82
lines changed

src/addrman.cpp

Lines changed: 80 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -552,77 +552,13 @@ void AddrManImpl::MakeTried(AddrInfo& info, int nId)
552552
info.fInTried = true;
553553
}
554554

555-
void AddrManImpl::Good_(const CService& addr, bool test_before_evict, int64_t nTime)
556-
{
557-
AssertLockHeld(cs);
558-
559-
int nId;
560-
561-
nLastGood = nTime;
562-
563-
AddrInfo* pinfo = Find(addr, &nId);
564-
565-
// if not found, bail out
566-
if (!pinfo)
567-
return;
568-
569-
AddrInfo& info = *pinfo;
570-
571-
// check whether we are talking about the exact same CService (including same port)
572-
if (!m_discriminate_ports && info != addr)
573-
return;
574-
575-
// update info
576-
info.nLastSuccess = nTime;
577-
info.nLastTry = nTime;
578-
info.nAttempts = 0;
579-
// nTime is not updated here, to avoid leaking information about
580-
// currently-connected peers.
581-
582-
// if it is already in the tried set, don't do anything else
583-
if (info.fInTried)
584-
return;
585-
586-
// if it is not in new, something bad happened
587-
if (!Assume(info.nRefCount > 0)) {
588-
return;
589-
}
590-
591-
// which tried bucket to move the entry to
592-
int tried_bucket = info.GetTriedBucket(nKey, m_asmap);
593-
int tried_bucket_pos = info.GetBucketPosition(nKey, false, tried_bucket);
594-
595-
// Will moving this address into tried evict another entry?
596-
if (test_before_evict && (vvTried[tried_bucket][tried_bucket_pos] != -1)) {
597-
if (m_tried_collisions.size() < ADDRMAN_SET_TRIED_COLLISION_SIZE) {
598-
m_tried_collisions.insert(nId);
599-
}
600-
// Output the entry we'd be colliding with, for debugging purposes
601-
auto colliding_entry = mapInfo.find(vvTried[tried_bucket][tried_bucket_pos]);
602-
if (fLogIPs) {
603-
LogPrint(BCLog::ADDRMAN, "Collision with %s while attempting to move %s to tried table. Collisions=%d\n",
604-
colliding_entry != mapInfo.end() ? colliding_entry->second.ToString() : "",
605-
addr.ToString(),
606-
m_tried_collisions.size());
607-
}
608-
} else {
609-
// move nId to the tried tables
610-
MakeTried(info, nId);
611-
if (fLogIPs) {
612-
LogPrint(BCLog::ADDRMAN, "Moved %s mapped to AS%i to tried[%i][%i]\n",
613-
addr.ToString(), addr.GetMappedAS(m_asmap), tried_bucket, tried_bucket_pos);
614-
}
615-
}
616-
}
617-
618-
bool AddrManImpl::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimePenalty)
555+
bool AddrManImpl::AddSingle(const CAddress& addr, const CNetAddr& source, int64_t nTimePenalty)
619556
{
620557
AssertLockHeld(cs);
621558

622559
if (!addr.IsRoutable())
623560
return false;
624561

625-
bool fNew = false;
626562
int nId;
627563
AddrInfo* pinfo = Find(addr, &nId);
628564

@@ -665,13 +601,12 @@ bool AddrManImpl::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTi
665601
pinfo = Create(addr, source, &nId);
666602
pinfo->nTime = std::max((int64_t)0, (int64_t)pinfo->nTime - nTimePenalty);
667603
nNew++;
668-
fNew = true;
669604
}
670605

671606
int nUBucket = pinfo->GetNewBucket(nKey, source, m_asmap);
672607
int nUBucketPos = pinfo->GetBucketPosition(nKey, true, nUBucket);
608+
bool fInsert = vvNew[nUBucket][nUBucketPos] == -1;
673609
if (vvNew[nUBucket][nUBucketPos] != nId) {
674-
bool fInsert = vvNew[nUBucket][nUBucketPos] == -1;
675610
if (!fInsert) {
676611
AddrInfo& infoExisting = mapInfo[vvNew[nUBucket][nUBucketPos]];
677612
if (infoExisting.IsTerrible() || (infoExisting.nRefCount > 1 && pinfo->nRefCount == 0)) {
@@ -691,7 +626,82 @@ bool AddrManImpl::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTi
691626
}
692627
}
693628
}
694-
return fNew;
629+
return fInsert;
630+
}
631+
632+
void AddrManImpl::Good_(const CService& addr, bool test_before_evict, int64_t nTime)
633+
{
634+
AssertLockHeld(cs);
635+
636+
int nId;
637+
638+
nLastGood = nTime;
639+
640+
AddrInfo* pinfo = Find(addr, &nId);
641+
642+
// if not found, bail out
643+
if (!pinfo)
644+
return;
645+
646+
AddrInfo& info = *pinfo;
647+
648+
// check whether we are talking about the exact same CService (including same port)
649+
if (!m_discriminate_ports && info != addr)
650+
return;
651+
652+
// update info
653+
info.nLastSuccess = nTime;
654+
info.nLastTry = nTime;
655+
info.nAttempts = 0;
656+
// nTime is not updated here, to avoid leaking information about
657+
// currently-connected peers.
658+
659+
// if it is already in the tried set, don't do anything else
660+
if (info.fInTried)
661+
return;
662+
663+
// if it is not in new, something bad happened
664+
if (!Assume(info.nRefCount > 0)) {
665+
return;
666+
}
667+
668+
// which tried bucket to move the entry to
669+
int tried_bucket = info.GetTriedBucket(nKey, m_asmap);
670+
int tried_bucket_pos = info.GetBucketPosition(nKey, false, tried_bucket);
671+
672+
// Will moving this address into tried evict another entry?
673+
if (test_before_evict && (vvTried[tried_bucket][tried_bucket_pos] != -1)) {
674+
if (m_tried_collisions.size() < ADDRMAN_SET_TRIED_COLLISION_SIZE) {
675+
m_tried_collisions.insert(nId);
676+
}
677+
// Output the entry we'd be colliding with, for debugging purposes
678+
auto colliding_entry = mapInfo.find(vvTried[tried_bucket][tried_bucket_pos]);
679+
if (fLogIPs) {
680+
LogPrint(BCLog::ADDRMAN, "Collision with %s while attempting to move %s to tried table. Collisions=%d\n",
681+
colliding_entry != mapInfo.end() ? colliding_entry->second.ToString() : "",
682+
addr.ToString(),
683+
m_tried_collisions.size());
684+
}
685+
} else {
686+
// move nId to the tried tables
687+
MakeTried(info, nId);
688+
if (fLogIPs) {
689+
LogPrint(BCLog::ADDRMAN, "Moved %s mapped to AS%i to tried[%i][%i]\n",
690+
addr.ToString(), addr.GetMappedAS(m_asmap), tried_bucket, tried_bucket_pos);
691+
}
692+
}
693+
}
694+
695+
bool AddrManImpl::Add_(const std::vector<CAddress> &vAddr, const CNetAddr& source, int64_t nTimePenalty)
696+
{
697+
int added{0};
698+
for (std::vector<CAddress>::const_iterator it = vAddr.begin(); it != vAddr.end(); it++) {
699+
added += AddSingle(*it, source, nTimePenalty) ? 1 : 0;
700+
}
701+
if (added > 0) {
702+
LogPrint(BCLog::ADDRMAN, "Added %i addresses (of %i) from %s: %i tried, %i new\n", added, vAddr.size(), source.ToString(), nTried, nNew);
703+
}
704+
return added > 0;
695705
}
696706

697707
void AddrManImpl::Attempt_(const CService& addr, bool fCountFailure, int64_t nTime)
@@ -1087,15 +1097,10 @@ size_t AddrManImpl::size() const
10871097
bool AddrManImpl::Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, int64_t nTimePenalty)
10881098
{
10891099
LOCK(cs);
1090-
int nAdd = 0;
10911100
Check();
1092-
for (std::vector<CAddress>::const_iterator it = vAddr.begin(); it != vAddr.end(); it++)
1093-
nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0;
1101+
auto ret = Add_(vAddr, source, nTimePenalty);
10941102
Check();
1095-
if (nAdd) {
1096-
LogPrint(BCLog::ADDRMAN, "Added %i addresses from %s: %i tried, %i new\n", nAdd, source.ToString(), nTried, nNew);
1097-
}
1098-
return nAdd > 0;
1103+
return ret;
10991104
}
11001105

11011106
void AddrManImpl::Good(const CService& addr, int64_t nTime)

src/addrman.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,15 @@ class AddrMan
7070
//! Return the number of (unique) addresses in all tables.
7171
size_t size() const;
7272

73-
//! Add addresses to addrman's new table.
73+
/**
74+
* Attempt to add one or more addresses to addrman's new table.
75+
*
76+
* @param[in] vAddr Address records to attempt to add.
77+
* @param[in] source The address of the node that sent us these addr records.
78+
* @param[in] nTimePenalty A "time penalty" to apply to the address record's nTime. If a peer
79+
* sends us an address record with nTime=n, then we'll add it to our
80+
* addrman with nTime=(n - nTimePenalty).
81+
* @return true if at least one address is successfully added. */
7482
bool Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, int64_t nTimePenalty = 0);
7583

7684
//! Mark an entry as accessible, possibly moving it from "new" to "tried".

src/addrman_impl.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,13 @@ class AddrManImpl
248248
//! Move an entry from the "new" table(s) to the "tried" table
249249
void MakeTried(AddrInfo& info, int nId) EXCLUSIVE_LOCKS_REQUIRED(cs);
250250

251+
/** Attempt to add a single address to addrman's new table.
252+
* @see AddrMan::Add() for parameters. */
253+
bool AddSingle(const CAddress& addr, const CNetAddr& source, int64_t nTimePenalty) EXCLUSIVE_LOCKS_REQUIRED(cs);
254+
251255
void Good_(const CService& addr, bool test_before_evict, int64_t time) EXCLUSIVE_LOCKS_REQUIRED(cs);
252256

253-
bool Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimePenalty) EXCLUSIVE_LOCKS_REQUIRED(cs);
257+
bool Add_(const std::vector<CAddress> &vAddr, const CNetAddr& source, int64_t nTimePenalty) EXCLUSIVE_LOCKS_REQUIRED(cs);
254258

255259
void Attempt_(const CService& addr, bool fCountFailure, int64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(cs);
256260

src/test/addrman_tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions)
374374
//Test: tried table collision!
375375
CService addr1 = ResolveService("250.1.1." + ToString(++num_addrs));
376376
uint32_t collisions{1};
377-
BOOST_CHECK(addrman.Add({CAddress(addr1, NODE_NONE)}, source));
377+
BOOST_CHECK(!addrman.Add({CAddress(addr1, NODE_NONE)}, source));
378378
BOOST_CHECK_EQUAL(addrman.size(), num_addrs - collisions);
379379

380380
CService addr2 = ResolveService("250.1.1." + ToString(++num_addrs));

test/functional/p2p_addr_relay.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ def relay_tests(self):
148148
msg = self.setup_addr_msg(num_ipv4_addrs)
149149
with self.nodes[0].assert_debug_log(
150150
[
151-
'Added {} addresses from 127.0.0.1: 0 tried'.format(num_ipv4_addrs),
152151
'received: addr (301 bytes) peer=1',
153152
]
154153
):

test/functional/p2p_addrv2_relay.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,6 @@ def run_test(self):
7474
addr_receiver = self.nodes[0].add_p2p_connection(AddrReceiver())
7575
msg.addrs = ADDRS
7676
with self.nodes[0].assert_debug_log([
77-
# The I2P address is not added to node's own addrman because it has no
78-
# I2P reachability (thus 10 - 1 = 9).
79-
'Added 9 addresses from 127.0.0.1: 0 tried',
8077
'received: addrv2 (159 bytes) peer=1',
8178
]):
8279
addr_source.send_and_ping(msg)

0 commit comments

Comments
 (0)