Skip to content

Commit 40fdb9e

Browse files
author
MarcoFalke
committed
Merge bitcoin/bitcoin#23713: refactor, test: refactor addrman_tried_collisions test to directly check for collisions
caac999 refactor: remove dependence on AddrManTest (josibake) f961c47 refactor: check Good() in tried_collisions test (josibake) 207f1c8 refactor: make AddrMan::Good return bool (josibake) Pull request description: Previously, the `addrman_tried_collisions` test behaved in the following way: 1. add an address to addrman 2. attempt to move the new address to the tried table (using `AddrMan.Good()`) 3. verify that `num_addrs` matched `size()` to check for collisions in the new table `AddrMan.size()`, however, returns the number of unique address in addrman, regardless of whether they are in new or tried. This means the test would still pass for addresses where a collision did occur in the tried table. After 3 collisions in the tried table, there would eventually be a collision in the new table when trying to add a new address, which was then detected by checking `num_addrs - collisions == size()`. While the collision in the new table was caused by a collision in the tried table, the test is misleading as it's not directly testing for collisions in the tried table and misses 3 collisions before identifying a collision in the new table. ### solution To more directly test the tried table, I refactored `AddrMan::Good()` to return a boolean after successfully adding an address to the tried table. This makes the test much cleaner by first adding an address to new, calling `Good` to move it to the tried table, and checking if it was successful or not. It is worth noting there are other reasons, aside from collisions, which will cause `Good` to return false. That being said, this is an improvement over the previous testing methodology. Additionally, having `Good()` return a boolean is useful outside of testing as it allows the caller to handle the case where `Good` is unable to move the entry to the tried table (e.g https://github.com/bitcoin/bitcoin/blob/a06364741358feae04813050e4225eb43fc386e3/src/rpc/net.cpp#L945). ### followup As a follow up to this PR, I plan to look at the following places `Good()` is called and see if it makes sense to handle the case where it is unable to add an entry to tried: * https://github.com/bitcoin/bitcoin/blob/a06364741358feae04813050e4225eb43fc386e3/src/rpc/net.cpp#L945 * https://github.com/bitcoin/bitcoin/blob/a06364741358feae04813050e4225eb43fc386e3/src/net.cpp#L2067 * https://github.com/bitcoin/bitcoin/blob/a06364741358feae04813050e4225eb43fc386e3/src/net_processing.cpp#L2708 ACKs for top commit: jnewbery: utACK caac999 mzumsande: Code review ACK caac999 Tree-SHA512: f328896b1f095e8d2581fcdbddce46fc0491731a0440c6fff01081fa5696cfb896dbbe1d183eda2c100f19aa111e1f8b096ef93582197edc6b791de563a58f99
2 parents 9015d11 + caac999 commit 40fdb9e

File tree

4 files changed

+35
-29
lines changed

4 files changed

+35
-29
lines changed

src/addrman.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ bool AddrManImpl::AddSingle(const CAddress& addr, const CNetAddr& source, int64_
614614
return fInsert;
615615
}
616616

617-
void AddrManImpl::Good_(const CService& addr, bool test_before_evict, int64_t nTime)
617+
bool AddrManImpl::Good_(const CService& addr, bool test_before_evict, int64_t nTime)
618618
{
619619
AssertLockHeld(cs);
620620

@@ -625,8 +625,7 @@ void AddrManImpl::Good_(const CService& addr, bool test_before_evict, int64_t nT
625625
AddrInfo* pinfo = Find(addr, &nId);
626626

627627
// if not found, bail out
628-
if (!pinfo)
629-
return;
628+
if (!pinfo) return false;
630629

631630
AddrInfo& info = *pinfo;
632631

@@ -638,13 +637,11 @@ void AddrManImpl::Good_(const CService& addr, bool test_before_evict, int64_t nT
638637
// currently-connected peers.
639638

640639
// if it is already in the tried set, don't do anything else
641-
if (info.fInTried)
642-
return;
640+
if (info.fInTried) return false;
643641

644642
// if it is not in new, something bad happened
645-
if (!Assume(info.nRefCount > 0)) {
646-
return;
647-
}
643+
if (!Assume(info.nRefCount > 0)) return false;
644+
648645

649646
// which tried bucket to move the entry to
650647
int tried_bucket = info.GetTriedBucket(nKey, m_asmap);
@@ -661,11 +658,13 @@ void AddrManImpl::Good_(const CService& addr, bool test_before_evict, int64_t nT
661658
colliding_entry != mapInfo.end() ? colliding_entry->second.ToString() : "",
662659
addr.ToString(),
663660
m_tried_collisions.size());
661+
return false;
664662
} else {
665663
// move nId to the tried tables
666664
MakeTried(info, nId);
667665
LogPrint(BCLog::ADDRMAN, "Moved %s mapped to AS%i to tried[%i][%i]\n",
668666
addr.ToString(), addr.GetMappedAS(m_asmap), tried_bucket, tried_bucket_pos);
667+
return true;
669668
}
670669
}
671670

@@ -1049,12 +1048,13 @@ bool AddrManImpl::Add(const std::vector<CAddress>& vAddr, const CNetAddr& source
10491048
return ret;
10501049
}
10511050

1052-
void AddrManImpl::Good(const CService& addr, int64_t nTime)
1051+
bool AddrManImpl::Good(const CService& addr, int64_t nTime)
10531052
{
10541053
LOCK(cs);
10551054
Check();
1056-
Good_(addr, /* test_before_evict */ true, nTime);
1055+
auto ret = Good_(addr, /*test_before_evict=*/true, nTime);
10571056
Check();
1057+
return ret;
10581058
}
10591059

10601060
void AddrManImpl::Attempt(const CService& addr, bool fCountFailure, int64_t nTime)
@@ -1157,9 +1157,9 @@ bool AddrMan::Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, in
11571157
return m_impl->Add(vAddr, source, nTimePenalty);
11581158
}
11591159

