MCPcopy Create free account
hub / github.com/ElementsProject/elements / getchaintips

Function getchaintips

src/rpc/blockchain.cpp:1906–2002  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1904};
1905
1906static RPCHelpMan getchaintips()
1907{
1908 return RPCHelpMan{"getchaintips",
1909 "Return information about all known tips in the block tree,"
1910 " including the main chain as well as orphaned branches.\n",
1911 {},
1912 RPCResult{
1913 RPCResult::Type::ARR, "", "",
1914 {{RPCResult::Type::OBJ, "", "",
1915 {
1916 {RPCResult::Type::NUM, "height", "height of the chain tip"},
1917 {RPCResult::Type::STR_HEX, "hash", "block hash of the tip"},
1918 {RPCResult::Type::NUM, "branchlen", "zero for main chain, otherwise length of branch connecting the tip to the main chain"},
1919 {RPCResult::Type::STR, "status", "status of the chain, \"active\" for the main chain\n"
1920 "Possible values for status:\n"
1921 "1. \"invalid\" This branch contains at least one invalid block\n"
1922 "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
1923 "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
1924 "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
1925 "5. \"active\" This is the tip of the active main chain, which is certainly valid"},
1926 }}}},
1927 RPCExamples{
1928 HelpExampleCli("getchaintips", "")
1929 + HelpExampleRpc("getchaintips", "")
1930 },
1931 [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1932{
1933 ChainstateManager& chainman = EnsureAnyChainman(request.context);
1934 LOCK(cs_main);
1935 CChain& active_chain = chainman.ActiveChain();
1936
1937 /*
1938 * Idea: The set of chain tips is the active chain tip, plus orphan blocks which do not have another orphan building off of them.
1939 * Algorithm:
1940 * - Make one pass through BlockIndex(), picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers.
1941 * - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip.
1942 * - Add the active chain tip
1943 */
1944 std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
1945 std::set<const CBlockIndex*> setOrphans;
1946 std::set<const CBlockIndex*> setPrevs;
1947
1948 for (const std::pair<const uint256, CBlockIndex*>& item : chainman.BlockIndex()) {
1949 if (!active_chain.Contains(item.second)) {
1950 setOrphans.insert(item.second);
1951 setPrevs.insert(item.second->pprev);
1952 }
1953 }
1954
1955 for (std::set<const CBlockIndex*>::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it) {
1956 if (setPrevs.erase(*it) == 0) {
1957 setTips.insert(*it);
1958 }
1959 }
1960
1961 // Always report the currently active tip.
1962 setTips.insert(active_chain.Tip());
1963

Callers

nothing calls this directly

Calls 14

HelpExampleCliFunction · 0.85
HelpExampleRpcFunction · 0.85
FindForkMethod · 0.80
HaveTxsDownloadedMethod · 0.80
ContainsMethod · 0.45
insertMethod · 0.45
beginMethod · 0.45
endMethod · 0.45
eraseMethod · 0.45
TipMethod · 0.45
pushKVMethod · 0.45
GetHexMethod · 0.45

Tested by

no test coverage detected