From 69e091f3e1f65b12cf1804e7d39651f55a01827a Mon Sep 17 00:00:00 2001 From: stratospher <44024636+stratospher@users.noreply.github.com> Date: Wed, 11 Oct 2023 10:51:21 +0530 Subject: [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. --- src/addrdb.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/addrdb.cpp') diff --git a/src/addrdb.cpp b/src/addrdb.cpp index 8cf932bcb6..6bd5a65132 100644 --- a/src/addrdb.cpp +++ b/src/addrdb.cpp @@ -185,7 +185,9 @@ void ReadFromStream(AddrMan& addr, DataStream& ssPeers) util::Result> LoadAddrman(const NetGroupManager& netgroupman, const ArgsManager& args) { auto check_addrman = std::clamp(args.GetIntArg("-checkaddrman", DEFAULT_ADDRMAN_CONSISTENCY_CHECKS), 0, 1000000); - auto addrman{std::make_unique(netgroupman, /*deterministic=*/false, /*consistency_check_ratio=*/check_addrman)}; + bool deterministic = HasTestOption(args, "addrman"); // use a deterministic addrman only for tests + + auto addrman{std::make_unique(netgroupman, /*deterministic=*/deterministic, /*consistency_check_ratio=*/check_addrman)}; const auto start{SteadyClock::now()}; const auto path_addr{args.GetDataDirNet() / "peers.dat"}; @@ -194,7 +196,7 @@ util::Result> LoadAddrman(const NetGroupManager& netgro LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman->Size(), Ticks(SteadyClock::now() - start)); } catch (const DbNotFoundError&) { // Addrman can be in an inconsistent state after failure, reset it - addrman = std::make_unique(netgroupman, /*deterministic=*/false, /*consistency_check_ratio=*/check_addrman); + addrman = std::make_unique(netgroupman, /*deterministic=*/deterministic, /*consistency_check_ratio=*/check_addrman); LogPrintf("Creating peers.dat because the file was not found (%s)\n", fs::quoted(fs::PathToString(path_addr))); DumpPeerAddresses(args, *addrman); } catch (const InvalidAddrManVersionError&) { @@ -202,7 +204,7 @@ util::Result> LoadAddrman(const NetGroupManager& netgro return util::Error{strprintf(_("Failed to rename invalid peers.dat file. Please move or delete it and try again."))}; } // Addrman can be in an inconsistent state after failure, reset it - addrman = std::make_unique(netgroupman, /*deterministic=*/false, /*consistency_check_ratio=*/check_addrman); + addrman = std::make_unique(netgroupman, /*deterministic=*/deterministic, /*consistency_check_ratio=*/check_addrman); 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))); DumpPeerAddresses(args, *addrman); } catch (const std::exception& e) { -- cgit v1.2.3