Merge pull request #5711

5ebe095 Trim RPC command table (Wladimir J. van der Laan)
4401b2d Removed main.h dependency from rpcserver.cpp (Eric Lombrozo)
This commit is contained in:
Wladimir J. van der Laan 2015-02-04 10:16:24 +01:00
commit 87ecfb0f96
No known key found for this signature in database
GPG key ID: 74810B012346C9A6
11 changed files with 308 additions and 125 deletions

View file

@ -234,6 +234,26 @@ bool static Bind(const CService &addr, unsigned int flags) {
return true;
}
void OnRPCStopped()
{
cvBlockChange.notify_all();
LogPrint("rpc", "RPC stopped.\n");
}
void OnRPCPreCommand(const CRPCCommand& cmd)
{
#ifdef ENABLE_WALLET
if (cmd.reqWallet && !pwalletMain)
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
#endif
// Observe safe mode
string strWarning = GetWarnings("rpc");
if (strWarning != "" && !GetBoolArg("-disablesafemode", false) &&
!cmd.okSafeMode)
throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning);
}
std::string HelpMessage(HelpMessageMode mode)
{
// When adding new options to the categories, please keep and ensure alphabetical ordering.
@ -802,6 +822,8 @@ bool AppInit2(boost::thread_group& threadGroup)
if (fServer)
{
uiInterface.InitMessage.connect(SetRPCWarmupStatus);
RPCServer::OnStopped(&OnRPCStopped);
RPCServer::OnPreCommand(&OnRPCPreCommand);
StartRPCThreads();
}

View file

@ -105,6 +105,7 @@ Value getblockcount(const Array& params, bool fHelp)
+ HelpExampleRpc("getblockcount", "")
);
LOCK(cs_main);
return chainActive.Height();
}
@ -121,6 +122,7 @@ Value getbestblockhash(const Array& params, bool fHelp)
+ HelpExampleRpc("getbestblockhash", "")
);
LOCK(cs_main);
return chainActive.Tip()->GetBlockHash().GetHex();
}
@ -137,6 +139,7 @@ Value getdifficulty(const Array& params, bool fHelp)
+ HelpExampleRpc("getdifficulty", "")
);
LOCK(cs_main);
return GetDifficulty();
}
@ -173,6 +176,8 @@ Value getrawmempool(const Array& params, bool fHelp)
+ HelpExampleRpc("getrawmempool", "true")
);
LOCK(cs_main);
bool fVerbose = false;
if (params.size() > 0)
fVerbose = params[0].get_bool();
@ -233,6 +238,8 @@ Value getblockhash(const Array& params, bool fHelp)
+ HelpExampleRpc("getblockhash", "1000")
);
LOCK(cs_main);
int nHeight = params[0].get_int();
if (nHeight < 0 || nHeight > chainActive.Height())
throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
@ -277,6 +284,8 @@ Value getblock(const Array& params, bool fHelp)
+ HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
);
LOCK(cs_main);
std::string strHash = params[0].get_str();
uint256 hash(uint256S(strHash));
@ -326,6 +335,8 @@ Value gettxoutsetinfo(const Array& params, bool fHelp)
+ HelpExampleRpc("gettxoutsetinfo", "")
);
LOCK(cs_main);
Object ret;
CCoinsStats stats;
@ -380,6 +391,8 @@ Value gettxout(const Array& params, bool fHelp)
+ HelpExampleRpc("gettxout", "\"txid\", 1")
);
LOCK(cs_main);
Object ret;
std::string strHash = params[0].get_str();
@ -436,6 +449,8 @@ Value verifychain(const Array& params, bool fHelp)
+ HelpExampleRpc("verifychain", "")
);
LOCK(cs_main);
int nCheckLevel = GetArg("-checklevel", 3);
int nCheckDepth = GetArg("-checkblocks", 288);
if (params.size() > 0)
@ -467,6 +482,8 @@ Value getblockchaininfo(const Array& params, bool fHelp)
+ HelpExampleRpc("getblockchaininfo", "")
);
LOCK(cs_main);
Object obj;
obj.push_back(Pair("chain", Params().NetworkIDString()));
obj.push_back(Pair("blocks", (int)chainActive.Height()));
@ -526,6 +543,8 @@ Value getchaintips(const Array& params, bool fHelp)
+ HelpExampleRpc("getchaintips", "")
);
LOCK(cs_main);
/* Build up a list of chain tips. We start with the list of all
known blocks, and successively remove blocks that appear as pprev
of another block. */

View file

