From c294457b5295789b9d3ff67ed2de8632928a3671 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Wed, 26 Jun 2024 10:56:02 +0000 Subject: [PATCH] merge bitcoin#20295: getblockfrompeer --- src/Makefile.am | 3 +- src/net_processing.cpp | 34 +++++++ src/net_processing.h | 10 ++ src/rest.cpp | 1 + src/rpc/blockchain.cpp | 117 ++++++++++++------------ src/rpc/blockchain.h | 14 --- src/rpc/client.cpp | 1 + src/rpc/coinjoin.cpp | 2 +- src/rpc/evo.cpp | 1 + src/rpc/governance.cpp | 2 +- src/rpc/masternode.cpp | 2 +- src/rpc/mining.cpp | 2 +- src/rpc/misc.cpp | 2 +- src/rpc/net.cpp | 19 +--- src/rpc/net.h | 15 --- src/rpc/quorums.cpp | 2 +- src/rpc/rawtransaction.cpp | 1 + src/rpc/server.cpp | 1 + src/rpc/server_util.cpp | 93 +++++++++++++++++++ src/rpc/server_util.h | 30 ++++++ src/validation.cpp | 1 + test/functional/rpc_getblockfrompeer.py | 76 +++++++++++++++ test/functional/test_runner.py | 1 + 23 files changed, 315 insertions(+), 115 deletions(-) delete mode 100644 src/rpc/net.h create mode 100644 src/rpc/server_util.cpp create mode 100644 src/rpc/server_util.h create mode 100755 test/functional/rpc_getblockfrompeer.py diff --git a/src/Makefile.am b/src/Makefile.am index d63dff71cf..c5d69a6c0a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -287,12 +287,12 @@ BITCOIN_CORE_H = \ rpc/blockchain.h \ rpc/client.h \ rpc/mining.h \ - rpc/net.h \ rpc/protocol.h \ rpc/rawtransaction_util.h \ rpc/register.h \ rpc/request.h \ rpc/server.h \ + rpc/server_util.h \ rpc/util.h \ saltedhasher.h \ scheduler.h \ @@ -510,6 +510,7 @@ libbitcoin_server_a_SOURCES = \ rpc/quorums.cpp \ rpc/rawtransaction.cpp \ rpc/server.cpp \ + rpc/server_util.cpp \ script/sigcache.cpp \ shutdown.cpp \ spork.cpp \ diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 0504616f38..d36d0c472c 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -398,6 +398,7 @@ public: /** Implement PeerManager */ void CheckForStaleTipAndEvictPeers() override; + bool FetchBlock(NodeId id, const uint256& hash, const CBlockIndex& index) override; bool GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) const override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex); bool IgnoresIncomingTxs() override { return m_ignore_incoming_txs; } void SendPings() override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);; @@ -1862,6 +1863,39 @@ 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; + + // Mark block as in-flight unless it already is + if (!MarkBlockAsInFlight(id, index.GetBlockHash(), &index)) return false; + + // Construct message to request the block + std::vector invs{CInv(MSG_BLOCK, 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 { + MarkBlockAsReceived(hash); + LogPrint(BCLog::NET, "Failed to request block %s from peer=%d\n", + hash.ToString(), id); + } + return success; +} + std::unique_ptr PeerManager::make(const CChainParams& chainparams, CConnman& connman, AddrMan& addrman, BanMan* banman, CScheduler &scheduler, ChainstateManager& chainman, CTxMemPool& pool, CMasternodeMetaMan& mn_metaman, CMasternodeSync& mn_sync, diff --git a/src/net_processing.h b/src/net_processing.h index 8c575a3e64..20e11f98cf 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -66,6 +66,16 @@ public: const std::unique_ptr& llmq_ctx, bool ignore_incoming_txs); virtual ~PeerManager() { } + /** + * Attempt to manually fetch block from a given peer. We must already have the header. + * + * @param[in] id The peer id + * @param[in] hash The block hash + * @param[in] pindex The blockindex + * @returns Whether a request was successfully made + */ + virtual bool FetchBlock(NodeId id, const uint256& hash, const CBlockIndex& pindex) = 0; + /** Get statistics from node state */ virtual bool GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) const = 0; diff --git a/src/rest.cpp b/src/rest.cpp index afae27398f..3665e82741 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 3123d8c8bc..940f44e1fb 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include #include #include @@ -29,6 +31,7 @@ #include #include #include +#include #include #include