Report status of chain tips

This commit is contained in:
Pieter Wuille 2014-11-27 10:46:55 +01:00
parent 9ff0bc9beb
commit 1b91be49f5
3 changed files with 34 additions and 1 deletions

View File

@ -20,6 +20,7 @@ if [ "x${ENABLE_BITCOIND}${ENABLE_UTILS}${ENABLE_WALLET}" = "x111" ]; then
${BUILDDIR}/qa/rpc-tests/listtransactions.py --srcdir "${BUILDDIR}/src" ${BUILDDIR}/qa/rpc-tests/listtransactions.py --srcdir "${BUILDDIR}/src"
${BUILDDIR}/qa/rpc-tests/txn_doublespend.py --srcdir "${BUILDDIR}/src" ${BUILDDIR}/qa/rpc-tests/txn_doublespend.py --srcdir "${BUILDDIR}/src"
${BUILDDIR}/qa/rpc-tests/txn_doublespend.py --mineblock --srcdir "${BUILDDIR}/src" ${BUILDDIR}/qa/rpc-tests/txn_doublespend.py --mineblock --srcdir "${BUILDDIR}/src"
${BUILDDIR}/qa/rpc-tests/getchaintips.py --srcdir "${BUILDDIR}/src"
#${BUILDDIR}/qa/rpc-tests/forknotify.py --srcdir "${BUILDDIR}/src" #${BUILDDIR}/qa/rpc-tests/forknotify.py --srcdir "${BUILDDIR}/src"
else else
echo "No rpc tests to run. Wallet, utils, and bitcoind must all be enabled" echo "No rpc tests to run. Wallet, utils, and bitcoind must all be enabled"

View File

@ -19,6 +19,7 @@ class GetChainTipsTest (BitcoinTestFramework):
assert_equal (len (tips), 1) assert_equal (len (tips), 1)
assert_equal (tips[0]['branchlen'], 0) assert_equal (tips[0]['branchlen'], 0)
assert_equal (tips[0]['height'], 200) assert_equal (tips[0]['height'], 200)
assert_equal (tips[0]['status'], 'active')
# Split the network and build two chains of different lengths. # Split the network and build two chains of different lengths.
self.split_network () self.split_network ()
@ -31,12 +32,14 @@ class GetChainTipsTest (BitcoinTestFramework):
shortTip = tips[0] shortTip = tips[0]
assert_equal (shortTip['branchlen'], 0) assert_equal (shortTip['branchlen'], 0)
assert_equal (shortTip['height'], 210) assert_equal (shortTip['height'], 210)
assert_equal (tips[0]['status'], 'active')
tips = self.nodes[3].getchaintips () tips = self.nodes[3].getchaintips ()
assert_equal (len (tips), 1) assert_equal (len (tips), 1)
longTip = tips[0] longTip = tips[0]
assert_equal (longTip['branchlen'], 0) assert_equal (longTip['branchlen'], 0)
assert_equal (longTip['height'], 220) assert_equal (longTip['height'], 220)
assert_equal (tips[0]['status'], 'active')
# Join the network halves and check that we now have two tips # Join the network halves and check that we now have two tips
# (at least at the nodes that previously had the short chain). # (at least at the nodes that previously had the short chain).
@ -47,7 +50,9 @@ class GetChainTipsTest (BitcoinTestFramework):
assert_equal (tips[0], longTip) assert_equal (tips[0], longTip)
assert_equal (tips[1]['branchlen'], 10) assert_equal (tips[1]['branchlen'], 10)
tips[1]['branchlen'] = 0; assert_equal (tips[1]['status'], 'valid-fork')
tips[1]['branchlen'] = 0
tips[1]['status'] = 'active'
assert_equal (tips[1], shortTip) assert_equal (tips[1], shortTip)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -496,11 +496,13 @@ Value getchaintips(const Array& params, bool fHelp)
" \"height\": xxxx, (numeric) height of the chain tip\n" " \"height\": xxxx, (numeric) height of the chain tip\n"
" \"hash\": \"xxxx\", (string) block hash of the tip\n" " \"hash\": \"xxxx\", (string) block hash of the tip\n"
" \"branchlen\": 0 (numeric) zero for main chain\n" " \"branchlen\": 0 (numeric) zero for main chain\n"
" \"status\": \"active\" (string) \"active\" for the main chain\n"
" },\n" " },\n"
" {\n" " {\n"
" \"height\": xxxx,\n" " \"height\": xxxx,\n"
" \"hash\": \"xxxx\",\n" " \"hash\": \"xxxx\",\n"
" \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n" " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
" \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
" }\n" " }\n"
"]\n" "]\n"
"\nExamples:\n" "\nExamples:\n"
@ -521,6 +523,9 @@ Value getchaintips(const Array& params, bool fHelp)
setTips.erase(pprev); setTips.erase(pprev);
} }
// Always report the currently active tip.
setTips.insert(chainActive.Tip());
/* Construct the output array. */ /* Construct the output array. */
Array res; Array res;
BOOST_FOREACH(const CBlockIndex* block, setTips) BOOST_FOREACH(const CBlockIndex* block, setTips)
@ -532,6 +537,28 @@ Value getchaintips(const Array& params, bool fHelp)
const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight; const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
obj.push_back(Pair("branchlen", branchLen)); obj.push_back(Pair("branchlen", branchLen));
string status;
if (chainActive.Contains(block)) {
// This block is part of the currently active chain.
status = "active";
} else if (block->nStatus & BLOCK_FAILED_MASK) {
// This block or one of its ancestors is invalid.
status = "invalid";
} else if (block->nChainTx == 0) {
// This block cannot be connected because full block data for it or one of its parents is missing.
status = "headers-only";
} else if (block->IsValid(BLOCK_VALID_SCRIPTS)) {
// This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
status = "valid-fork";
} else if (block->IsValid(BLOCK_VALID_TREE)) {
// The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
status = "valid-headers";
} else {
// No clue.
status = "unknown";
}
obj.push_back(Pair("status", status));
res.push_back(obj); res.push_back(obj);
} }