Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13115406
D8586.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
11 KB
Subscribers
None
D8586.diff
View Options
diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp
--- a/src/interfaces/wallet.cpp
+++ b/src/interfaces/wallet.cpp
@@ -6,17 +6,21 @@
#include <amount.h>
#include <chainparams.h>
+#include <config.h>
#include <consensus/validation.h>
#include <interfaces/chain.h>
#include <interfaces/handler.h>
#include <policy/fees.h>
#include <primitives/transaction.h>
+#include <rpc/server.h>
#include <script/standard.h>
#include <support/allocators/secure.h>
#include <sync.h>
#include <ui_interface.h>
#include <util/check.h>
+#include <util/ref.h>
#include <util/system.h>
+#include <wallet/context.h>
#include <wallet/fees.h>
#include <wallet/ismine.h>
#include <wallet/load.h>
@@ -461,18 +465,37 @@
public:
WalletClientImpl(Chain &chain,
std::vector<std::string> wallet_filenames)
- : m_chain(chain), m_wallet_filenames(std::move(wallet_filenames)) {}
+ : m_wallet_filenames(std::move(wallet_filenames)) {
+ m_context.chain = &chain;
+ }
+
+ void registerRpcs(const Span<const CRPCCommand> &commands) {
+ for (const CRPCCommand &command : commands) {
+ m_rpc_commands.emplace_back(
+ command.category, command.name,
+ [this, &command](Config &config,
+ const JSONRPCRequest &request,
+ UniValue &result, bool last_handler) {
+ return command.actor(config, {request, m_context},
+ result, last_handler);
+ },
+ command.argNames, command.unique_id);
+ m_rpc_handlers.emplace_back(
+ m_context.chain->handleRpc(m_rpc_commands.back()));
+ }
+ }
void registerRpcs() override {
- g_rpc_chain = &m_chain;
- RegisterWalletRPCCommands(m_chain, m_rpc_handlers);
- RegisterDumpRPCCommands(m_chain, m_rpc_handlers);
+ registerRpcs(GetWalletRPCCommands());
+ registerRpcs(GetWalletDumpRPCCommands());
}
bool verify(const CChainParams &chainParams) override {
- return VerifyWallets(chainParams, m_chain, m_wallet_filenames);
+ return VerifyWallets(chainParams, *m_context.chain,
+ m_wallet_filenames);
}
bool load(const CChainParams &chainParams) override {
- return LoadWallets(chainParams, m_chain, m_wallet_filenames);
+ return LoadWallets(chainParams, *m_context.chain,
+ m_wallet_filenames);
}
void start(CScheduler &scheduler) override {
return StartWallets(scheduler);
@@ -489,9 +512,10 @@
}
~WalletClientImpl() override { UnloadWallets(); }
- Chain &m_chain;
+ WalletContext m_context;
std::vector<std::string> m_wallet_filenames;
std::vector<std::unique_ptr<Handler>> m_rpc_handlers;
+ std::list<CRPCCommand> m_rpc_commands;
};
} // namespace
diff --git a/src/rpc/request.h b/src/rpc/request.h
--- a/src/rpc/request.h
+++ b/src/rpc/request.h
@@ -45,6 +45,14 @@
: id(NullUniValue), params(NullUniValue), fHelp(false),
context(contextIn) {}
+ //! Initializes request information from another request object and the
+ //! given context. The implementation should be updated if any members are
+ //! added or removed above.
+ JSONRPCRequest(const JSONRPCRequest &other, const util::Ref &contextIn)
+ : id(other.id), strMethod(other.strMethod), params(other.params),
+ fHelp(other.fHelp), URI(other.URI), authUser(other.authUser),
+ peerAddr(other.peerAddr), context(contextIn) {}
+
void parse(const UniValue &valRequest);
};
diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt
--- a/src/wallet/CMakeLists.txt
+++ b/src/wallet/CMakeLists.txt
@@ -14,6 +14,7 @@
../interfaces/wallet.cpp
coincontrol.cpp
coinselection.cpp
+ context.cpp
crypter.cpp
db.cpp
fees.cpp
diff --git a/src/wallet/context.h b/src/wallet/context.h
new file mode 100644
--- /dev/null
+++ b/src/wallet/context.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2020 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_WALLET_CONTEXT_H
+#define BITCOIN_WALLET_CONTEXT_H
+
+namespace interfaces {
+class Chain;
+} // namespace interfaces
+
+//! WalletContext struct containing references to state shared between CWallet
+//! instances, like the reference to the chain interface, and the list of opened
+//! wallets.
+//!
+//! Future shared state can be added here as an alternative to adding global
+//! variables.
+//!
+//! The struct isn't intended to have any member functions. It should just be a
+//! collection of state pointers that doesn't pull in dependencies or implement
+//! behavior.
+struct WalletContext {
+ interfaces::Chain *chain{nullptr};
+
+ //! Declare default constructor and destructor that are not inline, so code
+ //! instantiating the WalletContext struct doesn't need to #include class
+ //! definitions for smart pointer and container members.
+ WalletContext();
+ ~WalletContext();
+};
+
+#endif // BITCOIN_WALLET_CONTEXT_H
diff --git a/src/wallet/context.cpp b/src/wallet/context.cpp
new file mode 100644
--- /dev/null
+++ b/src/wallet/context.cpp
@@ -0,0 +1,8 @@
+// Copyright (c) 2020 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <wallet/context.h>
+
+WalletContext::WalletContext() {}
+WalletContext::~WalletContext() {}
diff --git a/src/wallet/rpcdump.h b/src/wallet/rpcdump.h
--- a/src/wallet/rpcdump.h
+++ b/src/wallet/rpcdump.h
@@ -5,23 +5,17 @@
#ifndef BITCOIN_WALLET_RPCDUMP_H
#define BITCOIN_WALLET_RPCDUMP_H
+#include <span.h>
#include <univalue.h>
#include <memory>
#include <vector>
class Config;
-class CRPCTable;
+class CRPCCommand;
class JSONRPCRequest;
-namespace interfaces {
-class Chain;
-class Handler;
-} // namespace interfaces
-
-void RegisterDumpRPCCommands(
- interfaces::Chain &chain,
- std::vector<std::unique_ptr<interfaces::Handler>> &handlers);
+Span<const CRPCCommand> GetWalletDumpRPCCommands();
UniValue importmulti(const Config &config, const JSONRPCRequest &request);
UniValue dumpwallet(const Config &config, const JSONRPCRequest &request);
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -2242,9 +2242,7 @@
return response;
}
-void RegisterDumpRPCCommands(
- interfaces::Chain &chain,
- std::vector<std::unique_ptr<interfaces::Handler>> &handlers) {
+Span<const CRPCCommand> GetWalletDumpRPCCommands() {
// clang-format off
static const CRPCCommand commands[] = {
// category name actor (function) argNames
@@ -2263,7 +2261,5 @@
};
// clang-format on
- for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) {
- handlers.emplace_back(chain.handleRpc(commands[vcidx]));
- }
+ return MakeSpan(commands);
}
diff --git a/src/wallet/rpcwallet.h b/src/wallet/rpcwallet.h
--- a/src/wallet/rpcwallet.h
+++ b/src/wallet/rpcwallet.h
@@ -6,34 +6,27 @@
#define BITCOIN_WALLET_RPCWALLET_H
#include <script/sighashtype.h>
+#include <span.h>
#include <memory>
#include <string>
#include <vector>
-class Config;
-class CRPCTable;
+class CRPCCommand;
class CTransaction;
class CWallet;
+class Config;
class JSONRPCRequest;
class LegacyScriptPubKeyMan;
struct PartiallySignedTransaction;
class UniValue;
+struct WalletContext;
-namespace interfaces {
-class Chain;
-class Handler;
-} // namespace interfaces
-
-//! Pointer to chain interface that needs to be declared as a global to be
-//! accessible loadwallet and createwallet methods. Due to limitations of the
-//! RPC framework, there's currently no direct way to pass in state to RPC
-//! methods without globals.
-extern interfaces::Chain *g_rpc_chain;
+namespace util {
+class Ref;
+}
-void RegisterWalletRPCCommands(
- interfaces::Chain &chain,
- std::vector<std::unique_ptr<interfaces::Handler>> &handlers);
+Span<const CRPCCommand> GetWalletRPCCommands();
/**
* Figures out what wallet, if any, to use for a JSONRPCRequest.
@@ -47,6 +40,7 @@
std::string HelpRequiringPassphrase(const CWallet *);
void EnsureWalletIsUnlocked(const CWallet *);
bool EnsureWalletIsAvailable(const CWallet *, bool avoidException);
+WalletContext &EnsureWalletContext(const util::Ref &context);
LegacyScriptPubKeyMan &EnsureLegacyScriptPubKeyMan(CWallet &wallet,
bool also_create = false);
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -23,12 +23,14 @@
#include <util/error.h>
#include <util/message.h> // For MessageSign()
#include <util/moneystr.h>
+#include <util/ref.h>
#include <util/string.h>
#include <util/system.h>
#include <util/translation.h>
#include <util/url.h>
#include <util/vector.h>
#include <wallet/coincontrol.h>
+#include <wallet/context.h>
#include <wallet/rpcwallet.h>
#include <wallet/wallet.h>
#include <wallet/walletdb.h>
@@ -146,6 +148,13 @@
}
}
+WalletContext &EnsureWalletContext(const util::Ref &context) {
+ if (!context.Has<WalletContext>()) {
+ throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet context not found");
+ }
+ return context.Get<WalletContext>();
+}
+
// also_create should only be set to true only when the RPC is expected to add
// things to a blank wallet and make it no longer blank
LegacyScriptPubKeyMan &EnsureLegacyScriptPubKeyMan(CWallet &wallet,
@@ -3174,6 +3183,7 @@
const CChainParams &chainParams = config.GetChainParams();
+ WalletContext &context = EnsureWalletContext(request.context);
WalletLocation location(request.params[0].get_str());
if (!location.Exists()) {
@@ -3193,7 +3203,7 @@
bilingual_str error;
std::vector<bilingual_str> warnings;
std::shared_ptr<CWallet> const wallet =
- LoadWallet(chainParams, *g_rpc_chain, location, error, warnings);
+ LoadWallet(chainParams, *context.chain, location, error, warnings);
if (!wallet) {
throw JSONRPCError(RPC_WALLET_ERROR, error.original);
}
@@ -3325,6 +3335,7 @@
}
.Check(request);
+ WalletContext &context = EnsureWalletContext(request.context);
uint64_t flags = 0;
if (!request.params[1].isNull() && request.params[1].get_bool()) {
flags |= WALLET_FLAG_DISABLE_PRIVATE_KEYS;
@@ -3357,7 +3368,7 @@
bilingual_str error;
std::shared_ptr<CWallet> wallet;
WalletCreationStatus status =
- CreateWallet(config.GetChainParams(), *g_rpc_chain, passphrase, flags,
+ CreateWallet(config.GetChainParams(), *context.chain, passphrase, flags,
request.params[0].get_str(), error, warnings, wallet);
switch (status) {
case WalletCreationStatus::CREATION_FAILED:
@@ -4994,9 +5005,7 @@
return error.original;
}
-void RegisterWalletRPCCommands(
- interfaces::Chain &chain,
- std::vector<std::unique_ptr<interfaces::Handler>> &handlers) {
+Span<const CRPCCommand> GetWalletRPCCommands() {
// clang-format off
static const CRPCCommand commands[] = {
// category name actor (function) argNames
@@ -5050,9 +5059,5 @@
};
// clang-format on
- for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) {
- handlers.emplace_back(chain.handleRpc(commands[vcidx]));
- }
+ return MakeSpan(commands);
}
-
-interfaces::Chain *g_rpc_chain = nullptr;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Mar 1, 11:03 (11 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5187467
Default Alt Text
D8586.diff (11 KB)
Attached To
D8586: Remove g_rpc_chain global
Event Timeline
Log In to Comment