rpc: Push down safe mode checks

This contains most of the changes of 10563 "remove safe mode", but doesn't
remove the safe mode yet, but put an `ObserveSafeMode()` check in
individual calls with okSafeMode=false.

This cleans up the ugly "okSafeMode" flag from the dispatch tables,
which is not a concern for the RPC server.

Extra-author: Wladimir J. van der Laan <laanwj@gmail.com>
This commit is contained in:
Andrew Chow 2017-06-08 17:38:23 -07:00 committed by Wladimir J. van der Laan
parent cee4fe1d53
commit ec6902d0ea
14 changed files with 186 additions and 147 deletions

View file

@ -130,6 +130,7 @@ BITCOIN_CORE_H = \
rpc/client.h \ rpc/client.h \
rpc/mining.h \ rpc/mining.h \
rpc/protocol.h \ rpc/protocol.h \
rpc/safemode.h \
rpc/server.h \ rpc/server.h \
rpc/register.h \ rpc/register.h \
scheduler.h \ scheduler.h \
@ -210,6 +211,7 @@ libbitcoin_server_a_SOURCES = \
rpc/misc.cpp \ rpc/misc.cpp \
rpc/net.cpp \ rpc/net.cpp \
rpc/rawtransaction.cpp \ rpc/rawtransaction.cpp \
rpc/safemode.cpp \
rpc/server.cpp \ rpc/server.cpp \
script/sigcache.cpp \ script/sigcache.cpp \
script/ismine.cpp \ script/ismine.cpp \

View file

