@@ -1596,88 +1596,86 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
1596
1596
if (!(pindex->nStatus & BLOCK_HAVE_DATA)) {
1597
1597
return ;
1598
1598
}
1599
- {
1600
- std::shared_ptr<const CBlock> pblock;
1601
- if (a_recent_block && a_recent_block->GetHash () == pindex->GetBlockHash ()) {
1602
- pblock = a_recent_block;
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));
1603
1622
} else if (inv.IsMsgWitnessBlk ()) {
1604
- // Fast-path: in this case it is possible to serve the block directly from disk,
1605
- // as the network format matches the format on disk
1606
- std::vector<uint8_t > block_data;
1607
- if (!ReadRawBlockFromDisk (block_data, pindex, m_chainparams.MessageStart ())) {
1608
- 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
+ }
1609
1633
}
1610
- m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::BLOCK, MakeSpan (block_data)));
1611
- // Don't set pblock as we've sent the block
1612
- } else {
1613
- // Send block from disk
1614
- std::shared_ptr<CBlock> pblockRead = std::make_shared<CBlock>();
1615
- if (!ReadBlockFromDisk (*pblockRead, pindex, m_chainparams.GetConsensus ())) {
1616
- 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 ]));
1617
1645
}
1618
- pblock = pblockRead;
1619
- }
1620
- if (pblock) {
1621
- if (inv.IsMsgBlk ()) {
1622
- m_connman.PushMessage (&pfrom, msgMaker.Make (SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::BLOCK, *pblock));
1623
- } else if (inv.IsMsgWitnessBlk ()) {
1624
- m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::BLOCK, *pblock));
1625
- } else if (inv.IsMsgFilteredBlk ()) {
1626
- bool sendMerkleBlock = false ;
1627
- CMerkleBlock merkleBlock;
1628
- if (pfrom.m_tx_relay != nullptr ) {
1629
- LOCK (pfrom.m_tx_relay ->cs_filter );
1630
- if (pfrom.m_tx_relay ->pfilter ) {
1631
- sendMerkleBlock = true ;
1632
- merkleBlock = CMerkleBlock (*pblock, *pfrom.m_tx_relay ->pfilter );
1633
- }
1634
- }
1635
- if (sendMerkleBlock) {
1636
- m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::MERKLEBLOCK, merkleBlock));
1637
- // CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see
1638
- // This avoids hurting performance by pointlessly requiring a round-trip
1639
- // Note that there is currently no way for a node to request any single transactions we didn't send here -
1640
- // they must either disconnect and retry or request the full block.
1641
- // Thus, the protocol spec specified allows for us to provide duplicate txn here,
1642
- // however we MUST always provide at least what the remote peer needs
1643
- typedef std::pair<unsigned int , uint256> PairType;
1644
- for (PairType& pair : merkleBlock.vMatchedTxn )
1645
- m_connman.PushMessage (&pfrom, msgMaker.Make (SERIALIZE_TRANSACTION_NO_WITNESS, NetMsgType::TX, *pblock->vtx [pair.first ]));
1646
- }
1647
- // else
1648
- // no response
1649
- } else if (inv.IsMsgCmpctBlk ()) {
1650
- // If a peer is asking for old blocks, we're almost guaranteed
1651
- // they won't have a useful mempool to match against a compact block,
1652
- // and we don't feel like constructing the object for them, so
1653
- // instead we respond with the full, non-compact block.
1654
- bool fPeerWantsWitness = State (pfrom.GetId ())->fWantsCmpctWitness ;
1655
- int nSendFlags = fPeerWantsWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS;
1656
- if (CanDirectFetch () && pindex->nHeight >= m_chainman.ActiveChain ().Height () - MAX_CMPCTBLOCK_DEPTH) {
1657
- if ((fPeerWantsWitness || !fWitnessesPresentInARecentCompactBlock ) && a_recent_compact_block && a_recent_compact_block->header .GetHash () == pindex->GetBlockHash ()) {
1658
- m_connman.PushMessage (&pfrom, msgMaker.Make (nSendFlags, NetMsgType::CMPCTBLOCK, *a_recent_compact_block));
1659
- } else {
1660
- CBlockHeaderAndShortTxIDs cmpctblock (*pblock, fPeerWantsWitness );
1661
- m_connman.PushMessage (&pfrom, msgMaker.Make (nSendFlags, NetMsgType::CMPCTBLOCK, cmpctblock));
1662
- }
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));
1663
1658
} else {
1664
- 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));
1665
1661
}
1662
+ } else {
1663
+ m_connman.PushMessage (&pfrom, msgMaker.Make (nSendFlags, NetMsgType::BLOCK, *pblock));
1666
1664
}
1667
1665
}
1666
+ }
1668
1667
1669
- {
1670
- LOCK (peer.m_block_inv_mutex );
1671
- // Trigger the peer node to send a getblocks request for the next batch of inventory
1672
- if (inv.hash == peer.m_continuation_block ) {
1673
- // Send immediately. This must send even if redundant,
1674
- // and we want it right after the last block so they don't
1675
- // wait for other stuff first.
1676
- std::vector<CInv> vInv;
1677
- vInv.push_back (CInv (MSG_BLOCK, m_chainman.ActiveChain ().Tip ()->GetBlockHash ()));
1678
- m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::INV, vInv));
1679
- peer.m_continuation_block .SetNull ();
1680
- }
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 ();
1681
1679
}
1682
1680
}
1683
1681
}
0 commit comments