From 3ac6dd5f5d3402d3738b6409f091f89c2490e640 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Tue, 31 Dec 2019 09:16:29 -0300 Subject: [PATCH] add negative height to getblock --- qa/rpc-tests/merkle_blocks.py | 9 +++++++++ src/rpc/blockchain.cpp | 9 +++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/merkle_blocks.py b/qa/rpc-tests/merkle_blocks.py index d9fec26f2..53acfe6ed 100755 --- a/qa/rpc-tests/merkle_blocks.py +++ b/qa/rpc-tests/merkle_blocks.py @@ -97,5 +97,14 @@ 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("106")["height"], 106) + assert_equal(self.nodes[0].getblock("-20")["height"], 87) + assert_equal(self.nodes[0].getblock("-107")["height"], 0) + assert_raises(JSONRPCException, self.nodes[0].getblock, ["-108"]) + if __name__ == '__main__': MerkleBlockTest().main() diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 0f6c6c760..387f58153 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -660,7 +660,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, relative to the head.\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" @@ -706,7 +706,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("-?[[:digit:]]+"); if (!regex_match(strHash, r)) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block height parameter"); } @@ -719,9 +719,14 @@ UniValue getblock(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block height parameter"); } + if(nHeight < 0) { + nHeight += chainActive.Height(); + } + if (nHeight < 0 || nHeight > chainActive.Height()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); } + strHash = chainActive[nHeight]->GetBlockHash().GetHex(); }