Skip to content

Commit

Permalink
Merge bitcoin#27745: addrman: select addresses by network follow-up
Browse files Browse the repository at this point in the history
cd8ef5b test: ensure addrman test is finite (Amiti Uttarwar)
b9f1e86 addrman: change asserts to Assumes (Amiti Uttarwar)
7687707 doc: update `Select` function description (Amiti Uttarwar)
2b6bd12 refactor: de-duplicate lookups (Amiti Uttarwar)

Pull request description:

  this PR addresses outstanding review comments from bitcoin#27214

ACKs for top commit:
  achow101:
    ACK cd8ef5b
  mzumsande:
    Code Review ACK cd8ef5b
  brunoerg:
    crACK cd8ef5b

Tree-SHA512: 669f67904263e3f51c39b175eabf5fa1b1e7b6841e889656afec33d0bd93fb446de9403f0a91b186ddeaf29498c8938484a0547b1188256c4e7c90db6f30bb55
  • Loading branch information
achow101 authored and sidhujag committed Jul 1, 2023
1 parent 53b7270 commit f70e00d
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 19 deletions.
28 changes: 13 additions & 15 deletions src/addrman.cpp
Expand Up @@ -756,16 +756,14 @@ std::pair<CAddress, NodeSeconds> AddrManImpl::Select_(bool new_only, std::option

// Iterate over the positions of that bucket, starting at the initial one,
// and looping around.
int i;
int i, position, node_id;
for (i = 0; i < ADDRMAN_BUCKET_SIZE; ++i) {
int position = (initial_position + i) % ADDRMAN_BUCKET_SIZE;
int node_id = GetEntry(search_tried, bucket, position);
position = (initial_position + i) % ADDRMAN_BUCKET_SIZE;
node_id = GetEntry(search_tried, bucket, position);
if (node_id != -1) {
if (network.has_value()) {
const auto it{mapInfo.find(node_id)};
assert(it != mapInfo.end());
const auto info{it->second};
if (info.GetNetwork() == *network) break;
if (Assume(it != mapInfo.end()) && it->second.GetNetwork() == *network) break;
} else {
break;
}
Expand All @@ -776,9 +774,7 @@ std::pair<CAddress, NodeSeconds> AddrManImpl::Select_(bool new_only, std::option
if (i == ADDRMAN_BUCKET_SIZE) continue;

// Find the entry to return.
int position = (initial_position + i) % ADDRMAN_BUCKET_SIZE;
int nId = GetEntry(search_tried, bucket, position);
const auto it_found{mapInfo.find(nId)};
const auto it_found{mapInfo.find(node_id)};
assert(it_found != mapInfo.end());
const AddrInfo& info{it_found->second};

Expand All @@ -797,15 +793,17 @@ int AddrManImpl::GetEntry(bool use_tried, size_t bucket, size_t position) const
{
AssertLockHeld(cs);

assert(position < ADDRMAN_BUCKET_SIZE);

if (use_tried) {
assert(bucket < ADDRMAN_TRIED_BUCKET_COUNT);
return vvTried[bucket][position];
if (Assume(position < ADDRMAN_BUCKET_SIZE) && Assume(bucket < ADDRMAN_TRIED_BUCKET_COUNT)) {
return vvTried[bucket][position];
}
} else {
assert(bucket < ADDRMAN_NEW_BUCKET_COUNT);
return vvNew[bucket][position];
if (Assume(position < ADDRMAN_BUCKET_SIZE) && Assume(bucket < ADDRMAN_NEW_BUCKET_COUNT)) {
return vvNew[bucket][position];
}
}

return -1;
}

std::vector<CAddress> AddrManImpl::GetAddr_(size_t max_addresses, size_t max_pct, std::optional<Network> network) const
Expand Down
6 changes: 4 additions & 2 deletions src/addrman.h
Expand Up @@ -148,8 +148,10 @@ class AddrMan
*
* @param[in] new_only Whether to only select addresses from the new table. Passing `true` returns
* an address from the new table or an empty pair. Passing `false` will return an
* address from either the new or tried table (it does not guarantee a tried entry).
* @param[in] network Select only addresses of this network (nullopt = all)
* empty pair or an address from either the new or tried table (it does not
* guarantee a tried entry).
* @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.
* seconds The last time we attempted to connect to that peer.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/addrman_impl.h
Expand Up @@ -255,7 +255,7 @@ class AddrManImpl

/** Helper to generalize looking up an addrman entry from either table.
*
* @return int The nid of the entry or -1 if the addrman position is empty.
* @return int The nid of the entry. If the addrman position is empty or not found, returns -1.
* */
int GetEntry(bool use_tried, size_t bucket, size_t position) const EXCLUSIVE_LOCKS_REQUIRED(cs);

Expand Down
6 changes: 5 additions & 1 deletion src/test/addrman_tests.cpp
Expand Up @@ -239,8 +239,9 @@ BOOST_AUTO_TEST_CASE(addrman_select_by_network)
// ensure that both new and tried table are selected from
bool new_selected{false};
bool tried_selected{false};
int counter = 256;

while (!new_selected || !tried_selected) {
while (--counter > 0 && (!new_selected || !tried_selected)) {
const CAddress selected{addrman->Select(/*new_only=*/false, NET_I2P).first};
BOOST_REQUIRE(selected == i2p_addr || selected == i2p_addr2);
if (selected == i2p_addr) {
Expand All @@ -249,6 +250,9 @@ BOOST_AUTO_TEST_CASE(addrman_select_by_network)
new_selected = true;
}
}

BOOST_CHECK(new_selected);
BOOST_CHECK(tried_selected);
}

BOOST_AUTO_TEST_CASE(addrman_select_special)
Expand Down

0 comments on commit f70e00d

Please sign in to comment.