0diff --git a/src/arith_uint256.h b/src/arith_uint256.h
1index e021947381..b07e8e9f41 100644
2--- a/src/arith_uint256.h
3+++ b/src/arith_uint256.h
4@@ -31,7 +31,7 @@ protected:
5 uint32_t pn[WIDTH];
6
7 public:
8- constexpr base_uint()
9+ explicit constexpr base_uint()
10 {
11 for (int i = 0; i < WIDTH; i++)
12 pn[i] = 0;
13@@ -243,8 +243,8 @@ class arith_uint256 : public base_uint<256>
14 {
15 public:
16 constexpr arith_uint256() = default;
17- constexpr arith_uint256(const base_uint<256>& b) : base_uint<256>(b) {}
18- constexpr arith_uint256(uint64_t b) : base_uint<256>(b) {}
19+ constexpr arith_uint256(const base_uint& b) : base_uint(b) {}
20+ constexpr arith_uint256(const uint64_t b) : base_uint(b) {}
21
22 /**
23 * The "compact" format is a representation of a whole
24diff --git a/src/test/headers_sync_chainwork_tests.cpp b/src/test/headers_sync_chainwork_tests.cpp
25index b696285d0e..264959f8c3 100644
26--- a/src/test/headers_sync_chainwork_tests.cpp
27+++ b/src/test/headers_sync_chainwork_tests.cpp
28@@ -13,32 +13,35 @@
29
30 #include <boost/test/unit_test.hpp>
31
32-constexpr int TARGET_BLOCKS{15000};
33+constexpr size_t TARGET_BLOCKS{15'000};
34 constexpr arith_uint256 CHAIN_WORK{TARGET_BLOCKS * 2};
35
36-struct HeadersGeneratorSetup : public RegTestingSetup {
37+struct HeadersGeneratorSetup : RegTestingSetup
38+{
39 /** Search for a nonce to meet (regtest) proof of work */
40- void FindProofOfWork(CBlockHeader& starting_header);
41+ static void FindProofOfWork(CBlockHeader& starting_header);
42 /**
43 * Generate headers in a chain that build off a given starting hash, using
44 * the given nVersion, advancing time by 1 second from the starting
45 * prev_time, and with a fixed merkle root hash.
46 */
47- void GenerateHeaders(std::vector<CBlockHeader>& headers, size_t count,
48- const uint256& starting_hash, const int nVersion, int prev_time,
49- const uint256& merkle_root, const uint32_t nBits);
50+ static void GenerateHeaders(
51+ std::vector<CBlockHeader>& headers, size_t count,
52+ const uint256& starting_hash, int nVersion, int prev_time,
53+ const uint256& merkle_root, uint32_t nBits);
54 };
55
56 void HeadersGeneratorSetup::FindProofOfWork(CBlockHeader& starting_header)
57 {
58 while (!CheckProofOfWork(starting_header.GetHash(), starting_header.nBits, Params().GetConsensus())) {
59- ++(starting_header.nNonce);
60+ ++starting_header.nNonce;
61 }
62 }
63
64-void HeadersGeneratorSetup::GenerateHeaders(std::vector<CBlockHeader>& headers,
65- size_t count, const uint256& starting_hash, const int nVersion, int prev_time,
66- const uint256& merkle_root, const uint32_t nBits)
67+void HeadersGeneratorSetup::GenerateHeaders(
68+ std::vector<CBlockHeader>& headers,
69+ const size_t count, const uint256& starting_hash, const int nVersion, int prev_time,
70+ const uint256& merkle_root, const uint32_t nBits)
71 {
72 uint256 prev_hash = starting_hash;
73
74@@ -48,7 +51,7 @@ void HeadersGeneratorSetup::GenerateHeaders(std::vector<CBlockHeader>& headers,
75 next_header.nVersion = nVersion;
76 next_header.hashPrevBlock = prev_hash;
77 next_header.hashMerkleRoot = merkle_root;
78- next_header.nTime = prev_time+1;
79+ next_header.nTime = prev_time + 1;
80 next_header.nBits = nBits;
81
82 FindProofOfWork(next_header);
83@@ -65,13 +68,20 @@ BOOST_FIXTURE_TEST_SUITE(headers_sync_chainwork_tests, HeadersGeneratorSetup)
84 // updates to the REDOWNLOAD phase successfully.
85 // 2. Then we deliver the second set of headers and verify that they fail
86 // processing (presumably due to commitments not matching).
87-static void SneakyRedownload(const std::vector<CBlockHeader>& first_chain, const std::vector<CBlockHeader>& second_chain, const CBlockIndex* chain_start);
88+static void SneakyRedownload(
89+ const std::span<const CBlockHeader> first_chain,
90+ const std::span<const CBlockHeader> second_chain,
91+ const CBlockIndex* chain_start);
92 // 3. Verify that repeating with the first set of headers in both phases is
93 // successful.
94-static void HappyPath(const std::vector<CBlockHeader>& first_chain, const CBlockIndex* chain_start);
95+static void HappyPath(
96+ const std::span<const CBlockHeader> first_chain,
97+ const CBlockIndex* chain_start);
98 // 4. Finally, repeat the second set of headers in both phases to demonstrate
99 // behavior when the chain a peer provides has too little work.
100-static void TooLittleWork(const std::vector<CBlockHeader>& second_chain, const CBlockIndex* chain_start);
101+static void TooLittleWork(
102+ const std::span<const CBlockHeader> second_chain,
103+ const CBlockIndex* chain_start);
104
105 BOOST_AUTO_TEST_CASE(headers_sync_state)
106 {
107@@ -94,81 +104,101 @@ BOOST_AUTO_TEST_CASE(headers_sync_state)
108 TooLittleWork(second_chain, chain_start);
109 }
110
111-static void SneakyRedownload(const std::vector<CBlockHeader>& first_chain, const std::vector<CBlockHeader>& second_chain, const CBlockIndex* chain_start)
112+static void SneakyRedownload(
113+ const std::span<const CBlockHeader> first_chain,
114+ const std::span<const CBlockHeader> second_chain,
115+ const CBlockIndex* chain_start)
116 {
117 // Feed the first chain to HeadersSyncState, by delivering 1 header
118 // initially and then the rest.
119 HeadersSyncState hss{0, Params().GetConsensus(), chain_start, CHAIN_WORK};
120- auto result{hss.ProcessNextHeaders(std::span{first_chain.begin(), 1}, true)};
121- BOOST_REQUIRE_EQUAL(hss.GetState(), HeadersSyncState::State::PRESYNC);
122- BOOST_CHECK(result.success);
123- BOOST_CHECK(result.request_more);
124- BOOST_CHECK_EQUAL(result.pow_validated_headers.size(), 0);
125- BOOST_CHECK_EQUAL(hss.NextHeadersRequestLocator().vHave.front(), first_chain.front().GetHash());
126+ {
127+ const auto [pow_validated_headers, success, request_more]{hss.ProcessNextHeaders({first_chain.begin(), 1}, true)};
128+ BOOST_REQUIRE_EQUAL(hss.GetState(), HeadersSyncState::State::PRESYNC);
129+ BOOST_CHECK(success);
130+ BOOST_CHECK(request_more);
131+ BOOST_CHECK_EQUAL(pow_validated_headers.size(), 0);
132+ BOOST_CHECK_EQUAL(hss.NextHeadersRequestLocator().vHave.front(), first_chain.front().GetHash());
133+ }
134
135 // Pretend the first header is still "full", so we don't abort.
136- result = hss.ProcessNextHeaders(std::span{first_chain.begin() + 1, first_chain.end()}, true);
137- // This chain should look valid, and we should have met the proof-of-work
138- // requirement during PRESYNC and transitioned to REDOWNLOAD.
139- BOOST_REQUIRE_EQUAL(hss.GetState(), HeadersSyncState::State::REDOWNLOAD);
140- BOOST_CHECK(result.success);
141- BOOST_CHECK(result.request_more);
142- BOOST_CHECK_EQUAL(result.pow_validated_headers.size(), 0);
143- // The locator should reset to genesis.
144- BOOST_CHECK_EQUAL(hss.NextHeadersRequestLocator().vHave.front(), Params().GenesisBlock().GetHash());
145+ {
146+ const auto [pow_validated_headers, success, request_more]{hss.ProcessNextHeaders({first_chain.begin() + 1, first_chain.end()}, true)};
147+ // This chain should look valid, and we should have met the proof-of-work
148+ // requirement during PRESYNC and transitioned to REDOWNLOAD.
149+ BOOST_REQUIRE_EQUAL(hss.GetState(), HeadersSyncState::State::REDOWNLOAD);
150+ BOOST_CHECK(success);
151+ BOOST_CHECK(request_more);
152+ BOOST_CHECK_EQUAL(pow_validated_headers.size(), 0);
153+ // The locator should reset to genesis.
154+ BOOST_CHECK_EQUAL(hss.NextHeadersRequestLocator().vHave.front(), Params().GenesisBlock().GetHash());
155+ }
156
157 // Try to sneakily feed back the second chain during REDOWNLOAD.
158- result = hss.ProcessNextHeaders(second_chain, true);
159- BOOST_REQUIRE_EQUAL(hss.GetState(), HeadersSyncState::State::FINAL);
160- BOOST_CHECK(!result.success); // foiled!
161- BOOST_CHECK_EQUAL(result.pow_validated_headers.size(), 0);
162+ {
163+ const auto [pow_validated_headers, success, request_more]{hss.ProcessNextHeaders(second_chain, true)};
164+ BOOST_REQUIRE_EQUAL(hss.GetState(), HeadersSyncState::State::FINAL);
165+ BOOST_CHECK(!success); // foiled!
166+ BOOST_CHECK(!request_more);
167+ BOOST_CHECK_EQUAL(pow_validated_headers.size(), 0);
168+ }
169 }
170
171-static void HappyPath(const std::vector<CBlockHeader>& first_chain, const CBlockIndex* chain_start)
172+static void HappyPath(
173+ const std::span<const CBlockHeader> first_chain,
174+ const CBlockIndex* chain_start)
175 {
176 // This time we feed the first chain twice.
177 HeadersSyncState hss{0, Params().GetConsensus(), chain_start, CHAIN_WORK};
178- auto result{hss.ProcessNextHeaders(first_chain, true)};
179- // Switched from PRESYNC to REDOWNLOAD after reaching sufficient work:
180- BOOST_REQUIRE_EQUAL(hss.GetState(), HeadersSyncState::State::REDOWNLOAD);
181- BOOST_CHECK(result.success);
182- BOOST_CHECK(result.request_more);
183- BOOST_CHECK_EQUAL(result.pow_validated_headers.size(), 0);
184- // The locator should reset to genesis.
185- BOOST_CHECK_EQUAL(hss.NextHeadersRequestLocator().vHave.front(), Params().GenesisBlock().GetHash());
186-
187- result = hss.ProcessNextHeaders(first_chain, true);
188- // Nothing left for the sync logic to do:
189- BOOST_REQUIRE_EQUAL(hss.GetState(), HeadersSyncState::State::FINAL);
190- BOOST_CHECK(result.success);
191- BOOST_CHECK(!result.request_more);
192- // All headers should be ready for acceptance:
193- BOOST_CHECK_EQUAL(result.pow_validated_headers.size(), first_chain.size());
194+ {
195+ const auto [pow_validated_headers, success, request_more]{hss.ProcessNextHeaders(first_chain, true)};
196+ // Switched from PRESYNC to REDOWNLOAD after reaching sufficient work:
197+ BOOST_REQUIRE_EQUAL(hss.GetState(), HeadersSyncState::State::REDOWNLOAD);
198+ BOOST_CHECK(success);
199+ BOOST_CHECK(request_more);
200+ BOOST_CHECK_EQUAL(pow_validated_headers.size(), 0);
201+ // The locator should reset to genesis.
202+ BOOST_CHECK_EQUAL(hss.NextHeadersRequestLocator().vHave.front(), Params().GenesisBlock().GetHash());
203+ }
204+
205+ {
206+ const auto [pow_validated_headers, success, request_more]{hss.ProcessNextHeaders(first_chain, true)};
207+ // Nothing left for the sync logic to do:
208+ BOOST_REQUIRE_EQUAL(hss.GetState(), HeadersSyncState::State::FINAL);
209+ BOOST_CHECK(success);
210+ BOOST_CHECK(!request_more);
211+ // All headers should be ready for acceptance:
212+ BOOST_CHECK_EQUAL(pow_validated_headers.size(), first_chain.size());
213+ }
214 }
215
216-static void TooLittleWork(const std::vector<CBlockHeader>& second_chain, const CBlockIndex* chain_start)
217+static void TooLittleWork(
218+ const std::span<const CBlockHeader> second_chain,
219+ const CBlockIndex* chain_start)
220 {
221- // Verify that just trying to process the second chain would not succeed
222- // (too little work).
223+ // Verify that just trying to process the second chain would not succeed (too little work).
224 HeadersSyncState hss{0, Params().GetConsensus(), chain_start, CHAIN_WORK};
225 BOOST_REQUIRE_EQUAL(hss.GetState(), HeadersSyncState::State::PRESYNC);
226 // Pretend just the first message is "full", so we don't abort.
227- auto result{hss.ProcessNextHeaders(std::span{second_chain.begin(), 1}, true)};
228- BOOST_REQUIRE_EQUAL(hss.GetState(), HeadersSyncState::State::PRESYNC);
229- BOOST_CHECK(result.success);
230- BOOST_CHECK(result.request_more);
231- BOOST_CHECK_EQUAL(result.pow_validated_headers.size(), 0);
232+ {
233+ const auto [pow_validated_headers, success, request_more]{hss.ProcessNextHeaders({second_chain.begin(), 1}, true)};
234+ BOOST_REQUIRE_EQUAL(hss.GetState(), HeadersSyncState::State::PRESYNC);
235+ BOOST_CHECK(success);
236+ BOOST_CHECK(request_more);
237+ BOOST_CHECK_EQUAL(pow_validated_headers.size(), 0);
238+ }
239
240 // Tell the sync logic that the headers message was not full, implying no
241 // more headers can be requested. For a low-work-chain, this should cause
242 // the sync to end with no headers for acceptance.
243- result = hss.ProcessNextHeaders(std::span{second_chain.begin() + 1, second_chain.end()}, false);
244- BOOST_REQUIRE_EQUAL(hss.GetState(), HeadersSyncState::State::FINAL);
245- BOOST_CHECK(!result.request_more);
246- BOOST_CHECK_EQUAL(result.pow_validated_headers.size(), 0);
247- // Nevertheless, no validation errors should have been detected with the
248- // chain:
249- BOOST_CHECK(result.success);
250+ {
251+ const auto [pow_validated_headers, success, request_more]{hss.ProcessNextHeaders({second_chain.begin() + 1, second_chain.end()}, false)};
252+ BOOST_REQUIRE_EQUAL(hss.GetState(), HeadersSyncState::State::FINAL);
253+ BOOST_CHECK(!request_more);
254+ BOOST_CHECK_EQUAL(pow_validated_headers.size(), 0);
255+ // Nevertheless, no validation errors should have been detected with the chain:
256+ BOOST_CHECK(success);
257+ }
258 }
259
260 BOOST_AUTO_TEST_SUITE_END()