MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / ValidateAndStoreRedownloadedHeader

Method ValidateAndStoreRedownloadedHeader

src/headerssync.cpp:215–278  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

213}
214
215bool HeadersSyncState::ValidateAndStoreRedownloadedHeader(const CBlockHeader& header)
216{
217 Assume(m_download_state == State::REDOWNLOAD);
218 if (m_download_state != State::REDOWNLOAD) return false;
219
220 int64_t next_height = m_redownload_buffer_last_height + 1;
221
222 // Ensure that we're working on a header that connects to the chain we're
223 // downloading.
224 if (header.hashPrevBlock != m_redownload_buffer_last_hash) {
225 LogDebug(BCLog::NET, "Initial headers sync aborted with peer=%d: non-continuous headers at height=%i (redownload phase)\n", m_id, next_height);
226 return false;
227 }
228
229 // Check that the difficulty adjustments are within our tolerance:
230 uint32_t previous_nBits{0};
231 if (!m_redownloaded_headers.empty()) {
232 previous_nBits = m_redownloaded_headers.back().nBits;
233 } else {
234 previous_nBits = m_chain_start.nBits;
235 }
236
237 if (!PermittedDifficultyTransition(m_consensus_params, next_height,
238 previous_nBits, header.nBits)) {
239 LogDebug(BCLog::NET, "Initial headers sync aborted with peer=%d: invalid difficulty transition at height=%i (redownload phase)\n", m_id, next_height);
240 return false;
241 }
242
243 // Track work on the redownloaded chain
244 m_redownload_chain_work += GetBlockProof(header);
245
246 if (m_redownload_chain_work >= m_minimum_required_work) {
247 m_process_all_remaining_headers = true;
248 }
249
250 // If we're at a header for which we previously stored a commitment, verify
251 // it is correct. Failure will result in aborting download.
252 // Also, don't check commitments once we've gotten to our target blockhash;
253 // it's possible our peer has extended its chain between our first sync and
254 // our second, and we don't want to return failure after we've seen our
255 // target blockhash just because we ran out of commitments.
256 if (!m_process_all_remaining_headers && next_height % m_params.commitment_period == m_commit_offset) {
257 if (m_header_commitments.size() == 0) {
258 LogDebug(BCLog::NET, "Initial headers sync aborted with peer=%d: commitment overrun at height=%i (redownload phase)\n", m_id, next_height);
259 // Somehow our peer managed to feed us a different chain and
260 // we've run out of commitments.
261 return false;
262 }
263 bool commitment = m_hasher(header.GetHash()) & 1;
264 bool expected_commitment = m_header_commitments.front();
265 m_header_commitments.pop_front();
266 if (commitment != expected_commitment) {
267 LogDebug(BCLog::NET, "Initial headers sync aborted with peer=%d: commitment mismatch at height=%i (redownload phase)\n", m_id, next_height);
268 return false;
269 }
270 }
271
272 // Store this header for later processing.

Callers

nothing calls this directly

Calls 9

GetBlockProofFunction · 0.85
emptyMethod · 0.45
backMethod · 0.45
sizeMethod · 0.45
GetHashMethod · 0.45
frontMethod · 0.45
pop_frontMethod · 0.45
emplace_backMethod · 0.45

Tested by

no test coverage detected