You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

server.cpp 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  1. // Copyright (c) 2010 Satoshi Nakamoto
  2. // Copyright (c) 2009-2016 The Bitcoin Core developers
  3. // Distributed under the MIT software license, see the accompanying
  4. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  5. #include "rpc/server.h"
  6. #include "base58.h"
  7. #include "fs.h"
  8. #include "init.h"
  9. #include "random.h"
  10. #include "sync.h"
  11. #include "ui_interface.h"
  12. #include "util.h"
  13. #include "utilstrencodings.h"
  14. #include <univalue.h>
  15. #include <boost/bind.hpp>
  16. #include <boost/foreach.hpp>
  17. #include <boost/shared_ptr.hpp>
  18. #include <boost/signals2/signal.hpp>
  19. #include <boost/thread.hpp>
  20. #include <boost/algorithm/string/case_conv.hpp> // for to_upper()
  21. #include <memory> // for unique_ptr
  22. #include <unordered_map>
  23. static bool fRPCRunning = false;
  24. static bool fRPCInWarmup = true;
  25. static std::string rpcWarmupStatus("RPC server started");
  26. static CCriticalSection cs_rpcWarmup;
  27. /* Timer-creating functions */
  28. static RPCTimerInterface* timerInterface = NULL;
  29. /* Map of name to timer. */
  30. static std::map<std::string, std::unique_ptr<RPCTimerBase> > deadlineTimers;
  31. static struct CRPCSignals
  32. {
  33. boost::signals2::signal<void ()> Started;
  34. boost::signals2::signal<void ()> Stopped;
  35. boost::signals2::signal<void (const CRPCCommand&)> PreCommand;
  36. } g_rpcSignals;
  37. void RPCServer::OnStarted(std::function<void ()> slot)
  38. {
  39. g_rpcSignals.Started.connect(slot);
  40. }
  41. void RPCServer::OnStopped(std::function<void ()> slot)
  42. {
  43. g_rpcSignals.Stopped.connect(slot);
  44. }
  45. void RPCServer::OnPreCommand(std::function<void (const CRPCCommand&)> slot)
  46. {
  47. g_rpcSignals.PreCommand.connect(boost::bind(slot, _1));
  48. }
  49. void RPCTypeCheck(const UniValue& params,
  50. const std::list<UniValue::VType>& typesExpected,
  51. bool fAllowNull)
  52. {
  53. unsigned int i = 0;
  54. BOOST_FOREACH(UniValue::VType t, typesExpected)
  55. {
  56. if (params.size() <= i)
  57. break;
  58. const UniValue& v = params[i];
  59. if (!(fAllowNull && v.isNull())) {
  60. RPCTypeCheckArgument(v, t);
  61. }
  62. i++;
  63. }
  64. }
  65. void RPCTypeCheckArgument(const UniValue& value, UniValue::VType typeExpected)
  66. {
  67. if (value.type() != typeExpected) {
  68. throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Expected type %s, got %s", uvTypeName(typeExpected), uvTypeName(value.type())));
  69. }
  70. }
  71. void RPCTypeCheckObj(const UniValue& o,
  72. const std::map<std::string, UniValueType>& typesExpected,
  73. bool fAllowNull,
  74. bool fStrict)
  75. {
  76. for (const auto& t : typesExpected) {
  77. const UniValue& v = find_value(o, t.first);
  78. if (!fAllowNull && v.isNull())
  79. throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing %s", t.first));
  80. if (!(t.second.typeAny || v.type() == t.second.type || (fAllowNull && v.isNull()))) {
  81. std::string err = strprintf("Expected type %s for %s, got %s",
  82. uvTypeName(t.second.type), t.first, uvTypeName(v.type()));
  83. throw JSONRPCError(RPC_TYPE_ERROR, err);
  84. }
  85. }
  86. if (fStrict)
  87. {
  88. BOOST_FOREACH(const std::string& k, o.getKeys())
  89. {
  90. if (typesExpected.count(k) == 0)
  91. {
  92. std::string err = strprintf("Unexpected key %s", k);
  93. throw JSONRPCError(RPC_TYPE_ERROR, err);
  94. }
  95. }
  96. }
  97. }
  98. CAmount AmountFromValue(const UniValue& value)
  99. {
  100. if (!value.isNum() && !value.isStr())
  101. throw JSONRPCError(RPC_TYPE_ERROR, "Amount is not a number or string");
  102. CAmount amount;
  103. if (!ParseFixedPoint(value.getValStr(), 8, &amount))
  104. throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
  105. if (!MoneyRange(amount))
  106. throw JSONRPCError(RPC_TYPE_ERROR, "Amount out of range");
  107. return amount;
  108. }
  109. UniValue ValueFromAmount(const CAmount& amount)
  110. {
  111. bool sign = amount < 0;
  112. int64_t n_abs = (sign ? -amount : amount);
  113. int64_t quotient = n_abs / COIN;
  114. int64_t remainder = n_abs % COIN;
  115. return UniValue(UniValue::VNUM,
  116. strprintf("%s%d.%08d", sign ? "-" : "", quotient, remainder));
  117. }
  118. uint256 ParseHashV(const UniValue& v, std::string strName)
  119. {
  120. std::string strHex;
  121. if (v.isStr())
  122. strHex = v.get_str();
  123. if (!IsHex(strHex)) // Note: IsHex("") is false
  124. throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
  125. if (64 != strHex.length())
  126. throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be of length %d (not %d)", strName, 64, strHex.length()));
  127. uint256 result;
  128. result.SetHex(strHex);
  129. return result;
  130. }
  131. uint256 ParseHashO(const UniValue& o, std::string strKey)
  132. {
  133. return ParseHashV(find_value(o, strKey), strKey);
  134. }
  135. std::vector<unsigned char> ParseHexV(const UniValue& v, std::string strName)
  136. {
  137. std::string strHex;
  138. if (v.isStr())
  139. strHex = v.get_str();
  140. if (!IsHex(strHex))
  141. throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
  142. return ParseHex(strHex);
  143. }
  144. std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey)
  145. {
  146. return ParseHexV(find_value(o, strKey), strKey);
  147. }
  148. /**
  149. * Note: This interface may still be subject to change.
  150. */
  151. std::string CRPCTable::help(const std::string& strCommand, const JSONRPCRequest& helpreq) const
  152. {
  153. std::string strRet;
  154. std::string category;
  155. std::set<rpcfn_type> setDone;
  156. std::vector<std::pair<std::string, const CRPCCommand*> > vCommands;
  157. for (std::map<std::string, const CRPCCommand*>::const_iterator mi = mapCommands.begin(); mi != mapCommands.end(); ++mi)
  158. vCommands.push_back(make_pair(mi->second->category + mi->first, mi->second));
  159. sort(vCommands.begin(), vCommands.end());
  160. JSONRPCRequest jreq(helpreq);
  161. jreq.fHelp = true;
  162. jreq.params = UniValue();
  163. BOOST_FOREACH(const PAIRTYPE(std::string, const CRPCCommand*)& command, vCommands)
  164. {
  165. const CRPCCommand *pcmd = command.second;
  166. std::string strMethod = pcmd->name;
  167. if ((strCommand != "" || pcmd->category == "hidden") && strMethod != strCommand)
  168. continue;
  169. jreq.strMethod = strMethod;
  170. try
  171. {
  172. rpcfn_type pfn = pcmd->actor;
  173. if (setDone.insert(pfn).second)
  174. (*pfn)(jreq);
  175. }
  176. catch (const std::exception& e)
  177. {
  178. // Help text is returned in an exception
  179. std::string strHelp = std::string(e.what());
  180. if (strCommand == "")
  181. {
  182. if (strHelp.find('\n') != std::string::npos)
  183. strHelp = strHelp.substr(0, strHelp.find('\n'));
  184. if (category != pcmd->category)
  185. {
  186. if (!category.empty())
  187. strRet += "\n";
  188. category = pcmd->category;
  189. std::string firstLetter = category.substr(0,1);
  190. boost::to_upper(firstLetter);
  191. strRet += "== " + firstLetter + category.substr(1) + " ==\n";
  192. }
  193. }
  194. strRet += strHelp + "\n";
  195. }
  196. }
  197. if (strRet == "")
  198. strRet = strprintf("help: unknown command: %s\n", strCommand);
  199. strRet = strRet.substr(0,strRet.size()-1);
  200. return strRet;
  201. }
  202. UniValue help(const JSONRPCRequest& jsonRequest)
  203. {
  204. if (jsonRequest.fHelp || jsonRequest.params.size() > 1)
  205. throw std::runtime_error(
  206. "help ( \"command\" )\n"
  207. "\nList all commands, or get help for a specified command.\n"
  208. "\nArguments:\n"
  209. "1. \"command\" (string, optional) The command to get help on\n"
  210. "\nResult:\n"
  211. "\"text\" (string) The help text\n"
  212. );
  213. std::string strCommand;
  214. if (jsonRequest.params.size() > 0)
  215. strCommand = jsonRequest.params[0].get_str();
  216. return tableRPC.help(strCommand, jsonRequest);
  217. }
  218. UniValue stop(const JSONRPCRequest& jsonRequest)
  219. {
  220. // Accept the deprecated and ignored 'detach' boolean argument
  221. if (jsonRequest.fHelp || jsonRequest.params.size() > 1)
  222. throw std::runtime_error(
  223. "stop\n"
  224. "\nStop Bitcoin server.");
  225. // Event loop will exit after current HTTP requests have been handled, so
  226. // this reply will get back to the client.
  227. StartShutdown();
  228. return "Bitcoin server stopping";
  229. }
  230. /**
  231. * Call Table
  232. */
  233. static const CRPCCommand vRPCCommands[] =
  234. { // category name actor (function) okSafe argNames
  235. // --------------------- ------------------------ ----------------------- ------ ----------
  236. /* Overall control/query calls */
  237. { "control", "help", &help, true, {"command"} },
  238. { "control", "stop", &stop, true, {} },
  239. };
  240. CRPCTable::CRPCTable()
  241. {
  242. unsigned int vcidx;
  243. for (vcidx = 0; vcidx < (sizeof(vRPCCommands) / sizeof(vRPCCommands[0])); vcidx++)
  244. {
  245. const CRPCCommand *pcmd;
  246. pcmd = &vRPCCommands[vcidx];
  247. mapCommands[pcmd->name] = pcmd;
  248. }
  249. }
  250. const CRPCCommand *CRPCTable::operator[](const std::string &name) const
  251. {
  252. std::map<std::string, const CRPCCommand*>::const_iterator it = mapCommands.find(name);
  253. if (it == mapCommands.end())
  254. return NULL;
  255. return (*it).second;
  256. }
  257. bool CRPCTable::appendCommand(const std::string& name, const CRPCCommand* pcmd)
  258. {
  259. if (IsRPCRunning())
  260. return false;
  261. // don't allow overwriting for now
  262. std::map<std::string, const CRPCCommand*>::const_iterator it = mapCommands.find(name);
  263. if (it != mapCommands.end())
  264. return false;
  265. mapCommands[name] = pcmd;
  266. return true;
  267. }
  268. bool StartRPC()
  269. {
  270. LogPrint(BCLog::RPC, "Starting RPC\n");
  271. fRPCRunning = true;
  272. g_rpcSignals.Started();
  273. return true;
  274. }
  275. void InterruptRPC()
  276. {
  277. LogPrint(BCLog::RPC, "Interrupting RPC\n");
  278. // Interrupt e.g. running longpolls
  279. fRPCRunning = false;
  280. }
  281. void StopRPC()
  282. {
  283. LogPrint(BCLog::RPC, "Stopping RPC\n");
  284. deadlineTimers.clear();
  285. DeleteAuthCookie();
  286. g_rpcSignals.Stopped();
  287. }
  288. bool IsRPCRunning()
  289. {
  290. return fRPCRunning;
  291. }
  292. void SetRPCWarmupStatus(const std::string& newStatus)
  293. {
  294. LOCK(cs_rpcWarmup);
  295. rpcWarmupStatus = newStatus;
  296. }
  297. void SetRPCWarmupFinished()
  298. {
  299. LOCK(cs_rpcWarmup);
  300. assert(fRPCInWarmup);
  301. fRPCInWarmup = false;
  302. }
  303. bool RPCIsInWarmup(std::string *outStatus)
  304. {
  305. LOCK(cs_rpcWarmup);
  306. if (outStatus)
  307. *outStatus = rpcWarmupStatus;
  308. return fRPCInWarmup;
  309. }
  310. void JSONRPCRequest::parse(const UniValue& valRequest)
  311. {
  312. // Parse request
  313. if (!valRequest.isObject())
  314. throw JSONRPCError(RPC_INVALID_REQUEST, "Invalid Request object");
  315. const UniValue& request = valRequest.get_obj();
  316. // Parse id now so errors from here on will have the id
  317. id = find_value(request, "id");
  318. // Parse method
  319. UniValue valMethod = find_value(request, "method");
  320. if (valMethod.isNull())
  321. throw JSONRPCError(RPC_INVALID_REQUEST, "Missing method");
  322. if (!valMethod.isStr())
  323. throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string");
  324. strMethod = valMethod.get_str();
  325. LogPrint(BCLog::RPC, "ThreadRPCServer method=%s\n", SanitizeString(strMethod));
  326. // Parse params
  327. UniValue valParams = find_value(request, "params");
  328. if (valParams.isArray() || valParams.isObject())
  329. params = valParams;
  330. else if (valParams.isNull())
  331. params = UniValue(UniValue::VARR);
  332. else
  333. throw JSONRPCError(RPC_INVALID_REQUEST, "Params must be an array or object");
  334. }
  335. static UniValue JSONRPCExecOne(const UniValue& req)
  336. {
  337. UniValue rpc_result(UniValue::VOBJ);
  338. JSONRPCRequest jreq;
  339. try {
  340. jreq.parse(req);
  341. UniValue result = tableRPC.execute(jreq);
  342. rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id);
  343. }
  344. catch (const UniValue& objError)
  345. {
  346. rpc_result = JSONRPCReplyObj(NullUniValue, objError, jreq.id);
  347. }
  348. catch (const std::exception& e)
  349. {
  350. rpc_result = JSONRPCReplyObj(NullUniValue,
  351. JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
  352. }
  353. return rpc_result;
  354. }
  355. std::string JSONRPCExecBatch(const UniValue& vReq)
  356. {
  357. UniValue ret(UniValue::VARR);
  358. for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++)
  359. ret.push_back(JSONRPCExecOne(vReq[reqIdx]));
  360. return ret.write() + "\n";
  361. }
  362. /**
  363. * Process named arguments into a vector of positional arguments, based on the
  364. * passed-in specification for the RPC call's arguments.
  365. */
  366. static inline JSONRPCRequest transformNamedArguments(const JSONRPCRequest& in, const std::vector<std::string>& argNames)
  367. {
  368. JSONRPCRequest out = in;
  369. out.params = UniValue(UniValue::VARR);
  370. // Build a map of parameters, and remove ones that have been processed, so that we can throw a focused error if
  371. // there is an unknown one.
  372. const std::vector<std::string>& keys = in.params.getKeys();
  373. const std::vector<UniValue>& values = in.params.getValues();
  374. std::unordered_map<std::string, const UniValue*> argsIn;
  375. for (size_t i=0; i<keys.size(); ++i) {
  376. argsIn[keys[i]] = &values[i];
  377. }
  378. // Process expected parameters.
  379. int hole = 0;
  380. for (const std::string &argName: argNames) {
  381. auto fr = argsIn.find(argName);
  382. if (fr != argsIn.end()) {
  383. for (int i = 0; i < hole; ++i) {
  384. // Fill hole between specified parameters with JSON nulls,
  385. // but not at the end (for backwards compatibility with calls
  386. // that act based on number of specified parameters).
  387. out.params.push_back(UniValue());
  388. }
  389. hole = 0;
  390. out.params.push_back(*fr->second);
  391. argsIn.erase(fr);
  392. } else {
  393. hole += 1;
  394. }
  395. }
  396. // If there are still arguments in the argsIn map, this is an error.
  397. if (!argsIn.empty()) {
  398. throw JSONRPCError(RPC_INVALID_PARAMETER, "Unknown named parameter " + argsIn.begin()->first);
  399. }
  400. // Return request with named arguments transformed to positional arguments
  401. return out;
  402. }
  403. UniValue CRPCTable::execute(const JSONRPCRequest &request) const
  404. {
  405. // Return immediately if in warmup
  406. {
  407. LOCK(cs_rpcWarmup);
  408. if (fRPCInWarmup)
  409. throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus);
  410. }
  411. // Find method
  412. const CRPCCommand *pcmd = tableRPC[request.strMethod];
  413. if (!pcmd)
  414. throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
  415. g_rpcSignals.PreCommand(*pcmd);
  416. try
  417. {
  418. // Execute, convert arguments to array if necessary
  419. if (request.params.isObject()) {
  420. return pcmd->actor(transformNamedArguments(request, pcmd->argNames));
  421. } else {
  422. return pcmd->actor(request);
  423. }
  424. }
  425. catch (const std::exception& e)
  426. {
  427. throw JSONRPCError(RPC_MISC_ERROR, e.what());
  428. }
  429. }
  430. std::vector<std::string> CRPCTable::listCommands() const
  431. {
  432. std::vector<std::string> commandList;
  433. typedef std::map<std::string, const CRPCCommand*> commandMap;
  434. std::transform( mapCommands.begin(), mapCommands.end(),
  435. std::back_inserter(commandList),
  436. boost::bind(&commandMap::value_type::first,_1) );
  437. return commandList;
  438. }
  439. std::string HelpExampleCli(const std::string& methodname, const std::string& args)
  440. {
  441. return "> bitcoin-cli " + methodname + " " + args + "\n";
  442. }
  443. std::string HelpExampleRpc(const std::string& methodname, const std::string& args)
  444. {
  445. return "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\":\"curltest\", "
  446. "\"method\": \"" + methodname + "\", \"params\": [" + args + "] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n";
  447. }
  448. void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface)
  449. {
  450. if (!timerInterface)
  451. timerInterface = iface;
  452. }
  453. void RPCSetTimerInterface(RPCTimerInterface *iface)
  454. {
  455. timerInterface = iface;
  456. }
  457. void RPCUnsetTimerInterface(RPCTimerInterface *iface)
  458. {
  459. if (timerInterface == iface)
  460. timerInterface = NULL;
  461. }
  462. void RPCRunLater(const std::string& name, std::function<void(void)> func, int64_t nSeconds)
  463. {
  464. if (!timerInterface)
  465. throw JSONRPCError(RPC_INTERNAL_ERROR, "No timer handler registered for RPC");
  466. deadlineTimers.erase(name);
  467. LogPrint(BCLog::RPC, "queue run of timer %s in %i seconds (using %s)\n", name, nSeconds, timerInterface->Name());
  468. deadlineTimers.emplace(name, std::unique_ptr<RPCTimerBase>(timerInterface->NewTimer(func, nSeconds*1000)));
  469. }
  470. int RPCSerializationFlags()
  471. {
  472. int flag = 0;
  473. if (GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) == 0)
  474. flag |= SERIALIZE_TRANSACTION_NO_WITNESS;
  475. return flag;
  476. }
  477. CRPCTable tableRPC;