@@ -1530,7 +1530,6 @@ static void RelayAddress(const CNode& originator,
1530
1530
1531
1531
void PeerManagerImpl::ProcessGetBlockData (CNode& pfrom, Peer& peer, const CInv& inv)
1532
1532
{
1533
- bool send = false ;
1534
1533
std::shared_ptr<const CBlock> a_recent_block;
1535
1534
std::shared_ptr<const CBlockHeaderAndShortTxIDs> a_recent_compact_block;
1536
1535
bool fWitnessesPresentInARecentCompactBlock ;
@@ -1566,120 +1565,117 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
1566
1565
1567
1566
LOCK (cs_main);
1568
1567
const CBlockIndex* pindex = m_chainman.m_blockman .LookupBlockIndex (inv.hash );
1569
- if (pindex) {
1570
- send = BlockRequestAllowed (pindex);
1571
- if (!send) {
1572
- LogPrint (BCLog::NET, " %s: ignoring request from peer=%i for old block that isn't in the main chain\n " , __func__, pfrom.GetId ());
1573
- }
1568
+ if (!pindex) {
1569
+ return ;
1570
+ }
1571
+ if (!BlockRequestAllowed (pindex)) {
1572
+ LogPrint (BCLog::NET, " %s: ignoring request from peer=%i for old block that isn't in the main chain\n " , __func__, pfrom.GetId ());
1573
+ return ;
1574
1574
}
1575
1575
const CNetMsgMaker msgMaker (pfrom.GetCommonVersion ());
1576
1576
// disconnect node in case we have reached the outbound limit for serving historical blocks
1577
- if (send &&
1578
- m_connman.OutboundTargetReached (true ) &&
1577
+ if (m_connman.OutboundTargetReached (true ) &&
1579
1578
(((pindexBestHeader != nullptr ) && (pindexBestHeader->GetBlockTime () - pindex->GetBlockTime () > HISTORICAL_BLOCK_AGE)) || inv.IsMsgFilteredBlk ()) &&
1580
1579
!pfrom.HasPermission (PF_DOWNLOAD) // nodes with the download permission may exceed target
1581
1580
) {
1582
1581
LogPrint (BCLog::NET, " historical block serving limit reached, disconnect peer=%d\n " , pfrom.GetId ());
1583
-
1584
- // disconnect node
1585
1582
pfrom.fDisconnect = true ;
1586
- send = false ;
1583
+ return ;
1587
1584
}
1588
1585
// Avoid leaking prune-height by never sending blocks below the NODE_NETWORK_LIMITED threshold
1589
- if (send && !pfrom.HasPermission (PF_NOBAN) && (
1586
+ if (!pfrom.HasPermission (PF_NOBAN) && (
1590
1587
(((pfrom.GetLocalServices () & NODE_NETWORK_LIMITED) == NODE_NETWORK_LIMITED) && ((pfrom.GetLocalServices () & NODE_NETWORK) != NODE_NETWORK) && (m_chainman.ActiveChain ().Tip ()->nHeight - pindex->nHeight > (int )NODE_NETWORK_LIMITED_MIN_BLOCKS + 2 /* add two blocks buffer extension for possible races */ ) )
1591
1588
)) {
1592
- LogPrint (BCLog::NET, " Ignore block request below NODE_NETWORK_LIMITED threshold from peer=%d\n " , pfrom.GetId ());
1593
-
1589
+ LogPrint (BCLog::NET, " Ignore block request below NODE_NETWORK_LIMITED threshold, disconnect peer=%d\n " , pfrom.GetId ());
1594
1590
// disconnect node and prevent it from stalling (would otherwise wait for the missing block)
1595
1591
pfrom.fDisconnect = true ;
1596
- send = false ;
1592
+ return ;
1597
1593
}
1598
1594
// Pruned nodes may have deleted the block, so check whether
1599
1595
// it's available before trying to send.
1600
- if (send && (pindex->nStatus & BLOCK_HAVE_DATA))
1601
- {
1602
- std::shared_ptr<const CBlock> pblock;
1603
- if (a_recent_block && a_recent_block->GetHash () == pindex->GetBlockHash ()) {
1604
- pblock = a_recent_block;
1596
+ if (!(pindex->nStatus & BLOCK_HAVE_DATA)) {
1597
+ return ;
1598
+ }
1599
+ std::shared_ptr<const CBlock> pblock;
1600
+ if (a_recent_block && a_recent_block->GetHash () == pindex->GetBlockHash ()) {
1601
+ pblock = a_recent_block;
1602
+ } else if (inv.IsMsgWitnessBlk ()) {
1603
+ // Fast-path: in this case it is possible to serve the block directly from disk,
1604
+ // as the network format matches the format on disk
1605
+ std::vector<uint8_t > block_data;
1606
+ if (!ReadRawBlockFromDisk (block_data, pindex, m_chainparams.MessageStart ())) {
1607
+ assert (!" cannot load block from disk" );
1608
+ }
1609
+ m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::BLOCK, MakeSpan (block_data)));
1610
+ // Don't set pblock as we've sent the block
1611
+ } else {
1612
+ // Send block from disk
1613
+ std::shared_ptr<CBlock> pblockRead = std::make_shared<CBlock>();
1614
+ if (!ReadBlockFromDisk (*pblockRead, pindex, m_chainparams.GetConsensus ())) {
1615
+ assert (!" cannot load block from disk" );
1616
+ }
1617
+ pblock = pblockRead;
1618
+ }
1619
+ if (pblock) {
1620
+ if (inv.IsMsgBlk ()) {
1621
+ m_connman.PushMessage (&pfrom, msgMaker.Make (SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::BLOCK, *pblock));
1605
1622
} else if (inv.IsMsgWitnessBlk ()) {
1606
- // Fast-path: in this case it is possible to serve the block directly from disk,
1607
- // as the network format matches the format on disk
1608
- std::vector<uint8_t > block_data;
1609
- if (!ReadRawBlockFromDisk (block_data, pindex, m_chainparams.MessageStart ())) {
1610
- assert (!" cannot load block from disk" );
1623
+ m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::BLOCK, *pblock));
1624
+ } else if (inv.IsMsgFilteredBlk ()) {
1625
+ bool sendMerkleBlock = false ;
1626
+ CMerkleBlock merkleBlock;
1627
+ if (pfrom.m_tx_relay != nullptr ) {
1628
+ LOCK (pfrom.m_tx_relay ->cs_filter );
1629
+ if (pfrom.m_tx_relay ->pfilter ) {
1630
+ sendMerkleBlock = true ;
1631
+ merkleBlock = CMerkleBlock (*pblock, *pfrom.m_tx_relay ->pfilter );
1632
+ }
1611
1633
}
1612
- m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::BLOCK, MakeSpan (block_data)));
1613
- // Don't set pblock as we've sent the block
1614
- } else {
1615
- // Send block from disk
1616
- std::shared_ptr<CBlock> pblockRead = std::make_shared<CBlock>();
1617
- if (!ReadBlockFromDisk (*pblockRead, pindex, m_chainparams.GetConsensus ())) {
1618
- assert (!" cannot load block from disk" );
1634
+ if (sendMerkleBlock) {
1635
+ m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::MERKLEBLOCK, merkleBlock));
1636
+ // CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see
1637
+ // This avoids hurting performance by pointlessly requiring a round-trip
1638
+ // Note that there is currently no way for a node to request any single transactions we didn't send here -
1639
+ // they must either disconnect and retry or request the full block.
1640
+ // Thus, the protocol spec specified allows for us to provide duplicate txn here,
1641
+ // however we MUST always provide at least what the remote peer needs
1642
+ typedef std::pair<unsigned int , uint256> PairType;
1643
+ for (PairType& pair : merkleBlock.vMatchedTxn )
1644
+ m_connman.PushMessage (&pfrom, msgMaker.Make (SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::TX, *pblock->vtx [pair.first ]));
1619
1645
}
1620
- pblock = pblockRead;
1621
- }
1622
- if (pblock) {
1623
- if (inv.IsMsgBlk ()) {
1624
- m_connman.PushMessage (&pfrom, msgMaker.Make (SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::BLOCK, *pblock));
1625
- } else if (inv.IsMsgWitnessBlk ()) {
1626
- m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::BLOCK, *pblock));
1627
- } else if (inv.IsMsgFilteredBlk ()) {
1628
- bool sendMerkleBlock = false ;
1629
- CMerkleBlock merkleBlock;
1630
- if (pfrom.m_tx_relay != nullptr ) {
1631
- LOCK (pfrom.m_tx_relay ->cs_filter );
1632
- if (pfrom.m_tx_relay ->pfilter ) {
1633
- sendMerkleBlock = true ;
1634
- merkleBlock = CMerkleBlock (*pblock, *pfrom.m_tx_relay ->pfilter );
1635
- }
1636
- }
1637
- if (sendMerkleBlock) {
1638
- m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::MERKLEBLOCK, merkleBlock));
1639
- // CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see
1640
- // This avoids hurting performance by pointlessly requiring a round-trip
1641
- // Note that there is currently no way for a node to request any single transactions we didn't send here -
1642
- // they must either disconnect and retry or request the full block.
1643
- // Thus, the protocol spec specified allows for us to provide duplicate txn here,
1644
- // however we MUST always provide at least what the remote peer needs
1645
- typedef std::pair<unsigned int , uint256> PairType;
1646
- for (PairType& pair : merkleBlock.vMatchedTxn )
1647
- m_connman.PushMessage (&pfrom, msgMaker.Make (SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::TX, *pblock->vtx [pair.first ]));
1648
- }
1649
- // else
1650
- // no response
1651
- } else if (inv.IsMsgCmpctBlk ()) {
1652
- // If a peer is asking for old blocks, we're almost guaranteed
1653
- // they won't have a useful mempool to match against a compact block,
1654
- // and we don't feel like constructing the object for them, so
1655
- // instead we respond with the full, non-compact block.
1656
- bool fPeerWantsWitness = State (pfrom.GetId ())->fWantsCmpctWitness ;
1657
- int nSendFlags = fPeerWantsWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
1658
- if (CanDirectFetch () && pindex->nHeight >= m_chainman.ActiveChain ().Height () - MAX_CMPCTBLOCK_DEPTH) {
1659
- if ((fPeerWantsWitness || !fWitnessesPresentInARecentCompactBlock ) && a_recent_compact_block && a_recent_compact_block->header .GetHash () == pindex->GetBlockHash ()) {
1660
- m_connman.PushMessage (&pfrom, msgMaker.Make (nSendFlags, NetMsgType::CMPCTBLOCK, *a_recent_compact_block));
1661
- } else {
1662
- CBlockHeaderAndShortTxIDs cmpctblock (*pblock, fPeerWantsWitness );
1663
- m_connman.PushMessage (&pfrom, msgMaker.Make (nSendFlags, NetMsgType::CMPCTBLOCK, cmpctblock));
1664
- }
1646
+ // else
1647
+ // no response
1648
+ } else if (inv.IsMsgCmpctBlk ()) {
1649
+ // If a peer is asking for old blocks, we're almost guaranteed
1650
+ // they won't have a useful mempool to match against a compact block,
1651
+ // and we don't feel like constructing the object for them, so
1652
+ // instead we respond with the full, non-compact block.
1653
+ bool fPeerWantsWitness = State (pfrom.GetId ())->fWantsCmpctWitness ;
1654
+ int nSendFlags = fPeerWantsWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
1655
+ if (CanDirectFetch () && pindex->nHeight >= m_chainman.ActiveChain ().Height () - MAX_CMPCTBLOCK_DEPTH) {
1656
+ if ((fPeerWantsWitness || !fWitnessesPresentInARecentCompactBlock ) && a_recent_compact_block && a_recent_compact_block->header .GetHash () == pindex->GetBlockHash ()) {
1657
+ m_connman.PushMessage (&pfrom, msgMaker.Make (nSendFlags, NetMsgType::CMPCTBLOCK, *a_recent_compact_block));
1665
1658
} else {
1666
- m_connman.PushMessage (&pfrom, msgMaker.Make (nSendFlags, NetMsgType::BLOCK, *pblock));
1659
+ CBlockHeaderAndShortTxIDs cmpctblock (*pblock, fPeerWantsWitness );
1660
+ m_connman.PushMessage (&pfrom, msgMaker.Make (nSendFlags, NetMsgType::CMPCTBLOCK, cmpctblock));
1667
1661
}
1662
+ } else {
1663
+ m_connman.PushMessage (&pfrom, msgMaker.Make (nSendFlags, NetMsgType::BLOCK, *pblock));
1668
1664
}
1669
1665
}
1666
+ }
1670
1667
1671
- {
1672
- LOCK (peer.m_block_inv_mutex );
1673
- // Trigger the peer node to send a getblocks request for the next batch of inventory
1674
- if (inv.hash == peer.m_continuation_block ) {
1675
- // Send immediately. This must send even if redundant,
1676
- // and we want it right after the last block so they don't
1677
- // wait for other stuff first.
1678
- std::vector<CInv> vInv;
1679
- vInv.push_back (CInv (MSG_BLOCK, m_chainman.ActiveChain ().Tip ()->GetBlockHash ()));
1680
- m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::INV, vInv));
1681
- peer.m_continuation_block .SetNull ();
1682
- }
1668
+ {
1669
+ LOCK (peer.m_block_inv_mutex );
1670
+ // Trigger the peer node to send a getblocks request for the next batch of inventory
1671
+ if (inv.hash == peer.m_continuation_block ) {
1672
+ // Send immediately. This must send even if redundant,
1673
+ // and we want it right after the last block so they don't
1674
+ // wait for other stuff first.
1675
+ std::vector<CInv> vInv;
1676
+ vInv.push_back (CInv (MSG_BLOCK, m_chainman.ActiveChain ().Tip ()->GetBlockHash ()));
1677
+ m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::INV, vInv));
1678
+ peer.m_continuation_block .SetNull ();
1683
1679
}
1684
1680
}
1685
1681
}
0 commit comments