1160-
void AddrMan::Good(const CService& addr, int64_t nTime)
1160+
bool AddrMan::Good(const CService& addr, int64_t nTime)
11611161
{
1162-
m_impl->Good(addr, nTime);
1162+
return m_impl->Good(addr, nTime);
11631163
}
11641164

11651165
void AddrMan::Attempt(const CService& addr, bool fCountFailure, int64_t nTime)

src/addrman.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,14 @@ class AddrMan
8181
* @return true if at least one address is successfully added. */
8282
bool Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, int64_t nTimePenalty = 0);
8383

84-
//! Mark an entry as accessible, possibly moving it from "new" to "tried".
85-
void Good(const CService& addr, int64_t nTime = GetAdjustedTime());
84+
/**
85+
* Mark an address record as accessible and attempt to move it to addrman's tried table.
86+
*
87+
* @param[in] addr Address record to attempt to move to tried table.
88+
* @param[in] nTime The time that we were last connected to this peer.
89+
* @return true if the address is successfully moved from the new table to the tried table.
90+
*/
91+
bool Good(const CService& addr, int64_t nTime = GetAdjustedTime());
8692

8793
//! Mark an entry as connection attempted to.
8894
void Attempt(const CService& addr, bool fCountFailure, int64_t nTime = GetAdjustedTime());

src/addrman_impl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ class AddrManImpl
115115
bool Add(const std::vector<CAddress>& vAddr, const CNetAddr& source, int64_t nTimePenalty)
116116
EXCLUSIVE_LOCKS_REQUIRED(!cs);
117117

118-
void Good(const CService& addr, int64_t nTime)
118+
bool Good(const CService& addr, int64_t nTime)
119119
EXCLUSIVE_LOCKS_REQUIRED(!cs);
120120

121121
void Attempt(const CService& addr, bool fCountFailure, int64_t nTime)
@@ -248,7 +248,7 @@ class AddrManImpl
248248
* @see AddrMan::Add() for parameters. */
249249
bool AddSingle(const CAddress& addr, const CNetAddr& source, int64_t nTimePenalty) EXCLUSIVE_LOCKS_REQUIRED(cs);
250250

251-
void Good_(const CService& addr, bool test_before_evict, int64_t time) EXCLUSIVE_LOCKS_REQUIRED(cs);
251+
bool Good_(const CService& addr, bool test_before_evict, int64_t time) EXCLUSIVE_LOCKS_REQUIRED(cs);
252252

253253
bool Add_(const std::vector<CAddress> &vAddr, const CNetAddr& source, int64_t nTimePenalty) EXCLUSIVE_LOCKS_REQUIRED(cs);
254254

src/test/addrman_tests.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -268,32 +268,32 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions)
268268

269269
BOOST_AUTO_TEST_CASE(addrman_tried_collisions)
270270
{
271-
AddrManTest addrman;
271+
auto addrman = std::make_unique<AddrMan>(std::vector<bool>(), /*deterministic=*/true, /*consistency_check_ratio=*/100);
272272

273273
CNetAddr source = ResolveIP("252.2.2.2");
274274

275275
uint32_t num_addrs{0};
276276

277-
BOOST_CHECK_EQUAL(addrman.size(), num_addrs);
277+
BOOST_CHECK_EQUAL(addrman->size(), num_addrs);
278278

279-
while (num_addrs < 64) { // Magic number! 250.1.1.1 - 250.1.1.64 do not collide with deterministic key = 1
279+
while (num_addrs < 35) { // Magic number! 250.1.1.1 - 250.1.1.35 do not collide in tried with deterministic key = 1
280280
CService addr = ResolveService("250.1.1." + ToString(++num_addrs));
281-
BOOST_CHECK(addrman.Add({CAddress(addr, NODE_NONE)}, source));
282-
addrman.Good(CAddress(addr, NODE_NONE));
281+
BOOST_CHECK(addrman->Add({CAddress(addr, NODE_NONE)}, source));
282+
283+
// Test: Add to tried without collision
284+
BOOST_CHECK(addrman->Good(CAddress(addr, NODE_NONE)));
283285

284-
// Test: No collision in tried table yet.
285-
BOOST_CHECK_EQUAL(addrman.size(), num_addrs);
286286
}
287287

288-
// Test: tried table collision!
288+
// Test: Unable to add to tried table due to collision!
289289
CService addr1 = ResolveService("250.1.1." + ToString(++num_addrs));
290-
uint32_t collisions{1};
291-
BOOST_CHECK(!addrman.Add({CAddress(addr1, NODE_NONE)}, source));
292-
BOOST_CHECK_EQUAL(addrman.size(), num_addrs - collisions);
290+
BOOST_CHECK(addrman->Add({CAddress(addr1, NODE_NONE)}, source));
291+
BOOST_CHECK(!addrman->Good(CAddress(addr1, NODE_NONE)));
293292

293+
// Test: Add the next address to tried without collision
294294
CService addr2 = ResolveService("250.1.1." + ToString(++num_addrs));
295-
BOOST_CHECK(addrman.Add({CAddress(addr2, NODE_NONE)}, source));
296-
BOOST_CHECK_EQUAL(addrman.size(), num_addrs - collisions);
295+
BOOST_CHECK(addrman->Add({CAddress(addr2, NODE_NONE)}, source));
296+
BOOST_CHECK(addrman->Good(CAddress(addr2, NODE_NONE)));
297297
}
298298

299299
BOOST_AUTO_TEST_CASE(addrman_find)

0 commit comments

Comments
 (0)