@ -30,6 +30,7 @@
#include "policy/policy.h" #include "policy/policy.h"
#include "rpc/server.h" #include "rpc/server.h"
#include "rpc/register.h" #include "rpc/register.h"
#include "rpc/safemode.h"
#include "rpc/blockchain.h" #include "rpc/blockchain.h"
#include "script/standard.h" #include "script/standard.h"
#include "script/sigcache.h" #include "script/sigcache.h"
@ -70,7 +71,6 @@
bool fFeeEstimatesInitialized = false; bool fFeeEstimatesInitialized = false;
static const bool DEFAULT_PROXYRANDOMIZE = true; static const bool DEFAULT_PROXYRANDOMIZE = true;
static const bool DEFAULT_REST_ENABLE = false; static const bool DEFAULT_REST_ENABLE = false;
static const bool DEFAULT_DISABLE_SAFEMODE = true;
static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false; static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false;
std::unique_ptr<CConnman> g_connman; std::unique_ptr<CConnman> g_connman;
@ -318,15 +318,6 @@ void OnRPCStopped()
LogPrint(BCLog::RPC, "RPC stopped.\n"); LogPrint(BCLog::RPC, "RPC stopped.\n");
} }
void OnRPCPreCommand(const CRPCCommand& cmd)
{
// Observe safe mode
std::string strWarning = GetWarnings("rpc");
if (strWarning != "" && !gArgs.GetBoolArg("-disablesafemode", DEFAULT_DISABLE_SAFEMODE) &&
!cmd.okSafeMode)
throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, std::string("Safe mode: ") + strWarning);
}
std::string HelpMessage(HelpMessageMode mode) std::string HelpMessage(HelpMessageMode mode)
{ {
const auto defaultBaseParams = CreateBaseChainParams(CBaseChainParams::MAIN); const auto defaultBaseParams = CreateBaseChainParams(CBaseChainParams::MAIN);
@ -721,7 +712,6 @@ bool AppInitServers(boost::thread_group& threadGroup)
{ {
RPCServer::OnStarted(&OnRPCStarted); RPCServer::OnStarted(&OnRPCStarted);
RPCServer::OnStopped(&OnRPCStopped); RPCServer::OnStopped(&OnRPCStopped);
RPCServer::OnPreCommand(&OnRPCPreCommand);
if (!InitHTTPServer()) if (!InitHTTPServer())
return false; return false;
if (!StartRPC()) if (!StartRPC())

View file

@ -29,7 +29,7 @@ static UniValue rpcNestedTest_rpc(const JSONRPCRequest& request)
static const CRPCCommand vRPCCommands[] = static const CRPCCommand vRPCCommands[] =
{ {
{ "test", "rpcNestedTest", &rpcNestedTest_rpc, true, {} }, { "test", "rpcNestedTest", &rpcNestedTest_rpc, {} },
}; };
void RPCNestedTests::rpcNestedTests() void RPCNestedTests::rpcNestedTests()

View file

@ -1532,35 +1532,35 @@ UniValue getchaintxstats(const JSONRPCRequest& request)
} }
static const CRPCCommand commands[] = static const CRPCCommand commands[] =
{ // category name actor (function) okSafe argNames { // category name actor (function) argNames
// --------------------- ------------------------ ----------------------- ------ ---------- // --------------------- ------------------------ ----------------------- ----------
{ "blockchain", "getblockchaininfo", &getblockchaininfo, true, {} }, { "blockchain", "getblockchaininfo", &getblockchaininfo, {} },
{ "blockchain", "getchaintxstats", &getchaintxstats, true, {"nblocks", "blockhash"} }, { "blockchain", "getchaintxstats", &getchaintxstats, {"nblocks", "blockhash"} },
{ "blockchain", "getbestblockhash", &getbestblockhash, true, {} }, { "blockchain", "getbestblockhash", &getbestblockhash, {} },
{ "blockchain", "getblockcount", &getblockcount, true, {} }, { "blockchain", "getblockcount", &getblockcount, {} },
{ "blockchain", "getblock", &getblock, true, {"blockhash","verbosity|verbose"} }, { "blockchain", "getblock", &getblock, {"blockhash","verbosity|verbose"} },
{ "blockchain", "getblockhash", &getblockhash, true, {"height"} }, { "blockchain", "getblockhash", &getblockhash, {"height"} },
{ "blockchain", "getblockheader", &getblockheader, true, {"blockhash","verbose"} }, { "blockchain", "getblockheader", &getblockheader, {"blockhash","verbose"} },
{ "blockchain", "getchaintips", &getchaintips, true, {} }, { "blockchain", "getchaintips", &getchaintips, {} },
{ "blockchain", "getdifficulty", &getdifficulty, true, {} }, { "blockchain", "getdifficulty", &getdifficulty, {} },
{ "blockchain", "getmempoolancestors", &getmempoolancestors, true, {"txid","verbose"} }, { "blockchain", "getmempoolancestors", &getmempoolancestors, {"txid","verbose"} },
{ "blockchain", "getmempooldescendants", &getmempooldescendants, true, {"txid","verbose"} }, { "blockchain", "getmempooldescendants", &getmempooldescendants, {"txid","verbose"} },
{ "blockchain", "getmempoolentry", &getmempoolentry, true, {"txid"} }, { "blockchain", "getmempoolentry", &getmempoolentry, {"txid"} },
{ "blockchain", "getmempoolinfo", &getmempoolinfo, true, {} }, { "blockchain", "getmempoolinfo", &getmempoolinfo, {} },
{ "blockchain", "getrawmempool", &getrawmempool, true, {"verbose"} }, { "blockchain", "getrawmempool", &getrawmempool, {"verbose"} },
{ "blockchain", "gettxout", &gettxout, true, {"txid","n","include_mempool"} }, { "blockchain", "gettxout", &gettxout, {"txid","n","include_mempool"} },
{ "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, {} }, { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, {} },
{ "blockchain", "pruneblockchain", &pruneblockchain, true, {"height"} }, { "blockchain", "pruneblockchain", &pruneblockchain, {"height"} },
{ "blockchain", "verifychain", &verifychain, true, {"checklevel","nblocks"} }, { "blockchain", "verifychain", &verifychain, {"checklevel","nblocks"} },
{ "blockchain", "preciousblock", &preciousblock, true, {"blockhash"} }, { "blockchain", "preciousblock", &preciousblock, {"blockhash"} },
/* Not shown in help */ /* Not shown in help */
{ "hidden", "invalidateblock", &invalidateblock, true, {"blockhash"} }, { "hidden", "invalidateblock", &invalidateblock, {"blockhash"} },
{ "hidden", "reconsiderblock", &reconsiderblock, true, {"blockhash"} }, { "hidden", "reconsiderblock", &reconsiderblock, {"blockhash"} },
{ "hidden", "waitfornewblock", &waitfornewblock, true, {"timeout"} }, { "hidden", "waitfornewblock", &waitfornewblock, {"timeout"} },
{ "hidden", "waitforblock", &waitforblock, true, {"blockhash","timeout"} }, { "hidden", "waitforblock", &waitforblock, {"blockhash","timeout"} },
{ "hidden", "waitforblockheight", &waitforblockheight, true, {"height","timeout"} }, { "hidden", "waitforblockheight", &waitforblockheight, {"height","timeout"} },
}; };
void RegisterBlockchainRPCCommands(CRPCTable &t) void RegisterBlockchainRPCCommands(CRPCTable &t)

View file

@ -967,20 +967,21 @@ UniValue estimaterawfee(const JSONRPCRequest& request)
} }
static const CRPCCommand commands[] = static const CRPCCommand commands[] =
{ // category name actor (function) okSafeMode { // category name actor (function) argNames
// --------------------- ------------------------ ----------------------- ---------- // --------------------- ------------------------ ----------------------- ----------
{ "mining", "getnetworkhashps", &getnetworkhashps, true, {"nblocks","height"} }, { "mining", "getnetworkhashps", &getnetworkhashps, {"nblocks","height"} },
{ "mining", "getmininginfo", &getmininginfo, true, {} }, { "mining", "getmininginfo", &getmininginfo, {} },
{ "mining", "prioritisetransaction", &prioritisetransaction, true, {"txid","dummy","fee_delta"} }, { "mining", "prioritisetransaction", &prioritisetransaction, {"txid","dummy","fee_delta"} },
{ "mining", "getblocktemplate", &getblocktemplate, true, {"template_request"} }, { "mining", "getblocktemplate", &getblocktemplate, {"template_request"} },
{ "mining", "submitblock", &submitblock, true, {"hexdata","dummy"} }, { "mining", "submitblock", &submitblock, {"hexdata","dummy"} },
{ "generating", "generatetoaddress", &generatetoaddress, true, {"nblocks","address","maxtries"} },
{ "util", "estimatefee", &estimatefee, true, {"nblocks"} }, { "generating", "generatetoaddress", &generatetoaddress, {"nblocks","address","maxtries"} },
{ "util", "estimatesmartfee", &estimatesmartfee, true, {"conf_target", "estimate_mode"} },
{ "hidden", "estimaterawfee", &estimaterawfee, true, {"conf_target", "threshold"} }, { "util", "estimatefee", &estimatefee, {"nblocks"} },
{ "util", "estimatesmartfee", &estimatesmartfee, {"nblocks", "estimate_mode"} },
{ "hidden", "estimaterawfee", &estimaterawfee, {"conf_target", "threshold"} },
}; };
void RegisterMiningRPCCommands(CRPCTable &t) void RegisterMiningRPCCommands(CRPCTable &t)

