diff options
author | Daniel Kraft <d@domob.eu> | 2014-08-03 18:12:19 +0200 |
---|---|---|
committer | Daniel Kraft <d@domob.eu> | 2014-08-03 18:12:19 +0200 |
commit | b33bd7a3be1cbcc8d255178307976b7762125b18 (patch) | |
tree | 7d1af753944e5813f0ef541efb0a28edf5a283e2 /src/rpcblockchain.cpp | |
parent | 6278bd57c662e29b07df9db50c47095c0bb44a82 (diff) |
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.
Diffstat (limited to 'src/rpcblockchain.cpp')
-rw-r--r-- | src/rpcblockchain.cpp | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 253693e624..1e5198b85c 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -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; +} |