aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Todd <pete@petertodd.org>2015-06-05 17:07:17 -0230
committerPeter Todd <pete@petertodd.org>2015-06-05 17:07:58 -0230
commit076badb60f33f0c32b035de220ca14c52a423a2a (patch)
treed77ab151e6e6660013ea675a75ea06e07cae92f4
parentab20ae807961982c54e92675bee4c4000b990b7b (diff)
Add getblockheader RPC call
Alternative to getblock that works even when the block itself has been pruned, returning all available information.
-rw-r--r--src/rpcblockchain.cpp82
-rw-r--r--src/rpcclient.cpp1
-rw-r--r--src/rpcserver.cpp1
-rw-r--r--src/rpcserver.h1
4 files changed, 85 insertions, 0 deletions
diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp
index e45368cb97..1baaaa7e10 100644
--- a/src/rpcblockchain.cpp
+++ b/src/rpcblockchain.cpp
@@ -51,6 +51,32 @@ double GetDifficulty(const CBlockIndex* blockindex)
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)
{
@@ -255,6 +281,62 @@ UniValue getblockhash(const UniValue& params, bool fHelp)
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)
{
if (fHelp || params.size() < 1 || params.size() > 2)
diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp
index f254da5de0..b15df6a9b9 100644
--- a/src/rpcclient.cpp
+++ b/src/rpcclient.cpp
@@ -71,6 +71,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "listunspent", 1 },
{ "listunspent", 2 },
{ "getblock", 1 },
+ { "getblockheader", 1 },
{ "gettransaction", 1 },
{ "getrawtransaction", 1 },
{ "createrawtransaction", 0 },
diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp
index e6bf008618..aba016be78 100644
--- a/src/rpcserver.cpp
+++ b/src/rpcserver.cpp
@@ -288,6 +288,7 @@ static const CRPCCommand vRPCCommands[] =
{ "blockchain", "getblockcount", &getblockcount, true },
{ "blockchain", "getblock", &getblock, true },
{ "blockchain", "getblockhash", &getblockhash, true },
+ { "blockchain", "getblockheader", &getblockheader, true },
{ "blockchain", "getchaintips", &getchaintips, true },
{ "blockchain", "getdifficulty", &getdifficulty, true },
{ "blockchain", "getmempoolinfo", &getmempoolinfo, true },
diff --git a/src/rpcserver.h b/src/rpcserver.h
index 7b462a8b79..2830d9c106 100644
--- a/src/rpcserver.h
+++ b/src/rpcserver.h
@@ -229,6 +229,7 @@ extern UniValue settxfee(const UniValue& params, bool fHelp);
extern UniValue getmempoolinfo(const UniValue& params, bool fHelp);
extern UniValue getrawmempool(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 gettxoutsetinfo(const UniValue& params, bool fHelp);
extern UniValue gettxout(const UniValue& params, bool fHelp);