aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSjors Provoost <sjors@sprovoost.nl>2024-06-07 11:22:44 +0200
committerSjors Provoost <sjors@sprovoost.nl>2024-06-18 18:47:51 +0200
commit8ecb6816781c7c7f423b501cbb2de3abd7250119 (patch)
tree33f35e170a988b4b4718eb9ddf55a1ae13742938
parent9c5cdf07f30f816cd134e2cd2dca9c27ef7067a5 (diff)
Introduce Mining interface
Start out with a single method isTestChain() that's used by the getblocktemplate RPC.
-rw-r--r--doc/developer-notes.md5
-rw-r--r--src/Makefile.am1
-rw-r--r--src/init.cpp2
-rw-r--r--src/init/bitcoin-node.cpp1
-rw-r--r--src/init/bitcoin-qt.cpp2
-rw-r--r--src/init/bitcoind.cpp2
-rw-r--r--src/interfaces/init.h2
-rw-r--r--src/interfaces/mining.h35
-rw-r--r--src/node/context.cpp1
-rw-r--r--src/node/context.h2
-rw-r--r--src/node/interfaces.cpp18
-rw-r--r--src/rpc/mining.cpp5
-rw-r--r--src/rpc/server_util.cpp8
-rw-r--r--src/rpc/server_util.h4
14 files changed, 85 insertions, 3 deletions
diff --git a/doc/developer-notes.md b/doc/developer-notes.md
index eb2bb41aa4..d9d5b392c5 100644
--- a/doc/developer-notes.md
+++ b/doc/developer-notes.md
@@ -1457,8 +1457,9 @@ independent (node, wallet, GUI), are defined in
there are [`interfaces::Chain`](../src/interfaces/chain.h), used by wallet to
access the node's latest chain state,
[`interfaces::Node`](../src/interfaces/node.h), used by the GUI to control the
-node, and [`interfaces::Wallet`](../src/interfaces/wallet.h), used by the GUI
-to control an individual wallet. There are also more specialized interface
+node, [`interfaces::Wallet`](../src/interfaces/wallet.h), used by the GUI
+to control an individual wallet and [`interfaces::Mining`](../src/interfaces/mining.h),
+used by RPC to generate block templates. There are also more specialized interface
types like [`interfaces::Handler`](../src/interfaces/handler.h)
[`interfaces::ChainClient`](../src/interfaces/chain.h) passed to and from
various interface methods.
diff --git a/src/Makefile.am b/src/Makefile.am
index 4a1973aa87..f95a6fa123 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -177,6 +177,7 @@ BITCOIN_CORE_H = \
interfaces/handler.h \
interfaces/init.h \
interfaces/ipc.h \
+ interfaces/mining.h \
interfaces/node.h \
interfaces/wallet.h \
kernel/blockmanager_opts.h \
diff --git a/src/init.cpp b/src/init.cpp
index 5bb82dc320..0c57dfea7f 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -31,6 +31,7 @@
#include <init/common.h>
#include <interfaces/chain.h>
#include <interfaces/init.h>
+#include <interfaces/mining.h>
#include <interfaces/node.h>
#include <kernel/context.h>
#include <key.h>
@@ -1117,6 +1118,7 @@ bool AppInitLockDataDirectory()
bool AppInitInterfaces(NodeContext& node)
{
node.chain = node.init->makeChain();
+ node.mining = node.init->makeMining();
return true;
}
diff --git a/src/init/bitcoin-node.cpp b/src/init/bitcoin-node.cpp
index 97b8dc1161..00a3822791 100644
--- a/src/init/bitcoin-node.cpp
+++ b/src/init/bitcoin-node.cpp
@@ -30,6 +30,7 @@ public:
}
std::unique_ptr<interfaces::Node> makeNode() override { return interfaces::MakeNode(m_node); }
std::unique_ptr<interfaces::Chain> makeChain() override { return interfaces::MakeChain(m_node); }
+ std::unique_ptr<interfaces::Mining> makeMining() override { return interfaces::MakeMining(m_node); }
std::unique_ptr<interfaces::WalletLoader> makeWalletLoader(interfaces::Chain& chain) override
{
return MakeWalletLoader(chain, *Assert(m_node.args));
diff --git a/src/init/bitcoin-qt.cpp b/src/init/bitcoin-qt.cpp
index 3003a8fde1..5209c72973 100644
--- a/src/init/bitcoin-qt.cpp
+++ b/src/init/bitcoin-qt.cpp
@@ -6,6 +6,7 @@
#include <interfaces/chain.h>
#include <interfaces/echo.h>
#include <interfaces/init.h>
+#include <interfaces/mining.h>
#include <interfaces/node.h>
#include <interfaces/wallet.h>
#include <node/context.h>
@@ -25,6 +26,7 @@ public:
}
std::unique_ptr<interfaces::Node> makeNode() override { return interfaces::MakeNode(m_node); }
std::unique_ptr<interfaces::Chain> makeChain() override { return interfaces::MakeChain(m_node); }
+ std::unique_ptr<interfaces::Mining> makeMining() override { return interfaces::MakeMining(m_node); }
std::unique_ptr<interfaces::WalletLoader> makeWalletLoader(interfaces::Chain& chain) override
{
return MakeWalletLoader(chain, *Assert(m_node.args));
diff --git a/src/init/bitcoind.cpp b/src/init/bitcoind.cpp
index b5df764017..48be8831d2 100644
--- a/src/init/bitcoind.cpp
+++ b/src/init/bitcoind.cpp
@@ -6,6 +6,7 @@
#include <interfaces/chain.h>
#include <interfaces/echo.h>
#include <interfaces/init.h>
+#include <interfaces/mining.h>
#include <interfaces/node.h>
#include <interfaces/wallet.h>
#include <node/context.h>
@@ -27,6 +28,7 @@ public:
}
std::unique_ptr<interfaces::Node> makeNode() override { return interfaces::MakeNode(m_node); }
std::unique_ptr<interfaces::Chain> makeChain() override { return interfaces::MakeChain(m_node); }
+ std::unique_ptr<interfaces::Mining> makeMining() override { return interfaces::MakeMining(m_node); }
std::unique_ptr<interfaces::WalletLoader> makeWalletLoader(interfaces::Chain& chain) override
{
return MakeWalletLoader(chain, *Assert(m_node.args));
diff --git a/src/interfaces/init.h b/src/interfaces/init.h
index addc45aa26..094ead399d 100644
--- a/src/interfaces/init.h
+++ b/src/interfaces/init.h
@@ -7,6 +7,7 @@
#include <interfaces/chain.h>
#include <interfaces/echo.h>
+#include <interfaces/mining.h>
#include <interfaces/node.h>
#include <interfaces/wallet.h>
@@ -32,6 +33,7 @@ public:
virtual ~Init() = default;
virtual std::unique_ptr<Node> makeNode() { return nullptr; }
virtual std::unique_ptr<Chain> makeChain() { return nullptr; }
+ virtual std::unique_ptr<Mining> makeMining() { return nullptr; }
virtual std::unique_ptr<WalletLoader> makeWalletLoader(Chain& chain) { return nullptr; }
virtual std::unique_ptr<Echo> makeEcho() { return nullptr; }
virtual Ipc* ipc() { return nullptr; }
diff --git a/src/interfaces/mining.h b/src/interfaces/mining.h
new file mode 100644
index 0000000000..afcd8d1cda
--- /dev/null
+++ b/src/interfaces/mining.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2024 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_INTERFACES_MINING_H
+#define BITCOIN_INTERFACES_MINING_H
+
+namespace node {
+struct NodeContext;
+} // namespace node
+
+namespace interfaces {
+
+//! Interface giving clients (RPC, Stratum v2 Template Provider in the future)
+//! ability to create block templates.
+
+class Mining
+{
+public:
+ virtual ~Mining() {}
+
+ //! If this chain is exclusively used for testing
+ virtual bool isTestChain() = 0;
+
+ //! Get internal node context. Useful for RPC and testing,
+ //! but not accessible across processes.
+ virtual node::NodeContext* context() { return nullptr; }
+};
+
+//! Return implementation of Mining interface.
+std::unique_ptr<Mining> MakeMining(node::NodeContext& node);
+
+} // namespace interfaces
+
+#endif // BITCOIN_INTERFACES_MINING_H
diff --git a/src/node/context.cpp b/src/node/context.cpp
index da05fde6ee..75dfaee866 100644
--- a/src/node/context.cpp
+++ b/src/node/context.cpp
@@ -7,6 +7,7 @@
#include <addrman.h>
#include <banman.h>
#include <interfaces/chain.h>
+#include <interfaces/mining.h>
#include <kernel/context.h>
#include <key.h>
#include <net.h>
diff --git a/src/node/context.h b/src/node/context.h
index 77838ea99b..a664fad80b 100644
--- a/src/node/context.h
+++ b/src/node/context.h
@@ -27,6 +27,7 @@ class PeerManager;
namespace interfaces {
class Chain;
class ChainClient;
+class Mining;
class Init;
class WalletLoader;
} // namespace interfaces
@@ -74,6 +75,7 @@ struct NodeContext {
std::vector<std::unique_ptr<interfaces::ChainClient>> chain_clients;
//! Reference to chain client that should used to load or create wallets
//! opened by the gui.
+ std::unique_ptr<interfaces::Mining> mining;
interfaces::WalletLoader* wallet_loader{nullptr};
std::unique_ptr<CScheduler> scheduler;
std::function<void()> rpc_interruption_point = [] {};
diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp
index 2b36f4ceae..e44cb51873 100644
--- a/src/node/interfaces.cpp
+++ b/src/node/interfaces.cpp
@@ -14,6 +14,7 @@
#include <init.h>
#include <interfaces/chain.h>
#include <interfaces/handler.h>
+#include <interfaces/mining.h>
#include <interfaces/node.h>
#include <interfaces/wallet.h>
#include <kernel/chain.h>
@@ -69,6 +70,7 @@ using interfaces::Chain;
using interfaces::FoundBlock;
using interfaces::Handler;
using interfaces::MakeSignalHandler;
+using interfaces::Mining;
using interfaces::Node;
using interfaces::WalletLoader;
using util::Join;
@@ -831,10 +833,26 @@ public:
ValidationSignals& validation_signals() { return *Assert(m_node.validation_signals); }
NodeContext& m_node;
};
+
+class MinerImpl : public Mining
+{
+public:
+ explicit MinerImpl(NodeContext& node) : m_node(node) {}
+
+ bool isTestChain() override
+ {
+ return chainman().GetParams().IsTestChain();
+ }
+
+ NodeContext* context() override { return &m_node; }
+ ChainstateManager& chainman() { return *Assert(m_node.chainman); }
+ NodeContext& m_node;
+};
} // namespace
} // namespace node
namespace interfaces {
std::unique_ptr<Node> MakeNode(node::NodeContext& context) { return std::make_unique<node::NodeImpl>(context); }
std::unique_ptr<Chain> MakeChain(node::NodeContext& context) { return std::make_unique<node::ChainImpl>(context); }
+std::unique_ptr<Mining> MakeMining(node::NodeContext& context) { return std::make_unique<node::MinerImpl>(context); }
} // namespace interfaces
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index 0f6853ef37..0e9d4829d2 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -16,6 +16,7 @@
#include <core_io.h>
#include <deploymentinfo.h>
#include <deploymentstatus.h>
+#include <interfaces/mining.h>
#include <key_io.h>
#include <net.h>
#include <node/context.h>
@@ -45,6 +46,7 @@
using node::BlockAssembler;
using node::CBlockTemplate;
+using interfaces::Mining;
using node::NodeContext;
using node::RegenerateCommitments;
using node::UpdateTime;
@@ -724,7 +726,8 @@ static RPCHelpMan getblocktemplate()
if (strMode != "template")
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
- if (!chainman.GetParams().IsTestChain()) {
+ Mining& miner = EnsureMining(node);
+ if (!miner.isTestChain()) {
const CConnman& connman = EnsureConnman(node);
if (connman.GetNodeCount(ConnectionDirection::Both) == 0) {
throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, PACKAGE_NAME " is not connected!");
diff --git a/src/rpc/server_util.cpp b/src/rpc/server_util.cpp
index efd4a43c28..0387cbb8e2 100644
--- a/src/rpc/server_util.cpp
+++ b/src/rpc/server_util.cpp
@@ -101,6 +101,14 @@ CConnman& EnsureConnman(const NodeContext& node)
return *node.connman;
}
+interfaces::Mining& EnsureMining(const NodeContext& node)
+{
+ if (!node.mining) {
+ throw JSONRPCError(RPC_INTERNAL_ERROR, "Node miner not found");
+ }
+ return *node.mining;
+}
+
PeerManager& EnsurePeerman(const NodeContext& node)
{
if (!node.peerman) {
diff --git a/src/rpc/server_util.h b/src/rpc/server_util.h
index a4a53166b4..1e6fb7e6a6 100644
--- a/src/rpc/server_util.h
+++ b/src/rpc/server_util.h
@@ -18,6 +18,9 @@ class BanMan;
namespace node {
struct NodeContext;
} // namespace node
+namespace interfaces {
+class Mining;
+} // namespace interfaces
node::NodeContext& EnsureAnyNodeContext(const std::any& context);
CTxMemPool& EnsureMemPool(const node::NodeContext& node);
@@ -31,6 +34,7 @@ ChainstateManager& EnsureAnyChainman(const std::any& context);
CBlockPolicyEstimator& EnsureFeeEstimator(const node::NodeContext& node);
CBlockPolicyEstimator& EnsureAnyFeeEstimator(const std::any& context);
CConnman& EnsureConnman(const node::NodeContext& node);
+interfaces::Mining& EnsureMining(const node::NodeContext& node);
PeerManager& EnsurePeerman(const node::NodeContext& node);
AddrMan& EnsureAddrman(const node::NodeContext& node);
AddrMan& EnsureAnyAddrman(const std::any& context);