Skip to content

Commit

Permalink
Auto merge of #2187 - bitcartel:1.0.7_getblock_by_height, r=bitcartel
Browse files Browse the repository at this point in the history
Closes #2186. RPC getblock now accepts height or hash.
  • Loading branch information
zkbot committed Mar 24, 2017
2 parents 7d9bf65 + 7d3b152 commit 23f792c
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 7 deletions.
41 changes: 34 additions & 7 deletions src/rpcblockchain.cpp
Expand Up @@ -15,6 +15,8 @@

#include <univalue.h>

#include <regex>

using namespace std;

extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
Expand Down Expand Up @@ -367,18 +369,18 @@ UniValue getblock(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
"getblock \"hash\" ( verbose )\n"
"\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
"If verbose is true, returns an Object with information about block <hash>.\n"
"getblock \"hash|height\" ( verbose )\n"
"\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash|height'.\n"
"If verbose is true, returns an Object with information about block <hash|height>.\n"
"\nArguments:\n"
"1. \"hash\" (string, required) The block hash\n"
"1. \"hash|height\" (string, required) The block hash or height\n"
"2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
"\nResult (for verbose = true):\n"
"{\n"
" \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
" \"hash\" : \"hash\", (string) the block hash (same as provided hash)\n"
" \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
" \"size\" : n, (numeric) The block size\n"
" \"height\" : n, (numeric) The block height or index\n"
" \"height\" : n, (numeric) The block height or index (same as provided height)\n"
" \"version\" : n, (numeric) The block version\n"
" \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
" \"tx\" : [ (array of string) The transaction ids\n"
Expand All @@ -387,7 +389,7 @@ UniValue getblock(const UniValue& params, bool fHelp)
" ],\n"
" \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
" \"nonce\" : n, (numeric) The nonce\n"
" \"bits\" : \"1d00ffff\", (string) The bits\n"
" \"bits\" : \"1d00ffff\", (string) The bits\n"
" \"difficulty\" : x.xxx, (numeric) The difficulty\n"
" \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
" \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
Expand All @@ -397,11 +399,36 @@ UniValue getblock(const UniValue& params, bool fHelp)
"\nExamples:\n"
+ HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
+ HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
+ HelpExampleCli("getblock", "12800")
+ HelpExampleRpc("getblock", "12800")
);

LOCK(cs_main);

std::string strHash = params[0].get_str();

// If height is supplied, find the hash
if (strHash.size() < (2 * sizeof(uint256))) {
// std::stoi allows characters, whereas we want to be strict
regex r("[[:digit:]]+");
if (!regex_match(strHash, r)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block height parameter");
}

int nHeight = -1;
try {
nHeight = std::stoi(strHash);
}
catch (const std::exception &e) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block height parameter");
}

if (nHeight < 0 || nHeight > chainActive.Height()) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
}
strHash = chainActive[nHeight]->GetBlockHash().GetHex();
}

uint256 hash(uint256S(strHash));

bool fVerbose = true;
Expand Down
10 changes: 10 additions & 0 deletions src/test/rpc_wallet_tests.cpp
Expand Up @@ -271,6 +271,16 @@ BOOST_AUTO_TEST_CASE(rpc_wallet)
obj = retValue.get_obj();
BOOST_CHECK_EQUAL(find_value(obj, "miner").get_real(), 3.125);
BOOST_CHECK_EQUAL(find_value(obj, "founders").get_real(), 0.0);

/*
* getblock
*/
BOOST_CHECK_THROW(CallRPC("getblock too many args"), runtime_error);
BOOST_CHECK_THROW(CallRPC("getblock -1"), runtime_error);
BOOST_CHECK_THROW(CallRPC("getblock 2147483647"), runtime_error); // allowed, but > height of active chain tip
BOOST_CHECK_THROW(CallRPC("getblock 2147483648"), runtime_error); // not allowed, > int32 used for nHeight
BOOST_CHECK_THROW(CallRPC("getblock 100badchars"), runtime_error);
BOOST_CHECK_NO_THROW(CallRPC("getblock 0"));
}

BOOST_AUTO_TEST_CASE(rpc_wallet_getbalance)
Expand Down

0 comments on commit 23f792c

Please sign in to comment.