10
10
#include < test/util/net.h>
11
11
#include < test/util/script.h>
12
12
#include < test/util/setup_common.h>
13
+ #include < uint256.h>
13
14
#include < validation.h>
14
15
15
16
namespace {
@@ -20,9 +21,7 @@ class HeadersSyncSetup : public TestingSetup
20
21
std::vector<CNode*> m_connections;
21
22
22
23
public:
23
- HeadersSyncSetup (const ChainType chain_type = ChainType::MAIN,
24
- TestOpts opts = {})
25
- : TestingSetup(chain_type, opts)
24
+ HeadersSyncSetup (const ChainType chain_type, TestOpts opts) : TestingSetup(chain_type, opts)
26
25
{
27
26
PeerManager::Options peerman_opts;
28
27
node::ApplyArgsManOptions (*m_node.args , peerman_opts);
@@ -116,9 +115,9 @@ CBlock ConsumeBlock(FuzzedDataProvider& fuzzed_data_provider, const uint256& pre
116
115
return block;
117
116
}
118
117
119
- void FinalizeHeader (CBlockHeader& header)
118
+ void FinalizeHeader (CBlockHeader& header, const ChainstateManager& chainman )
120
119
{
121
- while (!CheckProofOfWork (header.GetHash (), header.nBits , Params ().GetConsensus ())) {
120
+ while (!CheckProofOfWork (header.GetHash (), header.nBits , chainman. GetParams ().GetConsensus ())) {
122
121
++(header.nNonce );
123
122
}
124
123
}
@@ -144,17 +143,20 @@ FUZZ_TARGET(p2p_headers_presync, .init = initialize)
144
143
145
144
FuzzedDataProvider fuzzed_data_provider{buffer.data (), buffer.size ()};
146
145
147
- CBlockHeader base{Params ().GenesisBlock ()};
146
+ CBlockHeader base{chainman. GetParams ().GenesisBlock ()};
148
147
SetMockTime (base.nTime );
149
148
150
149
// The chain is just a single block, so this is equal to 1
151
150
size_t original_index_size{WITH_LOCK (cs_main, return chainman.m_blockman .m_block_index .size ())};
151
+ arith_uint256 total_work{WITH_LOCK (cs_main, return chainman.m_best_header ->nChainWork )};
152
+
153
+ std::vector<CBlockHeader> all_headers;
152
154
153
155
LIMITED_WHILE (fuzzed_data_provider.ConsumeBool (), 100 )
154
156
{
155
157
auto finalized_block = [&]() {
156
158
CBlock block = ConsumeBlock (fuzzed_data_provider, base.GetHash (), base.nBits );
157
- FinalizeHeader (block);
159
+ FinalizeHeader (block, chainman );
158
160
return block;
159
161
};
160
162
@@ -167,10 +169,12 @@ FUZZ_TARGET(p2p_headers_presync, .init = initialize)
167
169
headers.resize (FUZZ_MAX_HEADERS_RESULTS);
168
170
for (CBlock& header : headers) {
169
171
header = ConsumeHeader (fuzzed_data_provider, base.GetHash (), base.nBits );
170
- FinalizeHeader (header);
172
+ FinalizeHeader (header, chainman );
171
173
base = header;
172
174
}
173
175
176
+ all_headers.insert (all_headers.end (), headers.begin (), headers.end ());
177
+
174
178
auto headers_msg = NetMsg::Make (NetMsgType::HEADERS, TX_WITH_WITNESS (headers));
175
179
g_testing_setup->SendMessage (fuzzed_data_provider, std::move (headers_msg));
176
180
},
@@ -179,16 +183,28 @@ FUZZ_TARGET(p2p_headers_presync, .init = initialize)
179
183
auto block = finalized_block ();
180
184
CBlockHeaderAndShortTxIDs cmpct_block{block, fuzzed_data_provider.ConsumeIntegral <uint64_t >()};
181
185
186
+ all_headers.push_back (block);
187
+
182
188
auto headers_msg = NetMsg::Make (NetMsgType::CMPCTBLOCK, TX_WITH_WITNESS (cmpct_block));
183
189
g_testing_setup->SendMessage (fuzzed_data_provider, std::move (headers_msg));
184
190
},
185
191
[&]() NO_THREAD_SAFETY_ANALYSIS {
186
192
// Send a block
187
193
auto block = finalized_block ();
188
194
195
+ all_headers.push_back (block);
196
+
189
197
auto headers_msg = NetMsg::Make (NetMsgType::BLOCK, TX_WITH_WITNESS (block));
190
198
g_testing_setup->SendMessage (fuzzed_data_provider, std::move (headers_msg));
191
199
});
200
+
201
+ // This is a conservative overestimate, as base is only moved forward when sending headers. In theory,
202
+ // the longest chain generated by this test is 1600 (FUZZ_MAX_HEADERS_RESULTS * 100) headers. In that case,
203
+ // this variable will accurately reflect the chain's total work.
204
+ total_work += CalculateClaimedHeadersWork (all_headers);
205
+
206
+ // This test should never create a chain with more work than MinimumChainWork.
207
+ assert (total_work < chainman.MinimumChainWork ());
192
208
}
193
209
194
210
// The headers/blocks sent in this test should never be stored, as the chains don't have the work required
0 commit comments