diff --git a/src/Makefile.am b/src/Makefile.am index 407fdf5a8fd4..14eec4ee849a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -208,12 +208,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 \ scheduler.h \ script/descriptor.h \ @@ -364,6 +364,7 @@ libbitcoin_server_a_SOURCES = \ rpc/net.cpp \ rpc/rawtransaction.cpp \ rpc/server.cpp \ + rpc/server_util.cpp \ script/sigcache.cpp \ shutdown.cpp \ signet.cpp \ diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 44f9879a232e..60d379be3135 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -288,6 +288,7 @@ class PeerManagerImpl final : public PeerManager /** Implement PeerManager */ 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; @@ -1376,6 +1377,43 @@ 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; + + // Construct message to request the block + std::vector invs{CInv(MSG_BLOCK | MSG_WITNESS_FLAG, hash)}; + + // Mark block as in-flight unless it already is, or unless we don't have the header + if (index != nullptr) { + if (!BlockRequested(id, *index)) return false; + } + + // 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::make(const CChainParams& chainparams, CConnman& connman, CAddrMan& addrman, BanMan* banman, CScheduler& scheduler, ChainstateManager& chainman, CTxMemPool& pool, bool ignore_incoming_txs) diff --git a/src/net_processing.h b/src/net_processing.h index c537efb5db95..35f14bfb5b16 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -41,6 +41,16 @@ class PeerManager : public CValidationInterface, public NetEventsInterface CTxMemPool& pool, bool ignore_incoming_txs); virtual ~PeerManager() { } + /** + * Attempt to manually fetch block from a given peer. + * + * @param[in] id The peer id + * @param[in] hash The block hash + * @param[in] pindex The blockindex if we have the header, otherwise nullptr + * @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/qt/test/addressbooktests.cpp b/src/qt/test/addressbooktests.cpp index 39c69fe1848b..816273766b29 100644 --- a/src/qt/test/addressbooktests.cpp +++ b/src/qt/test/addressbooktests.cpp @@ -62,6 +62,8 @@ void TestAddAddressesToSendBook(interfaces::Node& node) TestChain100Setup test; node.setContext(&test.m_node); std::shared_ptr wallet = std::make_shared(node.context()->chain.get(), "", CreateMockWalletDatabase()); + wallet->m_default_address_type = OutputType::BECH32; + wallet->SetupLegacyScriptPubKeyMan(); wallet->LoadWallet(); diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp index e883337fb53c..37bf8d5d2875 100644 --- a/src/qt/test/wallettests.cpp +++ b/src/qt/test/wallettests.cpp @@ -140,6 +140,7 @@ void TestGUI(interfaces::Node& node) } node.setContext(&test.m_node); std::shared_ptr wallet = std::make_shared(node.context()->chain.get(), "", CreateMockWalletDatabase()); + wallet->m_default_address_type = OutputType::BECH32; wallet->LoadWallet(); { auto spk_man = wallet->GetOrCreateLegacyScriptPubKeyMan(); diff --git a/src/rest.cpp b/src/rest.cpp index e50ab33e5440..a79d7782d49e 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index c4a89c9772ab..9e3479f51472 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -18,6 +18,8 @@ #include #include #include +#include // For NodeId +#include #include #include #include @@ -28,6 +30,7 @@ #include #include #include +#include #include #include