@ -91,6 +91,8 @@ Value importprivkey(const Array& params, bool fHelp)
+ HelpExampleRpc("importprivkey", "\"mykey\", \"testing\", false")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
EnsureWalletIsUnlocked();
string strSecret = params[0].get_str();
@ -158,6 +160,8 @@ Value importaddress(const Array& params, bool fHelp)
+ HelpExampleRpc("importaddress", "\"myaddress\", \"testing\", false")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
CScript script;
CBitcoinAddress address(params[0].get_str());
@ -223,6 +227,8 @@ Value importwallet(const Array& params, bool fHelp)
+ HelpExampleRpc("importwallet", "\"test\"")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
EnsureWalletIsUnlocked();
ifstream file;
@ -322,6 +328,8 @@ Value dumpprivkey(const Array& params, bool fHelp)
+ HelpExampleRpc("dumpprivkey", "\"myaddress\"")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
EnsureWalletIsUnlocked();
string strAddress = params[0].get_str();
@ -351,6 +359,8 @@ Value dumpwallet(const Array& params, bool fHelp)
+ HelpExampleRpc("dumpwallet", "\"test\"")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
EnsureWalletIsUnlocked();
ofstream file;

View file

@ -88,6 +88,7 @@ Value getnetworkhashps(const Array& params, bool fHelp)
+ HelpExampleRpc("getnetworkhashps", "")
);
LOCK(cs_main);
return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1);
}
@ -107,6 +108,7 @@ Value getgenerate(const Array& params, bool fHelp)
+ HelpExampleRpc("getgenerate", "")
);
LOCK(cs_main);
return GetBoolArg("-gen", false);
}
@ -200,7 +202,6 @@ Value setgenerate(const Array& params, bool fHelp)
return Value::null;
}
#endif
@ -228,6 +229,9 @@ Value getmininginfo(const Array& params, bool fHelp)
+ HelpExampleRpc("getmininginfo", "")
);
LOCK(cs_main);
Object obj;
obj.push_back(Pair("blocks", (int)chainActive.Height()));
obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize));
@ -268,8 +272,9 @@ Value prioritisetransaction(const Array& params, bool fHelp)
+ HelpExampleRpc("prioritisetransaction", "\"txid\", 0.0, 10000")
);
uint256 hash = ParseHashStr(params[0].get_str(), "txid");
LOCK(cs_main);
uint256 hash = ParseHashStr(params[0].get_str(), "txid");
CAmount nAmount = params[2].get_int64();
mempool.PrioritiseTransaction(hash, params[0].get_str(), params[1].get_real(), nAmount);
@ -358,6 +363,8 @@ Value getblocktemplate(const Array& params, bool fHelp)
+ HelpExampleRpc("getblocktemplate", "")
);
LOCK(cs_main);
std::string strMode = "template";
Value lpval = Value::null;
if (params.size() > 0)

View file

@ -69,6 +69,12 @@ Value getinfo(const Array& params, bool fHelp)
+ HelpExampleRpc("getinfo", "")
);
#ifdef ENABLE_WALLET
LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
#else
LOCK(cs_main);
#endif
proxyType proxy;
GetProxy(NET_IPV4, proxy);
@ -172,6 +178,12 @@ Value validateaddress(const Array& params, bool fHelp)
+ HelpExampleRpc("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
);
#ifdef ENABLE_WALLET
LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
#else
LOCK(cs_main);
#endif
CBitcoinAddress address(params[0].get_str());
bool isValid = address.IsValid();
@ -329,6 +341,8 @@ Value verifymessage(const Array& params, bool fHelp)
+ HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"signature\", \"my message\"")
);
LOCK(cs_main);
string strAddress = params[0].get_str();
string strSign = params[1].get_str();
string strMessage = params[2].get_str();
@ -372,6 +386,8 @@ Value setmocktime(const Array& params, bool fHelp)
if (!Params().MineBlocksOnDemand())
throw runtime_error("setmocktime for regression testing (-regtest mode) only");
LOCK(cs_main);
RPCTypeCheck(params, boost::assign::list_of(int_type));
SetMockTime(params[0].get_int64());

View file

