Coverage Report

Created: 2026-10-07 20:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/root/bitcoin/src/test/fuzz/util/net.cpp
Line
Count
Source
1
// Copyright (c) 2009-present The Bitcoin Core developers
2
// Distributed under the MIT software license, see the accompanying
3
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5
#include <test/fuzz/util/net.h>
6
7
#include <compat/compat.h>
8
#include <netaddress.h>
9
#include <node/protocol_version.h>
10
#include <protocol.h>
11
#include <test/fuzz/FuzzedDataProvider.h>
12
#include <test/fuzz/util.h>
13
#include <test/util/net.h>
14
#include <util/sock.h>
15
#include <util/time.h>
16
17
#include <array>
18
#include <cassert>
19
#include <cerrno>
20
#include <cstdint>
21
#include <cstdlib>
22
#include <cstring>
23
#include <ranges>
24
#include <thread>
25
#include <vector>
26
27
class CNode;
28
29
CNetAddr ConsumeNetAddr(FuzzedDataProvider& fuzzed_data_provider, FastRandomContext* rand) noexcept
30
9.48k
{
31
9.48k
    struct NetAux {
32
9.48k
        Network net;
33
9.48k
        CNetAddr::BIP155Network bip155;
34
9.48k
        size_t len;
35
9.48k
    };
36
37
9.48k
    static constexpr std::array<NetAux, 6> nets{
38
9.48k
        NetAux{.net = Network::NET_IPV4, .bip155 = CNetAddr::BIP155Network::IPV4, .len = ADDR_IPV4_SIZE},
39
9.48k
        NetAux{.net = Network::NET_IPV6, .bip155 = CNetAddr::BIP155Network::IPV6, .len = ADDR_IPV6_SIZE},
40
9.48k
        NetAux{.net = Network::NET_ONION, .bip155 = CNetAddr::BIP155Network::TORV3, .len = ADDR_TORV3_SIZE},
41
9.48k
        NetAux{.net = Network::NET_I2P, .bip155 = CNetAddr::BIP155Network::I2P, .len = ADDR_I2P_SIZE},
42
9.48k
        NetAux{.net = Network::NET_CJDNS, .bip155 = CNetAddr::BIP155Network::CJDNS, .len = ADDR_CJDNS_SIZE},
43
9.48k
        NetAux{.net = Network::NET_INTERNAL, .bip155 = CNetAddr::BIP155Network{0}, .len = 0},
44
9.48k
    };
45
46
9.48k
    const size_t nets_index{rand == nullptr
  Branch (46:29): [True: 9.48k, False: 0]
47
9.48k
        ? fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, nets.size() - 1)
48
9.48k
        : static_cast<size_t>(rand->randrange(nets.size()))};
49
50
9.48k
    const auto& aux = nets[nets_index];
51
52
9.48k
    CNetAddr addr;
53
54
9.48k
    if (aux.net == Network::NET_INTERNAL) {
  Branch (54:9): [True: 374, False: 9.11k]
55
374
        if (rand == nullptr) {
  Branch (55:13): [True: 374, False: 0]
56
374
            addr.SetInternal(fuzzed_data_provider.ConsumeBytesAsString(32));
57
374
        } else {
58
0
            const auto v = rand->randbytes(32);
59
0
            addr.SetInternal(std::string{v.begin(), v.end()});
60
0
        }
61
374
        return addr;
62
374
    }
63
64
9.11k
    DataStream s;
65
66
9.11k
    s << static_cast<uint8_t>(aux.bip155);
67
68
9.11k
    std::vector<uint8_t> addr_bytes;
69
9.11k
    if (rand == nullptr) {
  Branch (69:9): [True: 9.11k, False: 0]
70
9.11k
        addr_bytes = fuzzed_data_provider.ConsumeBytes<uint8_t>(aux.len);
71
9.11k
        addr_bytes.resize(aux.len);
72
9.11k
    } else {
73
0
        addr_bytes = rand->randbytes(aux.len);
74
0
    }
75
9.11k
    if (aux.net == NET_IPV6 && addr_bytes[0] == CJDNS_PREFIX) { // Avoid generating IPv6 addresses that look like CJDNS.
  Branch (75:9): [True: 1.57k, False: 7.54k]
  Branch (75:32): [True: 3, False: 1.56k]
76
3
        addr_bytes[0] = 0x55; // Just an arbitrary number, anything != CJDNS_PREFIX would do.
77
3
    }
