Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down Expand Up @@ -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 \
Expand Down
38 changes: 38 additions & 0 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<CInv> 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> PeerManager::make(const CChainParams& chainparams, CConnman& connman, CAddrMan& addrman,
BanMan* banman, CScheduler& scheduler, ChainstateManager& chainman,
CTxMemPool& pool, bool ignore_incoming_txs)
Expand Down
10 changes: 10 additions & 0 deletions src/net_processing.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 2 additions & 0 deletions src/qt/test/addressbooktests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ void TestAddAddressesToSendBook(interfaces::Node& node)
TestChain100Setup test;
node.setContext(&test.m_node);
std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(node.context()->chain.get(), "", CreateMockWalletDatabase());
wallet->m_default_address_type = OutputType::BECH32;

wallet->SetupLegacyScriptPubKeyMan();
wallet->LoadWallet();

Expand Down
1 change: 1 addition & 0 deletions src/qt/test/wallettests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ void TestGUI(interfaces::Node& node)
}
node.setContext(&test.m_node);
std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(node.context()->chain.get(), "", CreateMockWalletDatabase());
wallet->m_default_address_type = OutputType::BECH32;
wallet->LoadWallet();
{
auto spk_man = wallet->GetOrCreateLegacyScriptPubKeyMan();
Expand Down
1 change: 1 addition & 0 deletions src/rest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <rpc/blockchain.h>
#include <rpc/protocol.h>
#include <rpc/server.h>
#include <rpc/server_util.h>
#include <streams.h>
#include <sync.h>
#include <txmempool.h>
Expand Down
86 changes: 37 additions & 49 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include <hash.h>
#include <index/blockfilterindex.h>
#include <index/coinstatsindex.h>
#include <net.h> // For NodeId
#include <net_processing.h>
#include <node/blockstorage.h>
#include <node/coinstats.h>
#include <node/context.h>
Expand All @@ -28,6 +30,7 @@
#include <policy/rbf.h>
#include <primitives/transaction.h>
#include <rpc/server.h>
#include <rpc/server_util.h>
#include <rpc/util.h>
#include <script/descriptor.h>
#include <streams.h>
Expand All @@ -36,7 +39,6 @@
#include <txmempool.h>
#include <undo.h>
#include <util/strencodings.h>
#include <util/system.h>
#include <util/translation.h>
#include <validation.h>
#include <validationinterface.h>
Expand All @@ -61,54 +63,6 @@ static Mutex cs_blockchange;
static std::condition_variable cond_blockchange;
static CUpdatedBlock latestblock GUARDED_BY(cs_blockchange);

NodeContext& EnsureAnyNodeContext(const std::any& context)
{
auto node_context = util::AnyPtr<NodeContext>(context);
if (!node_context) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Node context not found");
}
return *node_context;
}

CTxMemPool& EnsureMemPool(const NodeContext& node)
{
if (!node.mempool) {
throw JSONRPCError(RPC_CLIENT_MEMPOOL_DISABLED, "Mempool disabled or instance not found");
}
return *node.mempool;
}

CTxMemPool& EnsureAnyMemPool(const std::any& context)
{
return EnsureMemPool(EnsureAnyNodeContext(context));
}

ChainstateManager& EnsureChainman(const NodeContext& node)
{
if (!node.chainman) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Node chainman not found");
}
return *node.chainman;
}

ChainstateManager& EnsureAnyChainman(const std::any& context)
{
return EnsureChainman(EnsureAnyNodeContext(context));
}

CBlockPolicyEstimator& EnsureFeeEstimator(const NodeContext& node)
{
if (!node.fee_estimator) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Fee estimation disabled");
}
return *node.fee_estimator;
}

CBlockPolicyEstimator& EnsureAnyFeeEstimator(const std::any& context)
{
return EnsureFeeEstimator(EnsureAnyNodeContext(context));
}

/* Calculate the difficulty for a given block index.
*/
double GetDifficulty(const CBlockIndex* blockindex)
Expand Down Expand Up @@ -795,6 +749,39 @@ static RPCHelpMan getmempoolentry()
};
}

static RPCHelpMan getblockfrompeer()
{
return RPCHelpMan{"getblockfrompeer",
"\nAttempt to fetch block from a given peer.\n",
{
{"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash"},
{"nodeid", RPCArg::Type::NUM, RPCArg::Optional::NO, "The node ID (see getpeerinfo for node IDs)"},
},
RPCResult{RPCResult::Type::ANY, "", ""},
RPCExamples{
HelpExampleCli("getblockfrompeer", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" 0")
+ HelpExampleRpc("getblockfrompeer", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" 0")
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
const NodeContext& node = EnsureAnyNodeContext(request.context);
ChainstateManager& chainman = EnsureChainman(node);
PeerManager& peerman = EnsurePeerman(node);

uint256 hash(ParseHashV(request.params[0], "hash"));

const NodeId nodeid = static_cast<NodeId>(request.params[1].get_int64());

const CBlockIndex* const pblockindex = WITH_LOCK(cs_main, return chainman.m_blockman.LookupBlockIndex(hash););

if (!peerman.FetchBlock(nodeid, hash, pblockindex)) {
throw JSONRPCError(RPC_MISC_ERROR, "Failed to fetch block from peer");
}
return UniValue::VOBJ;
},
};
}

