mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-06-05 20:50:18 +02:00
Merge #19550: rpc: Add getindexinfo RPC
124e1ee1343f8bfb3748393ced9debdbdee60d3b doc: Add release notes for getindexinfo RPC (Fabian Jahr) c447b09458c89c946957a211a4f5373b92af44bf test: Add tests for getindexinfo RPC (Fabian Jahr) 667bc7a7f7c5d9a15eaf6957c3d8841a75efa7bc rpc: Add getindexinfo RPC (Fabian Jahr) Pull request description: As I was playing with indices a I was missing an RPC that gives information about the active indices in the node. I think this can be helpful for many users, especially since there are some new index candidates coming up (#14053, #18000) that can give a quick overview without the user having to parse the logs. Feature summary: - Adds new RPC `listindices` (placed in Util section) - That RPC only lists the actively running indices - For each index it gives the name, whether it is synced and up to which block height it is synced ACKs for top commit: laanwj: Re-ACK 124e1ee1343f8bfb3748393ced9debdbdee60d3b jonatack: Code review re-ACK 124e1ee per `git range-diff a57af89 47a5372 124e1ee` no change since my last re-ACK, rebase only Tree-SHA512: 3b7174c87951e6457fef099f530337803906baf32fb64261410b8def2c0917853d6a1bf3059cd590b1cc1523608f8916dafb327a431d27ecbf8d7454406b5b35
This commit is contained in:
commit
27eeb0337b
@ -115,6 +115,10 @@ Changes to Wallet or GUI related RPCs can be found in the GUI or Wallet section
|
|||||||
New RPCs
|
New RPCs
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
- The `getindexinfo` RPC returns the actively running indices of the node,
|
||||||
|
including their current sync status and height. It also accepts an `index_name`
|
||||||
|
to specify returning only the status of that index. (#19550)
|
||||||
|
|
||||||
Build System
|
Build System
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
@ -319,3 +319,12 @@ void BaseIndex::Stop()
|
|||||||
m_thread_sync.join();
|
m_thread_sync.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IndexSummary BaseIndex::GetSummary() const
|
||||||
|
{
|
||||||
|
IndexSummary summary{};
|
||||||
|
summary.name = GetName();
|
||||||
|
summary.synced = m_synced;
|
||||||
|
summary.best_block_height = m_best_block_index.load()->nHeight;
|
||||||
|
return summary;
|
||||||
|
}
|
||||||
|
@ -13,6 +13,12 @@
|
|||||||
|
|
||||||
class CBlockIndex;
|
class CBlockIndex;
|
||||||
|
|
||||||
|
struct IndexSummary {
|
||||||
|
std::string name;
|
||||||
|
bool synced{false};
|
||||||
|
int best_block_height{0};
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for indices of blockchain data. This implements
|
* Base class for indices of blockchain data. This implements
|
||||||
* CValidationInterface and ensures blocks are indexed sequentially according
|
* CValidationInterface and ensures blocks are indexed sequentially according
|
||||||
@ -106,6 +112,9 @@ public:
|
|||||||
|
|
||||||
/// Stops the instance from staying in sync with blockchain updates.
|
/// Stops the instance from staying in sync with blockchain updates.
|
||||||
void Stop();
|
void Stop();
|
||||||
|
|
||||||
|
/// Get a summary of the index and its state.
|
||||||
|
IndexSummary GetSummary() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BITCOIN_INDEX_BASE_H
|
#endif // BITCOIN_INDEX_BASE_H
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include <httpserver.h>
|
#include <httpserver.h>
|
||||||
|
#include <index/blockfilterindex.h>
|
||||||
|
#include <index/txindex.h>
|
||||||
#include <interfaces/chain.h>
|
#include <interfaces/chain.h>
|
||||||
#include <key_io.h>
|
#include <key_io.h>
|
||||||
#include <node/context.h>
|
#include <node/context.h>
|
||||||
@ -636,6 +638,60 @@ static RPCHelpMan echo(const std::string& name)
|
|||||||
static RPCHelpMan echo() { return echo("echo"); }
|
static RPCHelpMan echo() { return echo("echo"); }
|
||||||
static RPCHelpMan echojson() { return echo("echojson"); }
|
static RPCHelpMan echojson() { return echo("echojson"); }
|
||||||
|
|
||||||
|
static UniValue SummaryToJSON(const IndexSummary&& summary, std::string index_name)
|
||||||
|
{
|
||||||
|
UniValue ret_summary(UniValue::VOBJ);
|
||||||
|
if (!index_name.empty() && index_name != summary.name) return ret_summary;
|
||||||
|
|
||||||
|
UniValue entry(UniValue::VOBJ);
|
||||||
|
entry.pushKV("synced", summary.synced);
|
||||||
|
entry.pushKV("best_block_height", summary.best_block_height);
|
||||||
|
ret_summary.pushKV(summary.name, entry);
|
||||||
|
return ret_summary;
|
||||||
|
}
|
||||||
|
|
||||||
|
static RPCHelpMan getindexinfo()
|
||||||
|
{
|
||||||
|
return RPCHelpMan{"getindexinfo",
|
||||||
|
"\nReturns the status of one or all available indices currently running in the node.\n",
|
||||||
|
{
|
||||||
|
{"index_name", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "Filter results for an index with a specific name."},
|
||||||
|
},
|
||||||
|
RPCResult{
|
||||||
|
RPCResult::Type::OBJ, "", "", {
|
||||||
|
{
|
||||||
|
RPCResult::Type::OBJ, "name", "The name of the index",
|
||||||
|
{
|
||||||
|
{RPCResult::Type::BOOL, "synced", "Whether the index is synced or not"},
|
||||||
|
{RPCResult::Type::NUM, "best_block_height", "The block height to which the index is synced"},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RPCExamples{
|
||||||
|
HelpExampleCli("getindexinfo", "")
|
||||||
|
+ HelpExampleRpc("getindexinfo", "")
|
||||||
|
+ HelpExampleCli("getindexinfo", "txindex")
|
||||||
|
+ HelpExampleRpc("getindexinfo", "txindex")
|
||||||
|
},
|
||||||
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
|
{
|
||||||
|
UniValue result(UniValue::VOBJ);
|
||||||
|
const std::string index_name = request.params[0].isNull() ? "" : request.params[0].get_str();
|
||||||
|
|
||||||
|
if (g_txindex) {
|
||||||
|
result.pushKVs(SummaryToJSON(g_txindex->GetSummary(), index_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
ForEachBlockFilterIndex([&result, &index_name](const BlockFilterIndex& index) {
|
||||||
|
result.pushKVs(SummaryToJSON(index.GetSummary(), index_name));
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
void RegisterMiscRPCCommands(CRPCTable &t)
|
void RegisterMiscRPCCommands(CRPCTable &t)
|
||||||
{
|
{
|
||||||
// clang-format off
|
// clang-format off
|
||||||
@ -650,6 +706,7 @@ static const CRPCCommand commands[] =
|
|||||||
{ "util", "getdescriptorinfo", &getdescriptorinfo, {"descriptor"} },
|
{ "util", "getdescriptorinfo", &getdescriptorinfo, {"descriptor"} },
|
||||||
{ "util", "verifymessage", &verifymessage, {"address","signature","message"} },
|
{ "util", "verifymessage", &verifymessage, {"address","signature","message"} },
|
||||||
{ "util", "signmessagewithprivkey", &signmessagewithprivkey, {"privkey","message"} },
|
{ "util", "signmessagewithprivkey", &signmessagewithprivkey, {"privkey","message"} },
|
||||||
|
{ "util", "getindexinfo", &getindexinfo, {"index_name"} },
|
||||||
|
|
||||||
/* Not shown in help */
|
/* Not shown in help */
|
||||||
{ "hidden", "setmocktime", &setmocktime, {"timestamp"}},
|
{ "hidden", "setmocktime", &setmocktime, {"timestamp"}},
|
||||||
|
@ -61,6 +61,34 @@ class RpcMiscTest(BitcoinTestFramework):
|
|||||||
node.logging(include=['qt'])
|
node.logging(include=['qt'])
|
||||||
assert_equal(node.logging()['qt'], True)
|
assert_equal(node.logging()['qt'], True)
|
||||||
|
|
||||||
|
self.log.info("test getindexinfo")
|
||||||
|
# Without any indices running the RPC returns an empty object
|
||||||
|
assert_equal(node.getindexinfo(), {})
|
||||||
|
|
||||||
|
# Restart the node with indices and wait for them to sync
|
||||||
|
self.restart_node(0, ["-txindex", "-blockfilterindex"])
|
||||||
|
self.wait_until(lambda: all(i["synced"] for i in node.getindexinfo().values()))
|
||||||
|
|
||||||
|
# Returns a list of all running indices by default
|
||||||
|
assert_equal(
|
||||||
|
node.getindexinfo(),
|
||||||
|
{
|
||||||
|
"txindex": {"synced": True, "best_block_height": 200},
|
||||||
|
"basic block filter index": {"synced": True, "best_block_height": 200}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Specifying an index by name returns only the status of that index
|
||||||
|
assert_equal(
|
||||||
|
node.getindexinfo("txindex"),
|
||||||
|
{
|
||||||
|
"txindex": {"synced": True, "best_block_height": 200},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Specifying an unknown index name returns an empty result
|
||||||
|
assert_equal(node.getindexinfo("foo"), {})
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
RpcMiscTest().main()
|
RpcMiscTest().main()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user