@ -34,7 +34,8 @@ Value getconnectioncount(const Array& params, bool fHelp)
+ HelpExampleRpc("getconnectioncount", "")
);
LOCK(cs_vNodes);
LOCK2(cs_main, cs_vNodes);
return (int)vNodes.size();
}
@ -52,7 +53,8 @@ Value ping(const Array& params, bool fHelp)
);
// Request that each node send a ping during next message processing pass
LOCK(cs_vNodes);
LOCK2(cs_main, cs_vNodes);
BOOST_FOREACH(CNode* pNode, vNodes) {
pNode->fPingQueued = true;
}
@ -113,6 +115,8 @@ Value getpeerinfo(const Array& params, bool fHelp)
+ HelpExampleRpc("getpeerinfo", "")
);
LOCK(cs_main);
vector<CNodeStats> vstats;
CopyNodeStats(vstats);
@ -411,6 +415,8 @@ Value getnetworkinfo(const Array& params, bool fHelp)
+ HelpExampleRpc("getnetworkinfo", "")
);
LOCK(cs_main);
Object obj;
obj.push_back(Pair("version", CLIENT_VERSION));
obj.push_back(Pair("subversion",

View file

@ -169,6 +169,8 @@ Value getrawtransaction(const Array& params, bool fHelp)
+ HelpExampleRpc("getrawtransaction", "\"mytxid\", 1")
);
LOCK(cs_main);
uint256 hash = ParseHashV(params[0], "parameter 1");
bool fVerbose = false;
@ -256,6 +258,7 @@ Value listunspent(const Array& params, bool fHelp)
Array results;
vector<COutput> vecOutputs;
assert(pwalletMain != NULL);
LOCK2(cs_main, pwalletMain->cs_wallet);
pwalletMain->AvailableCoins(vecOutputs, false);
BOOST_FOREACH(const COutput& out, vecOutputs) {
if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth)
@ -334,6 +337,7 @@ Value createrawtransaction(const Array& params, bool fHelp)
+ HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\"")
);
LOCK(cs_main);
RPCTypeCheck(params, boost::assign::list_of(array_type)(obj_type));
Array inputs = params[0].get_array();
@ -428,6 +432,7 @@ Value decoderawtransaction(const Array& params, bool fHelp)
+ HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
);
LOCK(cs_main);
RPCTypeCheck(params, boost::assign::list_of(str_type));
CTransaction tx;
@ -466,6 +471,7 @@ Value decodescript(const Array& params, bool fHelp)
+ HelpExampleRpc("decodescript", "\"hexstring\"")
);
LOCK(cs_main);
RPCTypeCheck(params, boost::assign::list_of(str_type));
Object r;
@ -532,6 +538,11 @@ Value signrawtransaction(const Array& params, bool fHelp)
+ HelpExampleRpc("signrawtransaction", "\"myhex\"")
);
#ifdef ENABLE_WALLET
LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
#else
LOCK(cs_main);
#endif
RPCTypeCheck(params, boost::assign::list_of(str_type)(array_type)(array_type)(str_type), true);
vector<unsigned char> txData(ParseHexV(params[0], "argument 1"));
@ -591,7 +602,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
}
}
#ifdef ENABLE_WALLET
else
else if (pwalletMain)
EnsureWalletIsUnlocked();
#endif
@ -722,6 +733,7 @@ Value sendrawtransaction(const Array& params, bool fHelp)
+ HelpExampleRpc("sendrawtransaction", "\"signedhex\"")
);
LOCK(cs_main);
RPCTypeCheck(params, boost::assign::list_of(str_type)(bool_type));
// parse hex string from parameter

View file

