Skip to content

Commit 97e2435

Browse files
committed
Merge bitcoin/bitcoin#23053: [fuzz] Use public methods in addrman fuzz tests
4445211 [fuzz] Update comment in FillAddrman() (John Newbery) 640476e [fuzz] Make Fill() a free function in fuzz/addrman.cpp (John Newbery) 90ad8ad [fuzz] Make RandAddr() a free function in fuzz/addrman.cpp (John Newbery) 491975c [fuzz] Pass FuzzedDataProvider& into Fill() in addrman fuzz tests (John Newbery) 56303e3 [fuzz] Create a FastRandomContext in addrman fuzz tests (John Newbery) Pull request description: #22974 improved the performance of `CAddrMan::Good()` significantly so that it could be used directly in the fuzz tests, instead of those tests reaching directly into addrman's internal data structures. This PR continues the work of making the fuzz tests only use `CAddrMan`'s public methods and pulls the `Fill()` and `RandAddr()` methods from `CAddrManDeterministic` into free functions, since they no longer need access to `CAddrMan` internals. ACKs for top commit: theuni: utACK 4445211. Agree the failure seems unrelated, looks like some startup race. mzumsande: ACK 4445211 vasild: ACK 4445211 Tree-SHA512: fcf994e1dedd0012b77f632720b6423d51ceda4eb85c9efe572f2a1150117f9e511114a5206738dd94409137287577f3b01a9998f5237de845410d3d96e7cb7f
2 parents 99e5396 + 4445211 commit 97e2435

File tree

1 file changed

+71
-76
lines changed

1 file changed

+71
-76
lines changed

src/test/fuzz/addrman.cpp

Lines changed: 71 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <addrman_impl.h>
88
#include <chainparams.h>
99
#include <merkleblock.h>
10+
#include <random.h>
1011
#include <test/fuzz/FuzzedDataProvider.h>
1112
#include <test/fuzz/fuzz.h>
1213
#include <test/fuzz/util.h>
@@ -35,92 +36,86 @@ FUZZ_TARGET_INIT(data_stream_addr_man, initialize_addrman)
3536
}
3637
}
3738