78
9.11k
    if (aux.net == NET_CJDNS) { // Avoid generating CJDNS addresses that don't start with CJDNS_PREFIX because those are !IsValid().
  Branch (78:9): [True: 448, False: 8.66k]
79
448
        addr_bytes[0] = CJDNS_PREFIX;
80
448
    }
81
9.11k
    s << addr_bytes;
82
83
9.11k
    s >> CAddress::V2_NETWORK(addr);
84
85
9.11k
    return addr;
86
9.48k
}
87
88
CAddress ConsumeAddress(FuzzedDataProvider& fuzzed_data_provider) noexcept
89
9.48k
{
90
9.48k
    return {ConsumeService(fuzzed_data_provider), ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS), NodeSeconds{std::chrono::seconds{fuzzed_data_provider.ConsumeIntegral<uint32_t>()}}};
91
9.48k
}
92
93
template <typename P>
94
P ConsumeDeserializationParams(FuzzedDataProvider& fuzzed_data_provider) noexcept
95
0
{
96
0
    constexpr std::array ADDR_ENCODINGS{
97
0
        CNetAddr::Encoding::V1,
98
0
        CNetAddr::Encoding::V2,
99
0
    };
100
0
    constexpr std::array ADDR_FORMATS{
101
0
        CAddress::Format::Disk,
102
0
        CAddress::Format::Network,
103
0
    };
104
0
    if constexpr (std::is_same_v<P, CNetAddr::SerParams>) {
105
0
        return P{PickValue(fuzzed_data_provider, ADDR_ENCODINGS)};
106
0
    }
107
0
    if constexpr (std::is_same_v<P, CAddress::SerParams>) {
108
0
        return P{{PickValue(fuzzed_data_provider, ADDR_ENCODINGS)}, PickValue(fuzzed_data_provider, ADDR_FORMATS)};
109
0
    }
110
0
}
Unexecuted instantiation: _Z28ConsumeDeserializationParamsIN8CNetAddr9SerParamsEET_R18FuzzedDataProvider
Unexecuted instantiation: _Z28ConsumeDeserializationParamsIN8CAddress9SerParamsEET_R18FuzzedDataProvider
111
template CNetAddr::SerParams ConsumeDeserializationParams(FuzzedDataProvider&) noexcept;
112
template CAddress::SerParams ConsumeDeserializationParams(FuzzedDataProvider&) noexcept;
113
114
FuzzedSock::FuzzedSock(FuzzedDataProvider& fuzzed_data_provider, FakeSteadyClock& clock)
115
4.74k
    : Sock{fuzzed_data_provider.ConsumeIntegralInRange<SOCKET>(INVALID_SOCKET - 1, INVALID_SOCKET)},
116
4.74k
      m_fuzzed_data_provider{fuzzed_data_provider},
117
4.74k
      m_selectable{fuzzed_data_provider.ConsumeBool()},
118
4.74k
      m_clock{clock}
