Add optional cemented count to block_count RPC command (#2089)

* Add optional cemented count to block_count RPC command

* Require enable_control when requesting cemented block count (thanks @Dotcom)
This commit is contained in:
Wesley Shillingford 2019-06-21 14:07:25 +01:00 committed by GitHub
commit 84b76366e9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 111 additions and 28 deletions

View file

@ -758,6 +758,20 @@ TEST (block_store, account_count)
ASSERT_EQ (1, store.account_count (transaction));
}
TEST (block_store, cemented_count)
{
nano::logger_mt logger;
bool init (false);
nano::mdb_store store (init, logger, nano::unique_path ());
ASSERT_TRUE (!init);
auto transaction (store.tx_begin_write ());
ASSERT_EQ (0, store.cemented_count (transaction));
nano::genesis genesis;
auto hash (genesis.hash ());
store.initialize (transaction, genesis);
ASSERT_EQ (1, store.cemented_count (transaction));
}
TEST (block_store, sequence_increment)
{
nano::logger_mt logger;

View file

@ -1033,14 +1033,7 @@ int main (int argc, char * const * argv)
{
nano::inactive_node node (data_path);
auto transaction (node.node->store.tx_begin_read ());
uint64_t sum = 0;
for (auto i (node.node->store.latest_begin (transaction)), n (node.node->store.latest_end ()); i != n; ++i)
{
nano::account_info const & info (i->second);
sum += info.confirmation_height;
}
std::cout << "Total cemented block count: " << sum << std::endl;
std::cout << "Total cemented block count: " << node.node->store.cemented_count (transaction) << std::endl;
}
else if (vm.count ("debug_sys_logging"))
{

View file

@ -1161,6 +1161,13 @@ void nano::json_handler::block_count ()
auto transaction (node.store.tx_begin_read ());
response_l.put ("count", std::to_string (node.store.block_count (transaction).sum ()));
response_l.put ("unchecked", std::to_string (node.store.unchecked_count (transaction)));
const auto include_cemented = request.get<bool> ("include_cemented", false);
if (include_cemented)
{
response_l.put ("cemented", std::to_string (node.store.cemented_count (transaction)));
}
response_errors ();
}

View file

@ -2028,6 +2028,17 @@ void nano::mdb_store::confirmation_height_clear (nano::transaction const & trans
}
}
uint64_t nano::mdb_store::cemented_count (nano::transaction const & transaction_a)
{
uint64_t sum = 0;
for (auto i (latest_begin (transaction_a)), n (latest_end ()); i != n; ++i)
{
nano::account_info const & info (i->second);
sum += info.confirmation_height;
}
return sum;
}
void nano::mdb_store::pending_put (nano::transaction const & transaction_a, nano::pending_key const & key_a, nano::pending_info const & pending_a)
{
auto status (mdb_put (env.tx (transaction_a), get_pending_db (pending_a.epoch), nano::mdb_val (key_a), nano::mdb_val (pending_a), 0));

View file

@ -211,6 +211,7 @@ public:
size_t account_count (nano::transaction const &) override;
void confirmation_height_clear (nano::transaction const &, nano::account const & account, nano::account_info const & account_info) override;
void confirmation_height_clear (nano::transaction const &) override;
uint64_t cemented_count (nano::transaction const &) override;
nano::store_iterator<nano::account, nano::account_info> latest_v0_begin (nano::transaction const &, nano::account const &) override;
nano::store_iterator<nano::account, nano::account_info> latest_v0_begin (nano::transaction const &) override;
nano::store_iterator<nano::account, nano::account_info> latest_v0_end () override;

View file

@ -115,7 +115,7 @@ system ()
for (uint16_t i (0); i < count_a; ++i)
{
nano::node_config config (port_a + i, logging);
nano::system::add_node (config, nano::node_flags (), type_a);
add_node (config, nano::node_flags (), type_a);
}
}

View file

