aboutsummaryrefslogtreecommitdiff
path: root/src/net_processing.cpp
diff options
context:
space:
mode:
authorSjors Provoost <sjors@sprovoost.nl>2021-05-13 18:51:47 +0200
committerSjors Provoost <sjors@sprovoost.nl>2021-12-02 13:16:18 +0700
commitdce8c4c38111556ca480aa0e63c46b71f66b508f (patch)
treed43051c4e187c70cf3d700d8eb308012811b041a /src/net_processing.cpp
parentb884ababc29ce963826d8a4327ed6a5e629ff175 (diff)
downloadbitcoin-dce8c4c38111556ca480aa0e63c46b71f66b508f.tar.xz
rpc: getblockfrompeer
Co-authored-by: John Newbery <john@johnnewbery.com>
Diffstat (limited to 'src/net_processing.cpp')
-rw-r--r--src/net_processing.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index 3f755eb178..866a344dd3 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -312,6 +312,7 @@ public:
/** Implement PeerManager */
void StartScheduledTasks(CScheduler& scheduler) override;
void CheckForStaleTipAndEvictPeers() override;
+ bool FetchBlock(NodeId id, const uint256& hash, const CBlockIndex& index) override;
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) const override;
bool IgnoresIncomingTxs() override { return m_ignore_incoming_txs; }
void SendPings() override;
@@ -1427,6 +1428,41 @@ bool PeerManagerImpl::BlockRequestAllowed(const CBlockIndex* pindex)
(GetBlockProofEquivalentTime(*pindexBestHeader, *pindex, *pindexBestHeader, m_chainparams.GetConsensus()) < STALE_RELAY_AGE_LIMIT);
}
+bool PeerManagerImpl::FetchBlock(NodeId id, const uint256& hash, const CBlockIndex& index)
+{
+ if (fImporting || fReindex) return false;
+
+ LOCK(cs_main);
+ // Ensure this peer exists and hasn't been disconnected
+ CNodeState* state = State(id);
+ if (state == nullptr) return false;
+ // Ignore pre-segwit peers
+ if (!state->fHaveWitness) return false;
+
+ // Mark block as in-flight unless it already is
+ if (!BlockRequested(id, index)) return false;
+
+ // Construct message to request the block
+ std::vector<CInv> invs{CInv(MSG_BLOCK | MSG_WITNESS_FLAG, hash)};
+
+ // Send block request message to the peer
+ bool success = m_connman.ForNode(id, [this, &invs](CNode* node) {
+ const CNetMsgMaker msgMaker(node->GetCommonVersion());
+ this->m_connman.PushMessage(node, msgMaker.Make(NetMsgType::GETDATA, invs));
+ return true;
+ });
+
+ if (success) {
+ LogPrint(BCLog::NET, "Requesting block %s from peer=%d\n",
+ hash.ToString(), id);
+ } else {
+ RemoveBlockRequest(hash);
+ LogPrint(BCLog::NET, "Failed to request block %s from peer=%d\n",
+ hash.ToString(), id);
+ }
+ return success;
+}
+
std::unique_ptr<PeerManager> PeerManager::make(const CChainParams& chainparams, CConnman& connman, AddrMan& addrman,
BanMan* banman, ChainstateManager& chainman,
CTxMemPool& pool, bool ignore_incoming_txs)