mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-05 18:52:29 +02:00
Merge #8775: RPC refactoring: Access wallet using new GetWalletForJSONRPCRequest
d678771Wallet: Sanitise -wallet parameter (Luke Dashjr)9756be3Wallet/RPC: Use filename rather than CWallet pointer, for lockwallet RPCRunLater job name (Luke Dashjr)86be48aMore tightly couple EnsureWalletIsAvailable with GetWalletForJSONRPCRequest where appropriate (Luke Dashjr)a435632Move wallet RPC declarations to rpcwallet.h (Luke Dashjr)ad15734RPC: Pass on JSONRPCRequest metadata (URI/user/etc) for "help" method (Luke Dashjr)bf8a04aReformat touched lines with C++11 (Luke Dashjr)2e518e3Move nWalletUnlockTime to CWallet::nRelockTime, and name timed task unique per CWallet (Luke Dashjr)d77ad6dRPC: Do all wallet access through new GetWalletForJSONRPCRequest (Luke Dashjr)eca550fRPC/Wallet: Pass CWallet as pointer to helper functions (Luke Dashjr) Tree-SHA512: bfd592da841693390e16f83b451503eb5cedb71208089aa32b3fc45e973555584a3ed7696dd239f6409324464d565dacf0f3d0e36e8e13ae6a7843848465f960
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
#include "util.h"
|
||||
#include "utilstrencodings.h"
|
||||
#ifdef ENABLE_WALLET
|
||||
#include "wallet/rpcwallet.h"
|
||||
#include "wallet/wallet.h"
|
||||
#include "wallet/walletdb.h"
|
||||
#endif
|
||||
@@ -70,7 +71,9 @@ UniValue getinfo(const JSONRPCRequest& request)
|
||||
);
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
|
||||
CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
|
||||
|
||||
LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : NULL);
|
||||
#else
|
||||
LOCK(cs_main);
|
||||
#endif
|
||||
@@ -82,9 +85,9 @@ UniValue getinfo(const JSONRPCRequest& request)
|
||||
obj.push_back(Pair("version", CLIENT_VERSION));
|
||||
obj.push_back(Pair("protocolversion", PROTOCOL_VERSION));
|
||||
#ifdef ENABLE_WALLET
|
||||
if (pwalletMain) {
|
||||
obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
|
||||
obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
|
||||
if (pwallet) {
|
||||
obj.push_back(Pair("walletversion", pwallet->GetVersion()));
|
||||
obj.push_back(Pair("balance", ValueFromAmount(pwallet->GetBalance())));
|
||||
}
|
||||
#endif
|
||||
obj.push_back(Pair("blocks", (int)chainActive.Height()));
|
||||
@@ -95,12 +98,13 @@ UniValue getinfo(const JSONRPCRequest& request)
|
||||
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
|
||||
obj.push_back(Pair("testnet", Params().NetworkIDString() == CBaseChainParams::TESTNET));
|
||||
#ifdef ENABLE_WALLET
|
||||
if (pwalletMain) {
|
||||
obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime()));
|
||||
obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
|
||||
if (pwallet) {
|
||||
obj.push_back(Pair("keypoololdest", pwallet->GetOldestKeyPoolTime()));
|
||||
obj.push_back(Pair("keypoolsize", (int)pwallet->GetKeyPoolSize()));
|
||||
}
|
||||
if (pwallet && pwallet->IsCrypted()) {
|
||||
obj.push_back(Pair("unlocked_until", pwallet->nRelockTime));
|
||||
}
|
||||
if (pwalletMain && pwalletMain->IsCrypted())
|
||||
obj.push_back(Pair("unlocked_until", nWalletUnlockTime));
|
||||
obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())));
|
||||
#endif
|
||||
obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())));
|
||||
@@ -112,13 +116,17 @@ UniValue getinfo(const JSONRPCRequest& request)
|
||||
class DescribeAddressVisitor : public boost::static_visitor<UniValue>
|
||||
{
|
||||
public:
|
||||
CWallet * const pwallet;
|
||||
|
||||
DescribeAddressVisitor(CWallet *_pwallet) : pwallet(_pwallet) {}
|
||||
|
||||
UniValue operator()(const CNoDestination &dest) const { return UniValue(UniValue::VOBJ); }
|
||||
|
||||
UniValue operator()(const CKeyID &keyID) const {
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
CPubKey vchPubKey;
|
||||
obj.push_back(Pair("isscript", false));
|
||||
if (pwalletMain && pwalletMain->GetPubKey(keyID, vchPubKey)) {
|
||||
if (pwallet && pwallet->GetPubKey(keyID, vchPubKey)) {
|
||||
obj.push_back(Pair("pubkey", HexStr(vchPubKey)));
|
||||
obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
|
||||
}
|
||||
@@ -129,7 +137,7 @@ public:
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
CScript subscript;
|
||||
obj.push_back(Pair("isscript", true));
|
||||
if (pwalletMain && pwalletMain->GetCScript(scriptID, subscript)) {
|
||||
if (pwallet && pwallet->GetCScript(scriptID, subscript)) {
|
||||
std::vector<CTxDestination> addresses;
|
||||
txnouttype whichType;
|
||||
int nRequired;
|
||||
@@ -177,7 +185,9 @@ UniValue validateaddress(const JSONRPCRequest& request)
|
||||
);
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
|
||||
CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
|
||||
|
||||
LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : NULL);
|
||||
#else
|
||||
LOCK(cs_main);
|
||||
#endif
|
||||
@@ -197,16 +207,17 @@ UniValue validateaddress(const JSONRPCRequest& request)
|
||||
ret.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO;
|
||||
isminetype mine = pwallet ? IsMine(*pwallet, dest) : ISMINE_NO;
|
||||
ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false));
|
||||
ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false));
|
||||
UniValue detail = boost::apply_visitor(DescribeAddressVisitor(), dest);
|
||||
UniValue detail = boost::apply_visitor(DescribeAddressVisitor(pwallet), dest);
|
||||
ret.pushKVs(detail);
|
||||
if (pwalletMain && pwalletMain->mapAddressBook.count(dest))
|
||||
ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name));
|
||||
if (pwallet && pwallet->mapAddressBook.count(dest)) {
|
||||
ret.push_back(Pair("account", pwallet->mapAddressBook[dest].name));
|
||||
}
|
||||
CKeyID keyID;
|
||||
if (pwalletMain) {
|
||||
const auto& meta = pwalletMain->mapKeyMetadata;
|
||||
if (pwallet) {
|
||||
const auto& meta = pwallet->mapKeyMetadata;
|
||||
auto it = address.GetKeyID(keyID) ? meta.find(keyID) : meta.end();
|
||||
if (it == meta.end()) {
|
||||
it = meta.find(CScriptID(scriptPubKey));
|
||||
@@ -224,10 +235,13 @@ UniValue validateaddress(const JSONRPCRequest& request)
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Needed even with !ENABLE_WALLET, to pass (ignored) pointers around
|
||||
class CWallet;
|
||||
|
||||
/**
|
||||
* Used by addmultisigaddress / createmultisig:
|
||||
*/
|
||||
CScript _createmultisig_redeemScript(const UniValue& params)
|
||||
CScript _createmultisig_redeemScript(CWallet * const pwallet, const UniValue& params)
|
||||
{
|
||||
int nRequired = params[0].get_int();
|
||||
const UniValue& keys = params[1].get_array();
|
||||
@@ -249,16 +263,16 @@ CScript _createmultisig_redeemScript(const UniValue& params)
|
||||
#ifdef ENABLE_WALLET
|
||||
// Case 1: Bitcoin address and we have full public key:
|
||||
CBitcoinAddress address(ks);
|
||||
if (pwalletMain && address.IsValid())
|
||||
{
|
||||
if (pwallet && address.IsValid()) {
|
||||
CKeyID keyID;
|
||||
if (!address.GetKeyID(keyID))
|
||||
throw runtime_error(
|
||||
strprintf("%s does not refer to a key",ks));
|
||||
CPubKey vchPubKey;
|
||||
if (!pwalletMain->GetPubKey(keyID, vchPubKey))
|
||||
if (!pwallet->GetPubKey(keyID, vchPubKey)) {
|
||||
throw runtime_error(
|
||||
strprintf("no full public key for address %s",ks));
|
||||
}
|
||||
if (!vchPubKey.IsFullyValid())
|
||||
throw runtime_error(" Invalid public key: "+ks);
|
||||
pubkeys[i] = vchPubKey;
|
||||
@@ -290,6 +304,12 @@ CScript _createmultisig_redeemScript(const UniValue& params)
|
||||
|
||||
UniValue createmultisig(const JSONRPCRequest& request)
|
||||
{
|
||||
#ifdef ENABLE_WALLET
|
||||
CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
|
||||
#else
|
||||
CWallet * const pwallet = NULL;
|
||||
#endif
|
||||
|
||||
if (request.fHelp || request.params.size() < 2 || request.params.size() > 2)
|
||||
{
|
||||
string msg = "createmultisig nrequired [\"key\",...]\n"
|
||||
@@ -320,7 +340,7 @@ UniValue createmultisig(const JSONRPCRequest& request)
|
||||
}
|
||||
|
||||
// Construct using pay-to-script-hash:
|
||||
CScript inner = _createmultisig_redeemScript(request.params);
|
||||
CScript inner = _createmultisig_redeemScript(pwallet, request.params);
|
||||
CScriptID innerID(inner);
|
||||
CBitcoinAddress address(innerID);
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "uint256.h"
|
||||
#include "utilstrencodings.h"
|
||||
#ifdef ENABLE_WALLET
|
||||
#include "wallet/rpcwallet.h"
|
||||
#include "wallet/wallet.h"
|
||||
#endif
|
||||
|
||||
@@ -594,6 +595,10 @@ static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std::
|
||||
|
||||
UniValue signrawtransaction(const JSONRPCRequest& request)
|
||||
{
|
||||
#ifdef ENABLE_WALLET
|
||||
CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
|
||||
#endif
|
||||
|
||||
if (request.fHelp || request.params.size() < 1 || request.params.size() > 4)
|
||||
throw runtime_error(
|
||||
"signrawtransaction \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] [\"privatekey1\",...] sighashtype )\n"
|
||||
@@ -603,7 +608,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
|
||||
"The third optional argument (may be null) is an array of base58-encoded private\n"
|
||||
"keys that, if given, will be the only keys used to sign the transaction.\n"
|
||||
#ifdef ENABLE_WALLET
|
||||
+ HelpRequiringPassphrase() + "\n"
|
||||
+ HelpRequiringPassphrase(pwallet) + "\n"
|
||||
#endif
|
||||
|
||||
"\nArguments:\n"
|
||||
@@ -654,7 +659,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
|
||||
);
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
|
||||
LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : NULL);
|
||||
#else
|
||||
LOCK(cs_main);
|
||||
#endif
|
||||
@@ -717,8 +722,9 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
|
||||
}
|
||||
}
|
||||
#ifdef ENABLE_WALLET
|
||||
else if (pwalletMain)
|
||||
EnsureWalletIsUnlocked();
|
||||
else if (pwallet) {
|
||||
EnsureWalletIsUnlocked(pwallet);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Add previous txouts given in the RPC call:
|
||||
@@ -785,7 +791,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
|
||||
}
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
const CKeyStore& keystore = ((fGivenKeys || !pwalletMain) ? tempKeystore : *pwalletMain);
|
||||
const CKeyStore& keystore = ((fGivenKeys || !pwallet) ? tempKeystore : *pwallet);
|
||||
#else
|
||||
const CKeyStore& keystore = tempKeystore;
|
||||
#endif
|
||||
|
||||
@@ -178,7 +178,7 @@ vector<unsigned char> ParseHexO(const UniValue& o, string strKey)
|
||||
* Note: This interface may still be subject to change.
|
||||
*/
|
||||
|
||||
std::string CRPCTable::help(const std::string& strCommand) const
|
||||
std::string CRPCTable::help(const std::string& strCommand, const JSONRPCRequest& helpreq) const
|
||||
{
|
||||
string strRet;
|
||||
string category;
|
||||
@@ -189,16 +189,19 @@ std::string CRPCTable::help(const std::string& strCommand) const
|
||||
vCommands.push_back(make_pair(mi->second->category + mi->first, mi->second));
|
||||
sort(vCommands.begin(), vCommands.end());
|
||||
|
||||
JSONRPCRequest jreq(helpreq);
|
||||
jreq.fHelp = true;
|
||||
jreq.params = UniValue();
|
||||
|
||||
BOOST_FOREACH(const PAIRTYPE(string, const CRPCCommand*)& command, vCommands)
|
||||
{
|
||||
const CRPCCommand *pcmd = command.second;
|
||||
string strMethod = pcmd->name;
|
||||
if ((strCommand != "" || pcmd->category == "hidden") && strMethod != strCommand)
|
||||
continue;
|
||||
jreq.strMethod = strMethod;
|
||||
try
|
||||
{
|
||||
JSONRPCRequest jreq;
|
||||
jreq.fHelp = true;
|
||||
rpcfn_type pfn = pcmd->actor;
|
||||
if (setDone.insert(pfn).second)
|
||||
(*pfn)(jreq);
|
||||
@@ -247,7 +250,7 @@ UniValue help(const JSONRPCRequest& jsonRequest)
|
||||
if (jsonRequest.params.size() > 0)
|
||||
strCommand = jsonRequest.params[0].get_str();
|
||||
|
||||
return tableRPC.help(strCommand);
|
||||
return tableRPC.help(strCommand, jsonRequest);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ private:
|
||||
public:
|
||||
CRPCTable();
|
||||
const CRPCCommand* operator[](const std::string& name) const;
|
||||
std::string help(const std::string& name) const;
|
||||
std::string help(const std::string& name, const JSONRPCRequest& helpreq) const;
|
||||
|
||||
/**
|
||||
* Execute a method.
|
||||
@@ -190,16 +190,12 @@ extern uint256 ParseHashO(const UniValue& o, std::string strKey);
|
||||
extern std::vector<unsigned char> ParseHexV(const UniValue& v, std::string strName);
|
||||
extern std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey);
|
||||
|
||||
extern int64_t nWalletUnlockTime;
|
||||
extern CAmount AmountFromValue(const UniValue& value);
|
||||
extern UniValue ValueFromAmount(const CAmount& amount);
|
||||
extern double GetDifficulty(const CBlockIndex* blockindex = NULL);
|
||||
extern std::string HelpRequiringPassphrase();
|
||||
extern std::string HelpExampleCli(const std::string& methodname, const std::string& args);
|
||||
extern std::string HelpExampleRpc(const std::string& methodname, const std::string& args);
|
||||
|
||||
extern void EnsureWalletIsUnlocked();
|
||||
|
||||
bool StartRPC();
|
||||
void InterruptRPC();
|
||||
void StopRPC();
|
||||
|
||||
Reference in New Issue
Block a user