View file

@ -649,20 +649,20 @@ UniValue echo(const JSONRPCRequest& request)
} }
static const CRPCCommand commands[] = static const CRPCCommand commands[] =
{ // category name actor (function) okSafeMode { // category name actor (function) argNames
// --------------------- ------------------------ ----------------------- ---------- // --------------------- ------------------------ ----------------------- ----------
{ "control", "getinfo", &getinfo, true, {} }, /* uses wallet if enabled */ { "control", "getinfo", &getinfo, {} }, /* uses wallet if enabled */
{ "control", "getmemoryinfo", &getmemoryinfo, true, {"mode"} }, { "control", "getmemoryinfo", &getmemoryinfo, {"mode"} },
{ "util", "validateaddress", &validateaddress, true, {"address"} }, /* uses wallet if enabled */ { "util", "validateaddress", &validateaddress, {"address"} }, /* uses wallet if enabled */
{ "util", "createmultisig", &createmultisig, true, {"nrequired","keys"} }, { "util", "createmultisig", &createmultisig, {"nrequired","keys"} },
{ "util", "verifymessage", &verifymessage, true, {"address","signature","message"} }, { "util", "verifymessage", &verifymessage, {"address","signature","message"} },
{ "util", "signmessagewithprivkey", &signmessagewithprivkey, true, {"privkey","message"} }, { "util", "signmessagewithprivkey", &signmessagewithprivkey, {"privkey","message"} },
/* Not shown in help */ /* Not shown in help */
{ "hidden", "setmocktime", &setmocktime, true, {"timestamp"}}, { "hidden", "setmocktime", &setmocktime, {"timestamp"}},
{ "hidden", "echo", &echo, true, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}}, { "hidden", "echo", &echo, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}},
{ "hidden", "echojson", &echo, true, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}}, { "hidden", "echojson", &echo, {"arg0","arg1","arg2","arg3","arg4","arg5","arg6","arg7","arg8","arg9"}},
{ "hidden", "logging", &logging, true, {"include", "exclude"}}, { "hidden", "logging", &logging, {"include", "exclude"}},
}; };
void RegisterMiscRPCCommands(CRPCTable &t) void RegisterMiscRPCCommands(CRPCTable &t)

View file

@ -623,20 +623,20 @@ UniValue setnetworkactive(const JSONRPCRequest& request)
} }
static const CRPCCommand commands[] = static const CRPCCommand commands[] =
{ // category name actor (function) okSafeMode { // category name actor (function) argNames
// --------------------- ------------------------ ----------------------- ---------- // --------------------- ------------------------ ----------------------- ----------
{ "network", "getconnectioncount", &getconnectioncount, true, {} }, { "network", "getconnectioncount", &getconnectioncount, {} },
{ "network", "ping", &ping, true, {} }, { "network", "ping", &ping, {} },
{ "network", "getpeerinfo", &getpeerinfo, true, {} }, { "network", "getpeerinfo", &getpeerinfo, {} },
{ "network", "addnode", &addnode, true, {"node","command"} }, { "network", "addnode", &addnode, {"node","command"} },
{ "network", "disconnectnode", &disconnectnode, true, {"address", "nodeid"} }, { "network", "disconnectnode", &disconnectnode, {"address", "nodeid"} },
{ "network", "getaddednodeinfo", &getaddednodeinfo, true, {"node"} }, { "network", "getaddednodeinfo", &getaddednodeinfo, {"node"} },
{ "network", "getnettotals", &getnettotals, true, {} }, { "network", "getnettotals", &getnettotals, {} },
{ "network", "getnetworkinfo", &getnetworkinfo, true, {} }, { "network", "getnetworkinfo", &getnetworkinfo, {} },
{ "network", "setban", &setban, true, {"subnet", "command", "bantime", "absolute"} }, { "network", "setban", &setban, {"subnet", "command", "bantime", "absolute"} },
{ "network", "listbanned", &listbanned, true, {} }, { "network", "listbanned", &listbanned, {} },
{ "network", "clearbanned", &clearbanned, true, {} }, { "network", "clearbanned", &clearbanned, {} },
{ "network", "setnetworkactive", &setnetworkactive, true, {"state"} }, { "network", "setnetworkactive", &setnetworkactive, {"state"} },
}; };
void RegisterNetRPCCommands(CRPCTable &t) void RegisterNetRPCCommands(CRPCTable &t)

View file

