2011-05-14 20:10:21 +02:00
|
|
|
// Copyright (c) 2010 Satoshi Nakamoto
|
2015-12-13 17:58:29 +01:00
|
|
|
// Copyright (c) 2009-2015 The Bitcoin Core developers
|
2014-10-30 03:14:08 +01:00
|
|
|
// Distributed under the MIT software license, see the accompanying
|
2012-05-18 16:02:28 +02:00
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
2011-05-14 20:10:21 +02:00
|
|
|
|
2016-01-15 01:55:17 +01:00
|
|
|
#include "rpc/server.h"
|
2013-04-13 07:13:08 +02:00
|
|
|
|
|
|
|
#include "base58.h"
|
2011-06-18 18:46:01 +02:00
|
|
|
#include "init.h"
|
2014-10-19 10:46:17 +02:00
|
|
|
#include "random.h"
|
|
|
|
#include "sync.h"
|
2013-11-29 16:04:29 +01:00
|
|
|
#include "ui_interface.h"
|
2014-01-11 18:14:29 +01:00
|
|
|
#include "util.h"
|
2014-10-19 10:46:17 +02:00
|
|
|
#include "utilstrencodings.h"
|
2013-04-13 07:13:08 +02:00
|
|
|
|
2015-09-04 16:11:34 +02:00
|
|
|
#include <univalue.h>
|
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-23 07:53:17 +01:00
|
|
|
|
2011-08-10 13:53:13 +02:00
|
|
|
#include <boost/bind.hpp>
|
2011-07-13 11:56:38 +02:00
|
|
|
#include <boost/filesystem.hpp>
|
2011-08-10 15:07:46 +02:00
|
|
|
#include <boost/foreach.hpp>
|
2011-05-14 20:10:21 +02:00
|
|
|
#include <boost/iostreams/concepts.hpp>
|
|
|
|
#include <boost/iostreams/stream.hpp>
|
2011-08-10 13:53:13 +02:00
|
|
|
#include <boost/shared_ptr.hpp>
|
2014-10-19 10:46:17 +02:00
|
|
|
#include <boost/signals2/signal.hpp>
|
Split up util.cpp/h
Split up util.cpp/h into:
- string utilities (hex, base32, base64): no internal dependencies, no dependency on boost (apart from foreach)
- money utilities (parsesmoney, formatmoney)
- time utilities (gettime*, sleep, format date):
- and the rest (logging, argument parsing, config file parsing)
The latter is basically the environment and OS handling,
and is stripped of all utility functions, so we may want to
rename it to something else than util.cpp/h for clarity (Matt suggested
osinterface).
Breaks dependency of sha256.cpp on all the things pulled in by util.
2014-08-21 16:11:09 +02:00
|
|
|
#include <boost/thread.hpp>
|
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-23 07:53:17 +01:00
|
|
|
#include <boost/algorithm/string/case_conv.hpp> // for to_upper()
|
2014-08-20 21:15:16 +02:00
|
|
|
|
2014-10-19 10:46:17 +02:00
|
|
|
using namespace RPCServer;
|
2014-06-27 11:13:25 +02:00
|
|
|
using namespace std;
|
2011-05-14 20:10:21 +02:00
|
|
|
|
2012-05-13 06:43:24 +02:00
|
|
|
static bool fRPCRunning = false;
|
2014-10-29 18:08:31 +01:00
|
|
|
static bool fRPCInWarmup = true;
|
|
|
|
static std::string rpcWarmupStatus("RPC server started");
|
|
|
|
static CCriticalSection cs_rpcWarmup;
|
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-23 07:53:17 +01:00
|
|
|
/* Timer-creating functions */
|
2016-01-08 11:03:52 +01:00
|
|
|
static RPCTimerInterface* timerInterface = NULL;
|
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-23 07:53:17 +01:00
|
|
|
/* Map of name to timer.
|
|
|
|
* @note Can be changed to std::unique_ptr when C++11 */
|
|
|
|
static std::map<std::string, boost::shared_ptr<RPCTimerBase> > deadlineTimers;
|
2012-04-15 02:35:58 +02:00
|
|
|
|
2014-10-19 10:46:17 +02:00
|
|
|
static struct CRPCSignals
|
|
|
|
{
|
|
|
|
boost::signals2::signal<void ()> Started;
|
|
|
|
boost::signals2::signal<void ()> Stopped;
|
|
|
|
boost::signals2::signal<void (const CRPCCommand&)> PreCommand;
|
|
|
|
boost::signals2::signal<void (const CRPCCommand&)> PostCommand;
|
|
|
|
} g_rpcSignals;
|
|
|
|
|
|
|
|
void RPCServer::OnStarted(boost::function<void ()> slot)
|
|
|
|
{
|
|
|
|
g_rpcSignals.Started.connect(slot);
|
|
|
|
}
|
|
|
|
|
|
|
|
void RPCServer::OnStopped(boost::function<void ()> slot)
|
|
|
|
{
|
|
|
|
g_rpcSignals.Stopped.connect(slot);
|
|
|
|
}
|
|
|
|
|
|
|
|
void RPCServer::OnPreCommand(boost::function<void (const CRPCCommand&)> slot)
|
|
|
|
{
|
|
|
|
g_rpcSignals.PreCommand.connect(boost::bind(slot, _1));
|
|
|
|
}
|
|
|
|
|
|
|
|
void RPCServer::OnPostCommand(boost::function<void (const CRPCCommand&)> slot)
|
|
|
|
{
|
|
|
|
g_rpcSignals.PostCommand.connect(boost::bind(slot, _1));
|
|
|
|
}
|
|
|
|
|
2015-05-18 14:02:18 +02:00
|
|
|
void RPCTypeCheck(const UniValue& params,
|
|
|
|
const list<UniValue::VType>& typesExpected,
|
2012-08-20 22:18:17 +02:00
|
|
|
bool fAllowNull)
|
2012-06-23 00:36:42 +02:00
|
|
|
{
|
2012-07-05 19:25:52 +02:00
|
|
|
unsigned int i = 0;
|
2015-05-18 14:02:18 +02:00
|
|
|
BOOST_FOREACH(UniValue::VType t, typesExpected)
|
2012-06-23 00:36:42 +02:00
|
|
|
{
|
|
|
|
if (params.size() <= i)
|
|
|
|
break;
|
|
|
|
|
2015-05-18 14:02:18 +02:00
|
|
|
const UniValue& v = params[i];
|
2014-08-20 21:15:16 +02:00
|
|
|
if (!((v.type() == t) || (fAllowNull && (v.isNull()))))
|
2012-06-23 00:36:42 +02:00
|
|
|
{
|
|
|
|
string err = strprintf("Expected type %s, got %s",
|
2014-08-20 21:15:16 +02:00
|
|
|
uvTypeName(t), uvTypeName(v.type()));
|
2012-10-04 09:34:44 +02:00
|
|
|
throw JSONRPCError(RPC_TYPE_ERROR, err);
|
2012-06-23 00:36:42 +02:00
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-20 21:15:16 +02:00
|
|
|
void RPCTypeCheckObj(const UniValue& o,
|
|
|
|
const map<string, UniValue::VType>& typesExpected,
|
2012-08-20 22:18:17 +02:00
|
|
|
bool fAllowNull)
|
2012-06-23 00:36:42 +02:00
|
|
|
{
|
2015-05-18 14:02:18 +02:00
|
|
|
BOOST_FOREACH(const PAIRTYPE(string, UniValue::VType)& t, typesExpected)
|
2012-06-23 00:36:42 +02:00
|
|
|
{
|
2015-05-18 14:02:18 +02:00
|
|
|
const UniValue& v = find_value(o, t.first);
|
2014-08-20 21:15:16 +02:00
|
|
|
if (!fAllowNull && v.isNull())
|
2014-01-16 16:15:27 +01:00
|
|
|
throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing %s", t.first));
|
2012-08-20 22:18:17 +02:00
|
|
|
|
2014-08-20 21:15:16 +02:00
|
|
|
if (!((v.type() == t.second) || (fAllowNull && (v.isNull()))))
|
2012-06-23 00:36:42 +02:00
|
|
|
{
|
|
|
|
string err = strprintf("Expected type %s for %s, got %s",
|
2014-08-20 21:15:16 +02:00
|
|
|
uvTypeName(t.second), t.first, uvTypeName(v.type()));
|
2012-10-04 09:34:44 +02:00
|
|
|
throw JSONRPCError(RPC_TYPE_ERROR, err);
|
2012-06-23 00:36:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-18 14:02:18 +02:00
|
|
|
CAmount AmountFromValue(const UniValue& value)
|
2011-05-14 20:10:21 +02:00
|
|
|
{
|
2015-07-06 11:43:56 +02:00
|
|
|
if (!value.isNum() && !value.isStr())
|
|
|
|
throw JSONRPCError(RPC_TYPE_ERROR, "Amount is not a number or string");
|
2015-06-04 14:22:26 +02:00
|
|
|
CAmount amount;
|
2015-07-06 10:49:24 +02:00
|
|
|
if (!ParseFixedPoint(value.getValStr(), 8, &amount))
|
2012-10-04 09:34:44 +02:00
|
|
|
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
|
2015-06-04 14:22:26 +02:00
|
|
|
if (!MoneyRange(amount))
|
|
|
|
throw JSONRPCError(RPC_TYPE_ERROR, "Amount out of range");
|
|
|
|
return amount;
|
2011-05-14 20:10:21 +02:00
|
|
|
}
|
|
|
|
|
2015-05-13 21:29:19 +02:00
|
|
|
UniValue ValueFromAmount(const CAmount& amount)
|
2011-05-14 20:10:21 +02:00
|
|
|
{
|
2015-07-18 07:42:23 +02:00
|
|
|
bool sign = amount < 0;
|
|
|
|
int64_t n_abs = (sign ? -amount : amount);
|
|
|
|
int64_t quotient = n_abs / COIN;
|
|
|
|
int64_t remainder = n_abs % COIN;
|
|
|
|
return UniValue(UniValue::VNUM,
|
|
|
|
strprintf("%s%d.%08d", sign ? "-" : "", quotient, remainder));
|
2011-05-14 20:10:21 +02:00
|
|
|
}
|
|
|
|
|
2015-05-18 14:02:18 +02:00
|
|
|
uint256 ParseHashV(const UniValue& v, string strName)
|
2013-07-15 08:24:33 +02:00
|
|
|
{
|
|
|
|
string strHex;
|
2014-08-20 21:15:16 +02:00
|
|
|
if (v.isStr())
|
2013-07-15 08:24:33 +02:00
|
|
|
strHex = v.get_str();
|
|
|
|
if (!IsHex(strHex)) // Note: IsHex("") is false
|
|
|
|
throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
|
|
|
|
uint256 result;
|
|
|
|
result.SetHex(strHex);
|
|
|
|
return result;
|
|
|
|
}
|
2015-05-18 14:02:18 +02:00
|
|
|
uint256 ParseHashO(const UniValue& o, string strKey)
|
2013-07-15 08:24:33 +02:00
|
|
|
{
|
|
|
|
return ParseHashV(find_value(o, strKey), strKey);
|
|
|
|
}
|
2015-05-18 14:02:18 +02:00
|
|
|
vector<unsigned char> ParseHexV(const UniValue& v, string strName)
|
2013-07-15 08:24:33 +02:00
|
|
|
{
|
|
|
|
string strHex;
|
2014-08-20 21:15:16 +02:00
|
|
|
if (v.isStr())
|
2013-07-15 08:24:33 +02:00
|
|
|
strHex = v.get_str();
|
|
|
|
if (!IsHex(strHex))
|
|
|
|
throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
|
|
|
|
return ParseHex(strHex);
|
|
|
|
}
|
2015-05-18 14:02:18 +02:00
|
|
|
vector<unsigned char> ParseHexO(const UniValue& o, string strKey)
|
2013-07-15 08:24:33 +02:00
|
|
|
{
|
|
|
|
return ParseHexV(find_value(o, strKey), strKey);
|
|
|
|
}
|
2011-05-14 20:10:21 +02:00
|
|
|
|
2014-10-30 03:14:08 +01:00
|
|
|
/**
|
|
|
|
* Note: This interface may still be subject to change.
|
|
|
|
*/
|
2011-05-14 20:10:21 +02:00
|
|
|
|
2015-05-31 15:36:44 +02:00
|
|
|
std::string CRPCTable::help(const std::string& strCommand) const
|
2011-05-14 20:10:21 +02:00
|
|
|
{
|
|
|
|
string strRet;
|
2014-07-15 21:38:52 +02:00
|
|
|
string category;
|
2011-05-14 20:10:21 +02:00
|
|
|
set<rpcfn_type> setDone;
|
2014-07-15 21:38:52 +02:00
|
|
|
vector<pair<string, const CRPCCommand*> > vCommands;
|
|
|
|
|
2012-04-18 22:42:17 +02:00
|
|
|
for (map<string, const CRPCCommand*>::const_iterator mi = mapCommands.begin(); mi != mapCommands.end(); ++mi)
|
2014-07-15 21:38:52 +02:00
|
|
|
vCommands.push_back(make_pair(mi->second->category + mi->first, mi->second));
|
|
|
|
sort(vCommands.begin(), vCommands.end());
|
|
|
|
|
|
|
|
BOOST_FOREACH(const PAIRTYPE(string, const CRPCCommand*)& command, vCommands)
|
2011-05-14 20:10:21 +02:00
|
|
|
{
|
2014-07-15 21:38:52 +02:00
|
|
|
const CRPCCommand *pcmd = command.second;
|
|
|
|
string strMethod = pcmd->name;
|
2011-05-14 20:10:21 +02:00
|
|
|
// We already filter duplicates, but these deprecated screw up the sort order
|
2012-05-18 05:43:00 +02:00
|
|
|
if (strMethod.find("label") != string::npos)
|
2011-05-14 20:10:21 +02:00
|
|
|
continue;
|
2014-11-26 16:33:18 +01:00
|
|
|
if ((strCommand != "" || pcmd->category == "hidden") && strMethod != strCommand)
|
2011-05-14 20:10:21 +02:00
|
|
|
continue;
|
|
|
|
try
|
|
|
|
{
|
2015-05-13 21:29:19 +02:00
|
|
|
UniValue params;
|
2012-04-15 05:55:05 +02:00
|
|
|
rpcfn_type pfn = pcmd->actor;
|
2011-05-14 20:10:21 +02:00
|
|
|
if (setDone.insert(pfn).second)
|
|
|
|
(*pfn)(params, true);
|
|
|
|
}
|
2014-12-07 13:29:06 +01:00
|
|
|
catch (const std::exception& e)
|
2011-05-14 20:10:21 +02:00
|
|
|
{
|
|
|
|
// Help text is returned in an exception
|
|
|
|
string strHelp = string(e.what());
|
|
|
|
if (strCommand == "")
|
2014-07-15 21:38:52 +02:00
|
|
|
{
|
2012-04-15 22:47:24 +02:00
|
|
|
if (strHelp.find('\n') != string::npos)
|
2011-05-14 20:10:21 +02:00
|
|
|
strHelp = strHelp.substr(0, strHelp.find('\n'));
|
2014-07-15 21:38:52 +02:00
|
|
|
|
|
|
|
if (category != pcmd->category)
|
|
|
|
{
|
|
|
|
if (!category.empty())
|
|
|
|
strRet += "\n";
|
|
|
|
category = pcmd->category;
|
|
|
|
string firstLetter = category.substr(0,1);
|
|
|
|
boost::to_upper(firstLetter);
|
|
|
|
strRet += "== " + firstLetter + category.substr(1) + " ==\n";
|
|
|
|
}
|
|
|
|
}
|
2011-05-14 20:10:21 +02:00
|
|
|
strRet += strHelp + "\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (strRet == "")
|
2014-01-16 16:15:27 +01:00
|
|
|
strRet = strprintf("help: unknown command: %s\n", strCommand);
|
2011-05-14 20:10:21 +02:00
|
|
|
strRet = strRet.substr(0,strRet.size()-1);
|
|
|
|
return strRet;
|
|
|
|
}
|
|
|
|
|
2015-05-18 14:02:18 +02:00
|
|
|
UniValue help(const UniValue& params, bool fHelp)
|
2012-04-18 22:42:17 +02:00
|
|
|
{
|
|
|
|
if (fHelp || params.size() > 1)
|
|
|
|
throw runtime_error(
|
2013-10-29 12:29:44 +01:00
|
|
|
"help ( \"command\" )\n"
|
|
|
|
"\nList all commands, or get help for a specified command.\n"
|
|
|
|
"\nArguments:\n"
|
|
|
|
"1. \"command\" (string, optional) The command to get help on\n"
|
|
|
|
"\nResult:\n"
|
|
|
|
"\"text\" (string) The help text\n"
|
|
|
|
);
|
2012-04-18 22:42:17 +02:00
|
|
|
|
|
|
|
string strCommand;
|
|
|
|
if (params.size() > 0)
|
|
|
|
strCommand = params[0].get_str();
|
|
|
|
|
|
|
|
return tableRPC.help(strCommand);
|
|
|
|
}
|
|
|
|
|
2011-05-14 20:10:21 +02:00
|
|
|
|
2015-05-18 14:02:18 +02:00
|
|
|
UniValue stop(const UniValue& params, bool fHelp)
|
2011-05-14 20:10:21 +02:00
|
|
|
{
|
2013-01-20 18:50:30 +01:00
|
|
|
// Accept the deprecated and ignored 'detach' boolean argument
|
2012-09-19 04:54:43 +02:00
|
|
|
if (fHelp || params.size() > 1)
|
2011-05-14 20:10:21 +02:00
|
|
|
throw runtime_error(
|
2012-11-04 12:48:45 +01:00
|
|
|
"stop\n"
|
2013-10-29 12:29:44 +01:00
|
|
|
"\nStop Bitcoin server.");
|
2015-09-24 17:29:22 +02:00
|
|
|
// Event loop will exit after current HTTP requests have been handled, so
|
|
|
|
// this reply will get back to the client.
|
2012-06-11 07:40:14 +02:00
|
|
|
StartShutdown();
|
2012-05-13 16:09:14 +02:00
|
|
|
return "Bitcoin server stopping";
|
2011-05-14 20:10:21 +02:00
|
|
|
}
|
|
|
|
|
2014-10-30 03:14:08 +01:00
|
|
|
/**
|
|
|
|
* Call Table
|
|
|
|
*/
|
2012-04-21 01:37:34 +02:00
|
|
|
static const CRPCCommand vRPCCommands[] =
|
2015-04-12 17:56:44 +02:00
|
|
|
{ // category name actor (function) okSafeMode
|
|
|
|
// --------------------- ------------------------ ----------------------- ----------
|
2014-03-26 12:26:43 +01:00
|
|
|
/* Overall control/query calls */
|
2015-04-12 17:56:44 +02:00
|
|
|
{ "control", "help", &help, true },
|
|
|
|
{ "control", "stop", &stop, true },
|
2011-05-14 20:10:21 +02:00
|
|
|
};
|
|
|
|
|
2012-04-18 22:42:17 +02:00
|
|
|
CRPCTable::CRPCTable()
|
2012-04-15 05:55:05 +02:00
|
|
|
{
|
|
|
|
unsigned int vcidx;
|
|
|
|
for (vcidx = 0; vcidx < (sizeof(vRPCCommands) / sizeof(vRPCCommands[0])); vcidx++)
|
|
|
|
{
|
2012-04-21 01:37:34 +02:00
|
|
|
const CRPCCommand *pcmd;
|
2011-05-14 20:10:21 +02:00
|
|
|
|
2012-04-15 05:55:05 +02:00
|
|
|
pcmd = &vRPCCommands[vcidx];
|
|
|
|
mapCommands[pcmd->name] = pcmd;
|
|
|
|
}
|
|
|
|
}
|
2011-05-14 20:10:21 +02:00
|
|
|
|
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-23 07:53:17 +01:00
|
|
|
const CRPCCommand *CRPCTable::operator[](const std::string &name) const
|
2012-04-18 22:42:17 +02:00
|
|
|
{
|
|
|
|
map<string, const CRPCCommand*>::const_iterator it = mapCommands.find(name);
|
|
|
|
if (it == mapCommands.end())
|
|
|
|
return NULL;
|
|
|
|
return (*it).second;
|
|
|
|
}
|
2011-05-14 20:10:21 +02:00
|
|
|
|
2016-01-07 08:33:49 +01:00
|
|
|
bool CRPCTable::appendCommand(const std::string& name, const CRPCCommand* pcmd)
|
|
|
|
{
|
|
|
|
if (IsRPCRunning())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// don't allow overwriting for now
|
|
|
|
map<string, const CRPCCommand*>::const_iterator it = mapCommands.find(name);
|
|
|
|
if (it != mapCommands.end())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
mapCommands[name] = pcmd;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-23 07:53:17 +01:00
|
|
|
bool StartRPC()
|
2011-08-10 13:53:13 +02:00
|
|
|
{
|
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-23 07:53:17 +01:00
|
|
|
LogPrint("rpc", "Starting RPC\n");
|
2012-05-13 06:43:24 +02:00
|
|
|
fRPCRunning = true;
|
2014-10-19 10:46:17 +02:00
|
|
|
g_rpcSignals.Started();
|
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-23 07:53:17 +01:00
|
|
|
return true;
|
2013-03-07 04:31:26 +01:00
|
|
|
}
|
|
|
|
|
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-23 07:53:17 +01:00
|
|
|
void InterruptRPC()
|
2014-01-17 16:32:35 +01:00
|
|
|
{
|
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-23 07:53:17 +01:00
|
|
|
LogPrint("rpc", "Interrupting RPC\n");
|
|
|
|
// Interrupt e.g. running longpolls
|
|
|
|
fRPCRunning = false;
|
2014-01-17 16:32:35 +01:00
|
|
|
}
|
|
|
|
|
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-23 07:53:17 +01:00
|
|
|
void StopRPC()
|
2013-03-07 04:31:26 +01:00
|
|
|
{
|
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-23 07:53:17 +01:00
|
|
|
LogPrint("rpc", "Stopping RPC\n");
|
2013-05-07 16:47:00 +02:00
|
|
|
deadlineTimers.clear();
|
2014-10-19 10:46:17 +02:00
|
|
|
g_rpcSignals.Stopped();
|
2012-04-15 02:35:58 +02:00
|
|
|
}
|
|
|
|
|
2012-05-13 06:43:24 +02:00
|
|
|
bool IsRPCRunning()
|
|
|
|
{
|
|
|
|
return fRPCRunning;
|
|
|
|
}
|
|
|
|
|
2014-10-29 18:08:31 +01:00
|
|
|
void SetRPCWarmupStatus(const std::string& newStatus)
|
|
|
|
{
|
|
|
|
LOCK(cs_rpcWarmup);
|
|
|
|
rpcWarmupStatus = newStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetRPCWarmupFinished()
|
|
|
|
{
|
|
|
|
LOCK(cs_rpcWarmup);
|
|
|
|
assert(fRPCInWarmup);
|
|
|
|
fRPCInWarmup = false;
|
|
|
|
}
|
|
|
|
|
2014-11-26 13:51:02 +01:00
|
|
|
bool RPCIsInWarmup(std::string *outStatus)
|
|
|
|
{
|
|
|
|
LOCK(cs_rpcWarmup);
|
|
|
|
if (outStatus)
|
|
|
|
*outStatus = rpcWarmupStatus;
|
|
|
|
return fRPCInWarmup;
|
|
|
|
}
|
|
|
|
|
2015-05-18 14:02:18 +02:00
|
|
|
void JSONRequest::parse(const UniValue& valRequest)
|
2012-06-27 19:47:02 +02:00
|
|
|
{
|
|
|
|
// Parse request
|
2014-08-20 21:15:16 +02:00
|
|
|
if (!valRequest.isObject())
|
2012-10-04 09:34:44 +02:00
|
|
|
throw JSONRPCError(RPC_INVALID_REQUEST, "Invalid Request object");
|
2015-05-18 14:02:18 +02:00
|
|
|
const UniValue& request = valRequest.get_obj();
|
2012-06-27 19:47:02 +02:00
|
|
|
|
|
|
|
// Parse id now so errors from here on will have the id
|
|
|
|
id = find_value(request, "id");
|
|
|
|
|
|
|
|
// Parse method
|
2015-05-13 21:29:19 +02:00
|
|
|
UniValue valMethod = find_value(request, "method");
|
2014-08-20 21:15:16 +02:00
|
|
|
if (valMethod.isNull())
|
2012-10-04 09:34:44 +02:00
|
|
|
throw JSONRPCError(RPC_INVALID_REQUEST, "Missing method");
|
2014-08-20 21:15:16 +02:00
|
|
|
if (!valMethod.isStr())
|
2012-10-04 09:34:44 +02:00
|
|
|
throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string");
|
2012-06-27 19:47:02 +02:00
|
|
|
strMethod = valMethod.get_str();
|
2014-04-28 12:52:32 +02:00
|
|
|
if (strMethod != "getblocktemplate")
|
2015-02-08 01:59:58 +01:00
|
|
|
LogPrint("rpc", "ThreadRPCServer method=%s\n", SanitizeString(strMethod));
|
2012-06-27 19:47:02 +02:00
|
|
|
|
|
|
|
// Parse params
|
2015-05-13 21:29:19 +02:00
|
|
|
UniValue valParams = find_value(request, "params");
|
2014-08-20 21:15:16 +02:00
|
|
|
if (valParams.isArray())
|
2012-06-27 19:47:02 +02:00
|
|
|
params = valParams.get_array();
|
2014-08-20 21:15:16 +02:00
|
|
|
else if (valParams.isNull())
|
2015-05-18 14:02:18 +02:00
|
|
|
params = UniValue(UniValue::VARR);
|
2012-06-27 19:47:02 +02:00
|
|
|
else
|
2012-10-04 09:34:44 +02:00
|
|
|
throw JSONRPCError(RPC_INVALID_REQUEST, "Params must be an array");
|
2012-06-27 19:47:02 +02:00
|
|
|
}
|
|
|
|
|
2015-05-18 14:02:18 +02:00
|
|
|
static UniValue JSONRPCExecOne(const UniValue& req)
|
2012-06-24 08:01:28 +02:00
|
|
|
{
|
2015-05-10 14:48:35 +02:00
|
|
|
UniValue rpc_result(UniValue::VOBJ);
|
2012-06-24 08:01:28 +02:00
|
|
|
|
|
|
|
JSONRequest jreq;
|
|
|
|
try {
|
|
|
|
jreq.parse(req);
|
|
|
|
|
2015-05-13 21:29:19 +02:00
|
|
|
UniValue result = tableRPC.execute(jreq.strMethod, jreq.params);
|
2014-08-20 21:15:16 +02:00
|
|
|
rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id);
|
2012-06-24 08:01:28 +02:00
|
|
|
}
|
2015-05-18 14:02:18 +02:00
|
|
|
catch (const UniValue& objError)
|
2012-06-24 08:01:28 +02:00
|
|
|
{
|
2014-08-20 21:15:16 +02:00
|
|
|
rpc_result = JSONRPCReplyObj(NullUniValue, objError, jreq.id);
|
2012-06-24 08:01:28 +02:00
|
|
|
}
|
2014-12-07 13:29:06 +01:00
|
|
|
catch (const std::exception& e)
|
2012-06-24 08:01:28 +02:00
|
|
|
{
|
2014-08-20 21:15:16 +02:00
|
|
|
rpc_result = JSONRPCReplyObj(NullUniValue,
|
2012-10-04 09:34:44 +02:00
|
|
|
JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
|
2012-06-24 08:01:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return rpc_result;
|
|
|
|
}
|
|
|
|
|
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-23 07:53:17 +01:00
|
|
|
std::string JSONRPCExecBatch(const UniValue& vReq)
|
2012-06-24 08:01:28 +02:00
|
|
|
{
|
2015-06-02 11:41:00 +02:00
|
|
|
UniValue ret(UniValue::VARR);
|
2012-06-24 08:01:28 +02:00
|
|
|
for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++)
|
|
|
|
ret.push_back(JSONRPCExecOne(vReq[reqIdx]));
|
|
|
|
|
2014-08-20 21:15:16 +02:00
|
|
|
return ret.write() + "\n";
|
2012-06-24 08:01:28 +02:00
|
|
|
}
|
|
|
|
|
2015-05-13 21:29:19 +02:00
|
|
|
UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms) const
|
2012-04-09 21:07:25 +02:00
|
|
|
{
|
2015-07-02 03:34:31 +02:00
|
|
|
// Return immediately if in warmup
|
|
|
|
{
|
|
|
|
LOCK(cs_rpcWarmup);
|
|
|
|
if (fRPCInWarmup)
|
|
|
|
throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus);
|
|
|
|
}
|
|
|
|
|
2012-04-09 21:07:25 +02:00
|
|
|
// Find method
|
|
|
|
const CRPCCommand *pcmd = tableRPC[strMethod];
|
|
|
|
if (!pcmd)
|
2012-10-04 09:34:44 +02:00
|
|
|
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
|
2011-05-14 20:10:21 +02:00
|
|
|
|
2014-10-19 10:46:17 +02:00
|
|
|
g_rpcSignals.PreCommand(*pcmd);
|
2012-04-09 21:07:25 +02:00
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
// Execute
|
2014-10-19 10:46:17 +02:00
|
|
|
return pcmd->actor(params, false);
|
2012-04-09 21:07:25 +02:00
|
|
|
}
|
2014-12-07 13:29:06 +01:00
|
|
|
catch (const std::exception& e)
|
2012-04-09 21:07:25 +02:00
|
|
|
{
|
2012-10-04 09:34:44 +02:00
|
|
|
throw JSONRPCError(RPC_MISC_ERROR, e.what());
|
2012-04-09 21:07:25 +02:00
|
|
|
}
|
2014-10-19 10:46:17 +02:00
|
|
|
|
|
|
|
g_rpcSignals.PostCommand(*pcmd);
|
2012-04-09 21:07:25 +02:00
|
|
|
}
|
2011-05-14 20:10:21 +02:00
|
|
|
|
2016-02-27 04:57:12 +01:00
|
|
|
std::vector<std::string> CRPCTable::listCommands() const
|
|
|
|
{
|
|
|
|
std::vector<std::string> commandList;
|
|
|
|
typedef std::map<std::string, const CRPCCommand*> commandMap;
|
|
|
|
|
|
|
|
std::transform( mapCommands.begin(), mapCommands.end(),
|
|
|
|
std::back_inserter(commandList),
|
|
|
|
boost::bind(&commandMap::value_type::first,_1) );
|
|
|
|
return commandList;
|
|
|
|
}
|
|
|
|
|
2015-05-31 15:36:44 +02:00
|
|
|
std::string HelpExampleCli(const std::string& methodname, const std::string& args)
|
|
|
|
{
|
2013-11-29 15:48:07 +01:00
|
|
|
return "> bitcoin-cli " + methodname + " " + args + "\n";
|
|
|
|
}
|
|
|
|
|
2015-05-31 15:36:44 +02:00
|
|
|
std::string HelpExampleRpc(const std::string& methodname, const std::string& args)
|
|
|
|
{
|
2013-11-29 15:48:07 +01:00
|
|
|
return "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\":\"curltest\", "
|
|
|
|
"\"method\": \"" + methodname + "\", \"params\": [" + args + "] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n";
|
|
|
|
}
|
|
|
|
|
2016-01-08 11:03:52 +01:00
|
|
|
void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface)
|
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-23 07:53:17 +01:00
|
|
|
{
|
2016-01-08 11:03:52 +01:00
|
|
|
if (!timerInterface)
|
|
|
|
timerInterface = iface;
|
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-23 07:53:17 +01:00
|
|
|
}
|
|
|
|
|
2016-01-08 11:03:52 +01:00
|
|
|
void RPCSetTimerInterface(RPCTimerInterface *iface)
|
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-23 07:53:17 +01:00
|
|
|
{
|
2016-01-08 11:03:52 +01:00
|
|
|
timerInterface = iface;
|
|
|
|
}
|
|
|
|
|
|
|
|
void RPCUnsetTimerInterface(RPCTimerInterface *iface)
|
|
|
|
{
|
|
|
|
if (timerInterface == iface)
|
|
|
|
timerInterface = NULL;
|
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-23 07:53:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void RPCRunLater(const std::string& name, boost::function<void(void)> func, int64_t nSeconds)
|
|
|
|
{
|
2016-01-08 11:03:52 +01:00
|
|
|
if (!timerInterface)
|
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-23 07:53:17 +01:00
|
|
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "No timer handler registered for RPC");
|
|
|
|
deadlineTimers.erase(name);
|
|
|
|
LogPrint("rpc", "queue run of timer %s in %i seconds (using %s)\n", name, nSeconds, timerInterface->Name());
|
2015-10-29 03:25:32 +01:00
|
|
|
deadlineTimers.insert(std::make_pair(name, boost::shared_ptr<RPCTimerBase>(timerInterface->NewTimer(func, nSeconds*1000))));
|
evhttpd implementation
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*.
boost::asio is not part of C++11, so unlike other boost there is no
forwards-compatibility reason to stick with it. Together with #4738 (convert
json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with
regard to compile-time slowness.
- *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling
is handled by libevent, a work queue (with configurable depth and parallelism)
is used to handle application requests.
- *Wrap HTTP request in C++ class*; this makes the application code mostly
HTTP-server-neutral
- *Refactor RPC to move all http-specific code to a separate file*.
Theoreticaly this can allow building without HTTP server but with another RPC
backend, e.g. Qt's debug console (currently not implemented) or future RPC
mechanisms people may want to use.
- *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL
paths they want to handle.
By using a proven, high-performance asynchronous networking library (also used
by Tor) and HTTP server, problems such as #5674, #5655, #344 should be avoided.
What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests
pass. The aim for now is everything but SSL support.
Configuration options:
- `-rpcthreads`: repurposed as "number of work handler threads". Still
defaults to 4.
- `-rpcworkqueue`: maximum depth of work queue. When this is reached, new
requests will return a 500 Internal Error.
- `-rpctimeout`: inactivity time, in seconds, after which to disconnect a
client.
- `-debug=http`: low-level http activity logging
2015-01-23 07:53:17 +01:00
|
|
|
}
|
|
|
|
|
2016-01-07 08:33:49 +01:00
|
|
|
CRPCTable tableRPC;
|