15 #include <boost/asio.hpp>
16 #include <boost/asio/ip/v6_only.hpp>
17 #include <boost/bind.hpp>
18 #include <boost/filesystem.hpp>
19 #include <boost/foreach.hpp>
20 #include <boost/iostreams/concepts.hpp>
21 #include <boost/iostreams/stream.hpp>
22 #include <boost/algorithm/string.hpp>
23 #include <boost/lexical_cast.hpp>
24 #include <boost/asio/ssl.hpp>
25 #include <boost/filesystem/fstream.hpp>
26 #include <boost/shared_ptr.hpp>
30 using namespace boost;
34 static std::string strRPCUserColonPass;
37 static asio::io_service* rpc_io_service = NULL;
38 static ssl::context* rpc_ssl_context = NULL;
39 static boost::thread_group* rpc_worker_group = NULL;
41 static inline unsigned short GetDefaultRPCPort()
43 return GetBoolArg(
"-testnet",
false) ? 19337 : 9337;
49 error.push_back(
Pair(
"code", code));
50 error.push_back(
Pair(
"message", message));
55 const list<Value_type>& typesExpected,
61 if (params.size() <= i)
64 const Value& v = params[i];
67 string err =
strprintf(
"Expected type %s, got %s",
68 Value_type_name[t], Value_type_name[v.
type()]);
76 const map<string, Value_type>& typesExpected,
87 string err =
strprintf(
"Expected type %s for %s, got %s",
88 Value_type_name[t.second], t.first.c_str(), Value_type_name[v.
type()]);
97 if (dAmount <= 0.0 || dAmount > 336000000.0)
107 return (
double)amount / (double)COIN;
116 uBits.nBits = htonl((
int32_t)nBits);
129 set<rpcfn_type> setDone;
130 for (map<string, const CRPCCommand*>::const_iterator mi = mapCommands.begin(); mi != mapCommands.end(); ++mi)
133 string strMethod = mi->first;
135 if (strMethod.find(
"label") != string::npos)
137 if (strCommand !=
"" && strMethod != strCommand)
146 if (setDone.insert(pfn).second)
147 (*pfn)(params,
true);
149 catch (std::exception& e)
152 string strHelp = string(e.what());
153 if (strCommand ==
"")
154 if (strHelp.find(
'\n') != string::npos)
155 strHelp = strHelp.substr(0, strHelp.find(
'\n'));
156 strRet += strHelp +
"\n";
160 strRet =
strprintf(
"help: unknown command: %s\n", strCommand.c_str());
161 strRet = strRet.substr(0,strRet.size()-1);
167 if (fHelp || params.size() > 1)
170 "List commands, or get help for a command.");
173 if (params.size() > 0)
174 strCommand = params[0].
get_str();
183 if (fHelp || params.size() > 1)
186 "Stop Feathercoin server.");
189 return "Feathercoin server stopping";
202 {
"help", &
help,
true,
true,
false },
203 {
"stop", &
stop,
true,
true,
false },
207 {
"getpeerinfo", &
getpeerinfo,
true,
false,
false },
208 {
"addnode", &
addnode,
true,
true,
false },
212 {
"getgenerate", &
getgenerate,
true,
false,
false },
213 {
"setgenerate", &
setgenerate,
true,
false,
true },
215 {
"getinfo", &
getinfo,
true,
false,
false },
219 {
"setaccount", &
setaccount,
true,
false,
true },
220 {
"getaccount", &
getaccount,
false,
false,
true },
231 {
"walletlock", &
walletlock,
true,
false,
true },
234 {
"getbalance", &
getbalance,
false,
false,
true },
235 {
"move", &
movecmd,
false,
false,
true },
236 {
"sendfrom", &
sendfrom,
false,
false,
true },
237 {
"sendmany", &
sendmany,
false,
false,
true },
241 {
"getblock", &
getblock,
false,
false,
false },
246 {
"signmessage", &
signmessage,
false,
false,
true },
248 {
"getwork", &
getwork,
true,
false,
true },
249 {
"getworkex", &
getworkex,
true,
false,
true },
251 {
"settxfee", &
settxfee,
false,
false,
true },
253 {
"submitblock", &
submitblock,
false,
false,
false },
254 {
"setmininput", &
setmininput,
false,
false,
false },
256 {
"dumpprivkey", &
dumpprivkey,
true,
false,
true },
261 {
"makekeypair", &
makekeypair,
true,
false,
false },
262 {
"sendalert", &
sendalert,
true,
false,
false },
263 {
"listunspent", &
listunspent,
false,
false,
true },
270 {
"gettxout", &
gettxout,
true,
false,
false },
271 {
"lockunspent", &
lockunspent,
false,
false,
true },
273 {
"verifychain", &
verifychain,
true,
false,
false },
279 for (vcidx = 0; vcidx < (
sizeof(vRPCCommands) /
sizeof(vRPCCommands[0])); vcidx++)
283 pcmd = &vRPCCommands[vcidx];
284 mapCommands[pcmd->
name] = pcmd;
290 map<string, const CRPCCommand*>::const_iterator it = mapCommands.find(name);
291 if (it == mapCommands.end())
303 string HTTPPost(
const string& strMsg,
const map<string,string>& mapRequestHeaders)
306 s <<
"POST / HTTP/1.1\r\n"
308 <<
"Host: 127.0.0.1\r\n"
309 <<
"Content-Type: application/json\r\n"
310 <<
"Content-Length: " << strMsg.size() <<
"\r\n"
311 <<
"Connection: close\r\n"
312 <<
"Accept: application/json\r\n";
313 BOOST_FOREACH(
const PAIRTYPE(
string,
string)& item, mapRequestHeaders)
314 s << item.first <<
": " << item.second <<
"\r\n";
315 s <<
"\r\n" << strMsg;
325 struct tm* now_gmt = gmtime(&now);
326 string locale(setlocale(LC_TIME, NULL));
327 setlocale(LC_TIME,
"C");
328 strftime(buffer,
sizeof(buffer),
"%a, %d %b %Y %H:%M:%S +0000", now_gmt);
329 setlocale(LC_TIME, locale.c_str());
330 return string(buffer);
333 static string HTTPReply(
int nStatus,
const string& strMsg,
bool keepalive)
336 return strprintf(
"HTTP/1.0 401 Authorization Required\r\n"
338 "Server: feathercoin-json-rpc/%s\r\n"
339 "WWW-Authenticate: Basic realm=\"jsonrpc\"\r\n"
340 "Content-Type: text/html\r\n"
341 "Content-Length: 296\r\n"
343 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n"
344 "\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">\r\n"
347 "<TITLE>Error</TITLE>\r\n"
348 "<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=ISO-8859-1'>\r\n"
350 "<BODY><H1>401 Unauthorized.</H1></BODY>\r\n"
353 if (nStatus ==
HTTP_OK) cStatus =
"OK";
363 "Content-Length: %"PRIszu"\r\n"
364 "Content-Type: application/json\r\n"
365 "Server: feathercoin-json-rpc/%s\r\n"
371 keepalive ?
"keep-alive" :
"close",
378 string& http_method,
string& http_uri)
381 getline(stream, str);
384 vector<string> vWords;
385 boost::split(vWords, str, boost::is_any_of(
" "));
386 if (vWords.size() < 2)
390 http_method = vWords[0];
391 if (http_method !=
"GET" && http_method !=
"POST")
395 http_uri = vWords[1];
396 if (http_uri.size() == 0 || http_uri[0] !=
'/')
400 string strProto =
"";
401 if (vWords.size() > 2)
402 strProto = vWords[2];
405 const char *ver = strstr(strProto.c_str(),
"HTTP/1.");
415 getline(stream, str);
416 vector<string> vWords;
417 boost::split(vWords, str, boost::is_any_of(
" "));
418 if (vWords.size() < 2)
421 const char *ver = strstr(str.c_str(),
"HTTP/1.");
424 return atoi(vWords[1].c_str());
427 int ReadHTTPHeaders(std::basic_istream<char>& stream, map<string, string>& mapHeadersRet)
433 std::getline(stream, str);
434 if (str.empty() || str ==
"\r")
436 string::size_type nColon = str.find(
":");
437 if (nColon != string::npos)
439 string strHeader = str.substr(0, nColon);
440 boost::trim(strHeader);
441 boost::to_lower(strHeader);
442 string strValue = str.substr(nColon+1);
443 boost::trim(strValue);
444 mapHeadersRet[strHeader] = strValue;
445 if (strHeader ==
"content-length")
446 nLen =
atoi(strValue.c_str());
453 string>& mapHeadersRet,
string& strMessageRet,
456 mapHeadersRet.clear();
461 if (nLen < 0 || nLen > (
int)
MAX_SIZE)
467 vector<char> vch(nLen);
468 stream.read(&vch[0], nLen);
469 strMessageRet = string(vch.begin(), vch.end());
472 string sConHdr = mapHeadersRet[
"connection"];
474 if ((sConHdr !=
"close") && (sConHdr !=
"keep-alive"))
477 mapHeadersRet[
"connection"] =
"keep-alive";
479 mapHeadersRet[
"connection"] =
"close";
487 string strAuth = mapHeaders[
"authorization"];
488 if (strAuth.substr(0,6) !=
"Basic ")
490 string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64);
508 request.push_back(
Pair(
"method", strMethod));
509 request.push_back(
Pair(
"params", params));
510 request.push_back(
Pair(
"id",
id));
518 reply.push_back(
Pair(
"result", Value::null));
520 reply.push_back(
Pair(
"result", result));
521 reply.push_back(
Pair(
"error", error));
522 reply.push_back(
Pair(
"id",
id));
536 int code =
find_value(objError,
"code").get_int();
539 string strReply =
JSONRPCReply(Value::null, objError,
id);
540 stream << HTTPReply(nStatus, strReply,
false) << std::flush;
547 && (address.to_v6().is_v4_compatible()
548 || address.to_v6().is_v4_mapped()))
551 if (address == asio::ip::address_v4::loopback()
552 || address == asio::ip::address_v6::loopback()
555 && (address.to_v4().to_ulong() & 0xff000000) == 0x7f000000))
558 const string strAddress = address.to_string();
559 const vector<string>& vAllow =
mapMultiArgs[
"-rpcallowip"];
560 BOOST_FOREACH(
string strAllow, vAllow)
569 template <
typename Protocol>
572 SSLIOStreamDevice(asio::ssl::stream<typename Protocol::socket> &streamIn,
bool fUseSSLIn) : stream(streamIn)
575 fNeedHandshake = fUseSSLIn;
580 if (!fNeedHandshake)
return;
581 fNeedHandshake =
false;
582 stream.handshake(role);
584 std::streamsize
read(
char* s, std::streamsize n)
586 handshake(ssl::stream_base::server);
587 if (fUseSSL)
return stream.read_some(asio::buffer(s, n));
588 return stream.next_layer().read_some(asio::buffer(s, n));
590 std::streamsize
write(
const char* s, std::streamsize n)
592 handshake(ssl::stream_base::client);
593 if (fUseSSL)
return asio::write(stream, asio::buffer(s, n));
594 return asio::write(stream.next_layer(), asio::buffer(s, n));
596 bool connect(
const std::string& server,
const std::string& port)
598 ip::tcp::resolver resolver(stream.get_io_service());
599 ip::tcp::resolver::query query(server.c_str(), port.c_str());
600 ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
601 ip::tcp::resolver::iterator end;
602 boost::system::error_code
error = asio::error::host_not_found;
603 while (error && endpoint_iterator != end)
605 stream.lowest_layer().close();
606 stream.lowest_layer().connect(*endpoint_iterator++, error);
616 asio::ssl::stream<typename Protocol::socket>&
stream;
624 virtual std::iostream& stream() = 0;
625 virtual std::string peer_address_to_string()
const = 0;
626 virtual void close() = 0;
629 template <
typename Protocol>
634 asio::io_service& io_service,
635 ssl::context &context,
637 sslStream(io_service, context),
638 _d(sslStream, fUseSSL),
650 return peer.address().to_string();
658 typename Protocol::endpoint
peer;
663 iostreams::stream< SSLIOStreamDevice<Protocol> >
_stream;
669 template <
typename Protocol,
typename SocketAcceptorService>
670 static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor,
671 ssl::context& context,
674 const boost::system::error_code&
error);
679 template <
typename Protocol,
typename SocketAcceptorService>
680 static void RPCListen(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor,
681 ssl::context& context,
687 acceptor->async_accept(
690 boost::bind(&RPCAcceptHandler<Protocol, SocketAcceptorService>,
701 template <
typename Protocol,
typename SocketAcceptorService>
702 static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor,
703 ssl::context& context,
706 const boost::system::error_code&
error)
709 if (error != asio::error::operation_aborted && acceptor->is_open())
710 RPCListen(acceptor, context, fUseSSL);
739 strRPCUserColonPass =
mapArgs[
"-rpcuser"] +
":" +
mapArgs[
"-rpcpassword"];
740 if ((mapArgs[
"-rpcpassword"] ==
"") ||
741 (mapArgs[
"-rpcuser"] == mapArgs[
"-rpcpassword"]))
743 unsigned char rand_pwd[32];
744 RAND_bytes(rand_pwd, 32);
745 string strWhatAmI =
"To use feathercoind";
746 if (mapArgs.count(
"-server"))
747 strWhatAmI =
strprintf(
_(
"To use the %s option"),
"\"-server\"");
748 else if (mapArgs.count(
"-daemon"))
749 strWhatAmI =
strprintf(
_(
"To use the %s option"),
"\"-daemon\"");
751 _(
"%s, you must set a rpcpassword in the configuration file:\n"
753 "It is recommended you use the following random password:\n"
754 "rpcuser=feathercoinrpc\n"
756 "(you do not need to remember this password)\n"
757 "The username and password MUST NOT be the same.\n"
758 "If the file does not exist, create it with owner-readable-only file permissions.\n"
759 "It is also recommended to set alertnotify so you are notified of problems;\n"
760 "for example: alertnotify=echo %%s | mail -s \"Feathercoin Alert\" admin@foo.com\n"),
769 assert(rpc_io_service == NULL);
770 rpc_io_service =
new asio::io_service();
771 rpc_ssl_context =
new ssl::context(*rpc_io_service, ssl::context::sslv23);
777 rpc_ssl_context->set_options(ssl::context::no_sslv2);
779 filesystem::path pathCertFile(
GetArg(
"-rpcsslcertificatechainfile",
"server.cert"));
780 if (!pathCertFile.is_complete()) pathCertFile = filesystem::path(
GetDataDir()) / pathCertFile;
781 if (filesystem::exists(pathCertFile)) rpc_ssl_context->use_certificate_chain_file(pathCertFile.string());
782 else printf(
"ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string().c_str());
784 filesystem::path pathPKFile(
GetArg(
"-rpcsslprivatekeyfile",
"server.pem"));
785 if (!pathPKFile.is_complete()) pathPKFile = filesystem::path(
GetDataDir()) / pathPKFile;
786 if (filesystem::exists(pathPKFile)) rpc_ssl_context->use_private_key_file(pathPKFile.string(), ssl::context::pem);
787 else printf(
"ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string().c_str());
789 string strCiphers =
GetArg(
"-rpcsslciphers",
"TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH");
790 SSL_CTX_set_cipher_list(rpc_ssl_context->impl(), strCiphers.c_str());
794 const bool loopback = !mapArgs.count(
"-rpcallowip");
795 asio::ip::address bindAddress = loopback ? asio::ip::address_v6::loopback() : asio::ip::address_v6::any();
796 ip::tcp::endpoint endpoint(bindAddress,
GetArg(
"-rpcport", GetDefaultRPCPort()));
797 boost::system::error_code v6_only_error;
798 boost::shared_ptr<ip::tcp::acceptor> acceptor(
new ip::tcp::acceptor(*rpc_io_service));
800 bool fListening =
false;
804 acceptor->open(endpoint.protocol());
805 acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(
true));
808 acceptor->set_option(boost::asio::ip::v6_only(loopback), v6_only_error);
810 acceptor->bind(endpoint);
811 acceptor->listen(socket_base::max_connections);
813 RPCListen(acceptor, *rpc_ssl_context, fUseSSL);
817 catch(boost::system::system_error &e)
819 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());
824 if (!fListening || loopback || v6_only_error)
826 bindAddress = loopback ? asio::ip::address_v4::loopback() : asio::ip::address_v4::any();
827 endpoint.address(bindAddress);
829 acceptor.reset(
new ip::tcp::acceptor(*rpc_io_service));
830 acceptor->open(endpoint.protocol());
831 acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(
true));
832 acceptor->bind(endpoint);
833 acceptor->listen(socket_base::max_connections);
835 RPCListen(acceptor, *rpc_ssl_context, fUseSSL);
840 catch(boost::system::system_error &e)
842 strerr =
strprintf(
_(
"An error occurred while setting up the RPC port %u for listening on IPv4: %s"), endpoint.port(), e.what());
851 rpc_worker_group =
new boost::thread_group();
852 for (
int i = 0; i <
GetArg(
"-rpcthreads", 4); i++)
853 rpc_worker_group->create_thread(boost::bind(&asio::io_service::run, rpc_io_service));
858 if (rpc_io_service == NULL)
return;
860 rpc_io_service->stop();
861 rpc_worker_group->join_all();
862 delete rpc_worker_group; rpc_worker_group = NULL;
863 delete rpc_ssl_context; rpc_ssl_context = NULL;
864 delete rpc_io_service; rpc_io_service = NULL;
875 void parse(
const Value& valRequest);
894 strMethod = valMethod.
get_str();
895 if (strMethod !=
"getwork" && strMethod !=
"getworkex" && strMethod !=
"getblocktemplate")
896 printf(
"ThreadRPCServer method=%s\n", strMethod.c_str());
901 params = valParams.get_array();
923 catch (std::exception& e)
932 static string JSONRPCExecBatch(
const Array& vReq)
935 for (
unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++)
936 ret.push_back(JSONRPCExecOne(vReq[reqIdx]));
947 map<string, string> mapHeaders;
948 string strRequest, strMethod, strURI;
963 if (mapHeaders.count(
"authorization") == 0)
974 if (
mapArgs[
"-rpcpassword"].size() < 20)
980 if (mapHeaders[
"connection"] ==
"close")
995 jreq.
parse(valRequest);
1004 strReply = JSONRPCExecBatch(valRequest.
get_array());
1008 conn->
stream() << HTTPReply(
HTTP_OK, strReply, fRun) << std::flush;
1015 catch (std::exception& e)
1034 if (strWarning !=
"" && !
GetBoolArg(
"-disablesafemode") &&
1044 result = pcmd->
actor(params,
false);
1047 result = pcmd->
actor(params,
false);
1050 result = pcmd->
actor(params,
false);
1055 catch (std::exception& e)
1066 _(
"You must set rpcpassword=<password> in the configuration file:\n%s\n"
1067 "If the file does not exist, create it with owner-readable-only file permissions."),
1072 asio::io_service io_service;
1073 ssl::context context(io_service, ssl::context::sslv23);
1074 context.set_options(ssl::context::no_sslv2);
1075 asio::ssl::stream<asio::ip::tcp::socket> sslStream(io_service, context);
1077 iostreams::stream< SSLIOStreamDevice<asio::ip::tcp> > stream(d);
1079 throw runtime_error(
"couldn't connect to server");
1083 map<string, string> mapRequestHeaders;
1084 mapRequestHeaders[
"Authorization"] = string(
"Basic ") + strUserPass64;
1088 string strPost =
HTTPPost(strRequest, mapRequestHeaders);
1089 stream << strPost << std::flush;
1096 map<string, string> mapHeaders;
1101 throw runtime_error(
"incorrect rpcuser or rpcpassword (authorization failed)");
1103 throw runtime_error(
strprintf(
"server returned HTTP error %d", nStatus));
1104 else if (strReply.empty())
1105 throw runtime_error(
"no response from server");
1110 throw runtime_error(
"couldn't parse reply from server");
1113 throw runtime_error(
"expected reply to have result, error and id properties");
1121 template<
typename T>
1130 string strJSON = value.
get_str();
1132 throw runtime_error(
string(
"Error parsing JSON:")+strJSON);
1133 ConvertTo<T>(value2, fAllowNull);
1146 BOOST_FOREACH(
const std::string ¶m, strParams)
1147 params.push_back(param);
1149 int n = params.size();
1154 if (strMethod ==
"stop" && n > 0) ConvertTo<bool>(params[0]);
1155 if (strMethod ==
"getaddednodeinfo" && n > 0) ConvertTo<bool>(params[0]);
1156 if (strMethod ==
"setgenerate" && n > 0) ConvertTo<bool>(params[0]);
1157 if (strMethod ==
"setgenerate" && n > 1) ConvertTo<boost::int64_t>(params[1]);
1158 if (strMethod ==
"getnetworkhashps" && n > 0) ConvertTo<boost::int64_t>(params[0]);
1159 if (strMethod ==
"getnetworkhashps" && n > 1) ConvertTo<boost::int64_t>(params[1]);
1160 if (strMethod ==
"sendtoaddress" && n > 1) ConvertTo<double>(params[1]);
1161 if (strMethod ==
"settxfee" && n > 0) ConvertTo<double>(params[0]);
1162 if (strMethod ==
"setmininput" && n > 0) ConvertTo<double>(params[0]);
1163 if (strMethod ==
"getreceivedbyaddress" && n > 1) ConvertTo<boost::int64_t>(params[1]);
1164 if (strMethod ==
"getreceivedbyaccount" && n > 1) ConvertTo<boost::int64_t>(params[1]);
1165 if (strMethod ==
"listreceivedbyaddress" && n > 0) ConvertTo<boost::int64_t>(params[0]);
1166 if (strMethod ==
"listreceivedbyaddress" && n > 1) ConvertTo<bool>(params[1]);
1167 if (strMethod ==
"listreceivedbyaccount" && n > 0) ConvertTo<boost::int64_t>(params[0]);
1168 if (strMethod ==
"listreceivedbyaccount" && n > 1) ConvertTo<bool>(params[1]);
1169 if (strMethod ==
"getbalance" && n > 1) ConvertTo<boost::int64_t>(params[1]);
1170 if (strMethod ==
"getblockhash" && n > 0) ConvertTo<boost::int64_t>(params[0]);
1171 if (strMethod ==
"move" && n > 2) ConvertTo<double>(params[2]);
1172 if (strMethod ==
"move" && n > 3) ConvertTo<boost::int64_t>(params[3]);
1173 if (strMethod ==
"sendfrom" && n > 2) ConvertTo<double>(params[2]);
1174 if (strMethod ==
"sendfrom" && n > 3) ConvertTo<boost::int64_t>(params[3]);
1175 if (strMethod ==
"listtransactions" && n > 1) ConvertTo<boost::int64_t>(params[1]);
1176 if (strMethod ==
"listtransactions" && n > 2) ConvertTo<boost::int64_t>(params[2]);
1177 if (strMethod ==
"listaccounts" && n > 0) ConvertTo<boost::int64_t>(params[0]);
1178 if (strMethod ==
"walletpassphrase" && n > 1) ConvertTo<boost::int64_t>(params[1]);
1179 if (strMethod ==
"getblocktemplate" && n > 0) ConvertTo<Object>(params[0]);
1180 if (strMethod ==
"listsinceblock" && n > 1) ConvertTo<boost::int64_t>(params[1]);
1181 if (strMethod ==
"sendalert" && n > 2) ConvertTo<boost::int64_t>(params[2]);
1182 if (strMethod ==
"sendalert" && n > 3) ConvertTo<boost::int64_t>(params[3]);
1183 if (strMethod ==
"sendalert" && n > 4) ConvertTo<boost::int64_t>(params[4]);
1184 if (strMethod ==
"sendalert" && n > 5) ConvertTo<boost::int64_t>(params[5]);
1185 if (strMethod ==
"sendalert" && n > 6) ConvertTo<boost::int64_t>(params[6]);
1186 if (strMethod ==
"enforcecheckpoint" && n > 0) ConvertTo<bool>(params[0]);
1187 if (strMethod ==
"sendmany" && n > 1) ConvertTo<Object>(params[1]);
1188 if (strMethod ==
"sendmany" && n > 2) ConvertTo<boost::int64_t>(params[2]);
1189 if (strMethod ==
"addmultisigaddress" && n > 0) ConvertTo<boost::int64_t>(params[0]);
1190 if (strMethod ==
"addmultisigaddress" && n > 1) ConvertTo<Array>(params[1]);
1191 if (strMethod ==
"createmultisig" && n > 0) ConvertTo<boost::int64_t>(params[0]);
1192 if (strMethod ==
"createmultisig" && n > 1) ConvertTo<Array>(params[1]);
1193 if (strMethod ==
"listunspent" && n > 0) ConvertTo<boost::int64_t>(params[0]);
1194 if (strMethod ==
"listunspent" && n > 1) ConvertTo<boost::int64_t>(params[1]);
1195 if (strMethod ==
"listunspent" && n > 2) ConvertTo<Array>(params[2]);
1196 if (strMethod ==
"getblock" && n > 1) ConvertTo<bool>(params[1]);
1197 if (strMethod ==
"getrawtransaction" && n > 1) ConvertTo<boost::int64_t>(params[1]);
1198 if (strMethod ==
"createrawtransaction" && n > 0) ConvertTo<Array>(params[0]);
1199 if (strMethod ==
"createrawtransaction" && n > 1) ConvertTo<Object>(params[1]);
1200 if (strMethod ==
"signrawtransaction" && n > 1) ConvertTo<Array>(params[1],
true);
1201 if (strMethod ==
"signrawtransaction" && n > 2) ConvertTo<Array>(params[2],
true);
1202 if (strMethod ==
"gettxout" && n > 1) ConvertTo<boost::int64_t>(params[1]);
1203 if (strMethod ==
"gettxout" && n > 2) ConvertTo<bool>(params[2]);
1204 if (strMethod ==
"lockunspent" && n > 0) ConvertTo<bool>(params[0]);
1205 if (strMethod ==
"lockunspent" && n > 1) ConvertTo<Array>(params[1]);
1206 if (strMethod ==
"importprivkey" && n > 2) ConvertTo<bool>(params[2]);
1207 if (strMethod ==
"verifychain" && n > 0) ConvertTo<boost::int64_t>(params[0]);
1208 if (strMethod ==
"verifychain" && n > 1) ConvertTo<boost::int64_t>(params[1]);
1228 throw runtime_error(
"too few parameters");
1229 string strMethod = argv[1];
1232 std::vector<std::string> strParams(&argv[2], &argv[argc]);
1260 catch (boost::thread_interrupted) {
1263 catch (std::exception& e) {
1264 strPrint = string(
"error: ") + e.what();
1273 fprintf((nRet == 0 ? stdout : stderr),
"%s\n", strPrint.c_str());
1282 int main(
int argc,
char *argv[])
1286 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
1287 _CrtSetReportFile(_CRT_WARN, CreateFile(
"NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
1289 setbuf(stdin, NULL);
1290 setbuf(stdout, NULL);
1291 setbuf(stderr, NULL);
1295 if (argc >= 2 &&
string(argv[1]) ==
"-server")
1297 printf(
"server ready\n");
1298 ThreadRPCServer(NULL);
1305 catch (boost::thread_interrupted) {
1308 catch (std::exception& e) {
bool error(const char *format,...)
const boost::filesystem::path & GetDataDir(bool fNetSpecific)
const Object & get_obj() const
json_spirit::Value enforcecheckpoint(const json_spirit::Array ¶ms, bool fHelp)
string JSONRPCReply(const Value &result, const Value &error, const Value &id)
json_spirit::Value listtransactions(const json_spirit::Array ¶ms, bool fHelp)
#define strprintf(format,...)
SSLIOStreamDevice< Protocol > _d
json_spirit::Value decoderawtransaction(const json_spirit::Array ¶ms, bool fHelp)
std::streamsize read(char *s, std::streamsize n)
Bitcoin RPC command dispatcher.
json_spirit::Value getblockcount(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value listaccounts(const json_spirit::Array ¶ms, bool fHelp)
iostreams::stream< SSLIOStreamDevice< Protocol > > _stream
json_spirit::Value makekeypair(const json_spirit::Array ¶ms, bool fHelp)
Value help(const Array ¶ms, bool fHelp)
json_spirit::Value getbalance(const json_spirit::Array ¶ms, bool fHelp)
asio::ssl::stream< typename Protocol::socket > sslStream
bool ReadHTTPRequestLine(std::basic_istream< char > &stream, int &proto, string &http_method, string &http_uri)
CCriticalSection cs_wallet
string JSONRPCRequest(const string &strMethod, const Array ¶ms, const Value &id)
json_spirit::Value getworkex(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value gettxout(const json_spirit::Array ¶ms, bool fHelp)
void ServiceConnection(AcceptedConnection *conn)
json_spirit::Value getaccountaddress(const json_spirit::Array ¶ms, bool fHelp)
int64 AmountFromValue(const Value &value)
json_spirit::Value getaddressesbyaccount(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value listaddressgroupings(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value gettransaction(const json_spirit::Array ¶ms, bool fHelp)
const CRPCCommand * operator[](std::string name) const
json_spirit::Value listreceivedbyaccount(const json_spirit::Array ¶ms, bool fHelp)
string GetWarnings(string strFor)
Value stop(const Array ¶ms, bool fHelp)
json_spirit::Value execute(const std::string &method, const json_spirit::Array ¶ms) const
Execute a method.
json_spirit::Value createrawtransaction(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value listreceivedbyaddress(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value encryptwallet(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value walletpassphrase(const json_spirit::Array ¶ms, bool fHelp)
virtual ~AcceptedConnection()
json_spirit::Value getrawtransaction(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value sendfrom(const json_spirit::Array ¶ms, bool fHelp)
asio::ssl::stream< typename Protocol::socket > & stream
int ReadHTTPHeaders(std::basic_istream< char > &stream, map< string, string > &mapHeadersRet)
json_spirit::Value sendmany(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value sendtoaddress(const json_spirit::Array ¶ms, bool fHelp)
int ReadHTTPStatus(std::basic_istream< char > &stream, int &proto)
Object JSONRPCError(int code, const string &message)
int CommandLineRPC(int argc, char *argv[])
virtual std::iostream & stream()
Config::Object_type Object
json_spirit::Value gethashespersec(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value keypoolrefill(const json_spirit::Array ¶ms, bool fHelp)
AcceptedConnectionImpl(asio::io_service &io_service, ssl::context &context, bool fUseSSL)
const Array & get_array() const
json_spirit::Value walletpassphrasechange(const json_spirit::Array ¶ms, bool fHelp)
Array RPCConvertValues(const std::string &strMethod, const std::vector< std::string > &strParams)
Convert parameter values for RPC call from strings to command-specific JSON objects.
virtual std::string peer_address_to_string() const
virtual std::string peer_address_to_string() const =0
json_spirit::Value signmessage(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value getbestblockhash(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value signrawtransaction(const json_spirit::Array ¶ms, bool fHelp)
int ReadHTTPMessage(std::basic_istream< char > &stream, map< string, string > &mapHeadersRet, string &strMessageRet, int nProto)
json_spirit::Value walletlock(const json_spirit::Array ¶ms, bool fHelp)
string EncodeBase64(const unsigned char *pch, size_t len)
Object CallRPC(const string &strMethod, const Array ¶ms)
bool read_string(const String_type &s, Value_type &value)
void RPCTypeCheck(const Array ¶ms, const list< Value_type > &typesExpected, bool fAllowNull)
bool GetBoolArg(const std::string &strArg, bool fDefault)
Return boolean argument or default value.
json_spirit::Value createmultisig(const json_spirit::Array ¶ms, bool fHelp)
bool HTTPAuthorized(map< string, string > &mapHeaders)
std::string itostr(int n)
const Object_type::value_type::Value_type & find_value(const Object_type &obj, const String_type &name)
json_spirit::Value getgenerate(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value addmultisigaddress(const json_spirit::Array ¶ms, bool fHelp)
Object JSONRPCReplyObj(const Value &result, const Value &error, const Value &id)
json_spirit::Value getaccount(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value listlockunspent(const json_spirit::Array ¶ms, bool fHelp)
CClientUIInterface uiInterface
void write(const Value &value, std::ostream &os)
void handshake(ssl::stream_base::handshake_type role)
void ErrorReply(std::ostream &stream, const Object &objError, const Value &id)
json_spirit::Value lockunspent(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value dumpprivkey(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value getconnectioncount(const json_spirit::Array ¶ms, bool fHelp)
const String_type & get_str() const
json_spirit::Value importprivkey(const json_spirit::Array ¶ms, bool fHelp)
std::string help(std::string name) const
Note: This interface may still be subject to change.
std::streamsize write(const char *s, std::streamsize n)
json_spirit::Value backupwallet(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value settxfee(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value verifymessage(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value validateaddress(const json_spirit::Array ¶ms, bool fHelp)
string HTTPPost(const string &strMsg, const map< string, string > &mapRequestHeaders)
json_spirit::Value getdifficulty(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value getrawmempool(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value getblocktemplate(const json_spirit::Array ¶ms, bool fHelp)
std::string HexBits(unsigned int nBits)
json_spirit::Value getcheckpoint(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value getblock(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value setgenerate(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value addnode(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value getpeerinfo(const json_spirit::Array ¶ms, bool fHelp)
bool ClientAllowed(const boost::asio::ip::address &address)
int main(int argc, char *argv[])
Value_type::String_type write_string(const Value_type &value, bool pretty)
json_spirit::Value(* rpcfn_type)(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value sendrawtransaction(const json_spirit::Array ¶ms, bool fHelp)
bool IsSwitchChar(char c)
Value ValueFromAmount(int64 amount)
json_spirit::Value getnetworkhashps(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value getnewaddress(const json_spirit::Array ¶ms, bool fHelp)
string FormatFullVersion()
bool WildcardMatch(const char *psz, const char *mask)
json_spirit::Value sendcheckpoint(const json_spirit::Array ¶ms, bool fHelp)
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a boost::optional result...
json_spirit::Value movecmd(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value verifychain(const json_spirit::Array ¶ms, bool fHelp)
void ConvertTo(Value &value, bool fAllowNull=false)
virtual std::iostream & stream()=0
void parse(const Value &valRequest)
json_spirit::Value submitblock(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value gettxoutsetinfo(const json_spirit::Array ¶ms, bool fHelp)
bool TimingResistantEqual(const T &a, const T &b)
Timing-attack-resistant comparison.
json_spirit::Value setaccount(const json_spirit::Array ¶ms, 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.
json_spirit::Value getmininginfo(const json_spirit::Array ¶ms, bool fHelp)
std::string EncodeBase58(const unsigned char *pbegin, const unsigned char *pend)
json_spirit::Value setmininput(const json_spirit::Array ¶ms, bool fHelp)
SSLIOStreamDevice(asio::ssl::stream< typename Protocol::socket > &streamIn, bool fUseSSLIn)
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Return string argument or default value.
json_spirit::Value getblockhash(const json_spirit::Array ¶ms, bool fHelp)
vector< unsigned char > DecodeBase64(const char *p, bool *pfInvalid)
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
std::string get_str(std::string::const_iterator begin, std::string::const_iterator end)
json_spirit::Value getreceivedbyaccount(const json_spirit::Array ¶ms, bool fHelp)
map< string, vector< string > > mapMultiArgs
int64 roundint64(double d)
json_spirit::Value getinfo(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value getaddednodeinfo(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value sendalert(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value listunspent(const json_spirit::Array ¶ms, bool fHelp)
bool connect(const std::string &server, const std::string &port)
bool MoneyRange(int64 nValue)
json_spirit::Value getwork(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value getreceivedbyaddress(const json_spirit::Array ¶ms, bool fHelp)
json_spirit::Value listsinceblock(const json_spirit::Array ¶ms, bool fHelp)
map< string, string > mapArgs
int atoi(const std::string &str)
void PrintException(std::exception *pex, const char *pszThread)
boost::filesystem::path GetConfigFile()