| 1787 | } |
| 1788 | |
| 1789 | void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv& inv) |
| 1790 | { |
| 1791 | std::shared_ptr<const CBlock> a_recent_block; |
| 1792 | std::shared_ptr<const CBlockHeaderAndShortTxIDs> a_recent_compact_block; |
| 1793 | bool fWitnessesPresentInARecentCompactBlock; |
| 1794 | { |
| 1795 | LOCK(cs_most_recent_block); |
| 1796 | a_recent_block = most_recent_block; |
| 1797 | a_recent_compact_block = most_recent_compact_block; |
| 1798 | fWitnessesPresentInARecentCompactBlock = fWitnessesPresentInMostRecentCompactBlock; |
| 1799 | } |
| 1800 | |
| 1801 | bool need_activate_chain = false; |
| 1802 | { |
| 1803 | LOCK(cs_main); |
| 1804 | const CBlockIndex* pindex = m_chainman.m_blockman.LookupBlockIndex(inv.hash); |
| 1805 | if (pindex) { |
| 1806 | if (pindex->HaveTxsDownloaded() && !pindex->IsValid(BLOCK_VALID_SCRIPTS) && |
| 1807 | pindex->IsValid(BLOCK_VALID_TREE)) { |
| 1808 | // If we have the block and all of its parents, but have not yet validated it, |
| 1809 | // we might be in the middle of connecting it (ie in the unlock of cs_main |
| 1810 | // before ActivateBestChain but after AcceptBlock). |
| 1811 | // In this case, we need to run ActivateBestChain prior to checking the relay |
| 1812 | // conditions below. |
| 1813 | need_activate_chain = true; |
| 1814 | } |
| 1815 | } |
| 1816 | } // release cs_main before calling ActivateBestChain |
| 1817 | if (need_activate_chain) { |
| 1818 | BlockValidationState state; |
| 1819 | if (!m_chainman.ActiveChainstate().ActivateBestChain(state, a_recent_block)) { |
| 1820 | LogPrint(BCLog::NET, "failed to activate chain (%s)\n", state.ToString()); |
| 1821 | } |
| 1822 | } |
| 1823 | |
| 1824 | LOCK(cs_main); |
| 1825 | const CBlockIndex* pindex = m_chainman.m_blockman.LookupBlockIndex(inv.hash); |
| 1826 | if (!pindex) { |
| 1827 | return; |
| 1828 | } |
| 1829 | if (!BlockRequestAllowed(pindex)) { |
| 1830 | LogPrint(BCLog::NET, "%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom.GetId()); |
| 1831 | return; |
| 1832 | } |
| 1833 | const CNetMsgMaker msgMaker(pfrom.GetCommonVersion()); |
| 1834 | // disconnect node in case we have reached the outbound limit for serving historical blocks |
| 1835 | if (m_connman.OutboundTargetReached(true) && |
| 1836 | (((pindexBestHeader != nullptr) && (pindexBestHeader->GetBlockTime() - pindex->GetBlockTime() > HISTORICAL_BLOCK_AGE)) || inv.IsMsgFilteredBlk()) && |
| 1837 | !pfrom.HasPermission(NetPermissionFlags::Download) // nodes with the download permission may exceed target |
| 1838 | ) { |
| 1839 | LogPrint(BCLog::NET, "historical block serving limit reached, disconnect peer=%d\n", pfrom.GetId()); |
| 1840 | pfrom.fDisconnect = true; |
| 1841 | return; |
| 1842 | } |
| 1843 | // Avoid leaking prune-height by never sending blocks below the NODE_NETWORK_LIMITED threshold |
| 1844 | if (!pfrom.HasPermission(NetPermissionFlags::NoBan) && ( |
| 1845 | (((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 */) ) |
| 1846 | )) { |
nothing calls this directly
no test coverage detected