@ -16,6 +16,7 @@
#include "policy/policy.h" #include "policy/policy.h"
#include "policy/rbf.h" #include "policy/rbf.h"
#include "primitives/transaction.h" #include "primitives/transaction.h"
#include "rpc/safemode.h"
#include "rpc/server.h" #include "rpc/server.h"
#include "script/script.h" #include "script/script.h"
#include "script/script_error.h" #include "script/script_error.h"
@ -703,6 +704,7 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
+ HelpExampleRpc("signrawtransaction", "\"myhex\"") + HelpExampleRpc("signrawtransaction", "\"myhex\"")
); );
ObserveSafeMode();
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : nullptr); LOCK2(cs_main, pwallet ? &pwallet->cs_wallet : nullptr);
#else #else
@ -908,6 +910,7 @@ UniValue sendrawtransaction(const JSONRPCRequest& request)
+ HelpExampleRpc("sendrawtransaction", "\"signedhex\"") + HelpExampleRpc("sendrawtransaction", "\"signedhex\"")
); );
ObserveSafeMode();
LOCK(cs_main); LOCK(cs_main);
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL}); RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL});
@ -959,18 +962,18 @@ UniValue sendrawtransaction(const JSONRPCRequest& request)
} }
static const CRPCCommand commands[] = static const CRPCCommand commands[] =
{ // category name actor (function) okSafeMode { // category name actor (function) argNames
// --------------------- ------------------------ ----------------------- ---------- // --------------------- ------------------------ ----------------------- ----------
{ "rawtransactions", "getrawtransaction", &getrawtransaction, true, {"txid","verbose"} }, { "rawtransactions", "getrawtransaction", &getrawtransaction, {"txid","verbose"} },
{ "rawtransactions", "createrawtransaction", &createrawtransaction, true, {"inputs","outputs","locktime","replaceable"} }, { "rawtransactions", "createrawtransaction", &createrawtransaction, {"inputs","outputs","locktime","replaceable"} },
{ "rawtransactions", "decoderawtransaction", &decoderawtransaction, true, {"hexstring"} }, { "rawtransactions", "decoderawtransaction", &decoderawtransaction, {"hexstring"} },
{ "rawtransactions", "decodescript", &decodescript, true, {"hexstring"} }, { "rawtransactions", "decodescript", &decodescript, {"hexstring"} },
{ "rawtransactions", "sendrawtransaction", &sendrawtransaction, false, {"hexstring","allowhighfees"} }, { "rawtransactions", "sendrawtransaction", &sendrawtransaction, {"hexstring","allowhighfees"} },
{ "rawtransactions", "combinerawtransaction", &combinerawtransaction, true, {"txs"} }, { "rawtransactions", "combinerawtransaction", &combinerawtransaction, {"txs"} },
{ "rawtransactions", "signrawtransaction", &signrawtransaction, false, {"hexstring","prevtxs","privkeys","sighashtype"} }, /* uses wallet if enabled */ { "rawtransactions", "signrawtransaction", &signrawtransaction, {"hexstring","prevtxs","privkeys","sighashtype"} }, /* uses wallet if enabled */
{ "blockchain", "gettxoutproof", &gettxoutproof, true, {"txids", "blockhash"} }, { "blockchain", "gettxoutproof", &gettxoutproof, {"txids", "blockhash"} },
{ "blockchain", "verifytxoutproof", &verifytxoutproof, true, {"proof"} }, { "blockchain", "verifytxoutproof", &verifytxoutproof, {"proof"} },
}; };
void RegisterRawTransactionRPCCommands(CRPCTable &t) void RegisterRawTransactionRPCCommands(CRPCTable &t)

14
src/rpc/safemode.cpp Normal file
View file

@ -0,0 +1,14 @@
#include "safemode.h"
#include "rpc/protocol.h"
#include "util.h"
#include "warnings.h"
void ObserveSafeMode()
{
std::string warning = GetWarnings("rpc");
if (warning != "" && !gArgs.GetBoolArg("-disablesafemode", DEFAULT_DISABLE_SAFEMODE)) {
throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, std::string("Safe mode: ") + warning);
}
}

12
src/rpc/safemode.h Normal file
View file

@ -0,0 +1,12 @@
// Copyright (c) 2017 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_RPC_SAFEMODE_H
#define BITCOIN_RPC_SAFEMODE_H
static const bool DEFAULT_DISABLE_SAFEMODE = true;
void ObserveSafeMode();
#endif // BITCOIN_RPC_SAFEMODE_H

View file

@ -51,11 +51,6 @@ void RPCServer::OnStopped(std::function<void ()> slot)
g_rpcSignals.Stopped.connect(slot); g_rpcSignals.Stopped.connect(slot);
} }
void RPCServer::OnPreCommand(std::function<void (const CRPCCommand&)> slot)
{
g_rpcSignals.PreCommand.connect(boost::bind(slot, _1));
}
void RPCTypeCheck(const UniValue& params, void RPCTypeCheck(const UniValue& params,
const std::list<UniValue::VType>& typesExpected, const std::list<UniValue::VType>& typesExpected,
bool fAllowNull) bool fAllowNull)
@ -267,12 +262,12 @@ UniValue uptime(const JSONRPCRequest& jsonRequest)
* Call Table * Call Table
*/ */
static const CRPCCommand vRPCCommands[] = static const CRPCCommand vRPCCommands[] =
{ // category name actor (function) okSafe argNames { // category name actor (function) argNames
// --------------------- ------------------------ ----------------------- ------ ---------- // --------------------- ------------------------ ----------------------- ----------
/* Overall control/query calls */ /* Overall control/query calls */
{ "control", "help", &help, true, {"command"} }, { "control", "help", &help, {"command"} },
{ "control", "stop", &stop, true, {} }, { "control", "stop", &stop, {} },
{ "control", "uptime", &uptime, true, {} }, { "control", "uptime", &uptime, {} },
}; };
CRPCTable::CRPCTable() CRPCTable::CRPCTable()

