]> Git Repo - VerusCoin.git/blame - src/rpc/server.cpp
Add merge mining indicator to getmininginfo
[VerusCoin.git] / src / rpc / server.cpp
CommitLineData
69d605f4 1// Copyright (c) 2010 Satoshi Nakamoto
f914f1a7 2// Copyright (c) 2009-2014 The Bitcoin Core developers
77920402 3// Distributed under the MIT software license, see the accompanying
3a25a2b9 4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
69d605f4 5
4519a766 6#include "rpc/server.h"
51ed9ec9 7
0eeb4f5d 8#include "init.h"
3d31e09c 9#include "key_io.h"
4401b2d7
EL
10#include "random.h"
11#include "sync.h"
48ba56cd 12#include "ui_interface.h"
c037531d 13#include "util.h"
4401b2d7 14#include "utilstrencodings.h"
fc72c078
S
15#include "asyncrpcqueue.h"
16
17#include <memory>
51ed9ec9 18
afd64f76
WL
19#include <univalue.h>
20
914dc012 21#include <boost/bind.hpp>
95d888a6 22#include <boost/filesystem.hpp>
a0780ba0 23#include <boost/foreach.hpp>
69d605f4
WL
24#include <boost/iostreams/concepts.hpp>
25#include <boost/iostreams/stream.hpp>
914dc012 26#include <boost/shared_ptr.hpp>
4401b2d7 27#include <boost/signals2/signal.hpp>
ad49c256 28#include <boost/thread.hpp>
afd64f76 29#include <boost/algorithm/string/case_conv.hpp> // for to_upper()
5ce4c2a2 30
4401b2d7 31using namespace RPCServer;
40a158e1 32using namespace std;
69d605f4 33
ff6a7af1 34static bool fRPCRunning = false;
af82884a
DK
35static bool fRPCInWarmup = true;
36static std::string rpcWarmupStatus("RPC server started");
37static CCriticalSection cs_rpcWarmup;
afd64f76
WL
38/* Timer-creating functions */
39static std::vector<RPCTimerInterface*> timerInterfaces;
40/* Map of name to timer.
41 * @note Can be changed to std::unique_ptr when C++11 */
42static std::map<std::string, boost::shared_ptr<RPCTimerBase> > deadlineTimers;
e9205293 43
4401b2d7
EL
44static struct CRPCSignals
45{
46 boost::signals2::signal<void ()> Started;
47 boost::signals2::signal<void ()> Stopped;
48 boost::signals2::signal<void (const CRPCCommand&)> PreCommand;
49 boost::signals2::signal<void (const CRPCCommand&)> PostCommand;
50} g_rpcSignals;
51
52void RPCServer::OnStarted(boost::function<void ()> slot)
53{
54 g_rpcSignals.Started.connect(slot);
55}
56
57void RPCServer::OnStopped(boost::function<void ()> slot)
58{
59 g_rpcSignals.Stopped.connect(slot);
60}
61
62void RPCServer::OnPreCommand(boost::function<void (const CRPCCommand&)> slot)
63{
64 g_rpcSignals.PreCommand.connect(boost::bind(slot, _1));
65}
66
67void RPCServer::OnPostCommand(boost::function<void (const CRPCCommand&)> slot)
68{
69 g_rpcSignals.PostCommand.connect(boost::bind(slot, _1));
70}
71
d014114d
JS
72void RPCTypeCheck(const UniValue& params,
73 const list<UniValue::VType>& typesExpected,
cc6dfd1f 74 bool fAllowNull)
899d373b 75{
cc71666a 76 size_t i = 0;
d014114d 77 BOOST_FOREACH(UniValue::VType t, typesExpected)
899d373b
GA
78 {
79 if (params.size() <= i)
80 break;
81
d014114d 82 const UniValue& v = params[i];
ed21d5bd 83 if (!((v.type() == t) || (fAllowNull && (v.isNull()))))
899d373b
GA
84 {
85 string err = strprintf("Expected type %s, got %s",
ed21d5bd 86 uvTypeName(t), uvTypeName(v.type()));
738835d7 87 throw JSONRPCError(RPC_TYPE_ERROR, err);
899d373b
GA
88 }
89 i++;
90 }
91}
92
ed21d5bd
JG
93void RPCTypeCheckObj(const UniValue& o,
94 const map<string, UniValue::VType>& typesExpected,
cc6dfd1f 95 bool fAllowNull)
899d373b 96{
d014114d 97 BOOST_FOREACH(const PAIRTYPE(string, UniValue::VType)& t, typesExpected)
899d373b 98 {
d014114d 99 const UniValue& v = find_value(o, t.first);
ed21d5bd 100 if (!fAllowNull && v.isNull())
7d9d134b 101 throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing %s", t.first));
cc6dfd1f 102
ed21d5bd 103 if (!((v.type() == t.second) || (fAllowNull && (v.isNull()))))
899d373b
GA
104 {
105 string err = strprintf("Expected type %s for %s, got %s",
ed21d5bd 106 uvTypeName(t.second), t.first, uvTypeName(v.type()));
738835d7 107 throw JSONRPCError(RPC_TYPE_ERROR, err);
899d373b
GA
108 }
109 }
110}
111
d014114d 112CAmount AmountFromValue(const UniValue& value)
69d605f4 113{
84d1d5fd
WL
114 if (!value.isNum() && !value.isStr())
115 throw JSONRPCError(RPC_TYPE_ERROR, "Amount is not a number or string");
c66dff3d 116 CAmount amount;
fed500e2 117 if (!ParseFixedPoint(value.getValStr(), 8, &amount))
738835d7 118 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
c66dff3d
WL
119 if (!MoneyRange(amount))
120 throw JSONRPCError(RPC_TYPE_ERROR, "Amount out of range");
121 return amount;
69d605f4
WL
122}
123
851f58f9 124UniValue ValueFromAmount(const CAmount& amount)
69d605f4 125{
d5bf1afa
WL
126 bool sign = amount < 0;
127 int64_t n_abs = (sign ? -amount : amount);
128 int64_t quotient = n_abs / COIN;
129 int64_t remainder = n_abs % COIN;
130 return UniValue(UniValue::VNUM,
131 strprintf("%s%d.%08d", sign ? "-" : "", quotient, remainder));
69d605f4
WL
132}
133
d014114d 134uint256 ParseHashV(const UniValue& v, string strName)
463c9710
PT
135{
136 string strHex;
ed21d5bd 137 if (v.isStr())
463c9710
PT
138 strHex = v.get_str();
139 if (!IsHex(strHex)) // Note: IsHex("") is false
140 throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
141 uint256 result;
142 result.SetHex(strHex);
143 return result;
144}
d014114d 145uint256 ParseHashO(const UniValue& o, string strKey)
463c9710
PT
146{
147 return ParseHashV(find_value(o, strKey), strKey);
148}
d014114d 149vector<unsigned char> ParseHexV(const UniValue& v, string strName)
463c9710
PT
150{
151 string strHex;
ed21d5bd 152 if (v.isStr())
463c9710
PT
153 strHex = v.get_str();
154 if (!IsHex(strHex))
155 throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
156 return ParseHex(strHex);
157}
d014114d 158vector<unsigned char> ParseHexO(const UniValue& o, string strKey)
463c9710
PT
159{
160 return ParseHexV(find_value(o, strKey), strKey);
161}
69d605f4 162
77920402
MF
163/**
164 * Note: This interface may still be subject to change.
165 */
69d605f4 166
db954a65 167std::string CRPCTable::help(const std::string& strCommand) const
69d605f4 168{
69d605f4 169 string strRet;
6b5b7cbf 170 string category;
69d605f4 171 set<rpcfn_type> setDone;
6b5b7cbf
CL
172 vector<pair<string, const CRPCCommand*> > vCommands;
173
9862229d 174 for (map<string, const CRPCCommand*>::const_iterator mi = mapCommands.begin(); mi != mapCommands.end(); ++mi)
6b5b7cbf
CL
175 vCommands.push_back(make_pair(mi->second->category + mi->first, mi->second));
176 sort(vCommands.begin(), vCommands.end());
177
178 BOOST_FOREACH(const PAIRTYPE(string, const CRPCCommand*)& command, vCommands)
69d605f4 179 {
6b5b7cbf
CL
180 const CRPCCommand *pcmd = command.second;
181 string strMethod = pcmd->name;
69d605f4 182 // We already filter duplicates, but these deprecated screw up the sort order
47f48a65 183 if (strMethod.find("label") != string::npos)
69d605f4 184 continue;
bd9aebf1 185 if ((strCommand != "" || pcmd->category == "hidden") && strMethod != strCommand)
69d605f4
WL
186 continue;
187 try
188 {
851f58f9 189 UniValue params;
dc42bf52 190 rpcfn_type pfn = pcmd->actor;
69d605f4
WL
191 if (setDone.insert(pfn).second)
192 (*pfn)(params, true);
193 }
27df4123 194 catch (const std::exception& e)
69d605f4
WL
195 {
196 // Help text is returned in an exception
197 string strHelp = string(e.what());
198 if (strCommand == "")
6b5b7cbf 199 {
ab9dc75a 200 if (strHelp.find('\n') != string::npos)
69d605f4 201 strHelp = strHelp.substr(0, strHelp.find('\n'));
6b5b7cbf
CL
202
203 if (category != pcmd->category)
204 {
205 if (!category.empty())
206 strRet += "\n";
207 category = pcmd->category;
208 string firstLetter = category.substr(0,1);
209 boost::to_upper(firstLetter);
210 strRet += "== " + firstLetter + category.substr(1) + " ==\n";
211 }
212 }
69d605f4
WL
213 strRet += strHelp + "\n";
214 }
215 }
216 if (strRet == "")
7d9d134b 217 strRet = strprintf("help: unknown command: %s\n", strCommand);
69d605f4
WL
218 strRet = strRet.substr(0,strRet.size()-1);
219 return strRet;
220}
221
d014114d 222UniValue help(const UniValue& params, bool fHelp)
9862229d
PW
223{
224 if (fHelp || params.size() > 1)
225 throw runtime_error(
a6099ef3 226 "help ( \"command\" )\n"
227 "\nList all commands, or get help for a specified command.\n"
228 "\nArguments:\n"
229 "1. \"command\" (string, optional) The command to get help on\n"
230 "\nResult:\n"
231 "\"text\" (string) The help text\n"
232 );
9862229d
PW
233
234 string strCommand;
235 if (params.size() > 0)
236 strCommand = params[0].get_str();
237
238 return tableRPC.help(strCommand);
239}
240
9edf27ec 241extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
69d605f4 242
95c5c69b 243#ifdef ENABLE_WALLET
244void GenerateBitcoins(bool b, CWallet *pw, int t);
245#else
246void GenerateBitcoins(bool b, CWallet *pw);
247#endif
248
249
d014114d 250UniValue stop(const UniValue& params, bool fHelp)
69d605f4 251{
ebc4965c 252 char buf[64];
ce906ce7 253 // Accept the deprecated and ignored 'detach' boolean argument
3731f578 254 if (fHelp || params.size() > 1)
69d605f4 255 throw runtime_error(
92467073 256 "stop\n"
e80de3b2 257 "\nStop Komodo server.");
95c5c69b 258
259#ifdef ENABLE_WALLET
260 GenerateBitcoins(false, pwalletMain, 0);
261#else
262 GenerateBitcoins(false, 0);
263#endif
264
69d605f4 265 // Shutdown will take long enough that the response should get back
9247134e 266 StartShutdown();
b2a98c42 267 sprintf(buf,"%s server stopping",ASSETCHAINS_SYMBOL);
ebc4965c 268 return buf;
69d605f4
WL
269}
270
77920402
MF
271/**
272 * Call Table
273 */
e46704dd 274static const CRPCCommand vRPCCommands[] =
b9fb692d
JS
275{ // category name actor (function) okSafeMode
276 // --------------------- ------------------------ ----------------------- ----------
ab88ed93 277 /* Overall control/query calls */
b9fb692d
JS
278 { "control", "help", &help, true },
279 { "control", "stop", &stop, true },
ab88ed93
WL
280
281 /* P2P networking */
b9fb692d 282 { "network", "getnetworkinfo", &getnetworkinfo, true },
9d2974ed 283 { "network", "getdeprecationinfo", &getdeprecationinfo, true },
b9fb692d 284 { "network", "addnode", &addnode, true },
94ee48c4 285 { "network", "disconnectnode", &disconnectnode, true },
b9fb692d
JS
286 { "network", "getaddednodeinfo", &getaddednodeinfo, true },
287 { "network", "getconnectioncount", &getconnectioncount, true },
288 { "network", "getnettotals", &getnettotals, true },
289 { "network", "getpeerinfo", &getpeerinfo, true },
290 { "network", "ping", &ping, true },
ed3f13a0
JS
291 { "network", "setban", &setban, true },
292 { "network", "listbanned", &listbanned, true },
293 { "network", "clearbanned", &clearbanned, true },
ab88ed93
WL
294
295 /* Block chain and UTXO */
26204e59 296 { "blockchain", "coinsupply", &coinsupply, true },
b9fb692d
JS
297 { "blockchain", "getblockchaininfo", &getblockchaininfo, true },
298 { "blockchain", "getbestblockhash", &getbestblockhash, true },
299 { "blockchain", "getblockcount", &getblockcount, true },
300 { "blockchain", "getblock", &getblock, true },
8b78a819
T
301 { "blockchain", "getblockdeltas", &getblockdeltas, false },
302 { "blockchain", "getblockhashes", &getblockhashes, true },
b9fb692d 303 { "blockchain", "getblockhash", &getblockhash, true },
d3d5483e 304 { "blockchain", "getblockheader", &getblockheader, true },
b9fb692d
JS
305 { "blockchain", "getchaintips", &getchaintips, true },
306 { "blockchain", "getdifficulty", &getdifficulty, true },
307 { "blockchain", "getmempoolinfo", &getmempoolinfo, true },
308 { "blockchain", "getrawmempool", &getrawmempool, true },
309 { "blockchain", "gettxout", &gettxout, true },
59ed61b3
MC
310 { "blockchain", "gettxoutproof", &gettxoutproof, true },
311 { "blockchain", "verifytxoutproof", &verifytxoutproof, true },
b9fb692d
JS
312 { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true },
313 { "blockchain", "verifychain", &verifychain, true },
8b78a819 314 { "blockchain", "getspentinfo", &getspentinfo, false },
7f9283e5 315 //{ "blockchain", "paxprice", &paxprice, true },
316 //{ "blockchain", "paxpending", &paxpending, true },
317 //{ "blockchain", "paxprices", &paxprices, true },
336ab141 318 { "blockchain", "notaries", &notaries, true },
e73b2055 319 //{ "blockchain", "height_MoM", &height_MoM, true },
320 //{ "blockchain", "txMoMproof", &txMoMproof, true },
dbaf1154 321 { "blockchain", "minerids", &minerids, true },
d20fb2db 322 { "blockchain", "kvsearch", &kvsearch, true },
ab6e81ec 323 { "blockchain", "kvupdate", &kvupdate, true },
48ba56cd 324
e4f943d8
SS
325 /* Cross chain utilities */
326 { "crosschain", "MoMoMdata", &MoMoMdata, true },
327 { "crosschain", "calc_MoM", &calc_MoM, true },
328 { "crosschain", "height_MoM", &height_MoM, true },
329 { "crosschain", "assetchainproof", &assetchainproof, true },
330 { "crosschain", "crosschainproof", &crosschainproof, true },
292a9a71
SS
331 { "crosschain", "getNotarisationsForBlock", &getNotarisationsForBlock, true },
332 { "crosschain", "scanNotarisationsDB", &scanNotarisationsDB, true },
0b485d3c
SS
333 { "crosschain", "migrate_converttoexport", &migrate_converttoexport, true },
334 { "crosschain", "migrate_createimporttransaction", &migrate_createimporttransaction, true },
335 { "crosschain", "migrate_completeimporttransaction", &migrate_completeimporttransaction, true },
e4f943d8 336
4a85e067 337 /* Mining */
b9fb692d
JS
338 { "mining", "getblocktemplate", &getblocktemplate, true },
339 { "mining", "getmininginfo", &getmininginfo, true },
000499ae
JG
340 { "mining", "getlocalsolps", &getlocalsolps, true },
341 { "mining", "getnetworksolps", &getnetworksolps, true },
b9fb692d
JS
342 { "mining", "getnetworkhashps", &getnetworkhashps, true },
343 { "mining", "prioritisetransaction", &prioritisetransaction, true },
344 { "mining", "submitblock", &submitblock, true },
1b114e54 345 { "mining", "getblocksubsidy", &getblocksubsidy, true },
6b5b7cbf 346
8e8b6d70 347#ifdef ENABLE_MINING
6b5b7cbf 348 /* Coin generation */
b9fb692d
JS
349 { "generating", "getgenerate", &getgenerate, true },
350 { "generating", "setgenerate", &setgenerate, true },
351 { "generating", "generate", &generate, true },
6b5b7cbf 352#endif
ab88ed93
WL
353
354 /* Raw transactions */
b9fb692d
JS
355 { "rawtransactions", "createrawtransaction", &createrawtransaction, true },
356 { "rawtransactions", "decoderawtransaction", &decoderawtransaction, true },
357 { "rawtransactions", "decodescript", &decodescript, true },
358 { "rawtransactions", "getrawtransaction", &getrawtransaction, true },
359 { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false },
360 { "rawtransactions", "signrawtransaction", &signrawtransaction, false }, /* uses wallet if enabled */
3d8013a0
MC
361#ifdef ENABLE_WALLET
362 { "rawtransactions", "fundrawtransaction", &fundrawtransaction, false },
363#endif
271326fa 364/*
365 // auction
8ee5c997 366 { "auction", "auctionaddress", &auctionaddress, true },
367
271326fa 368 // lotto
8ee5c997 369 { "lotto", "lottoaddress", &lottoaddress, true },
370
271326fa 371 // fsm
7137a022 372 { "FSM", "FSMaddress", &FSMaddress, true },
3242301d 373 { "FSM", "FSMcreate", &FSMcreate, true },
374 { "FSM", "FSMlist", &FSMlist, true },
375 { "FSM", "FSMinfo", &FSMinfo, true },
8ee5c997 376
271326fa 377 // rewards
fdd22810 378 { "rewards", "rewardslist", &rewardslist, true },
379 { "rewards", "rewardsinfo", &rewardsinfo, true },
c4e7f616 380 { "rewards", "rewardscreatefunding", &rewardscreatefunding, true },
381 { "rewards", "rewardsaddfunding", &rewardsaddfunding, true },
e37d99ce 382 { "rewards", "rewardslock", &rewardslock, true },
383 { "rewards", "rewardsunlock", &rewardsunlock, true },
8a8ff823 384 { "rewards", "rewardsaddress", &rewardsaddress, true },
e37d99ce 385
271326fa 386 // faucet
096f8ed8 387 { "faucet", "faucetinfo", &faucetinfo, true },
8a8ff823 388 { "faucet", "faucetfund", &faucetfund, true },
389 { "faucet", "faucetget", &faucetget, true },
6ff08712 390 { "faucet", "faucetaddress", &faucetaddress, true },
cfea7a46 391
271326fa 392 // MofN
da629dfe 393 { "MofN", "mofnaddress", &mofnaddress, true },
287a373a 394
271326fa 395 // Channels
810f6366 396 { "channels", "channelsaddress", &channelsaddress, true },
54690bb0 397 { "channels", "channelsinfo", &channelsinfo, true },
810f6366 398 { "channels", "channelsopen", &channelsopen, true },
02da4225 399 { "channels", "channelspayment", &channelspayment, true },
400 { "channels", "channelscollect", &channelscollect, true },
401 { "channels", "channelsstop", &channelsstop, true },
402 { "channels", "channelsrefund", &channelsrefund, true },
c926780f 403
271326fa 404 // Oracles
366625ca 405 { "oracles", "oraclesaddress", &oraclesaddress, true },
406 { "oracles", "oracleslist", &oracleslist, true },
407 { "oracles", "oraclesinfo", &oraclesinfo, true },
408 { "oracles", "oraclescreate", &oraclescreate, true },
409 { "oracles", "oraclesregister", &oraclesregister, true },
410 { "oracles", "oraclessubscribe", &oraclessubscribe, true },
411 { "oracles", "oraclesdata", &oraclesdata, true },
26ca942e 412 { "oracles", "oraclessamples", &oraclessamples, true },
c926780f 413
271326fa 414 // Prices
c926780f 415 { "prices", "pricesaddress", &pricesaddress, true },
416
271326fa 417 // Pegs
c926780f 418 { "pegs", "pegsaddress", &pegsaddress, true },
419
271326fa 420 // Triggers
c926780f 421 { "triggers", "triggersaddress", &triggersaddress, true },
422
271326fa 423 // Payments
c926780f 424 { "payments", "paymentsaddress", &paymentsaddress, true },
425
271326fa 426 // Gateways
c926780f 427 { "gateways", "gatewaysaddress", &gatewaysaddress, true },
3515c101 428 { "gateways", "gatewayslist", &gatewayslist, true },
429 { "gateways", "gatewaysinfo", &gatewaysinfo, true },
430 { "gateways", "gatewaysbind", &gatewaysbind, true },
431 { "gateways", "gatewaysdeposit", &gatewaysdeposit, true },
432 { "gateways", "gatewaysclaim", &gatewaysclaim, true },
433 { "gateways", "gatewayswithdraw", &gatewayswithdraw, true },
5955955d 434 { "gateways", "gatewayspending", &gatewayspending, true },
6bde696a 435 { "gateways", "gatewaysmarkdone", &gatewaysmarkdone, true },
da629dfe 436
271326fa 437 // dice
c857567a 438 { "dice", "dicelist", &dicelist, true },
439 { "dice", "diceinfo", &diceinfo, true },
cfea7a46 440 { "dice", "dicefund", &dicefund, true },
587e715d 441 { "dice", "diceaddfunds", &diceaddfunds, true },
cfea7a46 442 { "dice", "dicebet", &dicebet, true },
cdd6d559 443 { "dice", "dicefinish", &dicefinish, true },
444 { "dice", "dicestatus", &dicestatus, true },
cfea7a46 445 { "dice", "diceaddress", &diceaddress, true },
ab88ed93 446
271326fa 447 // tokens
c66eb36d 448 { "tokens", "tokeninfo", &tokeninfo, true },
449 { "tokens", "tokenlist", &tokenlist, true },
143488c8 450 { "tokens", "tokenorders", &tokenorders, true },
451 { "tokens", "tokenaddress", &tokenaddress, true },
452 { "tokens", "tokenbalance", &tokenbalance, true },
453 { "tokens", "tokencreate", &tokencreate, true },
454 { "tokens", "tokentransfer", &tokentransfer, true },
455 { "tokens", "tokenbid", &tokenbid, true },
456 { "tokens", "tokencancelbid", &tokencancelbid, true },
b40d83c9 457 { "tokens", "tokenfillbid", &tokenfillbid, true },
143488c8 458 { "tokens", "tokenask", &tokenask, true },
ac8b2c68 459 //{ "tokens", "tokenswapask", &tokenswapask, true },
85bdc758 460 { "tokens", "tokencancelask", &tokencancelask, true },
143488c8 461 { "tokens", "tokenfillask", &tokenfillask, true },
ac8b2c68 462 //{ "tokens", "tokenfillswap", &tokenfillswap, true },
271326fa 463*/
464 /* Address index */
8b78a819
T
465 { "addressindex", "getaddressmempool", &getaddressmempool, true },
466 { "addressindex", "getaddressutxos", &getaddressutxos, false },
467 { "addressindex", "getaddressdeltas", &getaddressdeltas, false },
468 { "addressindex", "getaddresstxids", &getaddresstxids, false },
469 { "addressindex", "getaddressbalance", &getaddressbalance, false },
22007819 470 { "addressindex", "getsnapshot", &getsnapshot, false },
8b78a819 471
ab88ed93 472 /* Utility functions */
b9fb692d
JS
473 { "util", "createmultisig", &createmultisig, true },
474 { "util", "validateaddress", &validateaddress, true }, /* uses wallet if enabled */
475 { "util", "verifymessage", &verifymessage, true },
476 { "util", "estimatefee", &estimatefee, true },
477 { "util", "estimatepriority", &estimatepriority, true },
4e16a724 478 { "util", "z_validateaddress", &z_validateaddress, true }, /* uses wallet if enabled */
5539178c 479 { "util", "jumblr_deposit", &jumblr_deposit, true },
480 { "util", "jumblr_secret", &jumblr_secret, true },
eea03b7b 481 { "util", "jumblr_pause", &jumblr_pause, true },
482 { "util", "jumblr_resume", &jumblr_resume, true },
4a85e067 483
e3906925 484 { "util", "invalidateblock", &invalidateblock, true },
485 { "util", "reconsiderblock", &reconsiderblock, true },
bd9aebf1 486 /* Not shown in help */
b9fb692d 487 { "hidden", "setmocktime", &setmocktime, true },
4a85e067
WL
488#ifdef ENABLE_WALLET
489 /* Wallet */
9feb4b9e 490 { "wallet", "resendwallettransactions", &resendwallettransactions, true},
b9fb692d
JS
491 { "wallet", "addmultisigaddress", &addmultisigaddress, true },
492 { "wallet", "backupwallet", &backupwallet, true },
493 { "wallet", "dumpprivkey", &dumpprivkey, true },
494 { "wallet", "dumpwallet", &dumpwallet, true },
495 { "wallet", "encryptwallet", &encryptwallet, true },
496 { "wallet", "getaccountaddress", &getaccountaddress, true },
497 { "wallet", "getaccount", &getaccount, true },
498 { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true },
499 { "wallet", "getbalance", &getbalance, false },
4f02fc40 500 { "wallet", "getbalance64", &getbalance64, false },
b9fb692d 501 { "wallet", "getnewaddress", &getnewaddress, true },
2732d384 502// { "wallet", "getnewaddress64", &getnewaddress64, true },
b9fb692d
JS
503 { "wallet", "getrawchangeaddress", &getrawchangeaddress, true },
504 { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false },
505 { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false },
506 { "wallet", "gettransaction", &gettransaction, false },
507 { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false },
508 { "wallet", "getwalletinfo", &getwalletinfo, false },
509 { "wallet", "importprivkey", &importprivkey, true },
510 { "wallet", "importwallet", &importwallet, true },
511 { "wallet", "importaddress", &importaddress, true },
512 { "wallet", "keypoolrefill", &keypoolrefill, true },
513 { "wallet", "listaccounts", &listaccounts, false },
514 { "wallet", "listaddressgroupings", &listaddressgroupings, false },
515 { "wallet", "listlockunspent", &listlockunspent, false },
516 { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false },
517 { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false },
518 { "wallet", "listsinceblock", &listsinceblock, false },
519 { "wallet", "listtransactions", &listtransactions, false },
520 { "wallet", "listunspent", &listunspent, false },
521 { "wallet", "lockunspent", &lockunspent, true },
522 { "wallet", "move", &movecmd, false },
523 { "wallet", "sendfrom", &sendfrom, false },
524 { "wallet", "sendmany", &sendmany, false },
525 { "wallet", "sendtoaddress", &sendtoaddress, false },
526 { "wallet", "setaccount", &setaccount, true },
527 { "wallet", "settxfee", &settxfee, true },
528 { "wallet", "signmessage", &signmessage, true },
529 { "wallet", "walletlock", &walletlock, true },
530 { "wallet", "walletpassphrasechange", &walletpassphrasechange, true },
531 { "wallet", "walletpassphrase", &walletpassphrase, true },
6962bb3d 532 { "wallet", "zcbenchmark", &zc_benchmark, true },
730790f7 533 { "wallet", "zcrawkeygen", &zc_raw_keygen, true },
b7e4abd6 534 { "wallet", "zcrawjoinsplit", &zc_raw_joinsplit, true },
1737627c 535 { "wallet", "zcrawreceive", &zc_raw_receive, true },
c1c45943 536 { "wallet", "zcsamplejoinsplit", &zc_sample_joinsplit, true },
6c41028f 537 { "wallet", "z_listreceivedbyaddress",&z_listreceivedbyaddress,false },
a0a3334c
S
538 { "wallet", "z_getbalance", &z_getbalance, false },
539 { "wallet", "z_gettotalbalance", &z_gettotalbalance, false },
6e9c7629 540 { "wallet", "z_mergetoaddress", &z_mergetoaddress, false },
6d2d045c 541 { "wallet", "z_sendmany", &z_sendmany, false },
06c19063 542 { "wallet", "z_shieldcoinbase", &z_shieldcoinbase, false },
fc72c078 543 { "wallet", "z_getoperationstatus", &z_getoperationstatus, true },
c1eae280 544 { "wallet", "z_getoperationresult", &z_getoperationresult, true },
34f0001c 545 { "wallet", "z_listoperationids", &z_listoperationids, true },
c1c45943 546 { "wallet", "z_getnewaddress", &z_getnewaddress, true },
e709997f 547 { "wallet", "z_listaddresses", &z_listaddresses, true },
c1c45943 548 { "wallet", "z_exportkey", &z_exportkey, true },
92444edc 549 { "wallet", "z_importkey", &z_importkey, true },
e85b33a5
JG
550 { "wallet", "z_exportviewingkey", &z_exportviewingkey, true },
551 { "wallet", "z_importviewingkey", &z_importviewingkey, true },
92444edc 552 { "wallet", "z_exportwallet", &z_exportwallet, true },
d7d27bb3 553 { "wallet", "z_importwallet", &z_importwallet, true },
45232b19
S
554
555 // TODO: rearrange into another category
556 { "disclosure", "z_getpaymentdisclosure", &z_getpaymentdisclosure, true },
557 { "disclosure", "z_validatepaymentdisclosure", &z_validatepaymentdisclosure, true }
48ba56cd 558#endif // ENABLE_WALLET
69d605f4 559};
69d605f4 560
9862229d 561CRPCTable::CRPCTable()
dc42bf52 562{
dc42bf52
JG
563 unsigned int vcidx;
564 for (vcidx = 0; vcidx < (sizeof(vRPCCommands) / sizeof(vRPCCommands[0])); vcidx++)
565 {
e46704dd 566 const CRPCCommand *pcmd;
69d605f4 567
dc42bf52
JG
568 pcmd = &vRPCCommands[vcidx];
569 mapCommands[pcmd->name] = pcmd;
570 }
571}
69d605f4 572
afd64f76 573const CRPCCommand *CRPCTable::operator[](const std::string &name) const
9862229d
PW
574{
575 map<string, const CRPCCommand*>::const_iterator it = mapCommands.find(name);
576 if (it == mapCommands.end())
577 return NULL;
578 return (*it).second;
579}
69d605f4 580
34aca1b0
JS
581bool CRPCTable::appendCommand(const std::string& name, const CRPCCommand* pcmd)
582{
583 if (IsRPCRunning())
584 return false;
585
586 // don't allow overwriting for now
587 map<string, const CRPCCommand*>::const_iterator it = mapCommands.find(name);
588 if (it != mapCommands.end())
589 return false;
590
591 mapCommands[name] = pcmd;
592 return true;
593}
594
afd64f76 595bool StartRPC()
deb3572a 596{
afd64f76 597 LogPrint("rpc", "Starting RPC\n");
ff6a7af1 598 fRPCRunning = true;
4401b2d7 599 g_rpcSignals.Started();
fc72c078 600
008fccfa 601 // Launch one async rpc worker. The ability to launch multiple workers is not recommended at present and thus the option is disabled.
f86f625d 602 getAsyncRPCQueue()->addWorker();
06c19063 603/*
8d08172d
S
604 int n = GetArg("-rpcasyncthreads", 1);
605 if (n<1) {
606 LogPrintf("ERROR: Invalid value %d for -rpcasyncthreads. Must be at least 1.\n", n);
607 strerr = strprintf(_("An error occurred while setting up the Async RPC threads, invalid parameter value of %d (must be at least 1)."), n);
608 uiInterface.ThreadSafeMessageBox(strerr, "", CClientUIInterface::MSG_ERROR);
609 StartShutdown();
610 return;
611 }
612 for (int i = 0; i < n; i++)
f86f625d 613 getAsyncRPCQueue()->addWorker();
008fccfa 614*/
afd64f76 615 return true;
21eb5ada
GA
616}
617
afd64f76 618void InterruptRPC()
a8db31c8 619{
afd64f76
WL
620 LogPrint("rpc", "Interrupting RPC\n");
621 // Interrupt e.g. running longpolls
622 fRPCRunning = false;
a8db31c8
WL
623}
624
afd64f76 625void StopRPC()
21eb5ada 626{
afd64f76 627 LogPrint("rpc", "Stopping RPC\n");
92f2c1fe 628 deadlineTimers.clear();
4401b2d7 629 g_rpcSignals.Stopped();
fc72c078
S
630
631 // Tells async queue to cancel all operations and shutdown.
3b54bf58 632 LogPrintf("%s: waiting for async rpc workers to stop\n", __func__);
f86f625d 633 getAsyncRPCQueue()->closeAndWait();
e9205293
DJS
634}
635
ff6a7af1
LD
636bool IsRPCRunning()
637{
638 return fRPCRunning;
639}
640
af82884a
DK
641void SetRPCWarmupStatus(const std::string& newStatus)
642{
643 LOCK(cs_rpcWarmup);
644 rpcWarmupStatus = newStatus;
645}
646
647void SetRPCWarmupFinished()
648{
649 LOCK(cs_rpcWarmup);
650 assert(fRPCInWarmup);
651 fRPCInWarmup = false;
652}
653
78bdc810
JS
654bool RPCIsInWarmup(std::string *outStatus)
655{
656 LOCK(cs_rpcWarmup);
657 if (outStatus)
658 *outStatus = rpcWarmupStatus;
659 return fRPCInWarmup;
660}
661
d014114d 662void JSONRequest::parse(const UniValue& valRequest)
c6494d82
JG
663{
664 // Parse request
ed21d5bd 665 if (!valRequest.isObject())
738835d7 666 throw JSONRPCError(RPC_INVALID_REQUEST, "Invalid Request object");
d014114d 667 const UniValue& request = valRequest.get_obj();
c6494d82
JG
668
669 // Parse id now so errors from here on will have the id
670 id = find_value(request, "id");
671
672 // Parse method
851f58f9 673 UniValue valMethod = find_value(request, "method");
ed21d5bd 674 if (valMethod.isNull())
738835d7 675 throw JSONRPCError(RPC_INVALID_REQUEST, "Missing method");
ed21d5bd 676 if (!valMethod.isStr())
738835d7 677 throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string");
c6494d82 678 strMethod = valMethod.get_str();
cf0c47b2 679 if (strMethod != "getblocktemplate")
28d4cff0 680 LogPrint("rpc", "ThreadRPCServer method=%s\n", SanitizeString(strMethod));
c6494d82
JG
681
682 // Parse params
851f58f9 683 UniValue valParams = find_value(request, "params");
ed21d5bd 684 if (valParams.isArray())
c6494d82 685 params = valParams.get_array();
ed21d5bd 686 else if (valParams.isNull())
d014114d 687 params = UniValue(UniValue::VARR);
c6494d82 688 else
738835d7 689 throw JSONRPCError(RPC_INVALID_REQUEST, "Params must be an array");
c6494d82
JG
690}
691
d014114d 692static UniValue JSONRPCExecOne(const UniValue& req)
61338901 693{
38fc4b70 694 UniValue rpc_result(UniValue::VOBJ);
61338901
JG
695
696 JSONRequest jreq;
697 try {
698 jreq.parse(req);
699
851f58f9 700 UniValue result = tableRPC.execute(jreq.strMethod, jreq.params);
ed21d5bd 701 rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id);
61338901 702 }
d014114d 703 catch (const UniValue& objError)
61338901 704 {
ed21d5bd 705 rpc_result = JSONRPCReplyObj(NullUniValue, objError, jreq.id);
61338901 706 }
27df4123 707 catch (const std::exception& e)
61338901 708 {
ed21d5bd 709 rpc_result = JSONRPCReplyObj(NullUniValue,
738835d7 710 JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
61338901
JG
711 }
712
713 return rpc_result;
714}
715
afd64f76 716std::string JSONRPCExecBatch(const UniValue& vReq)
61338901 717{
bf3f5602 718 UniValue ret(UniValue::VARR);
cc71666a 719 for (size_t reqIdx = 0; reqIdx < vReq.size(); reqIdx++)
61338901
JG
720 ret.push_back(JSONRPCExecOne(vReq[reqIdx]));
721
ed21d5bd 722 return ret.write() + "\n";
61338901
JG
723}
724
851f58f9 725UniValue CRPCTable::execute(const std::string &strMethod, const UniValue &params) const
854d0130 726{
483672f7 727 // Return immediately if in warmup
854d0130 728 {
483672f7
FV
729 LOCK(cs_rpcWarmup);
730 if (fRPCInWarmup)
731 throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus);
854d0130
JG
732 }
733
4c8293dc 734 //printf("RPC call: %s\n", strMethod.c_str());
d82a969a 735
460c51fd
WL
736 // Find method
737 const CRPCCommand *pcmd = tableRPC[strMethod];
738 if (!pcmd)
f8f61a6d 739 {
740 throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method " + strMethod + " not found");
741 }
69d605f4 742
4401b2d7 743 g_rpcSignals.PreCommand(*pcmd);
460c51fd
WL
744
745 try
746 {
747 // Execute
4401b2d7 748 return pcmd->actor(params, false);
460c51fd 749 }
27df4123 750 catch (const std::exception& e)
460c51fd 751 {
738835d7 752 throw JSONRPCError(RPC_MISC_ERROR, e.what());
460c51fd 753 }
4401b2d7
EL
754
755 g_rpcSignals.PostCommand(*pcmd);
460c51fd 756}
69d605f4 757
db954a65
PK
758std::string HelpExampleCli(const std::string& methodname, const std::string& args)
759{
589c42c1 760 return "> komodo-cli " + methodname + " " + args + "\n";
bbb09365
WL
761}
762
db954a65
PK
763std::string HelpExampleRpc(const std::string& methodname, const std::string& args)
764{
bbb09365 765 return "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\":\"curltest\", "
41572034 766 "\"method\": \"" + methodname + "\", \"params\": [" + args + "] }' -H 'content-type: text/plain;' http://127.0.0.1:7771/\n";
bbb09365
WL
767}
768
66dfcc13
LR
769string experimentalDisabledHelpMsg(const string& rpc, const string& enableArg)
770{
771 return "\nWARNING: " + rpc + " is disabled.\n"
772 "To enable it, restart zcashd with the -experimentalfeatures and\n"
773 "-" + enableArg + " commandline options, or add these two lines\n"
774 "to the zcash.conf file:\n\n"
775 "experimentalfeatures=1\n"
776 + enableArg + "=1\n";
777}
778
afd64f76
WL
779void RPCRegisterTimerInterface(RPCTimerInterface *iface)
780{
781 timerInterfaces.push_back(iface);
782}
783
784void RPCUnregisterTimerInterface(RPCTimerInterface *iface)
785{
786 std::vector<RPCTimerInterface*>::iterator i = std::find(timerInterfaces.begin(), timerInterfaces.end(), iface);
787 assert(i != timerInterfaces.end());
788 timerInterfaces.erase(i);
789}
790
791void RPCRunLater(const std::string& name, boost::function<void(void)> func, int64_t nSeconds)
792{
793 if (timerInterfaces.empty())
794 throw JSONRPCError(RPC_INTERNAL_ERROR, "No timer handler registered for RPC");
795 deadlineTimers.erase(name);
796 RPCTimerInterface* timerInterface = timerInterfaces[0];
797 LogPrint("rpc", "queue run of timer %s in %i seconds (using %s)\n", name, nSeconds, timerInterface->Name());
c922edd0 798 deadlineTimers.insert(std::make_pair(name, boost::shared_ptr<RPCTimerBase>(timerInterface->NewTimer(func, nSeconds*1000))));
afd64f76
WL
799}
800
34aca1b0 801CRPCTable tableRPC;
fc72c078
S
802
803// Return async rpc queue
804std::shared_ptr<AsyncRPCQueue> getAsyncRPCQueue()
805{
f86f625d 806 return AsyncRPCQueue::sharedInstance();
fc72c078 807}
This page took 0.795084 seconds and 4 git commands to generate.