static RPCHelpMan getblockhash()
{
return RPCHelpMan{"getblockhash",
Expand Down Expand Up @@ -2638,6 +2625,7 @@ static const CRPCCommand commands[] =
{ "blockchain", &getbestblockhash, },
{ "blockchain", &getblockcount, },
{ "blockchain", &getblock, },
{ "blockchain", &getblockfrompeer, },
{ "blockchain", &getblockhash, },
{ "blockchain", &getblockheader, },
{ "blockchain", &getchaintips, },
Expand Down
9 changes: 0 additions & 9 deletions src/rpc/blockchain.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ extern RecursiveMutex cs_main;

class CBlock;
class CBlockIndex;
class CBlockPolicyEstimator;
class CChainState;
class CTxMemPool;
class ChainstateManager;
Expand Down Expand Up @@ -56,14 +55,6 @@ void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES],
void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex = true, int serialize_flags = 0, const CTxUndo* txundo = nullptr);

NodeContext& EnsureAnyNodeContext(const std::any& context);
CTxMemPool& EnsureMemPool(const NodeContext& node);
CTxMemPool& EnsureAnyMemPool(const std::any& context);
ChainstateManager& EnsureChainman(const NodeContext& node);
ChainstateManager& EnsureAnyChainman(const std::any& context);
CBlockPolicyEstimator& EnsureFeeEstimator(const NodeContext& node);
CBlockPolicyEstimator& EnsureAnyFeeEstimator(const std::any& context);

/**
* Helper to create UTXO snapshots given a chainstate and a file handle.
* @return a UniValue map containing metadata about the snapshot.
Expand Down
1 change: 1 addition & 0 deletions src/rpc/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "getbalance", 1, "minconf" },
{ "getbalance", 2, "include_watchonly" },
{ "getbalance", 3, "avoid_reuse" },
{ "getblockfrompeer", 1, "nodeid" },
{ "getblockhash", 0, "height" },
{ "waitforblockheight", 0, "height" },
{ "waitforblockheight", 1, "timeout" },
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/mining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
#include <pow.h>
#include <rpc/blockchain.h>
#include <rpc/mining.h>
#include <rpc/net.h>
#include <rpc/server.h>
#include <rpc/server_util.h>
#include <rpc/util.h>
#include <script/descriptor.h>
#include <script/script.h>
Expand Down
1 change: 1 addition & 0 deletions src/rpc/misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <outputtype.h>
#include <rpc/blockchain.h>
#include <rpc/server.h>
#include <rpc/server_util.h>
#include <rpc/util.h>
#include <scheduler.h>
#include <script/descriptor.h>
Expand Down
19 changes: 1 addition & 18 deletions src/rpc/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include <chainparams.h>
#include <clientversion.h>
#include <core_io.h>
#include <net.h>
#include <net_permissions.h>
#include <net_processing.h>
#include <net_types.h> // For banmap_t
Expand All @@ -17,12 +16,12 @@
#include <policy/settings.h>
#include <rpc/blockchain.h>
#include <rpc/protocol.h>
#include <rpc/server_util.h>
#include <rpc/util.h>
#include <sync.h>
#include <timedata.h>
#include <util/strencodings.h>
#include <util/string.h>
#include <util/system.h>
#include <util/translation.h>
#include <validation.h>
#include <version.h>
Expand All @@ -41,22 +40,6 @@ const std::vector<std::string> CONNECTION_TYPE_DOC{
"feeler (short-lived automatic connection for testing addresses)"
};

CConnman& EnsureConnman(const NodeContext& node)
{
if (!node.connman) {
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
}
return *node.connman;
}

PeerManager& EnsurePeerman(const NodeContext& node)
{
if (!node.peerman) {
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
}
return *node.peerman;
}

static RPCHelpMan getconnectioncount()
{
return RPCHelpMan{"getconnectioncount",
Expand Down
15 changes: 0 additions & 15 deletions src/rpc/net.h

This file was deleted.

1 change: 1 addition & 0 deletions src/rpc/rawtransaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <rpc/blockchain.h>
#include <rpc/rawtransaction_util.h>
#include <rpc/server.h>
#include <rpc/server_util.h>
#include <rpc/util.h>
#include <script/script.h>
#include <script/sign.h>
Expand Down
Loading