| 142 | BOOST_FIXTURE_TEST_SUITE(headers_sync_chainwork_tests, HeadersGeneratorSetup) |
| 143 | |
| 144 | BOOST_AUTO_TEST_CASE(sneaky_redownload) |
| 145 | { |
| 146 | const auto& first_chain{FirstChain()}; |
| 147 | const auto& second_chain{SecondChain()}; |
| 148 | |
| 149 | // Feed the first chain to HeadersSyncState, by delivering 1 header |
| 150 | // initially and then the rest. |
| 151 | HeadersSyncState hss{CreateState()}; |
| 152 | |
| 153 | // Just feed one header and check state. |
| 154 | // Pretend the message is still "full", so we don't abort. |
| 155 | CHECK_RESULT(hss.ProcessNextHeaders({{first_chain.front()}}, /*full_headers_message=*/true), |
| 156 | hss, /*exp_state=*/State::PRESYNC, |
| 157 | /*exp_success=*/true, /*exp_request_more=*/true, |
| 158 | /*exp_headers_size=*/0, /*exp_pow_validated_prev=*/std::nullopt, |
| 159 | /*exp_locator_hash=*/first_chain.front().GetHash()); |
| 160 | |
| 161 | // This chain should look valid, and we should have met the proof-of-work |
| 162 | // requirement during PRESYNC and transitioned to REDOWNLOAD. |
| 163 | CHECK_RESULT(hss.ProcessNextHeaders(std::span{first_chain}.subspan(1), true), |
| 164 | hss, /*exp_state=*/State::REDOWNLOAD, |
| 165 | /*exp_success=*/true, /*exp_request_more=*/true, |
| 166 | /*exp_headers_size=*/0, /*exp_pow_validated_prev=*/std::nullopt, |
| 167 | /*exp_locator_hash=*/genesis.GetHash()); |
| 168 | |
| 169 | // Below is the number of commitment bits that must randomly match between |
| 170 | // the two chains for this test to spuriously fail. 1 / 2^25 = |
| 171 | // 1 in 33'554'432 (somewhat less due to HeadersSyncState::m_commit_offset). |
| 172 | static_assert(TARGET_BLOCKS / COMMITMENT_PERIOD == 25); |
| 173 | |
| 174 | // Try to sneakily feed back the second chain during REDOWNLOAD. |
| 175 | CHECK_RESULT(hss.ProcessNextHeaders(second_chain, true), |
| 176 | hss, /*exp_state=*/State::FINAL, |
| 177 | /*exp_success=*/false, // Foiled! We detected mismatching headers. |
| 178 | /*exp_request_more=*/false, |
| 179 | /*exp_headers_size=*/0, /*exp_pow_validated_prev=*/std::nullopt, |
| 180 | /*exp_locator_hash=*/std::nullopt); |
| 181 | } |
| 182 | |
| 183 | BOOST_AUTO_TEST_CASE(happy_path) |
| 184 | { |