diff --git a/nano/core_test/ledger.cpp b/nano/core_test/ledger.cpp index b9ffb56497..790b1c962e 100644 --- a/nano/core_test/ledger.cpp +++ b/nano/core_test/ledger.cpp @@ -49,6 +49,7 @@ TEST (ledger, genesis_balance) ASSERT_EQ (nano::genesis_amount, amount); nano::account_info info; ASSERT_FALSE (store->account_get (transaction, nano::genesis_account, info)); + ASSERT_EQ (1, ledger.cache.account_count); // Frontier time should have been updated when genesis balance was added ASSERT_GE (nano::seconds_since_epoch (), info.modified); ASSERT_LT (nano::seconds_since_epoch () - info.modified, 10); @@ -163,6 +164,7 @@ TEST (ledger, process_send) ASSERT_TRUE (ledger.store.pending_get (transaction, nano::pending_key (key2.pub, hash1), pending2)); ASSERT_EQ (nano::genesis_amount, ledger.account_balance (transaction, nano::test_genesis_key.pub)); ASSERT_EQ (0, ledger.account_pending (transaction, key2.pub)); + ASSERT_EQ (store->account_count (transaction), ledger.cache.account_count); } TEST (ledger, process_receive) @@ -221,6 +223,7 @@ TEST (ledger, process_receive) ASSERT_FALSE (ledger.store.pending_get (transaction, nano::pending_key (key2.pub, hash3), pending1)); ASSERT_EQ (nano::test_genesis_key.pub, pending1.source); ASSERT_EQ (25, pending1.amount.number ()); + ASSERT_EQ (store->account_count (transaction), ledger.cache.account_count); } TEST (ledger, rollback_receiver) @@ -258,6 +261,7 @@ TEST (ledger, rollback_receiver) ASSERT_EQ (0, ledger.weight (key3.pub)); nano::account_info info2; ASSERT_TRUE (ledger.store.account_get (transaction, key2.pub, info2)); + ASSERT_EQ (store->account_count (transaction), ledger.cache.account_count); nano::pending_info pending1; ASSERT_TRUE (ledger.store.pending_get (transaction, nano::pending_key (key2.pub, info2.head), pending1)); } @@ -1226,6 +1230,7 @@ TEST (ledger, fail_open_fork_previous) ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, block3).code); nano::open_block block4 (block2.hash (), 1, key1.pub, key1.prv, key1.pub, *pool.generate (key1.pub)); ASSERT_EQ (nano::process_result::fork, ledger.process (transaction, block4).code); + ASSERT_EQ (store->account_count (transaction), ledger.cache.account_count); } TEST (ledger, fail_open_account_mismatch) @@ -1245,6 +1250,7 @@ TEST (ledger, fail_open_account_mismatch) nano::keypair badkey; nano::open_block block2 (block1.hash (), 1, badkey.pub, badkey.prv, badkey.pub, *pool.generate (badkey.pub)); ASSERT_NE (nano::process_result::progress, ledger.process (transaction, block2).code); + ASSERT_EQ (store->account_count (transaction), ledger.cache.account_count); } TEST (ledger, fail_receive_old) @@ -1707,6 +1713,7 @@ TEST (ledger, state_send_receive) ASSERT_EQ (nano::Gxrb_ratio, ledger.amount (transaction, receive1.hash ())); ASSERT_EQ (nano::genesis_amount, ledger.weight (nano::genesis_account)); ASSERT_FALSE (store->pending_exists (transaction, nano::pending_key (nano::genesis_account, send1.hash ()))); + ASSERT_EQ (store->account_count (transaction), ledger.cache.account_count); } TEST (ledger, state_receive) @@ -1796,6 +1803,7 @@ TEST (ledger, state_open) ASSERT_EQ (nano::Gxrb_ratio, ledger.balance (transaction, open1.hash ())); ASSERT_EQ (nano::Gxrb_ratio, ledger.amount (transaction, open1.hash ())); ASSERT_EQ (nano::genesis_amount, ledger.weight (nano::genesis_account)); + ASSERT_EQ (ledger.cache.account_count, store->account_count (transaction)); } // Make sure old block types can't be inserted after a state block. @@ -1984,6 +1992,7 @@ TEST (ledger, state_state_open_fork) nano::state_block open2 (destination.pub, 0, nano::genesis_account, nano::Gxrb_ratio, send1.hash (), destination.prv, destination.pub, *pool.generate (destination.pub)); ASSERT_EQ (nano::process_result::fork, ledger.process (transaction, open2).code); ASSERT_EQ (open1.root (), open2.root ()); + ASSERT_EQ (store->account_count (transaction), ledger.cache.account_count); } TEST (ledger, state_open_previous_fail) @@ -2154,6 +2163,7 @@ TEST (ledger, state_rollback_send) ASSERT_EQ (nano::genesis_amount, ledger.weight (nano::genesis_account)); ASSERT_FALSE (store->pending_exists (transaction, nano::pending_key (nano::genesis_account, send1.hash ()))); ASSERT_TRUE (store->block_successor (transaction, genesis.hash ()).is_zero ()); + ASSERT_EQ (store->account_count (transaction), ledger.cache.account_count); } TEST (ledger, state_rollback_receive) @@ -2180,6 +2190,7 @@ TEST (ledger, state_rollback_receive) ASSERT_FALSE (store->block_exists (transaction, receive1.hash ())); ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.account_balance (transaction, nano::genesis_account)); ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.weight (nano::genesis_account)); + ASSERT_EQ (store->account_count (transaction), ledger.cache.account_count); } TEST (ledger, state_rollback_received_send) @@ -2207,6 +2218,7 @@ TEST (ledger, state_rollback_received_send) ASSERT_EQ (nano::genesis_amount, ledger.weight (nano::genesis_account)); ASSERT_EQ (0, ledger.account_balance (transaction, key.pub)); ASSERT_EQ (0, ledger.weight (key.pub)); + ASSERT_EQ (store->account_count (transaction), ledger.cache.account_count); } TEST (ledger, state_rep_change_rollback) @@ -2254,6 +2266,7 @@ TEST (ledger, state_open_rollback) ASSERT_FALSE (store->pending_get (transaction, nano::pending_key (destination.pub, send1.hash ()), info)); ASSERT_EQ (nano::genesis_account, info.source); ASSERT_EQ (nano::Gxrb_ratio, info.amount.number ()); + ASSERT_EQ (store->account_count (transaction), ledger.cache.account_count); } TEST (ledger, state_send_change_rollback) @@ -2275,6 +2288,7 @@ TEST (ledger, state_send_change_rollback) ASSERT_EQ (nano::genesis_amount, ledger.account_balance (transaction, nano::genesis_account)); ASSERT_EQ (nano::genesis_amount, ledger.weight (nano::genesis_account)); ASSERT_EQ (0, ledger.weight (rep.pub)); + ASSERT_EQ (store->account_count (transaction), ledger.cache.account_count); } TEST (ledger, state_receive_change_rollback) @@ -2298,6 +2312,7 @@ TEST (ledger, state_receive_change_rollback) ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.account_balance (transaction, nano::genesis_account)); ASSERT_EQ (nano::genesis_amount - nano::Gxrb_ratio, ledger.weight (nano::genesis_account)); ASSERT_EQ (0, ledger.weight (rep.pub)); + ASSERT_EQ (store->account_count (transaction), ledger.cache.account_count); } TEST (ledger, epoch_blocks_v1_general) @@ -2461,6 +2476,7 @@ TEST (ledger, epoch_blocks_receive_upgrade) ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, send6).code); nano::state_block epoch4 (destination4.pub, 0, 0, 0, ledger.epoch_link (nano::epoch::epoch_2), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (destination4.pub)); ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, epoch4).code); + ASSERT_EQ (store->account_count (transaction), ledger.cache.account_count); } TEST (ledger, epoch_blocks_fork) diff --git a/nano/node/json_handler.cpp b/nano/node/json_handler.cpp index 4a0150d087..25598ed749 100644 --- a/nano/node/json_handler.cpp +++ b/nano/node/json_handler.cpp @@ -2295,8 +2295,7 @@ void nano::json_handler::frontiers () void nano::json_handler::account_count () { - auto transaction (node.store.tx_begin_read ()); - auto size (node.store.account_count (transaction)); + auto size (node.ledger.cache.account_count.load ()); response_l.put ("count", std::to_string (size)); response_errors (); } diff --git a/nano/node/network.cpp b/nano/node/network.cpp index 4b82b31bbc..a94a46b170 100644 --- a/nano/node/network.cpp +++ b/nano/node/network.cpp @@ -525,11 +525,7 @@ class network_message_visitor : public nano::message_visitor telemetry_data.unchecked_count = node.ledger.cache.unchecked_count; telemetry_data.genesis_block = nano::genesis ().hash (); telemetry_data.peer_count = node.network.size (); - - { - auto transaction = node.store.tx_begin_read (); - telemetry_data.account_count = node.store.account_count (transaction); - } + telemetry_data.account_count = node.ledger.cache.account_count; nano::telemetry_ack telemetry_ack (telemetry_data); channel->send (telemetry_ack); diff --git a/nano/node/rocksdb/rocksdb.cpp b/nano/node/rocksdb/rocksdb.cpp index 35056dbbb5..1fca537072 100644 --- a/nano/node/rocksdb/rocksdb.cpp +++ b/nano/node/rocksdb/rocksdb.cpp @@ -278,7 +278,6 @@ bool nano::rocksdb_store::is_caching_counts (nano::tables table_a) const { switch (table_a) { - case tables::accounts: case tables::send_blocks: case tables::receive_blocks: case tables::open_blocks: diff --git a/nano/secure/blockstore_partial.hpp b/nano/secure/blockstore_partial.hpp index ab723a3c3f..da83a8fc90 100644 --- a/nano/secure/blockstore_partial.hpp +++ b/nano/secure/blockstore_partial.hpp @@ -27,17 +27,18 @@ class block_store_partial : public block_store * If using a different store version than the latest then you may need * to modify some of the objects in the store to be appropriate for the version before an upgrade. */ - void initialize (nano::write_transaction const & transaction_a, nano::genesis const & genesis_a, nano::ledger_cache & ledge_cache_a) override + void initialize (nano::write_transaction const & transaction_a, nano::genesis const & genesis_a, nano::ledger_cache & ledger_cache_a) override { auto hash_l (genesis_a.hash ()); assert (latest_begin (transaction_a) == latest_end ()); nano::block_sideband sideband (nano::block_type::open, network_params.ledger.genesis_account, 0, network_params.ledger.genesis_amount, 1, nano::seconds_since_epoch (), nano::epoch::epoch_0); block_put (transaction_a, hash_l, *genesis_a.open, sideband); - ++ledge_cache_a.block_count; + ++ledger_cache_a.block_count; confirmation_height_put (transaction_a, network_params.ledger.genesis_account, nano::confirmation_height_info{ 1, genesis_a.hash () }); - ++ledge_cache_a.cemented_count; + ++ledger_cache_a.cemented_count; account_put (transaction_a, network_params.ledger.genesis_account, { hash_l, network_params.ledger.genesis_account, genesis_a.open->hash (), std::numeric_limits::max (), nano::seconds_since_epoch (), 1, nano::epoch::epoch_0 }); - ledge_cache_a.rep_weights.representation_put (network_params.ledger.genesis_account, std::numeric_limits::max ()); + ++ledger_cache_a.account_count; + ledger_cache_a.rep_weights.representation_put (network_params.ledger.genesis_account, std::numeric_limits::max ()); frontier_put (transaction_a, hash_l, network_params.ledger.genesis_account); } diff --git a/nano/secure/common.hpp b/nano/secure/common.hpp index 6fe99d6980..650bcbd9ee 100644 --- a/nano/secure/common.hpp +++ b/nano/secure/common.hpp @@ -477,6 +477,7 @@ class generate_cache bool reps = true; bool cemented_count = true; bool unchecked_count = true; + bool account_count = true; }; /* Holds an in-memory cache of various counts */ @@ -487,6 +488,7 @@ class ledger_cache std::atomic cemented_count{ 0 }; std::atomic block_count{ 0 }; std::atomic unchecked_count{ 0 }; + std::atomic account_count{ 0 }; }; nano::wallet_id random_wallet_id (); diff --git a/nano/secure/ledger.cpp b/nano/secure/ledger.cpp index de5a4616a3..98a1906c93 100644 --- a/nano/secure/ledger.cpp +++ b/nano/secure/ledger.cpp @@ -691,12 +691,13 @@ check_bootstrap_weights (true) if (!store.init_error ()) { auto transaction = store.tx_begin_read (); - if (generate_cache_a.reps) + if (generate_cache_a.reps || generate_cache_a.account_count) { for (auto i (store.latest_begin (transaction)), n (store.latest_end ()); i != n; ++i) { nano::account_info const & info (i->second); cache.rep_weights.representation_add (info.representative, info.balance.number ()); + ++cache.account_count; } } @@ -1043,6 +1044,7 @@ void nano::ledger::change_latest (nano::write_transaction const & transaction_a, { assert (!store.confirmation_height_exists (transaction_a, account_a)); store.confirmation_height_put (transaction_a, account_a, { 0, nano::block_hash (0) }); + ++cache.account_count; } if (!old_a.head.is_zero () && old_a.epoch () != new_a.epoch ()) { @@ -1055,6 +1057,8 @@ void nano::ledger::change_latest (nano::write_transaction const & transaction_a, { store.confirmation_height_del (transaction_a, account_a); store.account_del (transaction_a, account_a); + assert (cache.account_count > 0); + --cache.account_count; } }