Skip to content

Commit 957f3a2

Browse files
committed
fix net processing file for different template unserialize issue
1 parent 312da73 commit 957f3a2

File tree

1 file changed

+53
-10
lines changed

1 file changed

+53
-10
lines changed

src/net_processing.cpp

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,20 @@ static constexpr uint64_t CMPCTBLOCKS_VERSION{2};
209209

210210
// Internal stuff
211211
namespace {
212+
213+
struct HeaderWithTxCount {
214+
CBlockHeader header;
215+
216+
uint256 GetHash() const { return header.GetHash(); }
217+
218+
template<typename Stream>
219+
void Serialize(Stream& s) const {
220+
s << TX_WITH_WITNESS(header);
221+
WriteCompactSize(s, 0); // txcount = 0
222+
}
223+
// Unserialize not needed - this is only used for sending
224+
};
225+
212226
/** Blocks that are in flight, and that are in the queue to be downloaded. */
213227
struct QueuedBlock {
214228
/** BlockIndex. We must have this since we only request blocks when we've already validated the header. */
@@ -4352,7 +4366,9 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
43524366
}
43534367

43544368
// we must use CBlocks, as CBlockHeaders won't include the 0x00 nTx count at the end
4355-
std::vector<CBlock> vHeaders;
4369+
// Use HeaderWithTxCount (defined above) to serialize headers correctly for P2P.
4370+
// Our CBlock has extra fields that aren't part of the headers protocol.
4371+
std::vector<HeaderWithTxCount> vHeaders;
43564372
unsigned nCount = 0;
43574373
unsigned nSize = 0;
43584374
LogDebug(BCLog::NET, "getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.IsNull() ? "end" : hashStop.ToString(), pfrom.GetId());
@@ -4366,8 +4382,8 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
43664382
}
43674383

43684384
++nCount;
4369-
nSize += GetSerializeSize(header);
4370-
vHeaders.emplace_back(header);
4385+
nSize += GetSerializeSize(TX_WITH_WITNESS(header)) + 1; // header + txcount byte
4386+
vHeaders.push_back(HeaderWithTxCount{header});
43714387
if (nCount >= m_opts.max_headers_result
43724388
|| pindex->GetBlockHash() == hashStop)
43734389
break;
@@ -4394,8 +4410,9 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
43944410
// without the new block. By resetting the BestHeaderSent, we ensure we
43954411
// will re-announce the new block via headers (or compact blocks again)
43964412
// in the SendMessages logic.
4413+
43974414
nodestate->pindexBestHeaderSent = pindex ? pindex : m_chainman.ActiveChain().Tip();
4398-
MakeAndPushMessage(pfrom, NetMsgType::HEADERS, TX_WITH_WITNESS(vHeaders));
4415+
MakeAndPushMessage(pfrom, NetMsgType::HEADERS, vHeaders);
43994416
}
44004417
return;
44014418
}
@@ -4745,15 +4762,41 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
47454762
std::vector<CBlockHeader> headers;
47464763

47474764
// Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks.
4765+
size_t pos_before_count = vRecv.size();
47484766
unsigned int nCount = ReadCompactSize(vRecv);
4767+
LogPrintf("HEADERS DEBUG: nCount=%u, message_size=%zu\n", nCount, pos_before_count);
4768+
47494769
if (nCount > m_opts.max_headers_result) {
47504770
Misbehaving(*peer, strprintf("headers message size = %u", nCount));
47514771
return;
47524772
}
47534773
headers.resize(nCount);
47544774
for (unsigned int n = 0; n < nCount; n++) {
4755-
vRecv >> headers[n];
4756-
ReadCompactSize(vRecv); // ignore tx count; assume it is 0.
4775+
// vRecv >> headers[n];
4776+
// ReadCompactSize(vRecv); // ignore tx count; assume it is 0.
4777+
4778+
size_t pos_before_header = vRecv.size();
4779+
try {
4780+
vRecv >> headers[n];
4781+
} catch (const std::exception& e) {
4782+
LogPrintf("HEADERS DEBUG: Failed deserializing header %u/%u at stream pos %zu, remaining bytes: %zu, error: %s\n",
4783+
n, nCount, pos_before_header, vRecv.size(), e.what());
4784+
LogPrintf("HEADERS DEBUG: Header version=0x%08x, IsAuxpow=%d\n",
4785+
headers[n].nVersion, headers[n].IsAuxpow());
4786+
throw;
4787+
}
4788+
size_t pos_after_header = vRecv.size();
4789+
size_t header_size = pos_before_header - pos_after_header;
4790+
4791+
try {
4792+
uint64_t txcount = ReadCompactSize(vRecv); // ignore tx count; assume it is 0.
4793+
LogPrintf("HEADERS DEBUG: header %u/%u size=%zu bytes, txcount=%lu, IsAuxpow=%d\n",
4794+
n, nCount, header_size, txcount, headers[n].IsAuxpow());
4795+
} catch (const std::exception& e) {
4796+
LogPrintf("HEADERS DEBUG: Failed reading txcount after header %u/%u, header_size=%zu, error: %s\n",
4797+
n, nCount, header_size, e.what());
4798+
throw;
4799+
}
47574800
}
47584801

47594802

@@ -5822,7 +5865,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
58225865
// blocks, or if the peer doesn't want headers, just
58235866
// add all to the inv queue.
58245867
LOCK(peer->m_block_inv_mutex);
5825-
std::vector<CBlock> vHeaders;
5868+
std::vector<HeaderWithTxCount> vHeaders;
58265869
bool fRevertToInv = ((!peer->m_prefers_headers &&
58275870
(!state.m_requested_hb_cmpctblocks || peer->m_blocks_for_headers_relay.size() > 1)) ||
58285871
peer->m_blocks_for_headers_relay.size() > MAX_BLOCKS_TO_ANNOUNCE);
@@ -5860,14 +5903,14 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
58605903
pBestIndex = pindex;
58615904
if (fFoundStartingHeader) {
58625905
// add this to the headers message
5863-
vHeaders.emplace_back(pindex->GetBlockHeader(m_chainman.m_blockman));
5906+
vHeaders.push_back(HeaderWithTxCount{pindex->GetBlockHeader(m_chainman.m_blockman)});
58645907
} else if (PeerHasHeader(&state, pindex)) {
58655908
continue; // keep looking for the first new block
58665909
} else if (pindex->pprev == nullptr || PeerHasHeader(&state, pindex->pprev)) {
58675910
// Peer doesn't have this header but they do have the prior one.
58685911
// Start sending headers.
58695912
fFoundStartingHeader = true;
5870-
vHeaders.emplace_back(pindex->GetBlockHeader(m_chainman.m_blockman));
5913+
vHeaders.push_back(HeaderWithTxCount{pindex->GetBlockHeader(m_chainman.m_blockman)});
58715914
} else {
58725915
// Peer doesn't have this header or the prior one -- nothing will
58735916
// connect, so bail out.
@@ -5910,7 +5953,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
59105953
LogDebug(BCLog::NET, "%s: sending header %s to peer=%d\n", __func__,
59115954
vHeaders.front().GetHash().ToString(), pto->GetId());
59125955
}
5913-
MakeAndPushMessage(*pto, NetMsgType::HEADERS, TX_WITH_WITNESS(vHeaders));
5956+
MakeAndPushMessage(*pto, NetMsgType::HEADERS, vHeaders);
59145957
state.pindexBestHeaderSent = pBestIndex;
59155958
} else
59165959
fRevertToInv = true;

0 commit comments

Comments
 (0)