View file

@ -25,7 +25,6 @@ namespace RPCServer
{ {
void OnStarted(std::function<void ()> slot); void OnStarted(std::function<void ()> slot);
void OnStopped(std::function<void ()> slot); void OnStopped(std::function<void ()> slot);
void OnPreCommand(std::function<void (const CRPCCommand&)> slot);
} }
/** Wrapper for UniValue::VType, which includes typeAny: /** Wrapper for UniValue::VType, which includes typeAny:
@ -134,7 +133,6 @@ public:
std::string category; std::string category;
std::string name; std::string name;
rpcfn_type actor; rpcfn_type actor;
bool okSafeMode;
std::vector<std::string> argNames; std::vector<std::string> argNames;
}; };

View file

@ -4,6 +4,7 @@
#include "base58.h" #include "base58.h"
#include "chain.h" #include "chain.h"
#include "rpc/safemode.h"
#include "rpc/server.h" #include "rpc/server.h"
#include "init.h" #include "init.h"
#include "validation.h" #include "validation.h"
@ -174,6 +175,7 @@ UniValue abortrescan(const JSONRPCRequest& request)
+ HelpExampleRpc("abortrescan", "") + HelpExampleRpc("abortrescan", "")
); );
ObserveSafeMode();
if (!pwallet->IsScanning() || pwallet->IsAbortingRescan()) return false; if (!pwallet->IsScanning() || pwallet->IsAbortingRescan()) return false;
pwallet->AbortRescan(); pwallet->AbortRescan();
return true; return true;

View file

@ -16,6 +16,7 @@
#include "policy/policy.h" #include "policy/policy.h"
#include "policy/rbf.h" #include "policy/rbf.h"
#include "rpc/mining.h" #include "rpc/mining.h"
#include "rpc/safemode.h"
#include "rpc/server.h" #include "rpc/server.h"
#include "script/sign.h" #include "script/sign.h"
#include "timedata.h" #include "timedata.h"
@ -450,6 +451,7 @@ UniValue sendtoaddress(const JSONRPCRequest& request)
+ HelpExampleRpc("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"") + HelpExampleRpc("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"")
); );
ObserveSafeMode();
LOCK2(cs_main, pwallet->cs_wallet); LOCK2(cs_main, pwallet->cs_wallet);
CBitcoinAddress address(request.params[0].get_str()); CBitcoinAddress address(request.params[0].get_str());
@ -526,6 +528,7 @@ UniValue listaddressgroupings(const JSONRPCRequest& request)
+ HelpExampleRpc("listaddressgroupings", "") + HelpExampleRpc("listaddressgroupings", "")
); );
ObserveSafeMode();
LOCK2(cs_main, pwallet->cs_wallet); LOCK2(cs_main, pwallet->cs_wallet);
UniValue jsonGroupings(UniValue::VARR); UniValue jsonGroupings(UniValue::VARR);
@ -635,6 +638,7 @@ UniValue getreceivedbyaddress(const JSONRPCRequest& request)
+ HelpExampleRpc("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", 6") + HelpExampleRpc("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", 6")
); );
ObserveSafeMode();
LOCK2(cs_main, pwallet->cs_wallet); LOCK2(cs_main, pwallet->cs_wallet);
// Bitcoin address // Bitcoin address
@ -695,6 +699,7 @@ UniValue getreceivedbyaccount(const JSONRPCRequest& request)
+ HelpExampleRpc("getreceivedbyaccount", "\"tabby\", 6") + HelpExampleRpc("getreceivedbyaccount", "\"tabby\", 6")
); );
ObserveSafeMode();
LOCK2(cs_main, pwallet->cs_wallet); LOCK2(cs_main, pwallet->cs_wallet);
// Minimum confirmations // Minimum confirmations
@ -767,6 +772,7 @@ UniValue getbalance(const JSONRPCRequest& request)
+ HelpExampleRpc("getbalance", "\"*\", 6") + HelpExampleRpc("getbalance", "\"*\", 6")
); );
ObserveSafeMode();
LOCK2(cs_main, pwallet->cs_wallet); LOCK2(cs_main, pwallet->cs_wallet);
const UniValue& account_value = request.params[0]; const UniValue& account_value = request.params[0];
@ -811,6 +817,7 @@ UniValue getunconfirmedbalance(const JSONRPCRequest &request)
"getunconfirmedbalance\n" "getunconfirmedbalance\n"
"Returns the server's total unconfirmed balance\n"); "Returns the server's total unconfirmed balance\n");
ObserveSafeMode();
LOCK2(cs_main, pwallet->cs_wallet); LOCK2(cs_main, pwallet->cs_wallet);
return ValueFromAmount(pwallet->GetUnconfirmedBalance()); return ValueFromAmount(pwallet->GetUnconfirmedBalance());
@ -845,6 +852,7 @@ UniValue movecmd(const JSONRPCRequest& request)
+ HelpExampleRpc("move", "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\"") + HelpExampleRpc("move", "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\"")
); );
ObserveSafeMode();
LOCK2(cs_main, pwallet->cs_wallet); LOCK2(cs_main, pwallet->cs_wallet);
std::string strFrom = AccountFromValue(request.params[0]); std::string strFrom = AccountFromValue(request.params[0]);
@ -903,6 +911,7 @@ UniValue sendfrom(const JSONRPCRequest& request)
+ HelpExampleRpc("sendfrom", "\"tabby\", \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.01, 6, \"donation\", \"seans outpost\"") + HelpExampleRpc("sendfrom", "\"tabby\", \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.01, 6, \"donation\", \"seans outpost\"")
); );
ObserveSafeMode();
LOCK2(cs_main, pwallet->cs_wallet); LOCK2(cs_main, pwallet->cs_wallet);
std::string strAccount = AccountFromValue(request.params[0]); std::string strAccount = AccountFromValue(request.params[0]);
@ -986,6 +995,7 @@ UniValue sendmany(const JSONRPCRequest& request)
+ HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"") + HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"")
); );
ObserveSafeMode();
LOCK2(cs_main, pwallet->cs_wallet); LOCK2(cs_main, pwallet->cs_wallet);
if (pwallet->GetBroadcastTransactions() && !g_connman) { if (pwallet->GetBroadcastTransactions() && !g_connman) {
@ -1403,6 +1413,7 @@ UniValue listreceivedbyaddress(const JSONRPCRequest& request)
+ HelpExampleRpc("listreceivedbyaddress", "6, true, true") + HelpExampleRpc("listreceivedbyaddress", "6, true, true")
); );
ObserveSafeMode();
LOCK2(cs_main, pwallet->cs_wallet); LOCK2(cs_main, pwallet->cs_wallet);
return ListReceived(pwallet, request.params, false); return ListReceived(pwallet, request.params, false);
@ -1442,6 +1453,7 @@ UniValue listreceivedbyaccount(const JSONRPCRequest& request)
+ HelpExampleRpc("listreceivedbyaccount", "6, true, true") + HelpExampleRpc("listreceivedbyaccount", "6, true, true")
); );
ObserveSafeMode();
LOCK2(cs_main, pwallet->cs_wallet); LOCK2(cs_main, pwallet->cs_wallet);
return ListReceived(pwallet, request.params, true); return ListReceived(pwallet, request.params, true);
@ -1629,6 +1641,7 @@ UniValue listtransactions(const JSONRPCRequest& request)
+ HelpExampleRpc("listtransactions", "\"*\", 20, 100") + HelpExampleRpc("listtransactions", "\"*\", 20, 100")
); );
ObserveSafeMode();
LOCK2(cs_main, pwallet->cs_wallet); LOCK2(cs_main, pwallet->cs_wallet);
std::string strAccount = "*"; std::string strAccount = "*";
@ -1722,6 +1735,7 @@ UniValue listaccounts(const JSONRPCRequest& request)
+ HelpExampleRpc("listaccounts", "6") + HelpExampleRpc("listaccounts", "6")
); );
ObserveSafeMode();
LOCK2(cs_main, pwallet->cs_wallet); LOCK2(cs_main, pwallet->cs_wallet);
int nMinDepth = 1; int nMinDepth = 1;
@ -1830,6 +1844,7 @@ UniValue listsinceblock(const JSONRPCRequest& request)
+ HelpExampleRpc("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\", 6") + HelpExampleRpc("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\", 6")
); );
ObserveSafeMode();
LOCK2(cs_main, pwallet->cs_wallet); LOCK2(cs_main, pwallet->cs_wallet);
const CBlockIndex* pindex = nullptr; // Block index of the specified block or the common ancestor, if the block provided was in a deactivated chain. const CBlockIndex* pindex = nullptr; // Block index of the specified block or the common ancestor, if the block provided was in a deactivated chain.
@ -1961,6 +1976,7 @@ UniValue gettransaction(const JSONRPCRequest& request)
+ HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") + HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
); );
ObserveSafeMode();
LOCK2(cs_main, pwallet->cs_wallet); LOCK2(cs_main, pwallet->cs_wallet);
uint256 hash; uint256 hash;
@ -2022,6 +2038,7 @@ UniValue abandontransaction(const JSONRPCRequest& request)
+ HelpExampleRpc("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") + HelpExampleRpc("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
); );
ObserveSafeMode();
LOCK2(cs_main, pwallet->cs_wallet); LOCK2(cs_main, pwallet->cs_wallet);
uint256 hash; uint256 hash;
@ -2454,6 +2471,7 @@ UniValue listlockunspent(const JSONRPCRequest& request)
+ HelpExampleRpc("listlockunspent", "") + HelpExampleRpc("listlockunspent", "")
); );
ObserveSafeMode();
LOCK2(cs_main, pwallet->cs_wallet); LOCK2(cs_main, pwallet->cs_wallet);
std::vector<COutPoint> vOutpts; std::vector<COutPoint> vOutpts;
@ -2532,6 +2550,7 @@ UniValue getwalletinfo(const JSONRPCRequest& request)
+ HelpExampleRpc("getwalletinfo", "") + HelpExampleRpc("getwalletinfo", "")
); );
ObserveSafeMode();
LOCK2(cs_main, pwallet->cs_wallet); LOCK2(cs_main, pwallet->cs_wallet);
UniValue obj(UniValue::VOBJ); UniValue obj(UniValue::VOBJ);
@ -2684,6 +2703,8 @@ UniValue listunspent(const JSONRPCRequest& request)
+ HelpExampleRpc("listunspent", "6, 9999999, [] , true, { \"minimumAmount\": 0.005 } ") + HelpExampleRpc("listunspent", "6, 9999999, [] , true, { \"minimumAmount\": 0.005 } ")
); );
ObserveSafeMode();
int nMinDepth = 1; int nMinDepth = 1;
if (!request.params[0].isNull()) { if (!request.params[0].isNull()) {
RPCTypeCheckArgument(request.params[0], UniValue::VNUM); RPCTypeCheckArgument(request.params[0], UniValue::VNUM);
@ -2845,6 +2866,7 @@ UniValue fundrawtransaction(const JSONRPCRequest& request)
+ HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"") + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"")
); );
ObserveSafeMode();
RPCTypeCheck(request.params, {UniValue::VSTR}); RPCTypeCheck(request.params, {UniValue::VSTR});
CCoinControl coinControl; CCoinControl coinControl;
@ -3159,60 +3181,60 @@ extern UniValue removeprunedfunds(const JSONRPCRequest& request);
extern UniValue importmulti(const JSONRPCRequest& request); extern UniValue importmulti(const JSONRPCRequest& request);
static const CRPCCommand commands[] = static const CRPCCommand commands[] =
{ // category name actor (function) okSafeMode { // category name actor (function) argNames
// --------------------- ------------------------ ----------------------- ---------- // --------------------- ------------------------ ----------------------- ----------
{ "rawtransactions", "fundrawtransaction", &fundrawtransaction, false, {"hexstring","options"} }, { "rawtransactions", "fundrawtransaction", &fundrawtransaction, {"hexstring","options"} },
{ "hidden", "resendwallettransactions", &resendwallettransactions, true, {} }, { "hidden", "resendwallettransactions", &resendwallettransactions, {} },
{ "wallet", "abandontransaction", &abandontransaction, false, {"txid"} }, { "wallet", "abandontransaction", &abandontransaction, {"txid"} },
{ "wallet", "abortrescan", &abortrescan, false, {} }, { "wallet", "abortrescan", &abortrescan, {} },
{ "wallet", "addmultisigaddress", &addmultisigaddress, true, {"nrequired","keys","account"} }, { "wallet", "addmultisigaddress", &addmultisigaddress, {"nrequired","keys","account"} },
{ "wallet", "addwitnessaddress", &addwitnessaddress, true, {"address"} }, { "wallet", "addwitnessaddress", &addwitnessaddress, {"address"} },
{ "wallet", "backupwallet", &backupwallet, true, {"destination"} }, { "wallet", "backupwallet", &backupwallet, {"destination"} },
{ "wallet", "bumpfee", &bumpfee, true, {"txid", "options"} }, { "wallet", "bumpfee", &bumpfee, {"txid", "options"} },
{ "wallet", "dumpprivkey", &dumpprivkey, true, {"address"} }, { "wallet", "dumpprivkey", &dumpprivkey, {"address"} },
{ "wallet", "dumpwallet", &dumpwallet, true, {"filename"} }, { "wallet", "dumpwallet", &dumpwallet, {"filename"} },
{ "wallet", "encryptwallet", &encryptwallet, true, {"passphrase"} }, { "wallet", "encryptwallet", &encryptwallet, {"passphrase"} },
{ "wallet", "getaccountaddress", &getaccountaddress, true, {"account"} }, { "wallet", "getaccountaddress", &getaccountaddress, {"account"} },
{ "wallet", "getaccount", &getaccount, true, {"address"} }, { "wallet", "getaccount", &getaccount, {"address"} },
{ "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true, {"account"} }, { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, {"account"} },
{ "wallet", "getbalance", &getbalance, false, {"account","minconf","include_watchonly"} }, { "wallet", "getbalance", &getbalance, {"account","minconf","include_watchonly"} },
{ "wallet", "getnewaddress", &getnewaddress, true, {"account"} }, { "wallet", "getnewaddress", &getnewaddress, {"account"} },
{ "wallet", "getrawchangeaddress", &getrawchangeaddress, true, {} }, { "wallet", "getrawchangeaddress", &getrawchangeaddress, {} },
{ "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false, {"account","minconf"} }, { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, {"account","minconf"} },
{ "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false, {"address","minconf"} }, { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, {"address","minconf"} },
{ "wallet", "gettransaction", &gettransaction, false, {"txid","include_watchonly"} }, { "wallet", "gettransaction", &gettransaction, {"txid","include_watchonly"} },
{ "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false, {} }, { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, {} },
{ "wallet", "getwalletinfo", &getwalletinfo, false, {} }, { "wallet", "getwalletinfo", &getwalletinfo, {} },
{ "wallet", "importmulti", &importmulti, true, {"requests","options"} }, { "wallet", "importmulti", &importmulti, {"requests","options"} },
{ "wallet", "importprivkey", &importprivkey, true, {"privkey","label","rescan"} }, { "wallet", "importprivkey", &importprivkey, {"privkey","label","rescan"} },
{ "wallet", "importwallet", &importwallet, true, {"filename"} }, { "wallet", "importwallet", &importwallet, {"filename"} },
{ "wallet", "importaddress", &importaddress, true, {"address","label","rescan","p2sh"} }, { "wallet", "importaddress", &importaddress, {"address","label","rescan","p2sh"} },
{ "wallet", "importprunedfunds", &importprunedfunds, true, {"rawtransaction","txoutproof"} }, { "wallet", "importprunedfunds", &importprunedfunds, {"rawtransaction","txoutproof"} },
{ "wallet", "importpubkey", &importpubkey, true, {"pubkey","label","rescan"} }, { "wallet", "importpubkey", &importpubkey, {"pubkey","label","rescan"} },
{ "wallet", "keypoolrefill", &keypoolrefill, true, {"newsize"} }, { "wallet", "keypoolrefill", &keypoolrefill, {"newsize"} },
{ "wallet", "listaccounts", &listaccounts, false, {"minconf","include_watchonly"} }, { "wallet", "listaccounts", &listaccounts, {"minconf","include_watchonly"} },
{ "wallet", "listaddressgroupings", &listaddressgroupings, false, {} }, { "wallet", "listaddressgroupings", &listaddressgroupings, {} },
{ "wallet", "listlockunspent", &listlockunspent, false, {} }, { "wallet", "listlockunspent", &listlockunspent, {} },
{ "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false, {"minconf","include_empty","include_watchonly"} }, { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, {"minconf","include_empty","include_watchonly"} },
{ "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false, {"minconf","include_empty","include_watchonly"} }, { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, {"minconf","include_empty","include_watchonly"} },
{ "wallet", "listsinceblock", &listsinceblock, false, {"blockhash","target_confirmations","include_watchonly","include_removed"} }, { "wallet", "listsinceblock", &listsinceblock, {"blockhash","target_confirmations","include_watchonly","include_removed"} },
{ "wallet", "listtransactions", &listtransactions, false, {"account","count","skip","include_watchonly"} }, { "wallet", "listtransactions", &listtransactions, {"account","count","skip","include_watchonly"} },
{ "wallet", "listunspent", &listunspent, false, {"minconf","maxconf","addresses","include_unsafe","query_options"} }, { "wallet", "listunspent", &listunspent, {"minconf","maxconf","addresses","include_unsafe","query_options"} },
{ "wallet", "listwallets", &listwallets, true, {} }, { "wallet", "listwallets", &listwallets, {} },
{ "wallet", "lockunspent", &lockunspent, true, {"unlock","transactions"} }, { "wallet", "lockunspent", &lockunspent, {"unlock","transactions"} },
{ "wallet", "move", &movecmd, false, {"fromaccount","toaccount","amount","minconf","comment"} }, { "wallet", "move", &movecmd, {"fromaccount","toaccount","amount","minconf","comment"} },
{ "wallet", "sendfrom", &sendfrom, false, {"fromaccount","toaddress","amount","minconf","comment","comment_to"} }, { "wallet", "sendfrom", &sendfrom, {"fromaccount","toaddress","amount","minconf","comment","comment_to"} },
{ "wallet", "sendmany", &sendmany, false, {"fromaccount","amounts","minconf","comment","subtractfeefrom","replaceable","conf_target","estimate_mode"} }, { "wallet", "sendmany", &sendmany, {"fromaccount","amounts","minconf","comment","subtractfeefrom","replaceable","conf_target","estimate_mode"} },
{ "wallet", "sendtoaddress", &sendtoaddress, false, {"address","amount","comment","comment_to","subtractfeefromamount","replaceable","conf_target","estimate_mode"} }, { "wallet", "sendtoaddress", &sendtoaddress, {"address","amount","comment","comment_to","subtractfeefromamount","replaceable","conf_target","estimate_mode"} },
{ "wallet", "setaccount", &setaccount, true, {"address","account"} }, { "wallet", "setaccount", &setaccount, {"address","account"} },
{ "wallet", "settxfee", &settxfee, true, {"amount"} }, { "wallet", "settxfee", &settxfee, {"amount"} },
{ "wallet", "signmessage", &signmessage, true, {"address","message"} }, { "wallet", "signmessage", &signmessage, {"address","message"} },
{ "wallet", "walletlock", &walletlock, true, {} }, { "wallet", "walletlock", &walletlock, {} },
{ "wallet", "walletpassphrasechange", &walletpassphrasechange, true, {"oldpassphrase","newpassphrase"} }, { "wallet", "walletpassphrasechange", &walletpassphrasechange, {"oldpassphrase","newpassphrase"} },
{ "wallet", "walletpassphrase", &walletpassphrase, true, {"passphrase","timeout"} }, { "wallet", "walletpassphrase", &walletpassphrase, {"passphrase","timeout"} },
{ "wallet", "removeprunedfunds", &removeprunedfunds, true, {"txid"} }, { "wallet", "removeprunedfunds", &removeprunedfunds, {"txid"} },
{ "generating", "generate", &generate, true, {"nblocks","maxtries"} }, { "generating", "generate", &generate, {"nblocks","maxtries"} },
}; };
void RegisterWalletRPCCommands(CRPCTable &t) void RegisterWalletRPCCommands(CRPCTable &t)