@ -83,7 +83,17 @@ void nano::rpc_handler::process_request ()
else if (action == "process")
{
auto force = request.get_optional<bool> ("force");
if (force && !rpc_config.enable_control)
if (force.is_initialized () && *force && !rpc_config.enable_control)
{
json_error_response (response, rpc_control_disabled_ec.message ());
error = true;
}
}
else if (action == "block_count")
{
// Cemented blocks can take a while to generate so require control
auto include_cemented = request.get_optional<bool> ("include_cemented");
if (include_cemented.is_initialized () && *include_cemented && !rpc_config.enable_control)
{
json_error_response (response, rpc_control_disabled_ec.message ());
error = true;

View file

@ -4,6 +4,7 @@
#include <functional>
#include <string>
#include <vector>
namespace nano
{

View file

@ -2687,26 +2687,71 @@ TEST (rpc, work_peer_many)
TEST (rpc, block_count)
{
nano::system system (24000, 1);
auto & node1 (*system.nodes[0]);
enable_ipc_transport_tcp (node1.config.ipc_config.transport_tcp);
nano::node_rpc_config node_rpc_config;
nano::ipc::ipc_server ipc_server (node1, node_rpc_config);
nano::rpc_config rpc_config (true);
nano::ipc_rpc_processor ipc_rpc_processor (system.io_ctx, rpc_config);
nano::rpc rpc (system.io_ctx, rpc_config, ipc_rpc_processor);
rpc.start ();
boost::property_tree::ptree request1;
request1.put ("action", "block_count");
test_response response1 (request1, rpc.config.port, system.io_ctx);
system.deadline_set (5s);
while (response1.status == 0)
{
ASSERT_NO_ERROR (system.poll ());
nano::system system (24000, 1);
auto & node1 (*system.nodes[0]);
enable_ipc_transport_tcp (node1.config.ipc_config.transport_tcp);
nano::node_rpc_config node_rpc_config;
nano::ipc::ipc_server ipc_server (node1, node_rpc_config);
nano::rpc_config rpc_config (true);
nano::ipc_rpc_processor ipc_rpc_processor (system.io_ctx, rpc_config);
nano::rpc rpc (system.io_ctx, rpc_config, ipc_rpc_processor);
rpc.start ();
boost::property_tree::ptree request1;
request1.put ("action", "block_count");
{
test_response response1 (request1, rpc.config.port, system.io_ctx);
system.deadline_set (5s);
while (response1.status == 0)
{
ASSERT_NO_ERROR (system.poll ());
}
ASSERT_EQ (200, response1.status);
ASSERT_EQ ("1", response1.json.get<std::string> ("count"));
ASSERT_EQ ("0", response1.json.get<std::string> ("unchecked"));
{
ASSERT_FALSE (response1.json.get_optional<std::string> ("cemented").is_initialized ());
}
}
request1.put ("include_cemented", "true");
test_response response1 (request1, rpc.config.port, system.io_ctx);
system.deadline_set (5s);
while (response1.status == 0)
{
ASSERT_NO_ERROR (system.poll ());
}
ASSERT_EQ (200, response1.status);
ASSERT_EQ ("1", response1.json.get<std::string> ("count"));
ASSERT_EQ ("0", response1.json.get<std::string> ("unchecked"));
ASSERT_EQ ("1", response1.json.get<std::string> ("cemented"));
}
// Should not be able to get the cemented count when enable_control is false.
{
nano::system system (24000, 1);
auto & node1 (*system.nodes[0]);
enable_ipc_transport_tcp (node1.config.ipc_config.transport_tcp);
nano::node_rpc_config node_rpc_config;
nano::ipc::ipc_server ipc_server (node1, node_rpc_config);
nano::rpc_config rpc_config (false);
nano::ipc_rpc_processor ipc_rpc_processor (system.io_ctx, rpc_config);
nano::rpc rpc (system.io_ctx, rpc_config, ipc_rpc_processor);
rpc.start ();
boost::property_tree::ptree request1;
request1.put ("action", "block_count");
request1.put ("include_cemented", "true");
{
test_response response1 (request1, rpc.config.port, system.io_ctx);
system.deadline_set (5s);
while (response1.status == 0)
{
ASSERT_NO_ERROR (system.poll ());
}
ASSERT_EQ (200, response1.status);
std::error_code ec (nano::error_rpc::rpc_control_disabled);
ASSERT_EQ (response1.json.get<std::string> ("error"), ec.message ());
}
}
ASSERT_EQ (200, response1.status);
ASSERT_EQ ("1", response1.json.get<std::string> ("count"));
ASSERT_EQ ("0", response1.json.get<std::string> ("unchecked"));
}
TEST (rpc, frontier_count)

View file

@ -281,6 +281,7 @@ public:
virtual size_t account_count (nano::transaction const &) = 0;
virtual void confirmation_height_clear (nano::transaction const &, nano::account const & account, nano::account_info const & account_info) = 0;
virtual void confirmation_height_clear (nano::transaction const &) = 0;
virtual uint64_t cemented_count (nano::transaction const &) = 0;
virtual nano::store_iterator<nano::account, nano::account_info> latest_v0_begin (nano::transaction const &, nano::account const &) = 0;
virtual nano::store_iterator<nano::account, nano::account_info> latest_v0_begin (nano::transaction const &) = 0;
virtual nano::store_iterator<nano::account, nano::account_info> latest_v0_end () = 0;