diff --git a/doc/release-notes.md b/doc/release-notes.md --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -12,3 +12,4 @@ - Deprecated estimatefee RPC command - Improved help message for backup wallet RPC - Various bug fixes that improve node stability and performance + - Backport getblock RPC's new verbosity mode from bitcoin core for retrieving all transactions of a given block in full. diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -760,18 +760,24 @@ if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { throw std::runtime_error( - "getblock \"blockhash\" ( 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 .\n" + "getblock \"blockhash\" ( verbosity )\n" + "\nIf verbosity is 0 or false, returns a string that is " + "serialized, hex-encoded data for block 'hash'.\n" + "If verbosity is 1 or true, returns an Object with information " + "about block .\n" + "If verbosity is 2, returns an Object with information about block " + " and information about each transaction.\n" "\nArguments:\n" - "1. \"blockhash\" (string, required) The block hash\n" - "2. verbose (boolean, optional, default=true) true " - "for a json object, false for the hex encoded data\n" - "\nResult (for verbose = true):\n" + "1. \"blockhash\" (string, required) The block hash\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 block 'hash'.\n" + "\nResult (for verbosity = 1):\n" "{\n" - " \"hash\" : \"hash\", (string) the block hash (same as " + " \"hash\" : \"hash\", (string) The block hash (same as " "provided)\n" " \"confirmations\" : n, (numeric) The number of confirmations, " "or -1 if the block is not on the main chain\n" @@ -790,7 +796,7 @@ " \"mediantime\" : ttt, (numeric) The median 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" " \"chainwork\" : \"xxxx\", (string) Expected number of hashes " "required to produce the chain up to this block (in hex)\n" @@ -799,9 +805,16 @@ " \"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", "\"00000000c937983704a73af28acdec37b049d" "214adbda81d7e2a3dd146f6ed09\"") + @@ -814,9 +827,13 @@ std::string strHash = request.params[0].get_str(); uint256 hash(uint256S(strHash)); - bool fVerbose = true; + int verbosity = 1; if (request.params.size() > 1) { - fVerbose = request.params[1].get_bool(); + if (request.params[1].isNum()) { + verbosity = request.params[1].get_int(); + } else { + verbosity = request.params[1].get_bool() ? 1 : 0; + } } if (mapBlockIndex.count(hash) == 0) { @@ -839,7 +856,7 @@ throw JSONRPCError(RPC_MISC_ERROR, "Block not found on disk"); } - if (!fVerbose) { + if (verbosity <= 0) { CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); ssBlock << block; @@ -847,7 +864,7 @@ return strHex; } - return blockToJSON(config, block, pblockindex); + return blockToJSON(config, block, pblockindex, verbosity >= 2); } struct CCoinsStats { @@ -1748,7 +1765,7 @@ { "blockchain", "getchaintxstats", &getchaintxstats, {"nblocks", "blockhash"} }, { "blockchain", "getbestblockhash", getbestblockhash, {} }, { "blockchain", "getblockcount", getblockcount, {} }, - { "blockchain", "getblock", getblock, {"blockhash","verbose"} }, + { "blockchain", "getblock", getblock, {"blockhash","verbosity|verbose"} }, { "blockchain", "getblockhash", getblockhash, {"height"} }, { "blockchain", "getblockheader", getblockheader, {"blockhash","verbose"} }, { "blockchain", "getchaintips", getchaintips, {} }, diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -75,7 +75,7 @@ {"listunspent", 1, "maxconf"}, {"listunspent", 2, "addresses"}, {"listunspent", 4, "query_options"}, - {"getblock", 1, "verbose"}, + {"getblock", 1, "verbosity"}, {"getblockheader", 1, "verbose"}, {"getchaintxstats", 0, "nblocks"}, {"gettransaction", 1, "include_watchonly"}, diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -18,6 +18,8 @@ #include #include // for to_upper() +#include +#include #include #include @@ -461,8 +463,17 @@ } // Process expected parameters. int hole = 0; - for (const std::string &argName : argNames) { - auto fr = argsIn.find(argName); + for (const std::string &argNamePattern : argNames) { + std::vector vargNames; + boost::algorithm::split(vargNames, argNamePattern, + boost::algorithm::is_any_of("|")); + auto fr = argsIn.end(); + for (const std::string &argName : vargNames) { + fr = argsIn.find(argName); + if (fr != argsIn.end()) { + break; + } + } if (fr != argsIn.end()) { for (int i = 0; i < hole; ++i) { // Fill hole between specified parameters with JSON nulls, but