Skip to content

Commit 69e091f

Browse files
committed
[init] Create deterministic addrman in tests using -test=addrman
Supposing there are 2 different addresses to be placed in an addrman table. During every test run, a different [bucket,position] would be calculated for each address. These calculated [bucket,position] could end up being the same for the 2 different addresses in some test runs and result in collisions in the addrman. We wouldn't be able to predict when the collisions are going to happen because we can't predict the nKey value which is chosen at random. This can cause flaky tests. Improve this by allowing deterministic addrman creation in the functional tests. This creates an addrman with fixed `nKey` = 1 and we can know the [bucket,position] collisions beforehand, safely add more addresses in an addrman table and write more extensive tests.
1 parent be25ac3 commit 69e091f

File tree

2 files changed

+6
-3
lines changed

2 files changed

+6
-3
lines changed

src/addrdb.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,9 @@ void ReadFromStream(AddrMan& addr, DataStream& ssPeers)
185185
util::Result<std::unique_ptr<AddrMan>> LoadAddrman(const NetGroupManager& netgroupman, const ArgsManager& args)
186186
{
187187
auto check_addrman = std::clamp<int32_t>(args.GetIntArg("-checkaddrman", DEFAULT_ADDRMAN_CONSISTENCY_CHECKS), 0, 1000000);
188-
auto addrman{std::make_unique<AddrMan>(netgroupman, /*deterministic=*/false, /*consistency_check_ratio=*/check_addrman)};
188+
bool deterministic = HasTestOption(args, "addrman"); // use a deterministic addrman only for tests
189+
190+
auto addrman{std::make_unique<AddrMan>(netgroupman, /*deterministic=*/deterministic, /*consistency_check_ratio=*/check_addrman)};
189191

190192
const auto start{SteadyClock::now()};
191193
const auto path_addr{args.GetDataDirNet() / "peers.dat"};
@@ -194,15 +196,15 @@ util::Result<std::unique_ptr<AddrMan>> LoadAddrman(const NetGroupManager& netgro
194196
LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman->Size(), Ticks<std::chrono::milliseconds>(SteadyClock::now() - start));
195197
} catch (const DbNotFoundError&) {
196198
// Addrman can be in an inconsistent state after failure, reset it
197-
addrman = std::make_unique<AddrMan>(netgroupman, /*deterministic=*/false, /*consistency_check_ratio=*/check_addrman);
199+
addrman = std::make_unique<AddrMan>(netgroupman, /*deterministic=*/deterministic, /*consistency_check_ratio=*/check_addrman);
198200
LogPrintf("Creating peers.dat because the file was not found (%s)\n", fs::quoted(fs::PathToString(path_addr)));
199201
DumpPeerAddresses(args, *addrman);
200202
} catch (const InvalidAddrManVersionError&) {
201203
if (!RenameOver(path_addr, (fs::path)path_addr + ".bak")) {
202204
return util::Error{strprintf(_("Failed to rename invalid peers.dat file. Please move or delete it and try again."))};
203205
}
204206
// Addrman can be in an inconsistent state after failure, reset it
205-
addrman = std::make_unique<AddrMan>(netgroupman, /*deterministic=*/false, /*consistency_check_ratio=*/check_addrman);
207+
addrman = std::make_unique<AddrMan>(netgroupman, /*deterministic=*/deterministic, /*consistency_check_ratio=*/check_addrman);
206208
LogPrintf("Creating new peers.dat because the file version was not compatible (%s). Original backed up to peers.dat.bak\n", fs::quoted(fs::PathToString(path_addr)));
207209
DumpPeerAddresses(args, *addrman);
208210
} catch (const std::exception& e) {

src/common/args.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,7 @@ std::string HelpMessageOpt(const std::string &option, const std::string &message
683683
}
684684

685685
const std::vector<std::string> TEST_OPTIONS_DOC{
686+
"addrman (use deterministic addrman)",
686687
};
687688

688689
bool HasTestOption(const ArgsManager& args, const std::string& test_option)

0 commit comments

Comments
 (0)