aboutsummaryrefslogtreecommitdiff
path: root/src/rpc/blockchain.cpp
diff options
context:
space:
mode:
authorJames O'Beirne <james.obeirne@gmail.com>2019-03-29 17:55:08 -0400
committerJames O'Beirne <james.obeirne@pm.me>2023-09-30 06:41:23 -0400
commit0f64bac6030334d798ae205cd7af4bf248feddd9 (patch)
tree23341a71f629aa3d54f357bff569451e3ac3f303 /src/rpc/blockchain.cpp
parentbb0585779472962f40d9cdd9c6532132850d371c (diff)
downloadbitcoin-0f64bac6030334d798ae205cd7af4bf248feddd9.tar.xz
rpc: add getchainstates
Co-authored-by: Ryan Ofsky <ryan@ofsky.org>
Diffstat (limited to 'src/rpc/blockchain.cpp')
-rw-r--r--src/rpc/blockchain.cpp74
1 files changed, 74 insertions, 0 deletions
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index c7ffa0a0b2..0f4941b40c 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -2799,6 +2799,79 @@ static RPCHelpMan loadtxoutset()
};
}
+const std::vector<RPCResult> RPCHelpForChainstate{
+ {RPCResult::Type::NUM, "blocks", "number of blocks in this chainstate"},
+ {RPCResult::Type::STR_HEX, "bestblockhash", "blockhash of the tip"},
+ {RPCResult::Type::NUM, "difficulty", "difficulty of the tip"},
+ {RPCResult::Type::NUM, "verificationprogress", "progress towards the network tip"},
+ {RPCResult::Type::STR_HEX, "snapshot_blockhash", /*optional=*/true, "the base block of the snapshot this chainstate is based on, if any"},
+ {RPCResult::Type::NUM, "coins_db_cache_bytes", "size of the coinsdb cache"},
+ {RPCResult::Type::NUM, "coins_tip_cache_bytes", "size of the coinstip cache"},
+};
+
+static RPCHelpMan getchainstates()
+{
+return RPCHelpMan{
+ "getchainstates",
+ "\nReturn information about chainstates.\n",
+ {},
+ RPCResult{
+ RPCResult::Type::OBJ, "", "", {
+ {RPCResult::Type::NUM, "headers", "the number of headers seen so far"},
+ {RPCResult::Type::OBJ, "normal", /*optional=*/true, "fully validated chainstate containing blocks this node has validated starting from the genesis block", RPCHelpForChainstate},
+ {RPCResult::Type::OBJ, "snapshot", /*optional=*/true, "only present if an assumeutxo snapshot is loaded. Partially validated chainstate containing blocks this node has validated starting from the snapshot. After the snapshot is validated (when the 'normal' chainstate advances far enough to validate it), this chainstate will replace and become the 'normal' chainstate.", RPCHelpForChainstate},
+ }
+ },
+ RPCExamples{
+ HelpExampleCli("getchainstates", "")
+ + HelpExampleRpc("getchainstates", "")
+ },
+ [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
+{
+ LOCK(cs_main);
+ UniValue obj(UniValue::VOBJ);
+
+ NodeContext& node = EnsureAnyNodeContext(request.context);
+ ChainstateManager& chainman = *node.chainman;
+
+ auto make_chain_data = [&](const Chainstate& cs) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) {
+ AssertLockHeld(::cs_main);
+ UniValue data(UniValue::VOBJ);
+ if (!cs.m_chain.Tip()) {
+ return data;
+ }
+ const CChain& chain = cs.m_chain;
+ const CBlockIndex* tip = chain.Tip();
+
+ data.pushKV("blocks", (int)chain.Height());
+ data.pushKV("bestblockhash", tip->GetBlockHash().GetHex());
+ data.pushKV("difficulty", (double)GetDifficulty(tip));
+ data.pushKV("verificationprogress", GuessVerificationProgress(Params().TxData(), tip));
+ data.pushKV("coins_db_cache_bytes", cs.m_coinsdb_cache_size_bytes);
+ data.pushKV("coins_tip_cache_bytes", cs.m_coinstip_cache_size_bytes);
+ if (cs.m_from_snapshot_blockhash) {
+ data.pushKV("snapshot_blockhash", cs.m_from_snapshot_blockhash->ToString());
+ }
+ return data;
+ };
+
+ if (chainman.GetAll().size() > 1) {
+ for (Chainstate* chainstate : chainman.GetAll()) {
+ obj.pushKV(
+ chainstate->m_from_snapshot_blockhash ? "snapshot" : "normal",
+ make_chain_data(*chainstate));
+ }
+ } else {
+ obj.pushKV("normal", make_chain_data(chainman.ActiveChainstate()));
+ }
+ obj.pushKV("headers", chainman.m_best_header ? chainman.m_best_header->nHeight : -1);
+
+ return obj;
+}
+ };
+}
+
+
void RegisterBlockchainRPCCommands(CRPCTable& t)
{
static const CRPCCommand commands[]{
@@ -2824,6 +2897,7 @@ void RegisterBlockchainRPCCommands(CRPCTable& t)
{"blockchain", &getblockfilter},
{"blockchain", &dumptxoutset},
{"blockchain", &loadtxoutset},
+ {"blockchain", &getchainstates},
{"hidden", &invalidateblock},
{"hidden", &reconsiderblock},
{"hidden", &waitfornewblock},