@ -7,9 +7,11 @@
#include "base58.h"
#include "init.h"
#include "main.h"
#include "random.h"
#include "sync.h"
#include "ui_interface.h"
#include "util.h"
#include "utilstrencodings.h"
#ifdef ENABLE_WALLET
#include "wallet.h"
#endif
@ -23,11 +25,13 @@
#include <boost/iostreams/concepts.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/signals2/signal.hpp>
#include <boost/thread.hpp>
#include "json/json_spirit_writer_template.h"
using namespace boost::asio;
using namespace json_spirit;
using namespace RPCServer;
using namespace std;
static std::string strRPCUserColonPass;
@ -46,6 +50,34 @@ static boost::asio::io_service::work *rpc_dummy_work = NULL;
static std::vector<CSubNet> rpc_allow_subnets; //!< List of subnets to allow RPC connections from
static std::vector< boost::shared_ptr<ip::tcp::acceptor> > rpc_acceptors;
static struct CRPCSignals
{
boost::signals2::signal<void ()> Started;
boost::signals2::signal<void ()> Stopped;
boost::signals2::signal<void (const CRPCCommand&)> PreCommand;
boost::signals2::signal<void (const CRPCCommand&)> PostCommand;
} g_rpcSignals;
void RPCServer::OnStarted(boost::function<void ()> slot)
{
g_rpcSignals.Started.connect(slot);
}
void RPCServer::OnStopped(boost::function<void ()> slot)
{
g_rpcSignals.Stopped.connect(slot);
}
void RPCServer::OnPreCommand(boost::function<void (const CRPCCommand&)> slot)
{
g_rpcSignals.PreCommand.connect(boost::bind(slot, _1));
}
void RPCServer::OnPostCommand(boost::function<void (const CRPCCommand&)> slot)
{
g_rpcSignals.PostCommand.connect(boost::bind(slot, _1));
}
void RPCTypeCheck(const Array& params,
const list<Value_type>& typesExpected,
bool fAllowNull)
@ -239,112 +271,110 @@ Value stop(const Array& params, bool fHelp)
* Call Table
*/
static const CRPCCommand vRPCCommands[] =
{ // category name actor (function) okSafeMode threadSafe reqWallet
// --------------------- ------------------------ ----------------------- ---------- ---------- ---------
{ // category name actor (function) okSafeMode reqWallet
// --------------------- ------------------------ ----------------------- ---------- ---------
/* Overall control/query calls */
{ "control", "getinfo", &getinfo, true, false, false }, /* uses wallet if enabled */
{ "control", "help", &help, true, true, false },
{ "control", "stop", &stop, true, true, false },
{ "control", "getinfo", &getinfo, true, false }, /* uses wallet if enabled */
{ "control", "help", &help, true, false },
{ "control", "stop", &stop, true, false },
/* P2P networking */
{ "network", "getnetworkinfo", &getnetworkinfo, true, false, false },
{ "network", "addnode", &addnode, true, true, false },
{ "network", "getaddednodeinfo", &getaddednodeinfo, true, true, false },
{ "network", "getconnectioncount", &getconnectioncount, true, false, false },
{ "network", "getnettotals", &getnettotals, true, true, false },
{ "network", "getpeerinfo", &getpeerinfo, true, false, false },
{ "network", "ping", &ping, true, false, false },
{ "network", "getnetworkinfo", &getnetworkinfo, true, false },
{ "network", "addnode", &addnode, true, false },
{ "network", "getaddednodeinfo", &getaddednodeinfo, true, false },
{ "network", "getconnectioncount", &getconnectioncount, true, false },
{ "network", "getnettotals", &getnettotals, true, false },
{ "network", "getpeerinfo", &getpeerinfo, true, false },
{ "network", "ping", &ping, true, false },
/* Block chain and UTXO */
{ "blockchain", "getblockchaininfo", &getblockchaininfo, true, false, false },
{ "blockchain", "getbestblockhash", &getbestblockhash, true, false, false },
{ "blockchain", "getblockcount", &getblockcount, true, false, false },
{ "blockchain", "getblock", &getblock, true, false, false },
{ "blockchain", "getblockhash", &getblockhash, true, false, false },
{ "blockchain", "getchaintips", &getchaintips, true, false, false },
{ "blockchain", "getdifficulty", &getdifficulty, true, false, false },
{ "blockchain", "getmempoolinfo", &getmempoolinfo, true, true, false },
{ "blockchain", "getrawmempool", &getrawmempool, true, false, false },
{ "blockchain", "gettxout", &gettxout, true, false, false },
{ "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, false, false },
{ "blockchain", "verifychain", &verifychain, true, false, false },
{ "blockchain", "invalidateblock", &invalidateblock, true, true, false },
{ "blockchain", "reconsiderblock", &reconsiderblock, true, true, false },
{ "blockchain", "getblockchaininfo", &getblockchaininfo, true, false },
{ "blockchain", "getbestblockhash", &getbestblockhash, true, false },
{ "blockchain", "getblockcount", &getblockcount, true, false },
{ "blockchain", "getblock", &getblock, true, false },
{ "blockchain", "getblockhash", &getblockhash, true, false },
{ "blockchain", "getchaintips", &getchaintips, true, false },
{ "blockchain", "getdifficulty", &getdifficulty, true, false },
{ "blockchain", "getmempoolinfo", &getmempoolinfo, true, false },
{ "blockchain", "getrawmempool", &getrawmempool, true, false },
{ "blockchain", "gettxout", &gettxout, true, false },
{ "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, false },
{ "blockchain", "verifychain", &verifychain, true, false },
/* Mining */
{ "mining", "getblocktemplate", &getblocktemplate, true, false, false },
{ "mining", "getmininginfo", &getmininginfo, true, false, false },
{ "mining", "getnetworkhashps", &getnetworkhashps, true, false, false },
{ "mining", "prioritisetransaction", &prioritisetransaction, true, false, false },
{ "mining", "submitblock", &submitblock, true, true, false },
{ "mining", "getblocktemplate", &getblocktemplate, true, false },
{ "mining", "getmininginfo", &getmininginfo, true, false },
{ "mining", "getnetworkhashps", &getnetworkhashps, true, false },
{ "mining", "prioritisetransaction", &prioritisetransaction, true, false },
{ "mining", "submitblock", &submitblock, true, false },
#ifdef ENABLE_WALLET
/* Coin generation */
{ "generating", "getgenerate", &getgenerate, true, false, false },
{ "generating", "setgenerate", &setgenerate, true, true, false },
{ "generating", "getgenerate", &getgenerate, true, false },
{ "generating", "setgenerate", &setgenerate, true, false },
#endif
/* Raw transactions */
{ "rawtransactions", "createrawtransaction", &createrawtransaction, true, false, false },
{ "rawtransactions", "decoderawtransaction", &decoderawtransaction, true, false, false },
{ "rawtransactions", "decodescript", &decodescript, true, false, false },
{ "rawtransactions", "getrawtransaction", &getrawtransaction, true, false, false },
{ "rawtransactions", "sendrawtransaction", &sendrawtransaction, false, false, false },
{ "rawtransactions", "signrawtransaction", &signrawtransaction, false, false, false }, /* uses wallet if enabled */
{ "rawtransactions", "createrawtransaction", &createrawtransaction, true, false },
{ "rawtransactions", "decoderawtransaction", &decoderawtransaction, true, false },
{ "rawtransactions", "decodescript", &decodescript, true, false },
{ "rawtransactions", "getrawtransaction", &getrawtransaction, true, false },
{ "rawtransactions", "sendrawtransaction", &sendrawtransaction, false, false },
{ "rawtransactions", "signrawtransaction", &signrawtransaction, false, false }, /* uses wallet if enabled */
/* Utility functions */
{ "util", "createmultisig", &createmultisig, true, true , false },
{ "util", "validateaddress", &validateaddress, true, false, false }, /* uses wallet if enabled */
{ "util", "verifymessage", &verifymessage, true, false, false },
{ "util", "estimatefee", &estimatefee, true, true, false },
{ "util", "estimatepriority", &estimatepriority, true, true, false },
{ "util", "createmultisig", &createmultisig, true, false },
{ "util", "validateaddress", &validateaddress, true, false }, /* uses wallet if enabled */
{ "util", "verifymessage", &verifymessage, true, false },
{ "util", "estimatefee", &estimatefee, true, false },
{ "util", "estimatepriority", &estimatepriority, true, false },
/* Not shown in help */
{ "hidden", "invalidateblock", &invalidateblock, true, true, false },
{ "hidden", "reconsiderblock", &reconsiderblock, true, true, false },
{ "hidden", "setmocktime", &setmocktime, true, false, false },
{ "hidden", "invalidateblock", &invalidateblock, true, false },
{ "hidden", "reconsiderblock", &reconsiderblock, true, false },
{ "hidden", "setmocktime", &setmocktime, true, false },
#ifdef ENABLE_WALLET
/* Wallet */
{ "wallet", "addmultisigaddress", &addmultisigaddress, true, false, true },
{ "wallet", "backupwallet", &backupwallet, true, false, true },
{ "wallet", "dumpprivkey", &dumpprivkey, true, false, true },
{ "wallet", "dumpwallet", &dumpwallet, true, false, true },
{ "wallet", "encryptwallet", &encryptwallet, true, false, true },
{ "wallet", "getaccountaddress", &getaccountaddress, true, false, true },
{ "wallet", "getaccount", &getaccount, true, false, true },
{ "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true, false, true },
{ "wallet", "getbalance", &getbalance, false, false, true },
{ "wallet", "getnewaddress", &getnewaddress, true, false, true },
{ "wallet", "getrawchangeaddress", &getrawchangeaddress, true, false, true },
{ "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false, false, true },
{ "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false, false, true },
{ "wallet", "gettransaction", &gettransaction, false, false, true },
{ "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false, false, true },
{ "wallet", "getwalletinfo", &getwalletinfo, false, false, true },
{ "wallet", "importprivkey", &importprivkey, true, false, true },
{ "wallet", "importwallet", &importwallet, true, false, true },
{ "wallet", "importaddress", &importaddress, true, false, true },
{ "wallet", "keypoolrefill", &keypoolrefill, true, false, true },
{ "wallet", "listaccounts", &listaccounts, false, false, true },
{ "wallet", "listaddressgroupings", &listaddressgroupings, false, false, true },
{ "wallet", "listlockunspent", &listlockunspent, false, false, true },
{ "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false, false, true },
{ "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false, false, true },
{ "wallet", "listsinceblock", &listsinceblock, false, false, true },
{ "wallet", "listtransactions", &listtransactions, false, false, true },
{ "wallet", "listunspent", &listunspent, false, false, true },
{ "wallet", "lockunspent", &lockunspent, true, false, true },
{ "wallet", "move", &movecmd, false, false, true },
{ "wallet", "sendfrom", &sendfrom, false, false, true },
{ "wallet", "sendmany", &sendmany, false, false, true },
{ "wallet", "sendtoaddress", &sendtoaddress, false, false, true },
{ "wallet", "setaccount", &setaccount, true, false, true },
{ "wallet", "settxfee", &settxfee, true, false, true },
{ "wallet", "signmessage", &signmessage, true, false, true },
{ "wallet", "walletlock", &walletlock, true, false, true },
{ "wallet", "walletpassphrasechange", &walletpassphrasechange, true, false, true },
{ "wallet", "walletpassphrase", &walletpassphrase, true, false, true },
{ "wallet", "addmultisigaddress", &addmultisigaddress, true, true },
{ "wallet", "backupwallet", &backupwallet, true, true },
{ "wallet", "dumpprivkey", &dumpprivkey, true, true },
{ "wallet", "dumpwallet", &dumpwallet, true, true },
{ "wallet", "encryptwallet", &encryptwallet, true, true },
{ "wallet", "getaccountaddress", &getaccountaddress, true, true },
{ "wallet", "getaccount", &getaccount, true, true },
{ "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true, true },
{ "wallet", "getbalance", &getbalance, false, true },
{ "wallet", "getnewaddress", &getnewaddress, true, true },
{ "wallet", "getrawchangeaddress", &getrawchangeaddress, true, true },
{ "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false, true },
{ "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false, true },
{ "wallet", "gettransaction", &gettransaction, false, true },
{ "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false, true },
{ "wallet", "getwalletinfo", &getwalletinfo, false, true },
{ "wallet", "importprivkey", &importprivkey, true, true },
{ "wallet", "importwallet", &importwallet, true, true },
{ "wallet", "importaddress", &importaddress, true, true },
{ "wallet", "keypoolrefill", &keypoolrefill, true, true },
{ "wallet", "listaccounts", &listaccounts, false, true },
{ "wallet", "listaddressgroupings", &listaddressgroupings, false, true },
{ "wallet", "listlockunspent", &listlockunspent, false, true },
{ "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false, true },
{ "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false, true },
{ "wallet", "listsinceblock", &listsinceblock, false, true },
{ "wallet", "listtransactions", &listtransactions, false, true },
{ "wallet", "listunspent", &listunspent, false, true },
{ "wallet", "lockunspent", &lockunspent, true, true },
{ "wallet", "move", &movecmd, false, true },
{ "wallet", "sendfrom", &sendfrom, false, true },
{ "wallet", "sendmany", &sendmany, false, true },
{ "wallet", "sendtoaddress", &sendtoaddress, false, true },
{ "wallet", "setaccount", &setaccount, true, true },
{ "wallet", "settxfee", &settxfee, true, true },
{ "wallet", "signmessage", &signmessage, true, true },
{ "wallet", "walletlock", &walletlock, true, true },
{ "wallet", "walletpassphrasechange", &walletpassphrasechange, true, true },
{ "wallet", "walletpassphrase", &walletpassphrase, true, true },
#endif // ENABLE_WALLET
};
@ -693,6 +723,7 @@ void StartRPCThreads()
for (int i = 0; i < GetArg("-rpcthreads", 4); i++)
rpc_worker_group->create_thread(boost::bind(&boost::asio::io_service::run, rpc_io_service));
fRPCRunning = true;
g_rpcSignals.Started();
}
void StartDummyRPCThread()
@ -735,7 +766,7 @@ void StopRPCThreads()
deadlineTimers.clear();
rpc_io_service->stop();
cvBlockChange.notify_all();
g_rpcSignals.Stopped();
if (rpc_worker_group != NULL)
rpc_worker_group->join_all();
delete rpc_dummy_work; rpc_dummy_work = NULL;
@ -978,45 +1009,20 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s
const CRPCCommand *pcmd = tableRPC[strMethod];
if (!pcmd)
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
#ifdef ENABLE_WALLET
if (pcmd->reqWallet && !pwalletMain)
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
#endif
// Observe safe mode
string strWarning = GetWarnings("rpc");
if (strWarning != "" && !GetBoolArg("-disablesafemode", false) &&
!pcmd->okSafeMode)
throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning);
g_rpcSignals.PreCommand(*pcmd);
try
{
// Execute
Value result;
{
if (pcmd->threadSafe)
result = pcmd->actor(params, false);
#ifdef ENABLE_WALLET
else if (!pwalletMain) {
LOCK(cs_main);
result = pcmd->actor(params, false);
} else {
LOCK2(cs_main, pwalletMain->cs_wallet);
result = pcmd->actor(params, false);
}
#else // ENABLE_WALLET
else {
LOCK(cs_main);
result = pcmd->actor(params, false);
}
#endif // !ENABLE_WALLET
}
return result;
return pcmd->actor(params, false);
}
catch (const std::exception& e)
{
throw JSONRPCError(RPC_MISC_ERROR, e.what());
}
g_rpcSignals.PostCommand(*pcmd);
}
std::string HelpExampleCli(string methodname, string args){

View file

@ -19,6 +19,16 @@
#include "json/json_spirit_utils.h"
#include "json/json_spirit_writer_template.h"
class CRPCCommand;
namespace RPCServer
{
void OnStarted(boost::function<void ()> slot);
void OnStopped(boost::function<void ()> slot);
void OnPreCommand(boost::function<void (const CRPCCommand&)> slot);
void OnPostCommand(boost::function<void (const CRPCCommand&)> slot);
}
class CBlockIndex;
class CNetAddr;
@ -88,7 +98,6 @@ public:
std::string name;
rpcfn_type actor;
bool okSafeMode;
bool threadSafe;
bool reqWallet;
};

View file

@ -90,6 +90,8 @@ Value getnewaddress(const Array& params, bool fHelp)
+ HelpExampleRpc("getnewaddress", "")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
// Parse the account first so we don't generate a key if there's an error
string strAccount;
if (params.size() > 0)
@ -164,13 +166,14 @@ Value getaccountaddress(const Array& params, bool fHelp)
+ HelpExampleRpc("getaccountaddress", "\"myaccount\"")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
// Parse the account first so we don't generate a key if there's an error
string strAccount = AccountFromValue(params[0]);
Value ret;
ret = GetAccountAddress(strAccount).ToString();
return ret;
}
@ -189,6 +192,8 @@ Value getrawchangeaddress(const Array& params, bool fHelp)
+ HelpExampleRpc("getrawchangeaddress", "")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
if (!pwalletMain->IsLocked())
pwalletMain->TopUpKeyPool();
@ -219,11 +224,12 @@ Value setaccount(const Array& params, bool fHelp)
+ HelpExampleRpc("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"tabby\"")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
CBitcoinAddress address(params[0].get_str());
if (!address.IsValid())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
string strAccount;
if (params.size() > 1)
strAccount = AccountFromValue(params[1]);
@ -262,6 +268,8 @@ Value getaccount(const Array& params, bool fHelp)
+ HelpExampleRpc("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\"")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
CBitcoinAddress address(params[0].get_str());
if (!address.IsValid())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
@ -292,6 +300,8 @@ Value getaddressesbyaccount(const Array& params, bool fHelp)
+ HelpExampleRpc("getaddressesbyaccount", "\"tabby\"")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
string strAccount = AccountFromValue(params[0]);
// Find all addresses that have the given account
@ -363,6 +373,8 @@ Value sendtoaddress(const Array& params, bool fHelp)
+ HelpExampleRpc("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
CBitcoinAddress address(params[0].get_str());
if (!address.IsValid())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
@ -409,6 +421,8 @@ Value listaddressgroupings(const Array& params, bool fHelp)
+ HelpExampleRpc("listaddressgroupings", "")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
Array jsonGroupings;
map<CTxDestination, CAmount> balances = pwalletMain->GetAddressBalances();
BOOST_FOREACH(set<CTxDestination> grouping, pwalletMain->GetAddressGroupings())
@ -454,6 +468,8 @@ Value signmessage(const Array& params, bool fHelp)
+ HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"my message\"")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
EnsureWalletIsUnlocked();
string strAddress = params[0].get_str();
@ -504,6 +520,8 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
+ HelpExampleRpc("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", 6")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
// Bitcoin address
CBitcoinAddress address = CBitcoinAddress(params[0].get_str());
if (!address.IsValid())
@ -557,6 +575,8 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
+ HelpExampleRpc("getreceivedbyaccount", "\"tabby\", 6")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
// Minimum confirmations
int nMinDepth = 1;
if (params.size() > 1)
@ -643,6 +663,8 @@ Value getbalance(const Array& params, bool fHelp)
+ HelpExampleRpc("getbalance", "\"*\", 6")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
if (params.size() == 0)
return ValueFromAmount(pwalletMain->GetBalance());
@ -695,6 +717,9 @@ Value getunconfirmedbalance(const Array &params, bool fHelp)
throw runtime_error(
"getunconfirmedbalance\n"
"Returns the server's total unconfirmed balance\n");
LOCK2(cs_main, pwalletMain->cs_wallet);
return ValueFromAmount(pwalletMain->GetUnconfirmedBalance());
}
@ -721,6 +746,8 @@ Value movecmd(const Array& params, bool fHelp)
+ HelpExampleRpc("move", "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\"")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
string strFrom = AccountFromValue(params[0]);
string strTo = AccountFromValue(params[1]);
CAmount nAmount = AmountFromValue(params[2]);
@ -793,6 +820,8 @@ Value sendfrom(const Array& params, bool fHelp)
+ HelpExampleRpc("sendfrom", "\"tabby\", \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.01, 6, \"donation\", \"seans outpost\"")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
string strAccount = AccountFromValue(params[0]);
CBitcoinAddress address(params[1].get_str());
if (!address.IsValid())
@ -850,6 +879,8 @@ Value sendmany(const Array& params, bool fHelp)
+ HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
string strAccount = AccountFromValue(params[0]);
Object sendTo = params[1].get_obj();
int nMinDepth = 1;
@ -935,6 +966,8 @@ Value addmultisigaddress(const Array& params, bool fHelp)
throw runtime_error(msg);
}
LOCK2(cs_main, pwalletMain->cs_wallet);
string strAccount;
if (params.size() > 2)
strAccount = AccountFromValue(params[2]);
@ -1110,6 +1143,8 @@ Value listreceivedbyaddress(const Array& params, bool fHelp)
+ HelpExampleRpc("listreceivedbyaddress", "6, true, true")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
return ListReceived(params, false);
}
@ -1141,6 +1176,8 @@ Value listreceivedbyaccount(const Array& params, bool fHelp)
+ HelpExampleRpc("listreceivedbyaccount", "6, true, true")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
return ListReceived(params, true);
}
@ -1292,6 +1329,8 @@ Value listtransactions(const Array& params, bool fHelp)
+ HelpExampleRpc("listtransactions", "\"*\", 20, 100")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
string strAccount = "*";
if (params.size() > 0)
strAccount = params[0].get_str();
@ -1372,6 +1411,8 @@ Value listaccounts(const Array& params, bool fHelp)
+ HelpExampleRpc("listaccounts", "6")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
int nMinDepth = 1;
if (params.size() > 0)
nMinDepth = params[0].get_int();
@ -1460,6 +1501,8 @@ Value listsinceblock(const Array& params, bool fHelp)
+ HelpExampleRpc("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\", 6")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
CBlockIndex *pindex = NULL;
int target_confirms = 1;
isminefilter filter = ISMINE_SPENDABLE;
@ -1546,6 +1589,8 @@ Value gettransaction(const Array& params, bool fHelp)
+ HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
uint256 hash;
hash.SetHex(params[0].get_str());
@ -1594,6 +1639,8 @@ Value backupwallet(const Array& params, bool fHelp)
+ HelpExampleRpc("backupwallet", "\"backup.dat\"")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
string strDest = params[0].get_str();
if (!BackupWallet(*pwalletMain, strDest))
throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!");
@ -1616,6 +1663,8 @@ Value keypoolrefill(const Array& params, bool fHelp)
+ HelpExampleRpc("keypoolrefill", "")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
// 0 is interpreted by TopUpKeyPool() as the default keypool size given by -keypool
unsigned int kpSize = 0;
if (params.size() > 0) {
@ -1663,6 +1712,8 @@ Value walletpassphrase(const Array& params, bool fHelp)
+ HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
if (fHelp)
return true;
if (!pwalletMain->IsCrypted())
@ -1710,6 +1761,8 @@ Value walletpassphrasechange(const Array& params, bool fHelp)
+ HelpExampleRpc("walletpassphrasechange", "\"old one\", \"new one\"")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
if (fHelp)
return true;
if (!pwalletMain->IsCrypted())
@ -1756,6 +1809,8 @@ Value walletlock(const Array& params, bool fHelp)
+ HelpExampleRpc("walletlock", "")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
if (fHelp)
return true;
if (!pwalletMain->IsCrypted())
@ -1797,6 +1852,8 @@ Value encryptwallet(const Array& params, bool fHelp)
+ HelpExampleRpc("encryptwallet", "\"my pass phrase\"")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
if (fHelp)
return true;
if (pwalletMain->IsCrypted())
@ -1861,6 +1918,8 @@ Value lockunspent(const Array& params, bool fHelp)
+ HelpExampleRpc("lockunspent", "false, \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
if (params.size() == 1)
RPCTypeCheck(params, boost::assign::list_of(bool_type));
else
@ -1930,6 +1989,8 @@ Value listlockunspent(const Array& params, bool fHelp)
+ HelpExampleRpc("listlockunspent", "")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
vector<COutPoint> vOutpts;
pwalletMain->ListLockedCoins(vOutpts);
@ -1961,6 +2022,8 @@ Value settxfee(const Array& params, bool fHelp)
+ HelpExampleRpc("settxfee", "0.00001")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
// Amount
CAmount nAmount = 0;
if (params[0].get_real() != 0.0)
@ -1992,6 +2055,8 @@ Value getwalletinfo(const Array& params, bool fHelp)
+ HelpExampleRpc("getwalletinfo", "")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
Object obj;
obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));

View file

@ -142,6 +142,17 @@ public:
Enter(pszName, pszFile, nLine);
}
CMutexLock(Mutex* pmutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false)
{
if (!pmutexIn) return;
lock = boost::unique_lock<Mutex>(*pmutexIn, boost::defer_lock);
if (fTry)
TryEnter(pszName, pszFile, nLine);
else
Enter(pszName, pszFile, nLine);
}
~CMutexLock()
{
if (lock.owns_lock())