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

Method ProcessCompactBlockTxns

src/net_processing.cpp:3472–3557  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

3470}
3471
3472void PeerManagerImpl::ProcessCompactBlockTxns(CNode& pfrom, Peer& peer, const BlockTransactions& block_transactions)
3473{
3474 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
3475 bool fBlockRead{false};
3476 {
3477 LOCK(cs_main);
3478
3479 auto range_flight = mapBlocksInFlight.equal_range(block_transactions.blockhash);
3480 size_t already_in_flight = std::distance(range_flight.first, range_flight.second);
3481 bool requested_block_from_this_peer{false};
3482
3483 // Multimap ensures ordering of outstanding requests. It's either empty or first in line.
3484 bool first_in_flight = already_in_flight == 0 || (range_flight.first->second.first == pfrom.GetId());
3485
3486 while (range_flight.first != range_flight.second) {
3487 auto [node_id, block_it] = range_flight.first->second;
3488 if (node_id == pfrom.GetId() && block_it->partialBlock) {
3489 requested_block_from_this_peer = true;
3490 break;
3491 }
3492 range_flight.first++;
3493 }
3494
3495 if (!requested_block_from_this_peer) {
3496 LogDebug(BCLog::NET, "Peer %d sent us block transactions for block we weren't expecting\n", pfrom.GetId());
3497 return;
3498 }
3499
3500 PartiallyDownloadedBlock& partialBlock = *range_flight.first->second.second->partialBlock;
3501
3502 if (partialBlock.header.IsNull()) {
3503 // It is possible for the header to be empty if a previous call to FillBlock wiped the header, but left
3504 // the PartiallyDownloadedBlock pointer around (i.e. did not call RemoveBlockRequest). In this case, we
3505 // should not call LookupBlockIndex below.
3506 RemoveBlockRequest(block_transactions.blockhash, pfrom.GetId());
3507 Misbehaving(peer, "previous compact block reconstruction attempt failed");
3508 LogDebug(BCLog::NET, "Peer %d sent compact block transactions multiple times", pfrom.GetId());
3509 return;
3510 }
3511
3512 // We should not have gotten this far in compact block processing unless it's attached to a known header
3513 const CBlockIndex* prev_block{Assume(m_chainman.m_blockman.LookupBlockIndex(partialBlock.header.hashPrevBlock))};
3514 ReadStatus status = partialBlock.FillBlock(*pblock, block_transactions.txn,
3515 /*segwit_active=*/DeploymentActiveAfter(prev_block, m_chainman, Consensus::DEPLOYMENT_SEGWIT));
3516 if (status == READ_STATUS_INVALID) {
3517 RemoveBlockRequest(block_transactions.blockhash, pfrom.GetId()); // Reset in-flight state in case Misbehaving does not result in a disconnect
3518 Misbehaving(peer, "invalid compact block/non-matching block transactions");
3519 return;
3520 } else if (status == READ_STATUS_FAILED) {
3521 if (first_in_flight) {
3522 // Might have collided, fall back to getdata now :(
3523 // We keep the failed partialBlock to disallow processing another compact block announcement from the same
3524 // peer for the same block. We let the full block download below continue under the same m_downloading_since
3525 // timer.
3526 std::vector<CInv> invs;
3527 invs.emplace_back(MSG_BLOCK | GetFetchFlags(peer), block_transactions.blockhash);
3528 MakeAndPushMessage(pfrom, NetMsgType::GETDATA, invs);
3529 } else {

Callers

nothing calls this directly

Calls 8

ProcessBlockFunction · 0.85
GetIdMethod · 0.80
LookupBlockIndexMethod · 0.80
FillBlockMethod · 0.80
emplaceMethod · 0.80
DeploymentActiveAfterFunction · 0.70
IsNullMethod · 0.45
emplace_backMethod · 0.45

Tested by

no test coverage detected