Page MenuHomePhabricator

D8586.diff
No OneTemporary

D8586.diff

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

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)

Event Timeline