38-
class AddrManDeterministic : public AddrMan
39+
/**
40+
* Generate a random address. Always returns a valid address.
41+
*/
42+
CNetAddr RandAddr(FuzzedDataProvider& fuzzed_data_provider, FastRandomContext& fast_random_context)
3943
{
40-
public:
41-
FuzzedDataProvider& m_fuzzed_data_provider;
42-
43-
explicit AddrManDeterministic(std::vector<bool> asmap, FuzzedDataProvider& fuzzed_data_provider)
44-
: AddrMan(std::move(asmap), /* deterministic */ true, /* consistency_check_ratio */ 0)
45-
, m_fuzzed_data_provider(fuzzed_data_provider)
46-
{
47-
WITH_LOCK(m_impl->cs, m_impl->insecure_rand = FastRandomContext{ConsumeUInt256(fuzzed_data_provider)});
48-
}
49-
50-
/**
51-
* Generate a random address. Always returns a valid address.
52-
*/
53-
CNetAddr RandAddr() EXCLUSIVE_LOCKS_REQUIRED(m_impl->cs)
54-
{
55-
CNetAddr addr;
56-
if (m_fuzzed_data_provider.remaining_bytes() > 1 && m_fuzzed_data_provider.ConsumeBool()) {
57-
addr = ConsumeNetAddr(m_fuzzed_data_provider);
58-
} else {
59-
// The networks [1..6] correspond to CNetAddr::BIP155Network (private).
60-
static const std::map<uint8_t, uint8_t> net_len_map = {{1, ADDR_IPV4_SIZE},
61-
{2, ADDR_IPV6_SIZE},
62-
{4, ADDR_TORV3_SIZE},
63-
{5, ADDR_I2P_SIZE},
64-
{6, ADDR_CJDNS_SIZE}};
65-
uint8_t net = m_impl->insecure_rand.randrange(5) + 1; // [1..5]
66-
if (net == 3) {
67-
net = 6;
68-
}
69-
70-
CDataStream s(SER_NETWORK, PROTOCOL_VERSION | ADDRV2_FORMAT);
71-
72-
s << net;
73-
s << m_impl->insecure_rand.randbytes(net_len_map.at(net));
74-
75-
s >> addr;
76-
}
77-
78-
// Return a dummy IPv4 5.5.5.5 if we generated an invalid address.
79-
if (!addr.IsValid()) {
80-
in_addr v4_addr = {};
81-
v4_addr.s_addr = 0x05050505;
82-
addr = CNetAddr{v4_addr};
44+
CNetAddr addr;
45+
if (fuzzed_data_provider.remaining_bytes() > 1 && fuzzed_data_provider.ConsumeBool()) {
46+
addr = ConsumeNetAddr(fuzzed_data_provider);
47+
} else {
48+
// The networks [1..6] correspond to CNetAddr::BIP155Network (private).
49+
static const std::map<uint8_t, uint8_t> net_len_map = {{1, ADDR_IPV4_SIZE},
50+
{2, ADDR_IPV6_SIZE},
51+
{4, ADDR_TORV3_SIZE},
52+
{5, ADDR_I2P_SIZE},
53+
{6, ADDR_CJDNS_SIZE}};
54+
uint8_t net = fast_random_context.randrange(5) + 1; // [1..5]
55+
if (net == 3) {
56+
net = 6;
8357
}
8458

85-
return addr;
86-
}
87-
88-
/**
89-
* Fill this addrman with lots of addresses from lots of sources.
90-
*/
91-
void Fill()
92-
{
93-
LOCK(m_impl->cs);
59+
CDataStream s(SER_NETWORK, PROTOCOL_VERSION | ADDRV2_FORMAT);
9460

95-
// Add some of the addresses directly to the "tried" table.
61+
s << net;
62+
s << fast_random_context.randbytes(net_len_map.at(net));
9663

97-
// 0, 1, 2, 3 corresponding to 0%, 100%, 50%, 33%
98-
const size_t n = m_fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 3);
64+
s >> addr;
65+
}
9966

100-
const size_t num_sources = m_fuzzed_data_provider.ConsumeIntegralInRange<size_t>(1, 50);
101-
CNetAddr prev_source;
102-
// Use insecure_rand inside the loops instead of m_fuzzed_data_provider because when
103-
// the latter is exhausted it just returns 0.
104-
for (size_t i = 0; i < num_sources; ++i) {
105-
const auto source = RandAddr();
106-
const size_t num_addresses = m_impl->insecure_rand.randrange(500) + 1; // [1..500]
67+
// Return a dummy IPv4 5.5.5.5 if we generated an invalid address.
68+
if (!addr.IsValid()) {
69+
in_addr v4_addr = {};
70+
v4_addr.s_addr = 0x05050505;
71+
addr = CNetAddr{v4_addr};
72+
}
10773

108-
for (size_t j = 0; j < num_addresses; ++j) {
109-
const auto addr = CAddress{CService{RandAddr(), 8333}, NODE_NETWORK};
110-
const auto time_penalty = m_impl->insecure_rand.randrange(100000001);
111-
m_impl->Add_(addr, source, time_penalty);
74+
return addr;
75+
}
11276

113-
if (n > 0 && m_impl->mapInfo.size() % n == 0) {
114-
m_impl->Good_(addr, false, GetTime());
115-
}
77+
/** Fill addrman with lots of addresses from lots of sources. */
78+
void FillAddrman(AddrMan& addrman, FuzzedDataProvider& fuzzed_data_provider)
79+
{
80+
// Add a fraction of the addresses to the "tried" table.
81+
// 0, 1, 2, 3 corresponding to 0%, 100%, 50%, 33%
82+
const size_t n = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 3);
83+
84+
const size_t num_sources = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(1, 50);
85+
CNetAddr prev_source;
86+
// Generate a FastRandomContext seed to use inside the loops instead of
87+
// fuzzed_data_provider. When fuzzed_data_provider is exhausted it
88+
// just returns 0.
89+
FastRandomContext fast_random_context{ConsumeUInt256(fuzzed_data_provider)};
90+
for (size_t i = 0; i < num_sources; ++i) {
91+
const auto source = RandAddr(fuzzed_data_provider, fast_random_context);
92+
const size_t num_addresses = fast_random_context.randrange(500) + 1; // [1..500]
93+
94+
for (size_t j = 0; j < num_addresses; ++j) {
95+
const auto addr = CAddress{CService{RandAddr(fuzzed_data_provider, fast_random_context), 8333}, NODE_NETWORK};
96+
const auto time_penalty = fast_random_context.randrange(100000001);
97+
addrman.Add({addr}, source, time_penalty);
98+
99+
if (n > 0 && addrman.size() % n == 0) {
100+
addrman.Good(addr, GetTime());
101+
}
116102

117-
// Add 10% of the addresses from more than one source.
118-
if (m_impl->insecure_rand.randrange(10) == 0 && prev_source.IsValid()) {
119-
m_impl->Add_({addr}, prev_source, time_penalty);
120-
}
103+
// Add 10% of the addresses from more than one source.
104+
if (fast_random_context.randrange(10) == 0 && prev_source.IsValid()) {
105+
addrman.Add({addr}, prev_source, time_penalty);
121106
}
122-
prev_source = source;
123107
}
108+
prev_source = source;
109+
}
110+
}
111+
112+
class AddrManDeterministic : public AddrMan
113+
{
114+
public:
115+
explicit AddrManDeterministic(std::vector<bool> asmap, FuzzedDataProvider& fuzzed_data_provider)
116+
: AddrMan(std::move(asmap), /* deterministic */ true, /* consistency_check_ratio */ 0)
117+
{
118+
WITH_LOCK(m_impl->cs, m_impl->insecure_rand = FastRandomContext{ConsumeUInt256(fuzzed_data_provider)});
124119
}
125120

126121
/**
@@ -307,7 +302,7 @@ FUZZ_TARGET_INIT(addrman_serdeser, initialize_addrman)
307302

308303
CDataStream data_stream(SER_NETWORK, PROTOCOL_VERSION);
309304

310-
addr_man1.Fill();
305+
FillAddrman(addr_man1, fuzzed_data_provider);
311306
data_stream << addr_man1;
312307
data_stream >> addr_man2;
313308
assert(addr_man1 == addr_man2);

0 commit comments

Comments
 (0)