Skip to content

Commit

Permalink
Merge pull request bitcoin#3266 from PastaPastaPasta/backports-0.16-p…
Browse files Browse the repository at this point in the history
…r1-rpc

Backports 0.16 pr1-3: rpc
  • Loading branch information
UdjinM6 committed Jan 3, 2020
2 parents 1da2ac5 + 50ea6c7 commit 4b7c175
Show file tree
Hide file tree
Showing 25 changed files with 470 additions and 324 deletions.
10 changes: 4 additions & 6 deletions doc/developer-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -589,16 +589,14 @@ A few guidelines for introducing and reviewing new RPC interfaces:
is specified as-is in BIP22.

- Missing arguments and 'null' should be treated the same: as default values. If there is no
default value, both cases should fail in the same way.
default value, both cases should fail in the same way. The easiest way to follow this
guideline is detect unspecified arguments with `params[x].isNull()` instead of
`params.size() <= x`. The former returns true if the argument is either null or missing,
while the latter returns true if is missing, and false if it is null.

- *Rationale*: Avoids surprises when switching to name-based arguments. Missing name-based arguments
are passed as 'null'.

- *Exception*: Many legacy exceptions to this exist, one of the worst ones is
`getbalance` which follows a completely different code path based on the
number of arguments. We are still in the process of cleaning these up. Do not introduce
new ones.

- Try not to overload methods on argument type. E.g. don't make `getblock(true)` and `getblock("hash")`
do different things.

Expand Down
2 changes: 2 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ BITCOIN_CORE_H = \
rpc/client.h \
rpc/mining.h \
rpc/protocol.h \
rpc/safemode.h \
rpc/server.h \
rpc/register.h \
saltedhasher.h \
Expand Down Expand Up @@ -337,6 +338,7 @@ libdash_server_a_SOURCES = \
rpc/rawtransaction.cpp \
rpc/rpcevo.cpp \
rpc/rpcquorums.cpp \
rpc/safemode.cpp \
rpc/server.cpp \
rpc/privatesend.cpp \
script/sigcache.cpp \
Expand Down
20 changes: 15 additions & 5 deletions src/dash-cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ std::string HelpMessageCli()
strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections"));
strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
strUsage += HelpMessageOpt("-rpcclienttimeout=<n>", strprintf(_("Timeout in seconds during HTTP requests, or 0 for no timeout. (default: %d)"), DEFAULT_HTTP_CLIENT_TIMEOUT));
strUsage += HelpMessageOpt("-stdin", _("Read extra arguments from standard input, one per line until EOF/Ctrl-D (recommended for sensitive information such as passphrases)"));
strUsage += HelpMessageOpt("-stdinrpcpass", strprintf(_("Read RPC password from standard input as a single line. When combined with -stdin, the first line from standard input is used for the RPC password.")));
strUsage += HelpMessageOpt("-stdin", _("Read extra arguments from standard input, one per line until EOF/Ctrl-D (recommended for sensitive information such as passphrases). When combined with -stdinrpcpass, the first line from standard input is used for the RPC password."));
strUsage += HelpMessageOpt("-rpcwallet=<walletname>", _("Send RPC for non-default wallet on RPC server (argument is wallet filename in dashd directory, required if dashd/-Qt runs with multiple wallets)"));

return strUsage;
Expand Down Expand Up @@ -203,7 +204,7 @@ static void http_error_cb(enum evhttp_request_error err, void *ctx)
}
#endif