119
4.74k
{
120
4.74k
}
121
122
FuzzedSock::~FuzzedSock()
123
4.74k
{
124
    // Sock::~Sock() will be called after FuzzedSock::~FuzzedSock() and it will call
125
    // close(m_socket) if m_socket is not INVALID_SOCKET.
126
    // Avoid closing an arbitrary file descriptor (m_socket is just a random very high number which
127
    // theoretically may concide with a real opened file descriptor).
128
4.74k
    m_socket = INVALID_SOCKET;
129
4.74k
}
130
131
FuzzedSock& FuzzedSock::operator=(Sock&& other)
132
0
{
133
0
    assert(false && "Move of Sock into FuzzedSock not allowed.");
  Branch (133:5): [Folded, False: 0]
  Branch (133:5): [True: 0, Folded]
  Branch (133:5): [Folded, False: 0]
134
0
    return *this;
135
0
}
136
137
ssize_t FuzzedSock::Send(const void* data, size_t len, int flags) const
138
53.6k
{
139
53.6k
    constexpr std::array send_errnos{
140
53.6k
        EACCES,
141
53.6k
        EAGAIN,
142
53.6k
        EALREADY,
143
53.6k
        EBADF,
144
53.6k
        ECONNRESET,
145
53.6k
        EDESTADDRREQ,
146
53.6k
        EFAULT,
147
53.6k
        EINTR,
148
53.6k
        EINVAL,
149
53.6k
        EISCONN,
150
53.6k
        EMSGSIZE,
151
53.6k
        ENOBUFS,
152
53.6k
        ENOMEM,
153
53.6k
        ENOTCONN,
154
53.6k
        ENOTSOCK,
155
53.6k
        EOPNOTSUPP,
156
53.6k
        EPIPE,
157
53.6k
        EWOULDBLOCK,
158
53.6k
    };
159
53.6k
    if (m_fuzzed_data_provider.ConsumeBool()) {
  Branch (159:9): [True: 48.6k, False: 4.99k]
160
48.6k
        return len;
161
48.6k
    }
162
4.99k
    const ssize_t r = m_fuzzed_data_provider.ConsumeIntegralInRange<ssize_t>(-1, len);
163
4.99k
    if (r == -1) {
  Branch (163:9): [True: 860, False: 4.13k]
164
860
        SetFuzzedErrNo(m_fuzzed_data_provider, send_errnos);
165
860
    }
166
4.99k
    return r;
167
53.6k
}
168
169
ssize_t FuzzedSock::Recv(void* buf, size_t len, int flags) const
170
0
{
171
    // Have a permanent error at recv_errnos[0] because when the fuzzed data is exhausted
172
    // SetFuzzedErrNo() will always return the first element and we want to avoid Recv()
173
    // returning -1 and setting errno to EAGAIN repeatedly.
174
0
    constexpr std::array recv_errnos{
175
0
        ECONNREFUSED,
176
0
        EAGAIN,
177
0
        EBADF,
178
0
        EFAULT,
179
0
        EINTR,
180
0
        EINVAL,
181
0
        ENOMEM,
182
0
        ENOTCONN,
183
0
        ENOTSOCK,
184
0
        EWOULDBLOCK,
185
0
    };
186
0
    assert(buf != nullptr || len == 0);
  Branch (186:5): [True: 0, False: 0]
  Branch (186:5): [True: 0, False: 0]
  Branch (186:5): [True: 0, False: 0]
187
188
    // Do the latency before any of the "return" statements.
189
0
    if (m_fuzzed_data_provider.ConsumeBool() && std::getenv("FUZZED_SOCKET_FAKE_LATENCY") != nullptr) {
  Branch (189:9): [True: 0, False: 0]
  Branch (189:49): [True: 0, False: 0]
190
0
        std::this_thread::sleep_for(std::chrono::milliseconds{2});
191
0
    }
192
193
0
    if (len == 0 || m_fuzzed_data_provider.ConsumeBool()) {
  Branch (193:9): [True: 0, False: 0]
  Branch (193:21): [True: 0, False: 0]
194
0
        const ssize_t r = m_fuzzed_data_provider.ConsumeBool() ? 0 : -1;
  Branch (194:27): [True: 0, False: 0]
195
0
        if (r == -1) {
  Branch (195:13): [True: 0, False: 0]
196
0
            SetFuzzedErrNo(m_fuzzed_data_provider, recv_errnos);
197
0
        }
198
0
        return r;
199
0
    }
200
201
0
    size_t copied_so_far{0};
202
203
0
    if (!m_peek_data.empty()) {
  Branch (203:9): [True: 0, False: 0]
204
        // `MSG_PEEK` was used in the preceding `Recv()` call, copy the first bytes from `m_peek_data`.
205
0
        const size_t copy_len{std::min(len, m_peek_data.size())};
206
0
        std::memcpy(buf, m_peek_data.data(), copy_len);
207
0
        copied_so_far += copy_len;
208
0
        if ((flags & MSG_PEEK) == 0) {
  Branch (208:13): [True: 0, False: 0]
209
0
            m_peek_data.erase(m_peek_data.begin(), m_peek_data.begin() + copy_len);
210
0
        }
211
0
    }
212
213
0
    if (copied_so_far == len) {
  Branch (213:9): [True: 0, False: 0]
214
0
        return copied_so_far;
215
0
    }
216
217
0
    auto new_data = ConsumeRandomLengthByteVector(m_fuzzed_data_provider, len - copied_so_far);
218
0
    if (new_data.empty()) return copied_so_far;
  Branch (218:9): [True: 0, False: 0]
219
220
0
    std::memcpy(reinterpret_cast<uint8_t*>(buf) + copied_so_far, new_data.data(), new_data.size());
221
0
    copied_so_far += new_data.size();
222
223
0
    if ((flags & MSG_PEEK) != 0) {
  Branch (223:9): [True: 0, False: 0]
224
0
        m_peek_data.insert(m_peek_data.end(), new_data.begin(), new_data.end());
225
0
    }
226
227
0
    if (copied_so_far == len || m_fuzzed_data_provider.ConsumeBool()) {
  Branch (227:9): [True: 0, False: 0]
  Branch (227:33): [True: 0, False: 0]
228
0
        return copied_so_far;
229
0
    }
230
231
    // Pad to len bytes.
232
0
    std::memset(reinterpret_cast<uint8_t*>(buf) + copied_so_far, 0x0, len - copied_so_far);
233
234
0
    return len;
235
0
}
236
237
int FuzzedSock::Connect(const sockaddr*, socklen_t) const
238
0
{
239
    // Have a permanent error at connect_errnos[0] because when the fuzzed data is exhausted
240
    // SetFuzzedErrNo() will always return the first element and we want to avoid Connect()
241
    // returning -1 and setting errno to EAGAIN repeatedly.
242
0
    constexpr std::array connect_errnos{
243
0
        ECONNREFUSED,
244
0
        EAGAIN,
245
0
        ECONNRESET,
246
0
        EHOSTUNREACH,
247
0
        EINPROGRESS,
248
0
        EINTR,
249
0
        ENETUNREACH,
250
0
        ETIMEDOUT,
251
0
    };
252
0
    if (m_fuzzed_data_provider.ConsumeBool()) {
  Branch (252:9): [True: 0, False: 0]
253
0
        SetFuzzedErrNo(m_fuzzed_data_provider, connect_errnos);
254
0
        return -1;
255
0
    }
256
0
    return 0;
257
0
}
258
259
int FuzzedSock::Bind(const sockaddr*, socklen_t) const
260
0
{
261
    // Have a permanent error at bind_errnos[0] because when the fuzzed data is exhausted
262
    // SetFuzzedErrNo() will always set the global errno to bind_errnos[0]. We want to
263
    // avoid this method returning -1 and setting errno to a temporary error (like EAGAIN)
264
    // repeatedly because proper code should retry on temporary errors, leading to an
265
    // infinite loop.
266
0
    constexpr std::array bind_errnos{
267
0
        EACCES,
268
0
        EADDRINUSE,
269
0
        EADDRNOTAVAIL,
270
0
        EAGAIN,
271
0
    };
272
0
    if (m_fuzzed_data_provider.ConsumeBool()) {
  Branch (272:9): [True: 0, False: 0]
273
0
        SetFuzzedErrNo(m_fuzzed_data_provider, bind_errnos);
274
0
        return -1;
275
0
    }
276
0
    return 0;
277
0
}
278
279
int FuzzedSock::Listen(int) const
280
0
{
281
    // Have a permanent error at listen_errnos[0] because when the fuzzed data is exhausted
282
    // SetFuzzedErrNo() will always set the global errno to listen_errnos[0]. We want to
283
    // avoid this method returning -1 and setting errno to a temporary error (like EAGAIN)
284
    // repeatedly because proper code should retry on temporary errors, leading to an
285
    // infinite loop.
286
0
    constexpr std::array listen_errnos{
287
0
        EADDRINUSE,
288
0
        EINVAL,
289
0
        EOPNOTSUPP,
290
0
    };
291
0
    if (m_fuzzed_data_provider.ConsumeBool()) {
  Branch (291:9): [True: 0, False: 0]
292
0
        SetFuzzedErrNo(m_fuzzed_data_provider, listen_errnos);
293
0
        return -1;
294
0
    }
295
0
    return 0;
296
0
}
297
298
std::unique_ptr<Sock> FuzzedSock::Accept(sockaddr* addr, socklen_t* addr_len) const
299
0
{
300
0
    constexpr std::array accept_errnos{
301
0
        ECONNABORTED,
302
0
        EINTR,
303
0
        ENOMEM,
304
0
    };
305
0
    if (m_fuzzed_data_provider.ConsumeBool()) {
  Branch (305:9): [True: 0, False: 0]
306
0
        SetFuzzedErrNo(m_fuzzed_data_provider, accept_errnos);
307
0
        return std::unique_ptr<FuzzedSock>();
308
0
    }
309
0
    if (addr != nullptr) {
  Branch (309:9): [True: 0, False: 0]
310
        // Set a fuzzed address in the output argument addr.
311
0
        memset(addr, 0x00, *addr_len);
312
0
        if (m_fuzzed_data_provider.ConsumeBool()) {
  Branch (312:13): [True: 0, False: 0]
313
            // IPv4
314
0
            const socklen_t write_len = static_cast<socklen_t>(sizeof(sockaddr_in));
315
0
            if (*addr_len >= write_len) {
  Branch (315:17): [True: 0, False: 0]
316
0
                *addr_len = write_len;
317
0
                auto addr4 = reinterpret_cast<sockaddr_in*>(addr);
318
0
                addr4->sin_family = AF_INET;
319
0
                const auto sin_addr_bytes{m_fuzzed_data_provider.ConsumeBytes<std::byte>(sizeof(addr4->sin_addr))};
320
0
                std::ranges::copy(sin_addr_bytes, reinterpret_cast<std::byte*>(&addr4->sin_addr));
321
0
                addr4->sin_port = m_fuzzed_data_provider.ConsumeIntegralInRange<uint16_t>(1, 65535);
322
0
            }
323
0
        } else {
324
            // IPv6
325
0
            const socklen_t write_len = static_cast<socklen_t>(sizeof(sockaddr_in6));
326
0
            if (*addr_len >= write_len) {
  Branch (326:17): [True: 0, False: 0]
327
0
                *addr_len = write_len;
328
0
                auto addr6 = reinterpret_cast<sockaddr_in6*>(addr);
329
0
                addr6->sin6_family = AF_INET6;
330
0
                const auto sin_addr_bytes{m_fuzzed_data_provider.ConsumeBytes<std::byte>(sizeof(addr6->sin6_addr))};
331
0
                std::ranges::copy(sin_addr_bytes, reinterpret_cast<std::byte*>(&addr6->sin6_addr));
332
0
                addr6->sin6_port = m_fuzzed_data_provider.ConsumeIntegralInRange<uint16_t>(1, 65535);
333
0
            }
334
0
        }
335
0
    }
336
0
    return std::make_unique<FuzzedSock>(m_fuzzed_data_provider, m_clock);
337
0
}
338
339
int FuzzedSock::GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const
340
0
{
341
0
    constexpr std::array getsockopt_errnos{
342
0
        ENOMEM,
343
0
        ENOBUFS,
344
0
    };
345
0
    if (m_fuzzed_data_provider.ConsumeBool()) {
  Branch (345:9): [True: 0, False: 0]
346
0
        SetFuzzedErrNo(m_fuzzed_data_provider, getsockopt_errnos);
347
0
        return -1;
348
0
    }
349
0
    if (opt_val == nullptr) {
  Branch (349:9): [True: 0, False: 0]
350
0
        return 0;
351
0
    }
352
0
    std::memcpy(opt_val,
353
0
                ConsumeFixedLengthByteVector(m_fuzzed_data_provider, *opt_len).data(),
354
0
                *opt_len);
355
0
    return 0;
356
0
}
357
358
int FuzzedSock::SetSockOpt(int, int, const void*, socklen_t) const
359
0
{
360
0
    constexpr std::array setsockopt_errnos{
361
0
        ENOMEM,
362
0
        ENOBUFS,
363
0
    };
364
0
    if (m_fuzzed_data_provider.ConsumeBool()) {
  Branch (364:9): [True: 0, False: 0]
365
0
        SetFuzzedErrNo(m_fuzzed_data_provider, setsockopt_errnos);
366
0
        return -1;
367
0
    }
368
0
    return 0;
369
0
}
370
371
int FuzzedSock::GetSockName(sockaddr* name, socklen_t* name_len) const
372
0
{
373
0
    constexpr std::array getsockname_errnos{
374
0
        ECONNRESET,
375
0
        ENOBUFS,
376
0
    };
377
0
    if (m_fuzzed_data_provider.ConsumeBool()) {
  Branch (377:9): [True: 0, False: 0]
378
0
        SetFuzzedErrNo(m_fuzzed_data_provider, getsockname_errnos);
379
0
        return -1;
380
0
    }
381
0
    assert(name_len);
  Branch (381:5): [True: 0, False: 0]
382
0
    const auto bytes{ConsumeRandomLengthByteVector(m_fuzzed_data_provider, *name_len)};
383
0
    if (bytes.size() < (int)sizeof(sockaddr)) return -1;
  Branch (383:9): [True: 0, False: 0]
384
0
    std::memcpy(name, bytes.data(), bytes.size());
385
0
    *name_len = bytes.size();
386
0
    return 0;
387
0
}
388
389
bool FuzzedSock::SetNonBlocking() const
390
0
{
391
0
    constexpr std::array setnonblocking_errnos{
392
0
        EBADF,
393
0
        EPERM,
394
0
    };
395
0
    if (m_fuzzed_data_provider.ConsumeBool()) {
  Branch (395:9): [True: 0, False: 0]
396
0
        SetFuzzedErrNo(m_fuzzed_data_provider, setnonblocking_errnos);
397
0
        return false;
398
0
    }
399
0
    return true;
400
0
}
401
402
bool FuzzedSock::IsSelectable() const
403
0
{
404
0
    return m_selectable;
405
0
}
406
407
bool FuzzedSock::Wait(std::chrono::milliseconds timeout, Event requested, Event* occurred) const
408
0
{
409
0
    constexpr std::array wait_errnos{
410
0
        EBADF,
411
0
        EINTR,
412
0
        EINVAL,
413
0
    };
414
0
    if (m_fuzzed_data_provider.ConsumeBool()) {
  Branch (414:9): [True: 0, False: 0]
415
0
        SetFuzzedErrNo(m_fuzzed_data_provider, wait_errnos);
416
0
        return false;
417
0
    }
418
0
    if (occurred != nullptr) {
  Branch (418:9): [True: 0, False: 0]
419
        // We simulate the requested event as occurred when ConsumeBool()
420
        // returns false. This avoids simulating endless waiting if the
421
        // FuzzedDataProvider runs out of data.
422
0
        *occurred = m_fuzzed_data_provider.ConsumeBool() ? 0 : requested;
  Branch (422:21): [True: 0, False: 0]
423
0
    }
424
0
    m_clock += timeout;
425
0
    return true;
426
0
}
427
428
bool FuzzedSock::WaitMany(std::chrono::milliseconds timeout, EventsPerSock& events_per_sock) const
429
0
{
430
0
    for (auto& [sock, events] : events_per_sock) {
  Branch (430:31): [True: 0, False: 0]
431
0
        (void)sock;
432
        // We simulate the requested event as occurred when ConsumeBool()
433
        // returns false. This avoids simulating endless waiting if the
434
        // FuzzedDataProvider runs out of data.
435
0
        events.occurred = m_fuzzed_data_provider.ConsumeBool() ? 0 : events.requested;
  Branch (435:27): [True: 0, False: 0]
436
0
    }
437
0
    m_clock += timeout;
438
0
    return true;
439
0
}
440
441
bool FuzzedSock::IsConnected(std::string& errmsg) const
442
0
{
443
0
    if (m_fuzzed_data_provider.ConsumeBool()) {
  Branch (443:9): [True: 0, False: 0]
444
0
        return true;
445
0
    }
446
0
    errmsg = "disconnected at random by the fuzzer";
447
0
    return false;
448
0
}
449
450
void FillNode(FuzzedDataProvider& fuzzed_data_provider, ConnmanTestMsg& connman, CNode& node) noexcept
451
4.74k
{
452
4.74k
    auto successfully_connected = fuzzed_data_provider.ConsumeBool();
453
4.74k
    auto remote_services = ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS);
454
4.74k
    auto local_services = ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS);
455
4.74k
    auto version = fuzzed_data_provider.ConsumeIntegralInRange<int32_t>(MIN_PEER_PROTO_VERSION, std::numeric_limits<int32_t>::max());
456
4.74k
    auto relay_txs = fuzzed_data_provider.ConsumeBool();
457
4.74k
    connman.Handshake(node, successfully_connected, remote_services, local_services, version, relay_txs);
458
4.74k
}