Auto merge of #4280 - oxarbitrage:issue2197, r=daira
Allow negative heights in RPC calls For issue https://github.com/zcash/zcash/issues/2197 Currently adding the feature to `getblock` and `getblockhash`. There is another candidate: `getblocksubsidy` however i want to have some review about these 2 first before repeating what could be a bad approach.
This commit is contained in:
commit
6c00a8ccf9
|
@ -95,5 +95,21 @@ class MerkleBlockTest(BitcoinTestFramework):
|
|||
result = self.nodes[0].getblock(blockhash, 0)
|
||||
assert(c in string.hexdigits for c in result) # verbosity 0 returns raw hex
|
||||
|
||||
# Test getblock heights including negatives relative to the head
|
||||
assert_equal(self.nodes[0].getblock("0")["height"], 0)
|
||||
assert_raises(JSONRPCException, self.nodes[0].getblock, ["108"])
|
||||
assert_equal(self.nodes[0].getblock("107")["height"], 107)
|
||||
assert_equal(self.nodes[0].getblock("-1")["height"], 107)
|
||||
assert_equal(self.nodes[0].getblock("-2")["height"], 106)
|
||||
assert_equal(self.nodes[0].getblock("-20")["height"], 88)
|
||||
assert_equal(self.nodes[0].getblock("-107")["height"], 1)
|
||||
assert_equal(self.nodes[0].getblock("-108")["height"], 0)
|
||||
assert_raises(JSONRPCException, self.nodes[0].getblock, ["-109"])
|
||||
assert_raises(JSONRPCException, self.nodes[0].getblock, ["-0"])
|
||||
|
||||
# Test getblockhash negative heights
|
||||
assert_equal(self.nodes[0].getblockhash(-1), self.nodes[0].getblockhash(107))
|
||||
assert_equal(self.nodes[0].getblockhash(-2), self.nodes[0].getblockhash(106))
|
||||
|
||||
if __name__ == '__main__':
|
||||
MerkleBlockTest().main()
|
||||
|
|
|
@ -578,7 +578,7 @@ UniValue getblockhash(const UniValue& params, bool fHelp)
|
|||
"getblockhash index\n"
|
||||
"\nReturns hash of block in best-block-chain at index provided.\n"
|
||||
"\nArguments:\n"
|
||||
"1. index (numeric, required) The block index\n"
|
||||
"1. index (numeric, required) The block index. If negative then -1 is the last known valid block\n"
|
||||
"\nResult:\n"
|
||||
"\"hash\" (string) The block hash\n"
|
||||
"\nExamples:\n"
|
||||
|
@ -589,6 +589,11 @@ UniValue getblockhash(const UniValue& params, bool fHelp)
|
|||
LOCK(cs_main);
|
||||
|
||||
int nHeight = params[0].get_int();
|
||||
|
||||
if (nHeight < 0) {
|
||||
nHeight += chainActive.Height() + 1;
|
||||
}
|
||||
|
||||
if (nHeight < 0 || nHeight > chainActive.Height())
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
|
||||
|
||||
|
@ -662,7 +667,7 @@ UniValue getblock(const UniValue& params, bool fHelp)
|
|||
"If verbosity is 1, returns an Object with information about the block.\n"
|
||||
"If verbosity is 2, returns an Object with information about the block and information about each transaction. \n"
|
||||
"\nArguments:\n"
|
||||
"1. \"hash|height\" (string, required) The block hash or height\n"
|
||||
"1. \"hash|height\" (string, required) The block hash or height. Height can be negative where -1 is the last known valid block\n"
|
||||
"2. verbosity (numeric, optional, default=1) 0 for hex encoded data, 1 for a json object, and 2 for json object with transaction data\n"
|
||||
"\nResult (for verbosity = 0):\n"
|
||||
"\"data\" (string) A string that is serialized, hex-encoded data for the block.\n"
|
||||
|
@ -708,7 +713,7 @@ UniValue getblock(const UniValue& params, bool fHelp)
|
|||
// 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:]]+");
|
||||
regex r("(?:(-?)[1-9][0-9]*|[0-9]+)");
|
||||
if (!regex_match(strHash, r)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block height parameter");
|
||||
}
|
||||
|
@ -721,9 +726,14 @@ UniValue getblock(const UniValue& params, bool fHelp)
|
|||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block height parameter");
|
||||
}
|
||||
|
||||
if (nHeight < 0) {
|
||||
nHeight += chainActive.Height() + 1;
|
||||
}
|
||||
|
||||
if (nHeight < 0 || nHeight > chainActive.Height()) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
|
||||
}
|
||||
|
||||
strHash = chainActive[nHeight]->GetBlockHash().GetHex();
|
||||
}
|
||||
|
||||
|
|
|
@ -310,7 +310,8 @@ BOOST_AUTO_TEST_CASE(rpc_wallet)
|
|||
* getblock
|
||||
*/
|
||||
BOOST_CHECK_THROW(CallRPC("getblock too many args"), runtime_error);
|
||||
BOOST_CHECK_THROW(CallRPC("getblock -1"), runtime_error);
|
||||
BOOST_CHECK_NO_THROW(CallRPC("getblock -1")); // negative heights relative are allowed
|
||||
BOOST_CHECK_THROW(CallRPC("getblock -2147483647"), runtime_error); // allowed, but chain tip - height < 0
|
||||
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);
|
||||
|
|
Loading…
Reference in New Issue