Auto merge of #3179 - bitcartel:backport_transaction_details_in_getblock_v2bitcartel, r=str4d

Add improvements to getblock RPC output

Includes and supercedes #3095. Includes code cherry-picked from bitcoin/bitcoin#8704.
This commit is contained in:
Homu 2018-05-01 10:19:10 -07:00
commit 53fa6f1315
3 changed files with 47 additions and 15 deletions

View File

@ -7,6 +7,7 @@
# Test merkleblock fetch/validation
#
import string
from test_framework.test_framework import BitcoinTestFramework
from test_framework.authproxy import JSONRPCException
from test_framework.util import assert_equal, assert_raises, \
@ -86,5 +87,13 @@ class MerkleBlockTest(BitcoinTestFramework):
# ...or if we have a -txindex
assert_equal(self.nodes[2].verifytxoutproof(self.nodes[3].gettxoutproof([txid_spent])), [txid_spent])
# Quick test of getblock using blockhash and different levels of verbosity
result = self.nodes[0].getblock(blockhash, 2)
coinbase_txid = result["tx"][0]["txid"]
result = self.nodes[0].getblock(blockhash, 1)
assert_equal(coinbase_txid, result["tx"][0]) # verbosity 1 only lists txids
result = self.nodes[0].getblock(blockhash, 0)
assert(c in string.hexdigits for c in result) # verbosity 0 returns raw hex
if __name__ == '__main__':
MerkleBlockTest().main()

View File

@ -394,13 +394,16 @@ UniValue getblock(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
"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"
"getblock \"hash|height\" ( verbosity )\n"
"\nIf verbosity is 0, returns a string that is serialized, hex-encoded data for the block.\n"
"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"
"2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
"\nResult (for verbose = true):\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"
"\nResult (for verbosity = 1):\n"
"{\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"
@ -419,11 +422,17 @@ UniValue getblock(const UniValue& params, bool fHelp)
" \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
" \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
"}\n"
"\nResult (for verbose=false):\n"
"\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
"\nResult (for verbosity = 2):\n"
"{\n"
" ..., Same output as verbosity = 1.\n"
" \"tx\" : [ (array of Objects) The transactions in the format of the getrawtransaction RPC. Different from verbosity = 1 \"tx\" result.\n"
" ,...\n"
" ],\n"
" ,... Same output as verbosity = 1.\n"
"}\n"
"\nExamples:\n"
+ HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
+ HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
+ HelpExampleCli("getblock", "\"00000000febc373a1da2bd9f887b105ad79ddc26ac26c2b28652d64e5207c5b5\"")
+ HelpExampleRpc("getblock", "\"00000000febc373a1da2bd9f887b105ad79ddc26ac26c2b28652d64e5207c5b5\"")
+ HelpExampleCli("getblock", "12800")
+ HelpExampleRpc("getblock", "12800")
);
@ -456,9 +465,18 @@ UniValue getblock(const UniValue& params, bool fHelp)
uint256 hash(uint256S(strHash));
bool fVerbose = true;
if (params.size() > 1)
fVerbose = params[1].get_bool();
int verbosity = 1;
if (params.size() > 1) {
if(params[1].isNum()) {
verbosity = params[1].get_int();
} else {
verbosity = params[1].get_bool() ? 1 : 0;
}
}
if (verbosity < 0 || verbosity > 2) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Verbosity must be in range from 0 to 2");
}
if (mapBlockIndex.count(hash) == 0)
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
@ -472,7 +490,7 @@ UniValue getblock(const UniValue& params, bool fHelp)
if(!ReadBlockFromDisk(block, pblockindex))
throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
if (!fVerbose)
if (verbosity == 0)
{
CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
ssBlock << block;
@ -480,7 +498,7 @@ UniValue getblock(const UniValue& params, bool fHelp)
return strHex;
}
return blockToJSON(block, pblockindex);
return blockToJSON(block, pblockindex, verbosity >= 2);
}
UniValue gettxoutsetinfo(const UniValue& params, bool fHelp)

View File

@ -291,6 +291,11 @@ BOOST_AUTO_TEST_CASE(rpc_wallet)
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_CHECK_NO_THROW(CallRPC("getblock 0 0"));
BOOST_CHECK_NO_THROW(CallRPC("getblock 0 1"));
BOOST_CHECK_NO_THROW(CallRPC("getblock 0 2"));
BOOST_CHECK_THROW(CallRPC("getblock 0 -1"), runtime_error); // bad verbosity
BOOST_CHECK_THROW(CallRPC("getblock 0 3"), runtime_error); // bad verbosity
}
BOOST_AUTO_TEST_CASE(rpc_wallet_getbalance)