mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-13 11:25:02 -05:00
Merge pull request #1124 from sipa/rpcobj3
extension of #1103: encapsulate mapCommands in CRPCTable
This commit is contained in:
commit
457661f640
3 changed files with 129 additions and 105 deletions
|
@ -10,6 +10,7 @@
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "ui_interface.h"
|
#include "ui_interface.h"
|
||||||
|
#include "bitcoinrpc.h"
|
||||||
|
|
||||||
#undef printf
|
#undef printf
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
|
@ -22,9 +23,6 @@
|
||||||
#include <boost/filesystem/fstream.hpp>
|
#include <boost/filesystem/fstream.hpp>
|
||||||
typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> SSLStream;
|
typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> SSLStream;
|
||||||
|
|
||||||
#include "json/json_spirit_reader_template.h"
|
|
||||||
#include "json/json_spirit_writer_template.h"
|
|
||||||
#include "json/json_spirit_utils.h"
|
|
||||||
#define printf OutputDebugStringF
|
#define printf OutputDebugStringF
|
||||||
// MinGW 3.4.5 gets "fatal error: had to relocate PCH" if the json headers are
|
// MinGW 3.4.5 gets "fatal error: had to relocate PCH" if the json headers are
|
||||||
// precompiled in headers.h. The problem might be when the pch file goes over
|
// precompiled in headers.h. The problem might be when the pch file goes over
|
||||||
|
@ -37,8 +35,6 @@ using namespace boost::asio;
|
||||||
using namespace json_spirit;
|
using namespace json_spirit;
|
||||||
|
|
||||||
void ThreadRPCServer2(void* parg);
|
void ThreadRPCServer2(void* parg);
|
||||||
typedef Value(*rpcfn_type)(const Array& params, bool fHelp);
|
|
||||||
extern map<string, rpcfn_type> mapCallTable;
|
|
||||||
|
|
||||||
static std::string strRPCUserColonPass;
|
static std::string strRPCUserColonPass;
|
||||||
|
|
||||||
|
@ -168,23 +164,14 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex)
|
||||||
/// Note: This interface may still be subject to change.
|
/// Note: This interface may still be subject to change.
|
||||||
///
|
///
|
||||||
|
|
||||||
|
string CRPCTable::help(string strCommand) const
|
||||||
Value help(const Array& params, bool fHelp)
|
|
||||||
{
|
{
|
||||||
if (fHelp || params.size() > 1)
|
|
||||||
throw runtime_error(
|
|
||||||
"help [command]\n"
|
|
||||||
"List commands, or get help for a command.");
|
|
||||||
|
|
||||||
string strCommand;
|
|
||||||
if (params.size() > 0)
|
|
||||||
strCommand = params[0].get_str();
|
|
||||||
|
|
||||||
string strRet;
|
string strRet;
|
||||||
set<rpcfn_type> setDone;
|
set<rpcfn_type> setDone;
|
||||||
for (map<string, rpcfn_type>::iterator mi = mapCallTable.begin(); mi != mapCallTable.end(); ++mi)
|
for (map<string, const CRPCCommand*>::const_iterator mi = mapCommands.begin(); mi != mapCommands.end(); ++mi)
|
||||||
{
|
{
|
||||||
string strMethod = (*mi).first;
|
const CRPCCommand *pcmd = mi->second;
|
||||||
|
string strMethod = mi->first;
|
||||||
// We already filter duplicates, but these deprecated screw up the sort order
|
// We already filter duplicates, but these deprecated screw up the sort order
|
||||||
if (strMethod == "getamountreceived" ||
|
if (strMethod == "getamountreceived" ||
|
||||||
strMethod == "getallreceived" ||
|
strMethod == "getallreceived" ||
|
||||||
|
@ -196,7 +183,7 @@ Value help(const Array& params, bool fHelp)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Array params;
|
Array params;
|
||||||
rpcfn_type pfn = (*mi).second;
|
rpcfn_type pfn = pcmd->actor;
|
||||||
if (setDone.insert(pfn).second)
|
if (setDone.insert(pfn).second)
|
||||||
(*pfn)(params, true);
|
(*pfn)(params, true);
|
||||||
}
|
}
|
||||||
|
@ -216,6 +203,20 @@ Value help(const Array& params, bool fHelp)
|
||||||
return strRet;
|
return strRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value help(const Array& params, bool fHelp)
|
||||||
|
{
|
||||||
|
if (fHelp || params.size() > 1)
|
||||||
|
throw runtime_error(
|
||||||
|
"help [command]\n"
|
||||||
|
"List commands, or get help for a command.");
|
||||||
|
|
||||||
|
string strCommand;
|
||||||
|
if (params.size() > 0)
|
||||||
|
strCommand = params[0].get_str();
|
||||||
|
|
||||||
|
return tableRPC.help(strCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Value stop(const Array& params, bool fHelp)
|
Value stop(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
|
@ -2003,86 +2004,77 @@ Value getblock(const Array& params, bool fHelp)
|
||||||
// Call Table
|
// Call Table
|
||||||
//
|
//
|
||||||
|
|
||||||
pair<string, rpcfn_type> pCallTable[] =
|
|
||||||
{
|
static const CRPCCommand vRPCCommands[] =
|
||||||
make_pair("help", &help),
|
{ // name function safe mode?
|
||||||
make_pair("stop", &stop),
|
// ------------------------ ----------------------- ----------
|
||||||
make_pair("getblockcount", &getblockcount),
|
{ "help", &help, true },
|
||||||
make_pair("getblocknumber", &getblocknumber),
|
{ "stop", &stop, true },
|
||||||
make_pair("getconnectioncount", &getconnectioncount),
|
{ "getblockcount", &getblockcount, true },
|
||||||
make_pair("getdifficulty", &getdifficulty),
|
{ "getblocknumber", &getblocknumber, true },
|
||||||
make_pair("getgenerate", &getgenerate),
|
{ "getconnectioncount", &getconnectioncount, true },
|
||||||
make_pair("setgenerate", &setgenerate),
|
{ "getdifficulty", &getdifficulty, true },
|
||||||
make_pair("gethashespersec", &gethashespersec),
|
{ "getgenerate", &getgenerate, true },
|
||||||
make_pair("getinfo", &getinfo),
|
{ "setgenerate", &setgenerate, true },
|
||||||
make_pair("getmininginfo", &getmininginfo),
|
{ "gethashespersec", &gethashespersec, true },
|
||||||
make_pair("getnewaddress", &getnewaddress),
|
{ "getinfo", &getinfo, true },
|
||||||
make_pair("getaccountaddress", &getaccountaddress),
|
{ "getmininginfo", &getmininginfo, true },
|
||||||
make_pair("setaccount", &setaccount),
|
{ "getnewaddress", &getnewaddress, true },
|
||||||
make_pair("getaccount", &getaccount),
|
{ "getaccountaddress", &getaccountaddress, true },
|
||||||
make_pair("getaddressesbyaccount", &getaddressesbyaccount),
|
{ "setaccount", &setaccount, true },
|
||||||
make_pair("sendtoaddress", &sendtoaddress),
|
{ "getaccount", &getaccount, false },
|
||||||
make_pair("getreceivedbyaddress", &getreceivedbyaddress),
|
{ "getaddressesbyaccount", &getaddressesbyaccount, true },
|
||||||
make_pair("getreceivedbyaccount", &getreceivedbyaccount),
|
{ "sendtoaddress", &sendtoaddress, false },
|
||||||
make_pair("listreceivedbyaddress", &listreceivedbyaddress),
|
{ "getreceivedbyaddress", &getreceivedbyaddress, false },
|
||||||
make_pair("listreceivedbyaccount", &listreceivedbyaccount),
|
{ "getreceivedbyaccount", &getreceivedbyaccount, false },
|
||||||
make_pair("backupwallet", &backupwallet),
|
{ "listreceivedbyaddress", &listreceivedbyaddress, false },
|
||||||
make_pair("keypoolrefill", &keypoolrefill),
|
{ "listreceivedbyaccount", &listreceivedbyaccount, false },
|
||||||
make_pair("walletpassphrase", &walletpassphrase),
|
{ "backupwallet", &backupwallet, true },
|
||||||
make_pair("walletpassphrasechange", &walletpassphrasechange),
|
{ "keypoolrefill", &keypoolrefill, true },
|
||||||
make_pair("walletlock", &walletlock),
|
{ "walletpassphrase", &walletpassphrase, true },
|
||||||
make_pair("encryptwallet", &encryptwallet),
|
{ "walletpassphrasechange", &walletpassphrasechange, false },
|
||||||
make_pair("validateaddress", &validateaddress),
|
{ "walletlock", &walletlock, true },
|
||||||
make_pair("getbalance", &getbalance),
|
{ "encryptwallet", &encryptwallet, false },
|
||||||
make_pair("move", &movecmd),
|
{ "validateaddress", &validateaddress, true },
|
||||||
make_pair("sendfrom", &sendfrom),
|
{ "getbalance", &getbalance, false },
|
||||||
make_pair("sendmany", &sendmany),
|
{ "move", &movecmd, false },
|
||||||
make_pair("addmultisigaddress", &addmultisigaddress),
|
{ "sendfrom", &sendfrom, false },
|
||||||
make_pair("getblock", &getblock),
|
{ "sendmany", &sendmany, false },
|
||||||
make_pair("getblockhash", &getblockhash),
|
{ "addmultisigaddress", &addmultisigaddress, false },
|
||||||
make_pair("gettransaction", &gettransaction),
|
{ "getblock", &getblock, false },
|
||||||
make_pair("listtransactions", &listtransactions),
|
{ "getblockhash", &getblockhash, false },
|
||||||
make_pair("signmessage", &signmessage),
|
{ "gettransaction", &gettransaction, false },
|
||||||
make_pair("verifymessage", &verifymessage),
|
{ "listtransactions", &listtransactions, false },
|
||||||
make_pair("getwork", &getwork),
|
{ "signmessage", &signmessage, false },
|
||||||
make_pair("listaccounts", &listaccounts),
|
{ "verifymessage", &verifymessage, false },
|
||||||
make_pair("settxfee", &settxfee),
|
{ "getwork", &getwork, true },
|
||||||
make_pair("getmemorypool", &getmemorypool),
|
{ "listaccounts", &listaccounts, false },
|
||||||
make_pair("listsinceblock", &listsinceblock),
|
{ "settxfee", &settxfee, false },
|
||||||
make_pair("dumpprivkey", &dumpprivkey),
|
{ "getmemorypool", &getmemorypool, true },
|
||||||
make_pair("importprivkey", &importprivkey)
|
{ "listsinceblock", &listsinceblock, false },
|
||||||
|
{ "dumpprivkey", &dumpprivkey, false },
|
||||||
|
{ "importprivkey", &importprivkey, false },
|
||||||
};
|
};
|
||||||
map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0]));
|
|
||||||
|
|
||||||
string pAllowInSafeMode[] =
|
CRPCTable::CRPCTable()
|
||||||
{
|
{
|
||||||
"help",
|
unsigned int vcidx;
|
||||||
"stop",
|
for (vcidx = 0; vcidx < (sizeof(vRPCCommands) / sizeof(vRPCCommands[0])); vcidx++)
|
||||||
"getblockcount",
|
{
|
||||||
"getblocknumber", // deprecated
|
const CRPCCommand *pcmd;
|
||||||
"getconnectioncount",
|
|
||||||
"getdifficulty",
|
|
||||||
"getgenerate",
|
|
||||||
"setgenerate",
|
|
||||||
"gethashespersec",
|
|
||||||
"getinfo",
|
|
||||||
"getmininginfo",
|
|
||||||
"getnewaddress",
|
|
||||||
"getaccountaddress",
|
|
||||||
"getaccount",
|
|
||||||
"getaddressesbyaccount",
|
|
||||||
"backupwallet",
|
|
||||||
"keypoolrefill",
|
|
||||||
"walletpassphrase",
|
|
||||||
"walletlock",
|
|
||||||
"validateaddress",
|
|
||||||
"getwork",
|
|
||||||
"getmemorypool",
|
|
||||||
};
|
|
||||||
set<string> setAllowInSafeMode(pAllowInSafeMode, pAllowInSafeMode + sizeof(pAllowInSafeMode)/sizeof(pAllowInSafeMode[0]));
|
|
||||||
|
|
||||||
|
|
||||||
|
pcmd = &vRPCCommands[vcidx];
|
||||||
|
mapCommands[pcmd->name] = pcmd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const CRPCCommand *CRPCTable::operator[](string name) const
|
||||||
|
{
|
||||||
|
map<string, const CRPCCommand*>::const_iterator it = mapCommands.find(name);
|
||||||
|
if (it == mapCommands.end())
|
||||||
|
return NULL;
|
||||||
|
return (*it).second;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// HTTP protocol
|
// HTTP protocol
|
||||||
|
@ -2513,13 +2505,14 @@ void ThreadRPCServer2(void* parg)
|
||||||
throw JSONRPCError(-32600, "Params must be an array");
|
throw JSONRPCError(-32600, "Params must be an array");
|
||||||
|
|
||||||
// Find method
|
// Find method
|
||||||
map<string, rpcfn_type>::iterator mi = mapCallTable.find(strMethod);
|
const CRPCCommand *pcmd = tableRPC[strMethod];
|
||||||
if (mi == mapCallTable.end())
|
if (!pcmd)
|
||||||
throw JSONRPCError(-32601, "Method not found");
|
throw JSONRPCError(-32601, "Method not found");
|
||||||
|
|
||||||
// Observe safe mode
|
// Observe safe mode
|
||||||
string strWarning = GetWarnings("rpc");
|
string strWarning = GetWarnings("rpc");
|
||||||
if (strWarning != "" && !GetBoolArg("-disablesafemode") && !setAllowInSafeMode.count(strMethod))
|
if (strWarning != "" && !GetBoolArg("-disablesafemode") &&
|
||||||
|
!pcmd->okSafeMode)
|
||||||
throw JSONRPCError(-2, string("Safe mode: ") + strWarning);
|
throw JSONRPCError(-2, string("Safe mode: ") + strWarning);
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -2528,7 +2521,7 @@ void ThreadRPCServer2(void* parg)
|
||||||
Value result;
|
Value result;
|
||||||
{
|
{
|
||||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
result = (*(*mi).second)(params, false);
|
result = pcmd->actor(params, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send reply
|
// Send reply
|
||||||
|
@ -2769,3 +2762,5 @@ int main(int argc, char *argv[])
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
const CRPCTable tableRPC;
|
||||||
|
|
|
@ -3,5 +3,39 @@
|
||||||
// Distributed under the MIT/X11 software license, see the accompanying
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#ifndef _BITCOINRPC_H_
|
||||||
|
#define _BITCOINRPC_H_ 1
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "json/json_spirit_reader_template.h"
|
||||||
|
#include "json/json_spirit_writer_template.h"
|
||||||
|
#include "json/json_spirit_utils.h"
|
||||||
|
|
||||||
void ThreadRPCServer(void* parg);
|
void ThreadRPCServer(void* parg);
|
||||||
int CommandLineRPC(int argc, char *argv[]);
|
int CommandLineRPC(int argc, char *argv[]);
|
||||||
|
|
||||||
|
typedef json_spirit::Value(*rpcfn_type)(const json_spirit::Array& params, bool fHelp);
|
||||||
|
|
||||||
|
class CRPCCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string name;
|
||||||
|
rpcfn_type actor;
|
||||||
|
bool okSafeMode;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CRPCTable
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::map<std::string, const CRPCCommand*> mapCommands;
|
||||||
|
public:
|
||||||
|
CRPCTable();
|
||||||
|
const CRPCCommand* operator[](std::string name) const;
|
||||||
|
std::string help(std::string name) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const CRPCTable tableRPC;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -3,16 +3,11 @@
|
||||||
|
|
||||||
#include "base58.h"
|
#include "base58.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "json/json_spirit_reader_template.h"
|
#include "bitcoinrpc.h"
|
||||||
#include "json/json_spirit_writer_template.h"
|
|
||||||
#include "json/json_spirit_utils.h"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace json_spirit;
|
using namespace json_spirit;
|
||||||
|
|
||||||
typedef Value(*rpcfn_type)(const Array& params, bool fHelp);
|
|
||||||
extern map<string, rpcfn_type> mapCallTable;
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE(rpc_tests)
|
BOOST_AUTO_TEST_SUITE(rpc_tests)
|
||||||
|
|
||||||
static Array
|
static Array
|
||||||
|
@ -36,7 +31,7 @@ struct TestNetFixture
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_CASE(rpc_addmultisig, TestNetFixture)
|
BOOST_FIXTURE_TEST_CASE(rpc_addmultisig, TestNetFixture)
|
||||||
{
|
{
|
||||||
rpcfn_type addmultisig = mapCallTable["addmultisigaddress"];
|
rpcfn_type addmultisig = tableRPC["addmultisigaddress"]->actor;
|
||||||
|
|
||||||
// old, 65-byte-long:
|
// old, 65-byte-long:
|
||||||
const char* address1Hex = "0434e3e09f49ea168c5bbf53f877ff4206923858aab7c7e1df25bc263978107c95e35065a27ef6f1b27222db0ec97e0e895eaca603d3ee0d4c060ce3d8a00286c8";
|
const char* address1Hex = "0434e3e09f49ea168c5bbf53f877ff4206923858aab7c7e1df25bc263978107c95e35065a27ef6f1b27222db0ec97e0e895eaca603d3ee0d4c060ce3d8a00286c8";
|
||||||
|
|
Loading…
Add table
Reference in a new issue