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

Method ProcessNextHeaders

src/headerssync.cpp:68–137  ·  view source on GitHub ↗

Process the next batch of headers received from our peer. * Validate and store commitments, and compare total chainwork to our target to * see if we can switch to REDOWNLOAD mode. */

Source from the content-addressed store, hash-verified

66 * Validate and store commitments, and compare total chainwork to our target to
67 * see if we can switch to REDOWNLOAD mode. */
68HeadersSyncState::ProcessingResult HeadersSyncState::ProcessNextHeaders(
69 std::span<const CBlockHeader> received_headers, const bool full_headers_message)
70{
71 ProcessingResult ret;
72
73 Assume(!received_headers.empty());
74 if (received_headers.empty()) return ret;
75
76 Assume(m_download_state != State::FINAL);
77 if (m_download_state == State::FINAL) return ret;
78
79 if (m_download_state == State::PRESYNC) {
80 // During PRESYNC, we minimally validate block headers and
81 // occasionally add commitments to them, until we reach our work
82 // threshold (at which point m_download_state is updated to REDOWNLOAD).
83 ret.success = ValidateAndStoreHeadersCommitments(received_headers);
84 if (ret.success) {
85 if (full_headers_message || m_download_state == State::REDOWNLOAD) {
86 // A full headers message means the peer may have more to give us;
87 // also if we just switched to REDOWNLOAD then we need to re-request
88 // headers from the beginning.
89 ret.request_more = true;
90 } else {
91 Assume(m_download_state == State::PRESYNC);
92 // If we're in PRESYNC and we get a non-full headers
93 // message, then the peer's chain has ended and definitely doesn't
94 // have enough work, so we can stop our sync.
95 LogDebug(BCLog::NET, "Initial headers sync aborted with peer=%d: incomplete headers message at height=%i (presync phase)\n", m_id, m_current_height);
96 }
97 }
98 } else if (m_download_state == State::REDOWNLOAD) {
99 // During REDOWNLOAD, we compare our stored commitments to what we
100 // receive, and add headers to our redownload buffer. When the buffer
101 // gets big enough (meaning that we've checked enough commitments),
102 // we'll return a batch of headers to the caller for processing.
103 ret.success = true;
104 for (const auto& hdr : received_headers) {
105 if (!ValidateAndStoreRedownloadedHeader(hdr)) {
106 // Something went wrong -- the peer gave us an unexpected chain.
107 // We could consider looking at the reason for failure and
108 // punishing the peer, but for now just give up on sync.
109 ret.success = false;
110 break;
111 }
112 }
113
114 if (ret.success) {
115 // Return any headers that are ready for acceptance.
116 ret.pow_validated_headers = PopHeadersReadyForAcceptance();
117
118 // If we hit our target blockhash, then all remaining headers will be
119 // returned and we can clear any leftover internal state.
120 if (m_redownloaded_headers.empty() && m_process_all_remaining_headers) {
121 LogDebug(BCLog::NET, "Initial headers sync complete with peer=%d: releasing all at height=%i (redownload phase)\n", m_id, m_redownload_buffer_last_height);
122 } else if (full_headers_message) {
123 // If the headers message is full, we need to request more.
124 ret.request_more = true;
125 } else {

Callers 3

BOOST_AUTO_TEST_CASEFunction · 0.80
headerssync.cppFile · 0.80

Calls 1

emptyMethod · 0.45

Tested by 1

BOOST_AUTO_TEST_CASEFunction · 0.64