UniValue CallRPC(const std::string& strMethod, const UniValue& params)
static UniValue CallRPC(const std::string& strMethod, const UniValue& params)
{
std::string host;
// In preference order, we choose the following for the port:
Expand Down Expand Up @@ -235,7 +236,7 @@ UniValue CallRPC(const std::string& strMethod, const UniValue& params)
// Try fall back to cookie-based authentication if no password is provided
if (!GetAuthCookie(&strRPCUserColonPass)) {
throw std::runtime_error(strprintf(
_("Could not locate RPC credentials. No authentication cookie could be found, and no rpcpassword is set in the configuration file (%s)"),
_("Could not locate RPC credentials. No authentication cookie could be found, and RPC password is not set. See -rpcpassword and -stdinrpcpass. Configuration file: (%s)"),
GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)).string().c_str()));

}
Expand Down Expand Up @@ -306,15 +307,24 @@ int CommandLineRPC(int argc, char *argv[])
argc--;
argv++;
}
std::string rpcPass;
if (gArgs.GetBoolArg("-stdinrpcpass", false)) {
if (!std::getline(std::cin, rpcPass)) {
throw std::runtime_error("-stdinrpcpass specified but failed to read from standard input");
}
gArgs.ForceSetArg("-rpcpassword", rpcPass);
}
std::vector<std::string> args = std::vector<std::string>(&argv[1], &argv[argc]);
if (gArgs.GetBoolArg("-stdin", false)) {
// Read one arg per line from stdin and append
std::string line;
while (std::getline(std::cin,line))
while (std::getline(std::cin, line)) {
args.push_back(line);
}
}
if (args.size() < 1)
if (args.size() < 1) {
throw std::runtime_error("too few parameters (need at least command)");
}
std::string strMethod = args[0];
args.erase(args.begin()); // Remove trailing method name from arguments vector

Expand Down
12 changes: 1 addition & 11 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "policy/policy.h"
#include "rpc/server.h"
#include "rpc/register.h"
#include "rpc/safemode.h"
#include "rpc/blockchain.h"
#include "script/standard.h"
#include "script/sigcache.h"
Expand Down Expand Up @@ -98,7 +99,6 @@
bool fFeeEstimatesInitialized = false;
static const bool DEFAULT_PROXYRANDOMIZE = true;
static const bool DEFAULT_REST_ENABLE = false;
static const bool DEFAULT_DISABLE_SAFEMODE = true;
static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false;


Expand Down Expand Up @@ -418,15 +418,6 @@ void OnRPCStopped()
LogPrint(BCLog::RPC, "RPC stopped.\n");
}

void OnRPCPreCommand(const CRPCCommand& cmd)
{
// Observe safe mode
std::string strWarning = GetWarnings("rpc");
if (strWarning != "" && !gArgs.GetBoolArg("-disablesafemode", DEFAULT_DISABLE_SAFEMODE) &&
!cmd.okSafeMode)
throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, std::string("Safe mode: ") + strWarning);
}

