Bitcoin Core
31.1.0
P2P Digital Currency
Toggle main menu visibility
Loading...
Searching...
No Matches
src
test
fuzz
headerssync.cpp
Go to the documentation of this file.
1
// Copyright (c) 2022-present The Bitcoin Core developers
2
// Distributed under the MIT software license, see the accompanying
3
// file COPYING or https://opensource.org/license/mit.
4
5
#include <
arith_uint256.h
>
6
#include <chain.h>
7
#include <chainparams.h>
8
#include <
headerssync.h
>
9
#include <
test/fuzz/fuzz.h
>
10
#include <
test/fuzz/util.h
>
11
#include <
test/util/setup_common.h
>
12
#include <
uint256.h
>
13
#include <
util/chaintype.h
>
14
#include <util/time.h>
15
#include <validation.h>
16
17
#include <iterator>
18
#include <vector>
19
20
static
void
initialize_headers_sync_state_fuzz
()
21
{
22
static
const
auto
testing_setup =
MakeNoLogFileContext<>
(
23
/*chain_type=*/
ChainType::MAIN
);
24
}
25
26
void
MakeHeadersContinuous
(
27
const
CBlockHeader
& genesis_header,
28
const
std::vector<CBlockHeader>& all_headers,
29
std::vector<CBlockHeader>& new_headers)
30
{
31
Assume
(!new_headers.empty());
32
33
const
CBlockHeader
* prev_header{
34
all_headers.empty() ? &genesis_header : &all_headers.back()};
35
36
for
(
auto
& header : new_headers) {
37
header.hashPrevBlock = prev_header->
GetHash
();
38
39
prev_header = &header;
40
}
41
}
42
43
class
FuzzedHeadersSyncState
:
public
HeadersSyncState
44
{
45
public
:
46
FuzzedHeadersSyncState
(
const
HeadersSyncParams
& sync_params,
const
size_t
commit_offset,
47
const
CBlockIndex
& chain_start,
const
arith_uint256
& minimum_required_work)
48
:
HeadersSyncState
(
/*id=*/
0,
Params
().GetConsensus(), sync_params, chain_start, minimum_required_work)
49
{
50
const_cast<
size_t
&
>
(
m_commit_offset
) = commit_offset;
51
}
52
};
53
54
FUZZ_TARGET
(headers_sync_state, .
init
=
initialize_headers_sync_state_fuzz
)
55
{
56
SeedRandomStateForTest
(
SeedRand::ZEROS
);
57
FuzzedDataProvider
fuzzed_data_provider(buffer.data(), buffer.size());
58
59
CBlockHeader
genesis_header{
Params
().
GenesisBlock
()};
60
CBlockIndex
start_index(genesis_header);
61
62
SetMockTime
(
ConsumeTime
(fuzzed_data_provider,
/*min=*/
start_index.
GetMedianTimePast
()));
63
64
const
uint256
genesis_hash = genesis_header.
GetHash
();
65
start_index.
phashBlock
= &genesis_hash;
66
67
const
HeadersSyncParams
params{
68
.commitment_period = fuzzed_data_provider.
ConsumeIntegralInRange
<
size_t
>(1,
Params
().
HeadersSync
().
commitment_period
* 2),
69
.redownload_buffer_size = fuzzed_data_provider.
ConsumeIntegralInRange
<
size_t
>(0,
Params
().HeadersSync().redownload_buffer_size * 2),
70
};
71
arith_uint256
min_work{
UintToArith256
(
ConsumeUInt256
(fuzzed_data_provider))};
72
FuzzedHeadersSyncState
headers_sync(
73
params,
74
/*commit_offset=*/
fuzzed_data_provider.
ConsumeIntegralInRange
<
size_t
>(0, params.
commitment_period
- 1),
75
/*chain_start=*/
start_index,
76
/*minimum_required_work=*/
min_work);
77
78
// Store headers for potential redownload phase.
79
std::vector<CBlockHeader> all_headers;
80
std::vector<CBlockHeader>::const_iterator redownloaded_it;
81
bool
presync{
true
};
82
bool
requested_more{
true
};
83
84
while
(requested_more) {
85
std::vector<CBlockHeader> headers;
86
87
// Consume headers from fuzzer or maybe replay headers if we got to the
88
// redownload phase.
89
if
(presync || fuzzed_data_provider.
ConsumeBool
()) {
90
auto
deser_headers =
ConsumeDeserializable<std::vector<CBlockHeader>
>(fuzzed_data_provider);
91
if
(!deser_headers || deser_headers->empty())
return
;
92
93
if
(fuzzed_data_provider.
ConsumeBool
()) {
94
MakeHeadersContinuous
(genesis_header, all_headers, *deser_headers);
95
}
96
97
headers.swap(*deser_headers);
98
}
else
if
(
auto
num_headers_left{std::distance(redownloaded_it, all_headers.cend())}; num_headers_left > 0) {
99
// Consume some headers from the redownload buffer (At least one
100
// header is consumed).
101
auto
begin_it{redownloaded_it};
102
std::advance(redownloaded_it, fuzzed_data_provider.
ConsumeIntegralInRange
<
int
>(1, num_headers_left));
103
headers.insert(headers.cend(), begin_it, redownloaded_it);
104
}
105
106
if
(headers.empty())
return
;
107
auto
result = headers_sync.
ProcessNextHeaders
(headers, fuzzed_data_provider.
ConsumeBool
());
108
requested_more = result.
request_more
;
109
110
if
(result.request_more) {
111
if
(presync) {
112
all_headers.insert(all_headers.cend(), headers.cbegin(), headers.cend());
113
114
if
(headers_sync.
GetState
() == HeadersSyncState::State::REDOWNLOAD) {
115
presync =
false
;
116
redownloaded_it = all_headers.cbegin();
117
118
// If we get to redownloading, the presynced headers need
119
// to have the min amount of work on them.
120
assert
(
CalculateClaimedHeadersWork
(all_headers) >= min_work);
121
}
122
}
123
124
(void)headers_sync.
NextHeadersRequestLocator
();
125
}
126
}
127
}
UintToArith256
arith_uint256 UintToArith256(const uint256 &a)
Definition
arith_uint256.cpp:225
arith_uint256.h
Params
const CChainParams & Params()
Return the currently selected parameters.
Definition
chainparams.cpp:112
chaintype.h
ChainType::MAIN
@ MAIN
Definition
chaintype.h:12
Assume
#define Assume(val)
Assume is the identity function.
Definition
check.h:125
CBlockHeader
Nodes collect new transactions into a block, hash them into a hash tree, and scan through nonce value...
Definition
block.h:27
CBlockHeader::GetHash
uint256 GetHash() const
Definition
block.cpp:15
CBlockIndex
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition
chain.h:94
CBlockIndex::GetMedianTimePast
int64_t GetMedianTimePast() const
Definition
chain.h:233
CBlockIndex::phashBlock
const uint256 * phashBlock
pointer to the hash of the block, if any. Memory is owned by this CBlockIndex
Definition
chain.h:97
CChainParams::GenesisBlock
const CBlock & GenesisBlock() const
Definition
chainparams.h:94
CChainParams::HeadersSync
const HeadersSyncParams & HeadersSync() const
Definition
chainparams.h:117
FuzzedDataProvider
Definition
FuzzedDataProvider.h:32
FuzzedDataProvider::ConsumeBool
bool ConsumeBool()
Definition
FuzzedDataProvider.h:289
FuzzedDataProvider::ConsumeIntegralInRange
T ConsumeIntegralInRange(T min, T max)
Definition
FuzzedDataProvider.h:205
FuzzedHeadersSyncState
Definition
headerssync.cpp:44
FuzzedHeadersSyncState::FuzzedHeadersSyncState
FuzzedHeadersSyncState(const HeadersSyncParams &sync_params, const size_t commit_offset, const CBlockIndex &chain_start, const arith_uint256 &minimum_required_work)
Definition
headerssync.cpp:46
HeadersSyncState::HeadersSyncState
HeadersSyncState(NodeId id, const Consensus::Params &consensus_params, const HeadersSyncParams ¶ms, const CBlockIndex &chain_start, const arith_uint256 &minimum_required_work)
Construct a HeadersSyncState object representing a headers sync via this download-twice mechanism).
Definition
headerssync.cpp:17
HeadersSyncState::ProcessNextHeaders
ProcessingResult ProcessNextHeaders(std::span< const CBlockHeader > received_headers, bool full_headers_message)
Process a batch of headers, once a sync via this mechanism has started.
Definition
headerssync.cpp:68
HeadersSyncState::GetState
State GetState() const
Return the current state of our download.
Definition
headerssync.h:120
HeadersSyncState::m_commit_offset
const size_t m_commit_offset
The (secret) offset on the heights for which to create commitments.
Definition
headerssync.h:185
HeadersSyncState::NextHeadersRequestLocator
CBlockLocator NextHeadersRequestLocator() const
Issue the next GETHEADERS message to our peer.
Definition
headerssync.cpp:296
arith_uint256
256-bit unsigned big integer.
Definition
arith_uint256.h:231
uint256
256-bit opaque blob.
Definition
uint256.h:195
fuzz.h
FUZZ_TARGET
#define FUZZ_TARGET(...)
Definition
fuzz.h:35
headerssync.h
init
Definition
bitcoin-gui.cpp:17
setup_common.h
MakeNoLogFileContext
std::unique_ptr< T > MakeNoLogFileContext(const ChainType chain_type=ChainType::REGTEST, TestOpts opts={})
Make a test setup that has disk access to the debug.log file disabled.
Definition
setup_common.h:250
HeadersSyncParams
Configuration for headers sync memory usage.
Definition
chainparams.h:64
HeadersSyncParams::commitment_period
size_t commitment_period
Distance in blocks between header commitments.
Definition
chainparams.h:66
HeadersSyncState::ProcessingResult::request_more
bool request_more
Definition
headerssync.h:147
initialize_headers_sync_state_fuzz
static void initialize_headers_sync_state_fuzz()
Definition
headerssync.cpp:20
MakeHeadersContinuous
void MakeHeadersContinuous(const CBlockHeader &genesis_header, const std::vector< CBlockHeader > &all_headers, std::vector< CBlockHeader > &new_headers)
Definition
headerssync.cpp:26
ConsumeTime
NodeSeconds ConsumeTime(FuzzedDataProvider &fuzzed_data_provider, const std::optional< int64_t > &min, const std::optional< int64_t > &max) noexcept
Definition
util.cpp:34
util.h
ConsumeUInt256
uint256 ConsumeUInt256(FuzzedDataProvider &fuzzed_data_provider) noexcept
Definition
util.h:167
ConsumeDeserializable
std::optional< T > ConsumeDeserializable(FuzzedDataProvider &fuzzed_data_provider, const P ¶ms, const std::optional< size_t > &max_length=std::nullopt) noexcept
Definition
util.h:100
SeedRandomStateForTest
void SeedRandomStateForTest(SeedRand seedtype)
Seed the global RNG state for testing and log the seed value.
Definition
random.cpp:19
SeedRand::ZEROS
@ ZEROS
Seed with a compile time constant of zeros.
Definition
random.h:19
uint256.h
SetMockTime
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
Definition
time.cpp:44
CalculateClaimedHeadersWork
arith_uint256 CalculateClaimedHeadersWork(std::span< const CBlockHeader > headers)
Return the sum of the claimed work on a given set of headers.
Definition
validation.cpp:4106
assert
assert(!tx.IsCoinBase())
Generated on
for Bitcoin Core by
1.17.0