Master Core  v0.0.9 - 49a5c0d97abf09ef2911ddfe8d9551df59f9efd3-dirty
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
rpcserver.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include "rpcserver.h"
7 
8 #include "base58.h"
9 #include "init.h"
10 #include "main.h"
11 #include "ui_interface.h"
12 #include "util.h"
13 #ifdef ENABLE_WALLET
14 #include "wallet.h"
15 #endif
16 
17 #include <boost/algorithm/string.hpp>
18 #include <boost/asio.hpp>
19 #include <boost/asio/ssl.hpp>
20 #include <boost/bind.hpp>
21 #include <boost/filesystem.hpp>
22 #include <boost/foreach.hpp>
23 #include <boost/iostreams/concepts.hpp>
24 #include <boost/iostreams/stream.hpp>
25 #include <boost/shared_ptr.hpp>
26 #include "json/json_spirit_writer_template.h"
27 
28 using namespace std;
29 using namespace boost;
30 using namespace boost::asio;
31 using namespace json_spirit;
32 
33 static std::string strRPCUserColonPass;
34 
35 // These are created by StartRPCThreads, destroyed in StopRPCThreads
36 static asio::io_service* rpc_io_service = NULL;
37 static map<string, boost::shared_ptr<deadline_timer> > deadlineTimers;
38 static ssl::context* rpc_ssl_context = NULL;
39 static boost::thread_group* rpc_worker_group = NULL;
40 static boost::asio::io_service::work *rpc_dummy_work = NULL;
41 static std::vector< boost::shared_ptr<ip::tcp::acceptor> > rpc_acceptors;
42 
43 void RPCTypeCheck(const Array& params,
44  const list<Value_type>& typesExpected,
45  bool fAllowNull)
46 {
47  unsigned int i = 0;
48  BOOST_FOREACH(Value_type t, typesExpected)
49  {
50  if (params.size() <= i)
51  break;
52 
53  const Value& v = params[i];
54  if (!((v.type() == t) || (fAllowNull && (v.type() == null_type))))
55  {
56  string err = strprintf("Expected type %s, got %s",
57  Value_type_name[t], Value_type_name[v.type()]);
58  throw JSONRPCError(RPC_TYPE_ERROR, err);
59  }
60  i++;
61  }
62 }
63 
64 void RPCTypeCheck(const Object& o,
65  const map<string, Value_type>& typesExpected,
66  bool fAllowNull)
67 {
68  BOOST_FOREACH(const PAIRTYPE(string, Value_type)& t, typesExpected)
69  {
70  const Value& v = find_value(o, t.first);
71  if (!fAllowNull && v.type() == null_type)
72  throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing %s", t.first));
73 
74  if (!((v.type() == t.second) || (fAllowNull && (v.type() == null_type))))
75  {
76  string err = strprintf("Expected type %s for %s, got %s",
77  Value_type_name[t.second], t.first, Value_type_name[v.type()]);
78  throw JSONRPCError(RPC_TYPE_ERROR, err);
79  }
80  }
81 }
82 
83 int64_t AmountFromValue(const Value& value)
84 {
85  double dAmount = value.get_real();
86  if (dAmount <= 0.0 || dAmount > 21000000.0)
87  throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
88  int64_t nAmount = roundint64(dAmount * COIN);
89  if (!MoneyRange(nAmount))
90  throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
91  return nAmount;
92 }
93 
94 Value ValueFromAmount(int64_t amount)
95 {
96  return (double)amount / (double)COIN;
97 }
98 
99 std::string HexBits(unsigned int nBits)
100 {
101  union {
102  int32_t nBits;
103  char cBits[4];
104  } uBits;
105  uBits.nBits = htonl((int32_t)nBits);
106  return HexStr(BEGIN(uBits.cBits), END(uBits.cBits));
107 }
108 
109 uint256 ParseHashV(const Value& v, string strName)
110 {
111  string strHex;
112  if (v.type() == str_type)
113  strHex = v.get_str();
114  if (!IsHex(strHex)) // Note: IsHex("") is false
115  throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
116  uint256 result;
117  result.SetHex(strHex);
118  return result;
119 }
120 uint256 ParseHashO(const Object& o, string strKey)
121 {
122  return ParseHashV(find_value(o, strKey), strKey);
123 }
124 vector<unsigned char> ParseHexV(const Value& v, string strName)
125 {
126  string strHex;
127  if (v.type() == str_type)
128  strHex = v.get_str();
129  if (!IsHex(strHex))
130  throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
131  return ParseHex(strHex);
132 }
133 vector<unsigned char> ParseHexO(const Object& o, string strKey)
134 {
135  return ParseHexV(find_value(o, strKey), strKey);
136 }
137 
138 
142 
143 string CRPCTable::help(string strCommand) const
144 {
145  string strRet;
146  set<rpcfn_type> setDone;
147  for (map<string, const CRPCCommand*>::const_iterator mi = mapCommands.begin(); mi != mapCommands.end(); ++mi)
148  {
149  const CRPCCommand *pcmd = mi->second;
150  string strMethod = mi->first;
151  // We already filter duplicates, but these deprecated screw up the sort order
152  if (strMethod.find("label") != string::npos)
153  continue;
154  if (strCommand != "" && strMethod != strCommand)
155  continue;
156 #ifdef ENABLE_WALLET
157  if (pcmd->reqWallet && !pwalletMain)
158  continue;
159 #endif
160 
161  try
162  {
163  Array params;
164  rpcfn_type pfn = pcmd->actor;
165  if (setDone.insert(pfn).second)
166  (*pfn)(params, true);
167  }
168  catch (std::exception& e)
169  {
170  // Help text is returned in an exception
171  string strHelp = string(e.what());
172  if (strCommand == "")
173  if (strHelp.find('\n') != string::npos)
174  strHelp = strHelp.substr(0, strHelp.find('\n'));
175  strRet += strHelp + "\n";
176  }
177  }
178  if (strRet == "")
179  strRet = strprintf("help: unknown command: %s\n", strCommand);
180  strRet = strRet.substr(0,strRet.size()-1);
181  return strRet;
182 }
183 
184 Value help(const Array& params, bool fHelp)
185 {
186  if (fHelp || params.size() > 1)
187  throw runtime_error(
188  "help ( \"command\" )\n"
189  "\nList all commands, or get help for a specified command.\n"
190  "\nArguments:\n"
191  "1. \"command\" (string, optional) The command to get help on\n"
192  "\nResult:\n"
193  "\"text\" (string) The help text\n"
194  );
195 
196  string strCommand;
197  if (params.size() > 0)
198  strCommand = params[0].get_str();
199 
200  return tableRPC.help(strCommand);
201 }
202 
203 
204 Value stop(const Array& params, bool fHelp)
205 {
206  // Accept the deprecated and ignored 'detach' boolean argument
207  if (fHelp || params.size() > 1)
208  throw runtime_error(
209  "stop\n"
210  "\nStop MasterCore server.");
211  // Shutdown will take long enough that the response should get back
212  StartShutdown();
213  return "MasterCore server stopping";
214 }
215 
216 
217 
218 //
219 // Call Table
220 //
221 
222 
223 static const CRPCCommand vRPCCommands[] =
224 { // name actor (function) okSafeMode threadSafe reqWallet
225  // ------------------------ ----------------------- ---------- ---------- ---------
226  /* Overall control/query calls */
227  { "getinfo", &getinfo, true, false, false }, /* uses wallet if enabled */
228  { "help", &help, true, true, false },
229  { "stop", &stop, true, true, false },
230 
231  /* P2P networking */
232  { "getnetworkinfo", &getnetworkinfo, true, false, false },
233  { "addnode", &addnode, true, true, false },
234  { "getaddednodeinfo", &getaddednodeinfo, true, true, false },
235  { "getconnectioncount", &getconnectioncount, true, false, false },
236  { "getnettotals", &getnettotals, true, true, false },
237  { "getpeerinfo", &getpeerinfo, true, false, false },
238  { "ping", &ping, true, false, false },
239 
240  /* Block chain and UTXO */
241  { "getblockchaininfo", &getblockchaininfo, true, false, false },
242  { "getbestblockhash", &getbestblockhash, true, false, false },
243  { "getblockcount", &getblockcount, true, false, false },
244  { "getblock", &getblock, false, false, false },
245  { "getblockhash", &getblockhash, false, false, false },
246  { "getdifficulty", &getdifficulty, true, false, false },
247  { "getrawmempool", &getrawmempool, true, false, false },
248  { "gettxout", &gettxout, true, false, false },
249  { "gettxoutsetinfo", &gettxoutsetinfo, true, false, false },
250  { "verifychain", &verifychain, true, false, false },
251 
252  /* Mining */
253  { "getblocktemplate", &getblocktemplate, true, false, false },
254  { "getmininginfo", &getmininginfo, true, false, false },
255  { "getnetworkhashps", &getnetworkhashps, true, false, false },
256  { "submitblock", &submitblock, false, false, false },
257 
258  /* Raw transactions */
259  { "createrawtransaction", &createrawtransaction, false, false, false },
260  { "decoderawtransaction", &decoderawtransaction, false, false, false },
261  { "decodescript", &decodescript, false, false, false },
262  { "getrawtransaction", &getrawtransaction, false, false, false },
263  { "sendrawtransaction", &sendrawtransaction, false, false, false },
264  { "signrawtransaction", &signrawtransaction, false, false, false }, /* uses wallet if enabled */
265 
266  /* Utility functions */
267  { "createmultisig", &createmultisig, true, true , false },
268  { "validateaddress", &validateaddress, true, false, false }, /* uses wallet if enabled */
269  { "verifymessage", &verifymessage, false, false, false },
270 
271 #ifdef ENABLE_WALLET
272  /* Wallet */
273  { "addmultisigaddress", &addmultisigaddress, false, false, true },
274  { "backupwallet", &backupwallet, true, false, true },
275  { "dumpprivkey", &dumpprivkey, true, false, true },
276  { "dumpwallet", &dumpwallet, true, false, true },
277  { "encryptwallet", &encryptwallet, false, false, true },
278  { "getaccountaddress", &getaccountaddress, true, false, true },
279  { "getaccount", &getaccount, false, false, true },
280  { "getaddressesbyaccount", &getaddressesbyaccount, true, false, true },
281  { "getbalance", &getbalance, false, false, true },
282  { "getnewaddress", &getnewaddress, true, false, true },
283  { "getrawchangeaddress", &getrawchangeaddress, true, false, true },
284  { "getreceivedbyaccount", &getreceivedbyaccount, false, false, true },
285  { "getreceivedbyaddress", &getreceivedbyaddress, false, false, true },
286  { "gettransaction", &gettransaction, false, false, true },
287  { "getunconfirmedbalance", &getunconfirmedbalance, false, false, true },
288  { "getwalletinfo", &getwalletinfo, true, false, true },
289  { "importprivkey", &importprivkey, false, false, true },
290  { "importwallet", &importwallet, false, false, true },
291  { "keypoolrefill", &keypoolrefill, true, false, true },
292  { "listaccounts", &listaccounts, false, false, true },
293  { "listaddressgroupings", &listaddressgroupings, false, false, true },
294  { "listlockunspent", &listlockunspent, false, false, true },
295  { "listreceivedbyaccount", &listreceivedbyaccount, false, false, true },
296  { "listreceivedbyaddress", &listreceivedbyaddress, false, false, true },
297  { "listsinceblock", &listsinceblock, false, false, true },
298  { "listtransactions", &listtransactions, false, false, true },
299  { "listunspent", &listunspent, false, false, true },
300  { "lockunspent", &lockunspent, false, false, true },
301  { "move", &movecmd, false, false, true },
302  { "sendfrom", &sendfrom, false, false, true },
303  { "sendmany", &sendmany, false, false, true },
304  { "sendtoaddress", &sendtoaddress, false, false, true },
305  { "setaccount", &setaccount, true, false, true },
306  { "settxfee", &settxfee, false, false, true },
307  { "signmessage", &signmessage, false, false, true },
308  { "walletlock", &walletlock, true, false, true },
309  { "walletpassphrasechange", &walletpassphrasechange, false, false, true },
310  { "walletpassphrase", &walletpassphrase, true, false, true },
311 
312  /* Wallet-enabled mining */
313  { "getgenerate", &getgenerate, true, false, false },
314  { "gethashespersec", &gethashespersec, true, false, false },
315  { "getwork", &getwork, true, false, true },
316  { "setgenerate", &setgenerate, true, true, false },
317 
318  /* Master Protocol specific calls */
319  { "mscrpc", &mscrpc, true, false, false },
320  { "getallbalancesforid_MP", &getallbalancesforid_MP, false, false, true },
321  { "getbalance_MP", &getbalance_MP, false, false, true },
322  { "send_MP", &send_MP, false, false, true },
323  { "gettransaction_MP", &gettransaction_MP, false, false, true },
324  { "listtransactions_MP", &listtransactions_MP, false, false, true },
325  { "getproperty_MP", &getproperty_MP, false, false, true },
326  { "listproperties_MP", &listproperties_MP, false, false, true },
327  { "getcrowdsale_MP", &getcrowdsale_MP, false, false, true },
328  { "getgrants_MP", &getgrants_MP, false, false, true },
329  { "getactivedexsells_MP", &getactivedexsells_MP, false, false, true },
330  { "getactivecrowdsales_MP", &getactivecrowdsales_MP, false, false, true },
331 #if 0
332  { "trade_MP", &trade_MP, false, false, true },
333  { "getorderbook_MP", &getorderbook_MP, false, false, true },
334  { "gettradessince_MP", &gettradessince_MP, false, false, true },
335  { "getopenorders_MP", &getopenorders_MP, false, false, true },
336  { "gettradehistory_MP", &gettradehistory_MP, false, false, true },
337  { "gettrade_MP", &gettrade_MP, false, false, true },
338 #endif
339  { "sendtoowners_MP", &sendtoowners_MP, false, false, true },
340  { "sendrawtx_MP", &sendrawtx_MP, false, false, true },
341  { "getsto_MP", &getsto_MP, false, false, true },
342  { "getinfo_MP", &getinfo_MP, false, false, true },
343  { "listblocktransactions_MP", &listblocktransactions_MP, false, false, true },
344  { "getallbalancesforaddress_MP", &getallbalancesforaddress_MP, false, false, true },
345 
346 #endif // ENABLE_WALLET
347 };
348 
350 {
351  unsigned int vcidx;
352  for (vcidx = 0; vcidx < (sizeof(vRPCCommands) / sizeof(vRPCCommands[0])); vcidx++)
353  {
354  const CRPCCommand *pcmd;
355 
356  pcmd = &vRPCCommands[vcidx];
357  mapCommands[pcmd->name] = pcmd;
358  }
359 }
360 
361 const CRPCCommand *CRPCTable::operator[](string name) const
362 {
363  map<string, const CRPCCommand*>::const_iterator it = mapCommands.find(name);
364  if (it == mapCommands.end())
365  return NULL;
366  return (*it).second;
367 }
368 
369 
370 bool HTTPAuthorized(map<string, string>& mapHeaders)
371 {
372  string strAuth = mapHeaders["authorization"];
373  if (strAuth.substr(0,6) != "Basic ")
374  return false;
375  string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64);
376  string strUserPass = DecodeBase64(strUserPass64);
377  return TimingResistantEqual(strUserPass, strRPCUserColonPass);
378 }
379 
380 void ErrorReply(std::ostream& stream, const Object& objError, const Value& id)
381 {
382  // Send error reply from json-rpc error object
383  int nStatus = HTTP_INTERNAL_SERVER_ERROR;
384  int code = find_value(objError, "code").get_int();
385  if (code == RPC_INVALID_REQUEST) nStatus = HTTP_BAD_REQUEST;
386  else if (code == RPC_METHOD_NOT_FOUND) nStatus = HTTP_NOT_FOUND;
387  string strReply = JSONRPCReply(Value::null, objError, id);
388  stream << HTTPReply(nStatus, strReply, false) << std::flush;
389 }
390 
391 bool ClientAllowed(const boost::asio::ip::address& address)
392 {
393  // Make sure that IPv4-compatible and IPv4-mapped IPv6 addresses are treated as IPv4 addresses
394  if (address.is_v6()
395  && (address.to_v6().is_v4_compatible()
396  || address.to_v6().is_v4_mapped()))
397  return ClientAllowed(address.to_v6().to_v4());
398 
399  if (address == asio::ip::address_v4::loopback()
400  || address == asio::ip::address_v6::loopback()
401  || (address.is_v4()
402  // Check whether IPv4 addresses match 127.0.0.0/8 (loopback subnet)
403  && (address.to_v4().to_ulong() & 0xff000000) == 0x7f000000))
404  return true;
405 
406  const string strAddress = address.to_string();
407  const vector<string>& vAllow = mapMultiArgs["-rpcallowip"];
408  BOOST_FOREACH(string strAllow, vAllow)
409  if (WildcardMatch(strAddress, strAllow))
410  return true;
411  return false;
412 }
413 
415 {
416 public:
417  virtual ~AcceptedConnection() {}
418 
419  virtual std::iostream& stream() = 0;
420  virtual std::string peer_address_to_string() const = 0;
421  virtual void close() = 0;
422 };
423 
424 template <typename Protocol>
426 {
427 public:
429  asio::io_service& io_service,
430  ssl::context &context,
431  bool fUseSSL) :
432  sslStream(io_service, context),
433  _d(sslStream, fUseSSL),
434  _stream(_d)
435  {
436  }
437 
438  virtual std::iostream& stream()
439  {
440  return _stream;
441  }
442 
443  virtual std::string peer_address_to_string() const
444  {
445  return peer.address().to_string();
446  }
447 
448  virtual void close()
449  {
450  _stream.close();
451  }
452 
453  typename Protocol::endpoint peer;
454  asio::ssl::stream<typename Protocol::socket> sslStream;
455 
456 private:
458  iostreams::stream< SSLIOStreamDevice<Protocol> > _stream;
459 };
460 
462 
463 // Forward declaration required for RPCListen
464 template <typename Protocol, typename SocketAcceptorService>
465 static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor,
466  ssl::context& context,
467  bool fUseSSL,
468  boost::shared_ptr< AcceptedConnection > conn,
469  const boost::system::error_code& error);
470 
474 template <typename Protocol, typename SocketAcceptorService>
475 static void RPCListen(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor,
476  ssl::context& context,
477  const bool fUseSSL)
478 {
479  // Accept connection
480  boost::shared_ptr< AcceptedConnectionImpl<Protocol> > conn(new AcceptedConnectionImpl<Protocol>(acceptor->get_io_service(), context, fUseSSL));
481 
482  acceptor->async_accept(
483  conn->sslStream.lowest_layer(),
484  conn->peer,
485  boost::bind(&RPCAcceptHandler<Protocol, SocketAcceptorService>,
486  acceptor,
487  boost::ref(context),
488  fUseSSL,
489  conn,
490  _1));
491 }
492 
493 
497 template <typename Protocol, typename SocketAcceptorService>
498 static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor,
499  ssl::context& context,
500  const bool fUseSSL,
501  boost::shared_ptr< AcceptedConnection > conn,
502  const boost::system::error_code& error)
503 {
504  // Immediately start accepting new connections, except when we're cancelled or our socket is closed.
505  if (error != asio::error::operation_aborted && acceptor->is_open())
506  RPCListen(acceptor, context, fUseSSL);
507 
508  AcceptedConnectionImpl<ip::tcp>* tcp_conn = dynamic_cast< AcceptedConnectionImpl<ip::tcp>* >(conn.get());
509 
510  if (error)
511  {
512  // TODO: Actually handle errors
513  LogPrintf("%s: Error: %s\n", __func__, error.message());
514  }
515  // Restrict callers by IP. It is important to
516  // do this before starting client thread, to filter out
517  // certain DoS and misbehaving clients.
518  else if (tcp_conn && !ClientAllowed(tcp_conn->peer.address()))
519  {
520  // Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake.
521  if (!fUseSSL)
522  conn->stream() << HTTPReply(HTTP_FORBIDDEN, "", false) << std::flush;
523  conn->close();
524  }
525  else {
526  ServiceConnection(conn.get());
527  conn->close();
528  }
529 }
530 
532 {
533  strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"];
534  if (((mapArgs["-rpcpassword"] == "") ||
535  (mapArgs["-rpcuser"] == mapArgs["-rpcpassword"])) && Params().RequireRPCPassword())
536  {
537  unsigned char rand_pwd[32];
538  RAND_bytes(rand_pwd, 32);
539  string strWhatAmI = "To use mastercored";
540  if (mapArgs.count("-server"))
541  strWhatAmI = strprintf(_("To use the %s option"), "\"-server\"");
542  else if (mapArgs.count("-daemon"))
543  strWhatAmI = strprintf(_("To use the %s option"), "\"-daemon\"");
545  _("%s, you must set a rpcpassword in the configuration file:\n"
546  "%s\n"
547  "It is recommended you use the following random password:\n"
548  "rpcuser=bitcoinrpc\n"
549  "rpcpassword=%s\n"
550  "(you do not need to remember this password)\n"
551  "The username and password MUST NOT be the same.\n"
552  "If the file does not exist, create it with owner-readable-only file permissions.\n"
553  "It is also recommended to set alertnotify so you are notified of problems;\n"
554  "for example: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com\n"),
555  strWhatAmI,
556  GetConfigFile().string(),
557  EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32)),
559  StartShutdown();
560  return;
561  }
562 
563  assert(rpc_io_service == NULL);
564  rpc_io_service = new asio::io_service();
565  rpc_ssl_context = new ssl::context(*rpc_io_service, ssl::context::sslv23);
566 
567  const bool fUseSSL = GetBoolArg("-rpcssl", false);
568 
569  if (fUseSSL)
570  {
571  rpc_ssl_context->set_options(ssl::context::no_sslv2);
572 
573  filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert"));
574  if (!pathCertFile.is_complete()) pathCertFile = filesystem::path(GetDataDir()) / pathCertFile;
575  if (filesystem::exists(pathCertFile)) rpc_ssl_context->use_certificate_chain_file(pathCertFile.string());
576  else LogPrintf("ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string());
577 
578  filesystem::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem"));
579  if (!pathPKFile.is_complete()) pathPKFile = filesystem::path(GetDataDir()) / pathPKFile;
580  if (filesystem::exists(pathPKFile)) rpc_ssl_context->use_private_key_file(pathPKFile.string(), ssl::context::pem);
581  else LogPrintf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string());
582 
583  string strCiphers = GetArg("-rpcsslciphers", "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH");
584  SSL_CTX_set_cipher_list(rpc_ssl_context->impl(), strCiphers.c_str());
585  }
586 
587  // Try a dual IPv6/IPv4 socket, falling back to separate IPv4 and IPv6 sockets
588  const bool loopback = !mapArgs.count("-rpcallowip");
589  asio::ip::address bindAddress = loopback ? asio::ip::address_v6::loopback() : asio::ip::address_v6::any();
590  ip::tcp::endpoint endpoint(bindAddress, GetArg("-rpcport", Params().RPCPort()));
591  boost::system::error_code v6_only_error;
592 
593  bool fListening = false;
594  std::string strerr;
595  try
596  {
597  boost::shared_ptr<ip::tcp::acceptor> acceptor(new ip::tcp::acceptor(*rpc_io_service));
598  acceptor->open(endpoint.protocol());
599  acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
600 
601  // Try making the socket dual IPv6/IPv4 (if listening on the "any" address)
602  acceptor->set_option(boost::asio::ip::v6_only(loopback), v6_only_error);
603 
604  acceptor->bind(endpoint);
605  acceptor->listen(socket_base::max_connections);
606 
607  RPCListen(acceptor, *rpc_ssl_context, fUseSSL);
608 
609  rpc_acceptors.push_back(acceptor);
610  fListening = true;
611  }
612  catch(boost::system::system_error &e)
613  {
614  strerr = strprintf(_("An error occurred while setting up the RPC port %u for listening on IPv6, falling back to IPv4: %s"), endpoint.port(), e.what());
615  }
616  try {
617  // If dual IPv6/IPv4 failed (or we're opening loopback interfaces only), open IPv4 separately
618  if (!fListening || loopback || v6_only_error)
619  {
620  bindAddress = loopback ? asio::ip::address_v4::loopback() : asio::ip::address_v4::any();
621  endpoint.address(bindAddress);
622 
623  boost::shared_ptr<ip::tcp::acceptor> acceptor(new ip::tcp::acceptor(*rpc_io_service));
624  acceptor->open(endpoint.protocol());
625  acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
626  acceptor->bind(endpoint);
627  acceptor->listen(socket_base::max_connections);
628 
629  RPCListen(acceptor, *rpc_ssl_context, fUseSSL);
630 
631  rpc_acceptors.push_back(acceptor);
632  fListening = true;
633  }
634  }
635  catch(boost::system::system_error &e)
636  {
637  strerr = strprintf(_("An error occurred while setting up the RPC port %u for listening on IPv4: %s"), endpoint.port(), e.what());
638  }
639 
640  if (!fListening) {
642  StartShutdown();
643  return;
644  }
645 
646  rpc_worker_group = new boost::thread_group();
647  for (int i = 0; i < GetArg("-rpcthreads", 4); i++)
648  rpc_worker_group->create_thread(boost::bind(&asio::io_service::run, rpc_io_service));
649 }
650 
652 {
653  if(rpc_io_service == NULL)
654  {
655  rpc_io_service = new asio::io_service();
656  /* Create dummy "work" to keep the thread from exiting when no timeouts active,
657  * see http://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio/reference/io_service.html#boost_asio.reference.io_service.stopping_the_io_service_from_running_out_of_work */
658  rpc_dummy_work = new asio::io_service::work(*rpc_io_service);
659  rpc_worker_group = new boost::thread_group();
660  rpc_worker_group->create_thread(boost::bind(&asio::io_service::run, rpc_io_service));
661  }
662 }
663 
665 {
666  if (rpc_io_service == NULL) return;
667 
668  // First, cancel all timers and acceptors
669  // This is not done automatically by ->stop(), and in some cases the destructor of
670  // asio::io_service can hang if this is skipped.
671  boost::system::error_code ec;
672  BOOST_FOREACH(const boost::shared_ptr<ip::tcp::acceptor> &acceptor, rpc_acceptors)
673  {
674  acceptor->cancel(ec);
675  if (ec)
676  LogPrintf("%s: Warning: %s when cancelling acceptor", __func__, ec.message());
677  }
678  rpc_acceptors.clear();
679  BOOST_FOREACH(const PAIRTYPE(std::string, boost::shared_ptr<deadline_timer>) &timer, deadlineTimers)
680  {
681  timer.second->cancel(ec);
682  if (ec)
683  LogPrintf("%s: Warning: %s when cancelling timer", __func__, ec.message());
684  }
685  deadlineTimers.clear();
686 
687  rpc_io_service->stop();
688  if (rpc_worker_group != NULL)
689  rpc_worker_group->join_all();
690  delete rpc_dummy_work; rpc_dummy_work = NULL;
691  delete rpc_worker_group; rpc_worker_group = NULL;
692  delete rpc_ssl_context; rpc_ssl_context = NULL;
693  delete rpc_io_service; rpc_io_service = NULL;
694 }
695 
696 void RPCRunHandler(const boost::system::error_code& err, boost::function<void(void)> func)
697 {
698  if (!err)
699  func();
700 }
701 
702 void RPCRunLater(const std::string& name, boost::function<void(void)> func, int64_t nSeconds)
703 {
704  assert(rpc_io_service != NULL);
705 
706  if (deadlineTimers.count(name) == 0)
707  {
708  deadlineTimers.insert(make_pair(name,
709  boost::shared_ptr<deadline_timer>(new deadline_timer(*rpc_io_service))));
710  }
711  deadlineTimers[name]->expires_from_now(posix_time::seconds(nSeconds));
712  deadlineTimers[name]->async_wait(boost::bind(RPCRunHandler, _1, func));
713 }
714 
716 {
717 public:
718  Value id;
719  string strMethod;
720  Array params;
721 
722  JSONRequest() { id = Value::null; }
723  void parse(const Value& valRequest);
724 };
725 
726 void JSONRequest::parse(const Value& valRequest)
727 {
728  // Parse request
729  if (valRequest.type() != obj_type)
730  throw JSONRPCError(RPC_INVALID_REQUEST, "Invalid Request object");
731  const Object& request = valRequest.get_obj();
732 
733  // Parse id now so errors from here on will have the id
734  id = find_value(request, "id");
735 
736  // Parse method
737  Value valMethod = find_value(request, "method");
738  if (valMethod.type() == null_type)
739  throw JSONRPCError(RPC_INVALID_REQUEST, "Missing method");
740  if (valMethod.type() != str_type)
741  throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string");
742  strMethod = valMethod.get_str();
743  if (strMethod != "getwork" && strMethod != "getblocktemplate")
744  LogPrint("rpc", "ThreadRPCServer method=%s\n", strMethod);
745 
746  // Parse params
747  Value valParams = find_value(request, "params");
748  if (valParams.type() == array_type)
749  params = valParams.get_array();
750  else if (valParams.type() == null_type)
751  params = Array();
752  else
753  throw JSONRPCError(RPC_INVALID_REQUEST, "Params must be an array");
754 }
755 
756 
757 static Object JSONRPCExecOne(const Value& req)
758 {
759  Object rpc_result;
760 
761  JSONRequest jreq;
762  try {
763  jreq.parse(req);
764 
765  Value result = tableRPC.execute(jreq.strMethod, jreq.params);
766  rpc_result = JSONRPCReplyObj(result, Value::null, jreq.id);
767  }
768  catch (Object& objError)
769  {
770  rpc_result = JSONRPCReplyObj(Value::null, objError, jreq.id);
771  }
772  catch (std::exception& e)
773  {
774  rpc_result = JSONRPCReplyObj(Value::null,
775  JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
776  }
777 
778  return rpc_result;
779 }
780 
781 static string JSONRPCExecBatch(const Array& vReq)
782 {
783  Array ret;
784  for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++)
785  ret.push_back(JSONRPCExecOne(vReq[reqIdx]));
786 
787  return write_string(Value(ret), false) + "\n";
788 }
789 
791 {
792  bool fRun = true;
793  while (fRun && !ShutdownRequested())
794  {
795  int nProto = 0;
796  map<string, string> mapHeaders;
797  string strRequest, strMethod, strURI;
798 
799  // Read HTTP request line
800  if (!ReadHTTPRequestLine(conn->stream(), nProto, strMethod, strURI))
801  break;
802 
803  // Read HTTP message headers and body
804  ReadHTTPMessage(conn->stream(), mapHeaders, strRequest, nProto);
805 
806  if (strURI != "/") {
807  conn->stream() << HTTPReply(HTTP_NOT_FOUND, "", false) << std::flush;
808  break;
809  }
810 
811  // Check authorization
812  if (mapHeaders.count("authorization") == 0)
813  {
814  conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush;
815  break;
816  }
817  if (!HTTPAuthorized(mapHeaders))
818  {
819  LogPrintf("ThreadRPCServer incorrect password attempt from %s\n", conn->peer_address_to_string());
820  /* Deter brute-forcing short passwords.
821  If this results in a DoS the user really
822  shouldn't have their RPC port exposed. */
823  if (mapArgs["-rpcpassword"].size() < 20)
824  MilliSleep(250);
825 
826  conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush;
827  break;
828  }
829  if (mapHeaders["connection"] == "close")
830  fRun = false;
831 
832  JSONRequest jreq;
833  try
834  {
835  // Parse request
836  Value valRequest;
837  if (!read_string(strRequest, valRequest))
838  throw JSONRPCError(RPC_PARSE_ERROR, "Parse error");
839 
840  string strReply;
841 
842  // singleton request
843  if (valRequest.type() == obj_type) {
844  jreq.parse(valRequest);
845 
846  Value result = tableRPC.execute(jreq.strMethod, jreq.params);
847 
848  // Send reply
849  strReply = JSONRPCReply(result, Value::null, jreq.id);
850 
851  // array of requests
852  } else if (valRequest.type() == array_type)
853  strReply = JSONRPCExecBatch(valRequest.get_array());
854  else
855  throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error");
856 
857  conn->stream() << HTTPReply(HTTP_OK, strReply, fRun) << std::flush;
858  }
859  catch (Object& objError)
860  {
861  ErrorReply(conn->stream(), objError, jreq.id);
862  break;
863  }
864  catch (std::exception& e)
865  {
866  ErrorReply(conn->stream(), JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
867  break;
868  }
869  }
870 }
871 
872 json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_spirit::Array &params) const
873 {
874  // Find method
875  const CRPCCommand *pcmd = tableRPC[strMethod];
876  if (!pcmd)
877  throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
878 #ifdef ENABLE_WALLET
879  if (pcmd->reqWallet && !pwalletMain)
880  throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
881 #endif
882 
883  // Observe safe mode
884  string strWarning = GetWarnings("rpc");
885  if (strWarning != "" && !GetBoolArg("-disablesafemode", false) &&
886  !pcmd->okSafeMode)
887  throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning);
888 
889  try
890  {
891  // Execute
892  Value result;
893  {
894  if (pcmd->threadSafe)
895  result = pcmd->actor(params, false);
896 #ifdef ENABLE_WALLET
897  else if (!pwalletMain) {
898  LOCK(cs_main);
899  result = pcmd->actor(params, false);
900  } else {
902  result = pcmd->actor(params, false);
903  }
904 #else // ENABLE_WALLET
905  else {
906  LOCK(cs_main);
907  result = pcmd->actor(params, false);
908  }
909 #endif // !ENABLE_WALLET
910  }
911  return result;
912  }
913  catch (std::exception& e)
914  {
915  throw JSONRPCError(RPC_MISC_ERROR, e.what());
916  }
917 }
918 
919 std::string HelpExampleCli(string methodname, string args){
920  return "> bitcoin-cli " + methodname + " " + args + "\n";
921 }
922 
923 std::string HelpExampleRpc(string methodname, string args){
924  return "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\":\"curltest\", "
925  "\"method\": \"" + methodname + "\", \"params\": [" + args + "] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n";
926 }
927 
const boost::filesystem::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:973
uint256 send_MP(const string &FromAddress, const string &ToAddress, const string &RedeemAddress, unsigned int PropertyID, uint64_t Amount)
CClientUIInterface uiInterface
Definition: util.cpp:100
void SetHex(const char *psz)
Definition: uint256.h:305
static std::vector< boost::shared_ptr< ip::tcp::acceptor > > rpc_acceptors
Definition: rpcserver.cpp:41
json_spirit::Value setgenerate(const json_spirit::Array &params, bool fHelp)
bool HTTPAuthorized(map< string, string > &mapHeaders)
Definition: rpcserver.cpp:370
json_spirit::Value signmessage(const json_spirit::Array &params, bool fHelp)
Array params
Definition: rpcserver.cpp:720
Value createrawtransaction(const Array &params, bool fHelp)
void RPCRunLater(const std::string &name, boost::function< void(void)> func, int64_t nSeconds)
Definition: rpcserver.cpp:702
static string JSONRPCExecBatch(const Array &vReq)
Definition: rpcserver.cpp:781
json_spirit::Value movecmd(const json_spirit::Array &params, bool fHelp)
static Object JSONRPCExecOne(const Value &req)
Definition: rpcserver.cpp:757
Value stop(const Array &params, bool fHelp)
Definition: rpcserver.cpp:204
json_spirit::Value walletpassphrasechange(const json_spirit::Array &params, bool fHelp)
bool okSafeMode
Definition: rpcserver.h:60
SSLIOStreamDevice< Protocol > _d
Definition: rpcserver.cpp:457
virtual void close()
Definition: rpcserver.cpp:448
string JSONRPCReply(const Value &result, const Value &error, const Value &id)
Value help(const Array &params, bool fHelp)
Definition: rpcserver.cpp:184
Bitcoin RPC command dispatcher.
Definition: rpcserver.h:68
rpcfn_type actor
Definition: rpcserver.h:59
Value getallbalancesforid_MP(const Array &params, bool fHelp)
iostreams::stream< SSLIOStreamDevice< Protocol > > _stream
Definition: rpcserver.cpp:458
Value addnode(const Array &params, bool fHelp)
Definition: rpcnet.cpp:145
Definition: init.h:13
vector< unsigned char > ParseHexO(const Object &o, string strKey)
Definition: rpcserver.cpp:133
uint256 ParseHashO(const Object &o, string strKey)
Definition: rpcserver.cpp:120
Value sendtoowners_MP(const Array &params, bool fHelp)
bool threadSafe
Definition: rpcserver.h:61
asio::ssl::stream< typename Protocol::socket > sslStream
Definition: rpcserver.cpp:454
#define PAIRTYPE(t1, t2)
Definition: util.h:48
static boost::asio::io_service::work * rpc_dummy_work
Definition: rpcserver.cpp:40
Value getblockcount(const Array &params, bool fHelp)
CCriticalSection cs_wallet
Main wallet lock.
Definition: wallet.h:132
void MilliSleep(int64_t n)
Definition: util.h:79
bool ShutdownRequested()
Definition: init.cpp:103
#define END(a)
Definition: util.h:42
bool ReadHTTPRequestLine(std::basic_istream< char > &stream, int &proto, string &http_method, string &http_uri)
Value getinfo(const Array &params, bool fHelp)
Definition: rpcmisc.cpp:29
json_spirit::Value gettradehistory_MP(const json_spirit::Array &params, bool fHelp)
std::string HelpExampleRpc(string methodname, string args)
Definition: rpcserver.cpp:923
Value sendrawtransaction(const Array &params, bool fHelp)
const CRPCCommand * operator[](std::string name) const
Definition: rpcserver.cpp:361
void StartShutdown()
Definition: init.cpp:99
Value importwallet(const Array &params, bool fHelp)
Definition: rpcdump.cpp:136
CCriticalSection cs_main
Definition: main.cpp:43
std::string EncodeBase58(const unsigned char *pbegin, const unsigned char *pend)
Encode a byte sequence as a base58-encoded string.
Definition: base58.cpp:66
string GetWarnings(string strFor)
Format a string that describes several potential problems detected by the core.
Definition: main.cpp:3204
json_spirit::Value execute(const std::string &method, const json_spirit::Array &params) const
Execute a method.
Definition: rpcserver.cpp:872
#define strprintf
Definition: util.h:116
Value gettxoutsetinfo(const Array &params, bool fHelp)
Value getactivedexsells_MP(const Array &params, bool fHelp)
STL namespace.
bool MoneyRange(int64_t nValue)
Definition: core.h:19
bool IsHex(const string &str)
Definition: util.cpp:409
void RPCRunHandler(const boost::system::error_code &err, boost::function< void(void)> func)
Definition: rpcserver.cpp:696
Value dumpwallet(const Array &params, bool fHelp)
Definition: rpcdump.cpp:267
json_spirit::Value gettradessince_MP(const json_spirit::Array &params, bool fHelp)
virtual ~AcceptedConnection()
Definition: rpcserver.cpp:417
Object JSONRPCError(int code, const string &message)
Value getblockchaininfo(const Array &params, bool fHelp)
Value getblock(const Array &params, bool fHelp)
Value getnetworkinfo(const Array &params, bool fHelp)
Definition: rpcnet.cpp:337
Value sendrawtx_MP(const Array &params, bool fHelp)
json_spirit::Value getorderbook_MP(const json_spirit::Array &params, bool fHelp)
void RPCTypeCheck(const Array &params, const list< Value_type > &typesExpected, bool fAllowNull)
Definition: rpcserver.cpp:43
virtual std::iostream & stream()
Definition: rpcserver.cpp:438
static ssl::context * rpc_ssl_context
Definition: rpcserver.cpp:38
Value getdifficulty(const Array &params, bool fHelp)
void ErrorReply(std::ostream &stream, const Object &objError, const Value &id)
Definition: rpcserver.cpp:380
Value decodescript(const Array &params, bool fHelp)
Value importprivkey(const Array &params, bool fHelp)
Definition: rpcdump.cpp:67
Value gettransaction_MP(const Array &params, bool fHelp)
AcceptedConnectionImpl(asio::io_service &io_service, ssl::context &context, bool fUseSSL)
Definition: rpcserver.cpp:428
json_spirit::Value getopenorders_MP(const json_spirit::Array &params, bool fHelp)
void ServiceConnection(AcceptedConnection *conn)
Definition: rpcserver.cpp:790
bool reqWallet
Definition: rpcserver.h:62
virtual std::string peer_address_to_string() const
Definition: rpcserver.cpp:443
Value getsto_MP(const Array &params, bool fHelp)
virtual std::string peer_address_to_string() const =0
static void RPCListen(boost::shared_ptr< basic_socket_acceptor< Protocol, SocketAcceptorService > > acceptor, ssl::context &context, const bool fUseSSL)
Sets up I/O resources to accept and handle a new connection.
Definition: rpcserver.cpp:475
json_spirit::Value listunspent(const json_spirit::Array &params, bool fHelp)
#define LOCK2(cs1, cs2)
Definition: sync.h:157
std::string name
Definition: rpcserver.h:58
Value decoderawtransaction(const Array &params, bool fHelp)
json_spirit::Value getunconfirmedbalance(const json_spirit::Array &params, bool fHelp)
std::string HexBits(unsigned int nBits)
Definition: rpcserver.cpp:99
static asio::io_service * rpc_io_service
Definition: rpcserver.cpp:36
bool GetBoolArg(const std::string &strArg, bool fDefault)
Return boolean argument or default value.
Definition: util.cpp:519
#define LogPrintf(...)
Definition: util.h:117
int ReadHTTPMessage(std::basic_istream< char > &stream, map< string, string > &mapHeadersRet, string &strMessageRet, int nProto)
Value ValueFromAmount(int64_t amount)
Definition: rpcserver.cpp:94
Value listblocktransactions_MP(const Array &params, bool fHelp)
json_spirit::Value gethashespersec(const json_spirit::Array &params, bool fHelp)
json_spirit::Value listreceivedbyaddress(const json_spirit::Array &params, bool fHelp)
static int LogPrint(const char *category, const char *format)
Definition: util.h:143
#define LOCK(cs)
Definition: sync.h:156
json_spirit::Value getnewaddress(const json_spirit::Array &params, bool fHelp)
json_spirit::Value walletlock(const json_spirit::Array &params, bool fHelp)
Value mscrpc(const Array &params, bool fHelp)
json_spirit::Value settxfee(const json_spirit::Array &params, bool fHelp)
Value getconnectioncount(const Array &params, bool fHelp)
Definition: rpcnet.cpp:20
static bool error(const char *format)
Definition: util.h:148
Value getmininginfo(const Array &params, bool fHelp)
Definition: rpcmining.cpp:235
json_spirit::Value listaddressgroupings(const json_spirit::Array &params, bool fHelp)
Protocol::endpoint peer
Definition: rpcserver.cpp:453
static map< string, boost::shared_ptr< deadline_timer > > deadlineTimers
Definition: rpcserver.cpp:37
static boost::thread_group * rpc_worker_group
Definition: rpcserver.cpp:39
json_spirit::Value sendmany(const json_spirit::Array &params, bool fHelp)
json_spirit::Value keypoolrefill(const json_spirit::Array &params, bool fHelp)
Value getrawmempool(const Array &params, bool fHelp)
Value listtransactions_MP(const Array &params, bool fHelp)
std::string help(std::string name) const
Note: This interface may still be subject to change.
Definition: rpcserver.cpp:143
string HTTPReply(int nStatus, const string &strMsg, bool keepalive)
Definition: rpcprotocol.cpp:57
const CRPCTable tableRPC
Definition: rpcserver.cpp:928
Value submitblock(const Array &params, bool fHelp)
Definition: rpcmining.cpp:591
static std::string strRPCUserColonPass
Definition: rpcserver.cpp:33
Value getnettotals(const Array &params, bool fHelp)
Definition: rpcnet.cpp:312
Value getallbalancesforaddress_MP(const Array &params, bool fHelp)
json_spirit::Value getgenerate(const json_spirit::Array &params, bool fHelp)
void StopRPCThreads()
Definition: rpcserver.cpp:664
Value getpeerinfo(const Array &params, bool fHelp)
Definition: rpcnet.cpp:72
Value createmultisig(const Array &params, bool fHelp)
Definition: rpcmisc.cpp:239
#define BEGIN(a)
Definition: util.h:41
json_spirit::Value trade_MP(const json_spirit::Array &params, bool fHelp)
256-bit unsigned integer
Definition: uint256.h:531
Object JSONRPCReplyObj(const Value &result, const Value &error, const Value &id)
static const int64_t COIN
Definition: util.h:38
json_spirit::Value listaccounts(const json_spirit::Array &params, bool fHelp)
json_spirit::Value getwalletinfo(const json_spirit::Array &params, bool fHelp)
json_spirit::Value listsinceblock(const json_spirit::Array &params, bool fHelp)
json_spirit::Value encryptwallet(const json_spirit::Array &params, bool fHelp)
const CChainParams & Params()
Return the currently selected parameters.
bool ClientAllowed(const boost::asio::ip::address &address)
Definition: rpcserver.cpp:391
static const CRPCCommand vRPCCommands[]
Definition: rpcserver.cpp:223
string strMethod
Definition: rpcserver.cpp:719
vector< unsigned char > ParseHexV(const Value &v, string strName)
Definition: rpcserver.cpp:124
bool WildcardMatch(const char *psz, const char *mask)
Definition: util.cpp:875
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a boost::optional result...
Definition: ui_interface.h:105
Value signrawtransaction(const Array &params, bool fHelp)
virtual std::iostream & stream()=0
void parse(const Value &valRequest)
Definition: rpcserver.cpp:726
Value getbalance_MP(const Array &params, bool fHelp)
Value getgrants_MP(const Array &params, bool fHelp)
json_spirit::Value sendfrom(const json_spirit::Array &params, bool fHelp)
int64_t AmountFromValue(const Value &value)
Definition: rpcserver.cpp:83
bool TimingResistantEqual(const T &a, const T &b)
Timing-attack-resistant comparison.
Definition: util.h:414
Value getaddednodeinfo(const Array &params, bool fHelp)
Definition: rpcnet.cpp:195
json_spirit::Value gettransaction(const json_spirit::Array &params, bool fHelp)
Value getrawtransaction(const Array &params, bool fHelp)
boost::signals2::signal< bool(const std::string &message, const std::string &caption, unsigned int style), boost::signals2::last_value< bool > > ThreadSafeMessageBox
Show message box.
Definition: ui_interface.h:75
Value verifymessage(const Array &params, bool fHelp)
Definition: rpcmisc.cpp:282
Value getbestblockhash(const Array &params, bool fHelp)
Value getcrowdsale_MP(const Array &params, bool fHelp)
json_spirit::Value getreceivedbyaccount(const json_spirit::Array &params, bool fHelp)
json_spirit::Value listtransactions(const json_spirit::Array &params, bool fHelp)
uint256 ParseHashV(const Value &v, string strName)
Definition: rpcserver.cpp:109
std::string HelpExampleCli(string methodname, string args)
Definition: rpcserver.cpp:919
Value getnetworkhashps(const Array &params, bool fHelp)
Definition: rpcmining.cpp:94
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Return string argument or default value.
Definition: util.cpp:505
Value getblockhash(const Array &params, bool fHelp)
json_spirit::Value walletpassphrase(const json_spirit::Array &params, bool fHelp)
int64_t roundint64(double d)
Definition: util.h:252
json_spirit::Value lockunspent(const json_spirit::Array &params, bool fHelp)
Value getblocktemplate(const Array &params, bool fHelp)
Definition: rpcmining.cpp:403
json_spirit::Value sendtoaddress(const json_spirit::Array &params, bool fHelp)
Value gettxout(const Array &params, bool fHelp)
static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor< Protocol, SocketAcceptorService > > acceptor, ssl::context &context, bool fUseSSL, boost::shared_ptr< AcceptedConnection > conn, const boost::system::error_code &error)
Accept and handle incoming connection.
Definition: rpcserver.cpp:498
vector< unsigned char > DecodeBase64(const char *p, bool *pfInvalid)
Definition: util.cpp:598
json_spirit::Value listreceivedbyaccount(const json_spirit::Array &params, bool fHelp)
Value ping(const Array &params, bool fHelp)
Definition: rpcnet.cpp:37
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
Definition: util.h:263
json_spirit::Value getreceivedbyaddress(const json_spirit::Array &params, bool fHelp)
json_spirit::Value backupwallet(const json_spirit::Array &params, bool fHelp)
map< string, vector< string > > mapMultiArgs
Definition: util.cpp:90
json_spirit::Value getwork(const json_spirit::Array &params, bool fHelp)
Value gettrade_MP(const Array &params, bool fHelp)
json_spirit::Value addmultisigaddress(const json_spirit::Array &params, bool fHelp)
Value verifychain(const Array &params, bool fHelp)
json_spirit::Value getrawchangeaddress(const json_spirit::Array &params, bool fHelp)
vector< unsigned char > ParseHex(const char *psz)
Definition: util.cpp:419
Value validateaddress(const Array &params, bool fHelp)
Definition: rpcmisc.cpp:129
Value getactivecrowdsales_MP(const Array &params, bool fHelp)
json_spirit::Value listlockunspent(const json_spirit::Array &params, bool fHelp)
json_spirit::Value getaccount(const json_spirit::Array &params, bool fHelp)
json_spirit::Value(* rpcfn_type)(const json_spirit::Array &params, bool fHelp)
Definition: rpcserver.h:53
json_spirit::Value getbalance(const json_spirit::Array &params, bool fHelp)
Value getinfo_MP(const Array &params, bool fHelp)
Value listproperties_MP(const Array &params, bool fHelp)
Value getproperty_MP(const Array &params, bool fHelp)
json_spirit::Value setaccount(const json_spirit::Array &params, bool fHelp)
CWallet * pwalletMain
map< string, string > mapArgs
Definition: util.cpp:89
void StartRPCThreads()
Definition: rpcserver.cpp:531
boost::filesystem::path GetConfigFile()
Definition: util.cpp:1012
Value dumpprivkey(const Array &params, bool fHelp)
Definition: rpcdump.cpp:234
json_spirit::Value getaddressesbyaccount(const json_spirit::Array &params, bool fHelp)
void StartDummyRPCThread()
Definition: rpcserver.cpp:651
json_spirit::Value getaccountaddress(const json_spirit::Array &params, bool fHelp)