Add getblockheader RPC call
Alternative to getblock that works even when the block itself has been pruned, returning all available information.
This commit is contained in:
parent
ab20ae8079
commit
076badb60f
4 changed files with 85 additions and 0 deletions
|
@ -51,6 +51,32 @@ double GetDifficulty(const CBlockIndex* blockindex)
|
||||||
return dDiff;
|
return dDiff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UniValue blockheaderToJSON(const CBlockIndex* blockindex)
|
||||||
|
{
|
||||||
|
UniValue result(UniValue::VOBJ);
|
||||||
|
result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex()));
|
||||||
|
int confirmations = -1;
|
||||||
|
// Only report confirmations if the block is on the main chain
|
||||||
|
if (chainActive.Contains(blockindex))
|
||||||
|
confirmations = chainActive.Height() - blockindex->nHeight + 1;
|
||||||
|
result.push_back(Pair("confirmations", confirmations));
|
||||||
|
result.push_back(Pair("height", blockindex->nHeight));
|
||||||
|
result.push_back(Pair("version", blockindex->nVersion));
|
||||||
|
result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex()));
|
||||||
|
result.push_back(Pair("time", (int64_t)blockindex->nTime));
|
||||||
|
result.push_back(Pair("nonce", (uint64_t)blockindex->nNonce));
|
||||||
|
result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits)));
|
||||||
|
result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
|
||||||
|
result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
|
||||||
|
|
||||||
|
if (blockindex->pprev)
|
||||||
|
result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
|
||||||
|
CBlockIndex *pnext = chainActive.Next(blockindex);
|
||||||
|
if (pnext)
|
||||||
|
result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false)
|
UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false)
|
||||||
{
|
{
|
||||||
|
@ -255,6 +281,62 @@ UniValue getblockhash(const UniValue& params, bool fHelp)
|
||||||
return pblockindex->GetBlockHash().GetHex();
|
return pblockindex->GetBlockHash().GetHex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UniValue getblockheader(const UniValue& params, bool fHelp)
|
||||||
|
{
|
||||||
|
if (fHelp || params.size() < 1 || params.size() > 2)
|
||||||
|
throw runtime_error(
|
||||||
|
"getblockheader \"hash\" ( verbose )\n"
|
||||||
|
"\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n"
|
||||||
|
"If verbose is true, returns an Object with information about blockheader <hash>.\n"
|
||||||
|
"\nArguments:\n"
|
||||||
|
"1. \"hash\" (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"
|
||||||
|
"{\n"
|
||||||
|
" \"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"
|
||||||
|
" \"height\" : n, (numeric) The block height or index\n"
|
||||||
|
" \"version\" : n, (numeric) The block version\n"
|
||||||
|
" \"merkleroot\" : \"xxxx\", (string) The merkle root\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"
|
||||||
|
" \"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"
|
||||||
|
"}\n"
|
||||||
|
"\nResult (for verbose=false):\n"
|
||||||
|
"\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
|
||||||
|
"\nExamples:\n"
|
||||||
|
+ HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
|
||||||
|
+ HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
|
||||||
|
);
|
||||||
|
|
||||||
|
LOCK(cs_main);
|
||||||
|
|
||||||
|
std::string strHash = params[0].get_str();
|
||||||
|
uint256 hash(uint256S(strHash));
|
||||||
|
|
||||||
|
bool fVerbose = true;
|
||||||
|
if (params.size() > 1)
|
||||||
|
fVerbose = params[1].get_bool();
|
||||||
|
|
||||||
|
if (mapBlockIndex.count(hash) == 0)
|
||||||
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
|
||||||
|
|
||||||
|
CBlockIndex* pblockindex = mapBlockIndex[hash];
|
||||||
|
|
||||||
|
if (!fVerbose)
|
||||||
|
{
|
||||||
|
CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
|
ssBlock << pblockindex->GetBlockHeader();
|
||||||
|
std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
|
||||||
|
return strHex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return blockheaderToJSON(pblockindex);
|
||||||
|
}
|
||||||
|
|
||||||
UniValue getblock(const UniValue& params, bool fHelp)
|
UniValue getblock(const UniValue& params, bool fHelp)
|
||||||
{
|
{
|
||||||
if (fHelp || params.size() < 1 || params.size() > 2)
|
if (fHelp || params.size() < 1 || params.size() > 2)
|
||||||
|
|
|
@ -71,6 +71,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
||||||
{ "listunspent", 1 },
|
{ "listunspent", 1 },
|
||||||
{ "listunspent", 2 },
|
{ "listunspent", 2 },
|
||||||
{ "getblock", 1 },
|
{ "getblock", 1 },
|
||||||
|
{ "getblockheader", 1 },
|
||||||
{ "gettransaction", 1 },
|
{ "gettransaction", 1 },
|
||||||
{ "getrawtransaction", 1 },
|
{ "getrawtransaction", 1 },
|
||||||
{ "createrawtransaction", 0 },
|
{ "createrawtransaction", 0 },
|
||||||
|
|
|
@ -288,6 +288,7 @@ static const CRPCCommand vRPCCommands[] =
|
||||||
{ "blockchain", "getblockcount", &getblockcount, true },
|
{ "blockchain", "getblockcount", &getblockcount, true },
|
||||||
{ "blockchain", "getblock", &getblock, true },
|
{ "blockchain", "getblock", &getblock, true },
|
||||||
{ "blockchain", "getblockhash", &getblockhash, true },
|
{ "blockchain", "getblockhash", &getblockhash, true },
|
||||||
|
{ "blockchain", "getblockheader", &getblockheader, true },
|
||||||
{ "blockchain", "getchaintips", &getchaintips, true },
|
{ "blockchain", "getchaintips", &getchaintips, true },
|
||||||
{ "blockchain", "getdifficulty", &getdifficulty, true },
|
{ "blockchain", "getdifficulty", &getdifficulty, true },
|
||||||
{ "blockchain", "getmempoolinfo", &getmempoolinfo, true },
|
{ "blockchain", "getmempoolinfo", &getmempoolinfo, true },
|
||||||
|
|
|
@ -229,6 +229,7 @@ extern UniValue settxfee(const UniValue& params, bool fHelp);
|
||||||
extern UniValue getmempoolinfo(const UniValue& params, bool fHelp);
|
extern UniValue getmempoolinfo(const UniValue& params, bool fHelp);
|
||||||
extern UniValue getrawmempool(const UniValue& params, bool fHelp);
|
extern UniValue getrawmempool(const UniValue& params, bool fHelp);
|
||||||
extern UniValue getblockhash(const UniValue& params, bool fHelp);
|
extern UniValue getblockhash(const UniValue& params, bool fHelp);
|
||||||
|
extern UniValue getblockheader(const UniValue& params, bool fHelp);
|
||||||
extern UniValue getblock(const UniValue& params, bool fHelp);
|
extern UniValue getblock(const UniValue& params, bool fHelp);
|
||||||
extern UniValue gettxoutsetinfo(const UniValue& params, bool fHelp);
|
extern UniValue gettxoutsetinfo(const UniValue& params, bool fHelp);
|
||||||
extern UniValue gettxout(const UniValue& params, bool fHelp);
|
extern UniValue gettxout(const UniValue& params, bool fHelp);
|
||||||
|
|
Loading…
Reference in a new issue