mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-12 23:18:14 +01:00
Implement "getchaintips" RPC command to monitor blockchain forks.
Port over https://github.com/chronokings/huntercoin/pull/19 from Huntercoin: This implements a new RPC command "getchaintips" that can be used to find all currently active chain heads. This is similar to the -printblocktree startup option, but it can be used without restarting just via the RPC interface on a running daemon.
This commit is contained in:
@@ -461,3 +461,73 @@ Value getblockchaininfo(const Array& params, bool fHelp)
|
||||
obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex()));
|
||||
return obj;
|
||||
}
|
||||
|
||||
/* Comparison function for sorting the getchaintips heads. */
|
||||
struct CompareBlocksByHeight
|
||||
{
|
||||
bool operator()(const CBlockIndex* a, const CBlockIndex* b) const
|
||||
{
|
||||
/* Make sure that unequal blocks with the same height do not compare
|
||||
equal. Use the pointers themselves to make a distinction. */
|
||||
|
||||
if (a->nHeight != b->nHeight)
|
||||
return (a->nHeight > b->nHeight);
|
||||
|
||||
return a < b;
|
||||
}
|
||||
};
|
||||
|
||||
Value getchaintips(const Array& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
"getchaintips\n"
|
||||
"Return information about all known tips in the block tree,"
|
||||
" including the main chain as well as orphaned branches.\n"
|
||||
"\nResult:\n"
|
||||
"[\n"
|
||||
" {\n"
|
||||
" \"height\": xxxx, (numeric) height of the chain tip\n"
|
||||
" \"hash\": \"xxxx\", (string) block hash of the tip\n"
|
||||
" \"branchlen\": 0 (numeric) zero for main chain\n"
|
||||
" },\n"
|
||||
" {\n"
|
||||
" \"height\": xxxx,\n"
|
||||
" \"hash\": \"xxxx\",\n"
|
||||
" \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
|
||||
" }\n"
|
||||
"]\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("getchaintips", "")
|
||||
+ HelpExampleRpc("getchaintips", "")
|
||||
);
|
||||
|
||||
/* Build up a list of chain tips. We start with the list of all
|
||||
known blocks, and successively remove blocks that appear as pprev
|
||||
of another block. */
|
||||
std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
|
||||
BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
|
||||
setTips.insert(item.second);
|
||||
BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
|
||||
{
|
||||
const CBlockIndex* pprev = item.second->pprev;
|
||||
if (pprev)
|
||||
setTips.erase(pprev);
|
||||
}
|
||||
|
||||
/* Construct the output array. */
|
||||
Array res;
|
||||
BOOST_FOREACH(const CBlockIndex* block, setTips)
|
||||
{
|
||||
Object obj;
|
||||
obj.push_back(Pair("height", block->nHeight));
|
||||
obj.push_back(Pair("hash", block->phashBlock->GetHex()));
|
||||
|
||||
const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
|
||||
obj.push_back(Pair("branchlen", branchLen));
|
||||
|
||||
res.push_back(obj);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user