Browse Source

Merge pull request #5386

1b91be4 Report status of chain tips (Pieter Wuille)
0.10
Wladimir J. van der Laan 10 years ago
parent
commit
0ddf4416cc
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 1
      qa/pull-tester/rpc-tests.sh
  2. 7
      qa/rpc-tests/getchaintips.py
  3. 27
      src/rpcblockchain.cpp

1
qa/pull-tester/rpc-tests.sh

@ -20,6 +20,7 @@ if [ "x${ENABLE_BITCOIND}${ENABLE_UTILS}${ENABLE_WALLET}" = "x111" ]; then @@ -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/txn_doublespend.py --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"
else
echo "No rpc tests to run. Wallet, utils, and bitcoind must all be enabled"

7
qa/rpc-tests/getchaintips.py

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

27
src/rpcblockchain.cpp

@ -496,11 +496,13 @@ Value getchaintips(const Array& params, bool fHelp) @@ -496,11 +496,13 @@ Value getchaintips(const Array& params, bool fHelp)
" \"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"
" \"status\": \"active\" (string) \"active\" for the 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"
" \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
" }\n"
"]\n"
"\nExamples:\n"
@ -521,6 +523,9 @@ Value getchaintips(const Array& params, bool fHelp) @@ -521,6 +523,9 @@ Value getchaintips(const Array& params, bool fHelp)
setTips.erase(pprev);
}
// Always report the currently active tip.
setTips.insert(chainActive.Tip());
/* Construct the output array. */
Array res;
BOOST_FOREACH(const CBlockIndex* block, setTips)
@ -532,6 +537,28 @@ Value getchaintips(const Array& params, bool fHelp) @@ -532,6 +537,28 @@ Value getchaintips(const Array& params, bool fHelp)
const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
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);
}

Loading…
Cancel
Save