std::string HelpMessage(HelpMessageMode mode)
{
const auto defaultBaseParams = CreateBaseChainParams(CBaseChainParams::MAIN);
Expand Down Expand Up @@ -894,7 +885,6 @@ bool AppInitServers(boost::thread_group& threadGroup)
{
RPCServer::OnStarted(&OnRPCStarted);
RPCServer::OnStopped(&OnRPCStopped);
RPCServer::OnPreCommand(&OnRPCPreCommand);
if (!InitHTTPServer())
return false;
if (!StartRPC())
Expand Down
2 changes: 1 addition & 1 deletion src/qt/test/rpcnestedtests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ static UniValue rpcNestedTest_rpc(const JSONRPCRequest& request)

static const CRPCCommand vRPCCommands[] =
{
{ "test", "rpcNestedTest", &rpcNestedTest_rpc, true, {} },
{ "test", "rpcNestedTest", &rpcNestedTest_rpc, {} },
};

void RPCNestedTests::rpcNestedTests()
Expand Down
108 changes: 64 additions & 44 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -826,14 +826,14 @@ UniValue getblockheaders(const JSONRPCRequest& request)
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");

int nCount = MAX_HEADERS_RESULTS;
if (request.params.size() > 1)
if (!request.params[1].isNull())
nCount = request.params[1].get_int();

if (nCount <= 0 || nCount > (int)MAX_HEADERS_RESULTS)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Count is out of range");

bool fVerbose = true;
if (request.params.size() > 2)
if (!request.params[2].isNull())
fVerbose = request.params[2].get_bool();

CBlockIndex* pblockindex = mapBlockIndex[hash];
Expand Down Expand Up @@ -923,7 +923,7 @@ UniValue getmerkleblocks(const JSONRPCRequest& request)
}

int nCount = MAX_HEADERS_RESULTS;
if (request.params.size() > 2)
if (!request.params[2].isNull())
nCount = request.params[2].get_int();

if (nCount <= 0 || nCount > (int)MAX_HEADERS_RESULTS) {
Expand Down Expand Up @@ -1565,10 +1565,10 @@ UniValue getchaintips(const JSONRPCRequest& request)
int nBranchMin = -1;
int nCountMax = INT_MAX;

if(request.params.size() >= 1)
if(!request.params[0].isNull())
nCountMax = request.params[0].get_int();

if(request.params.size() == 2)
if(!request.params[1].isNull())
nBranchMin = request.params[1].get_int();

/* Construct the output array. */
Expand Down Expand Up @@ -1790,11 +1790,11 @@ UniValue getchaintxstats(const JSONRPCRequest& request)
const CBlockIndex* pindex;
int blockcount = 30 * 24 * 60 * 60 / Params().GetConsensus().nPowTargetSpacing; // By default: 1 month

if (request.params.size() > 0 && !request.params[0].isNull()) {
if (!request.params[0].isNull()) {
blockcount = request.params[0].get_int();
}

bool havehash = request.params.size() > 1 && !request.params[1].isNull();
bool havehash = !request.params[1].isNull();
uint256 hash;
if (havehash) {
hash = uint256S(request.params[1].get_str());
Expand Down Expand Up @@ -2123,26 +2123,26 @@ UniValue getspecialtxes(const JSONRPCRequest& request)
uint256 hash(uint256S(strHash));

int nTxType = -1;
if (request.params.size() > 1) {
if (!request.params[1].isNull()) {
nTxType = request.params[1].get_int();
}

int nCount = 10;
if (request.params.size() > 2) {
if (!request.params[2].isNull()) {
nCount = request.params[2].get_int();
if (nCount < 0)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count");
}

int nSkip = 0;
if (request.params.size() > 3) {
if (!request.params[3].isNull()) {
nSkip = request.params[3].get_int();
if (nSkip < 0)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative skip");
}

int nVerbosity = 0;
if (request.params.size() > 4) {
if (!request.params[4].isNull()) {
nVerbosity = request.params[4].get_int();
if (nVerbosity < 0 || nVerbosity > 2) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Verbosity must be in range 0..2");
Expand Down Expand Up @@ -2186,42 +2186,62 @@ UniValue getspecialtxes(const JSONRPCRequest& request)
return result;
}

UniValue savemempool(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() != 0) {
throw std::runtime_error(
"savemempool\n"
"\nDumps the mempool to disk.\n"
"\nExamples:\n"
+ HelpExampleCli("savemempool", "")
+ HelpExampleRpc("savemempool", "")
);
}

if (!DumpMempool()) {
throw JSONRPCError(RPC_MISC_ERROR, "Unable to dump mempool to disk");
}

return NullUniValue;
}

static const CRPCCommand commands[] =
{ // category name actor (function) okSafe argNames
// --------------------- ------------------------ ----------------------- ------ ----------
{ "blockchain", "getblockchaininfo", &getblockchaininfo, true, {} },
{ "blockchain", "getchaintxstats", &getchaintxstats, true, {"nblocks", "blockhash"} },
{ "blockchain", "getblockstats", &getblockstats, true, {"hash_or_height", "stats"} },
{ "blockchain", "getbestblockhash", &getbestblockhash, true, {} },
{ "blockchain", "getbestchainlock", &getbestchainlock, true, {} },
{ "blockchain", "getblockcount", &getblockcount, true, {} },
{ "blockchain", "getblock", &getblock, true, {"blockhash","verbosity|verbose"} },
{ "blockchain", "getblockhashes", &getblockhashes, true, {"high","low"} },
{ "blockchain", "getblockhash", &getblockhash, true, {"height"} },
{ "blockchain", "getblockheader", &getblockheader, true, {"blockhash","verbose"} },
{ "blockchain", "getblockheaders", &getblockheaders, true, {"blockhash","count","verbose"} },
{ "blockchain", "getmerkleblocks", &getmerkleblocks, true, {"filter","blockhash","count"} },
{ "blockchain", "getchaintips", &getchaintips, true, {"count","branchlen"} },
{ "blockchain", "getdifficulty", &getdifficulty, true, {} },
{ "blockchain", "getmempoolancestors", &getmempoolancestors, true, {"txid","verbose"} },
{ "blockchain", "getmempooldescendants", &getmempooldescendants, true, {"txid","verbose"} },
{ "blockchain", "getmempoolentry", &getmempoolentry, true, {"txid"} },
{ "blockchain", "getmempoolinfo", &getmempoolinfo, true, {} },
{ "blockchain", "getrawmempool", &getrawmempool, true, {"verbose"} },
{ "blockchain", "getspecialtxes", &getspecialtxes, true, {"blockhash", "type", "count", "skip", "verbosity"} },
{ "blockchain", "gettxout", &gettxout, true, {"txid","n","include_mempool"} },
{ "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, {} },
{ "blockchain", "pruneblockchain", &pruneblockchain, true, {"height"} },
{ "blockchain", "verifychain", &verifychain, true, {"checklevel","nblocks"} },

{ "blockchain", "preciousblock", &preciousblock, true, {"blockhash"} },
{ // category name actor (function) argNames
// --------------------- ------------------------ ----------------------- ----------
{ "blockchain", "getblockchaininfo", &getblockchaininfo, {} },
{ "blockchain", "getchaintxstats", &getchaintxstats, {"nblocks", "blockhash"} },
{ "blockchain", "getblockstats", &getblockstats, {"hash_or_height", "stats"} },
{ "blockchain", "getbestblockhash", &getbestblockhash, {} },
{ "blockchain", "getbestchainlock", &getbestchainlock, {} },
{ "blockchain", "getblockcount", &getblockcount, {} },
{ "blockchain", "getblock", &getblock, {"blockhash","verbosity|verbose"} },
{ "blockchain", "getblockhashes", &getblockhashes, {"high","low"} },
{ "blockchain", "getblockhash", &getblockhash, {"height"} },
{ "blockchain", "getblockheader", &getblockheader, {"blockhash","verbose"} },
{ "blockchain", "getblockheaders", &getblockheaders, {"blockhash","count","verbose"} },
{ "blockchain", "getmerkleblocks", &getmerkleblocks, {"filter","blockhash","count"} },
{ "blockchain", "getchaintips", &getchaintips, {"count","branchlen"} },
{ "blockchain", "getdifficulty", &getdifficulty, {} },
{ "blockchain", "getmempoolancestors", &getmempoolancestors, {"txid","verbose"} },
{ "blockchain", "getmempooldescendants", &getmempooldescendants, {"txid","verbose"} },
{ "blockchain", "getmempoolentry", &getmempoolentry, {"txid"} },
{ "blockchain", "getmempoolinfo", &getmempoolinfo, {} },
{ "blockchain", "getrawmempool", &getrawmempool, {"verbose"} },
{ "blockchain", "getspecialtxes", &getspecialtxes, {"blockhash", "type", "count", "skip", "verbosity"} },
{ "blockchain", "gettxout", &gettxout, {"txid","n","include_mempool"} },
{ "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, {} },
{ "blockchain", "pruneblockchain", &pruneblockchain, {"height"} },
{ "blockchain", "savemempool", &savemempool, {} },
{ "blockchain", "verifychain", &verifychain, {"checklevel","nblocks"} },

{ "blockchain", "preciousblock", &preciousblock, {"blockhash"} },

/* Not shown in help */
{ "hidden", "invalidateblock", &invalidateblock, true, {"blockhash"} },
{ "hidden", "reconsiderblock", &reconsiderblock, true, {"blockhash"} },
{ "hidden", "waitfornewblock", &waitfornewblock, true, {"timeout"} },
{ "hidden", "waitforblock", &waitforblock, true, {"blockhash","timeout"} },
{ "hidden", "waitforblockheight", &waitforblockheight, true, {"height","timeout"} },
{ "hidden", "invalidateblock", &invalidateblock, {"blockhash"} },
{ "hidden", "reconsiderblock", &reconsiderblock, {"blockhash"} },
{ "hidden", "waitfornewblock", &waitfornewblock, {"timeout"} },
{ "hidden", "waitforblock", &waitforblock, {"blockhash","timeout"} },
{ "hidden", "waitforblockheight", &waitforblockheight, {"height","timeout"} },
};

void RegisterBlockchainRPCCommands(CRPCTable &t)
Expand Down
Loading

0 comments on commit 4b7c175

Please sign in to comment.