diff --git a/nano/core_test/block_store.cpp b/nano/core_test/block_store.cpp index 04f3e955f..d5fbf633d 100644 --- a/nano/core_test/block_store.cpp +++ b/nano/core_test/block_store.cpp @@ -412,214 +412,6 @@ TEST (block_store, genesis) ASSERT_EQ (nano::dev::genesis->account (), nano::dev::genesis_key.pub); } -// This test checks for basic operations in the unchecked table such as putting a new block, retrieving it, and -// deleting it from the database -TEST (unchecked, simple) -{ - nano::test::system system{}; - nano::logger_mt logger{}; - auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - nano::unchecked_map unchecked{ *store, false }; - ASSERT_TRUE (!store->init_error ()); - nano::block_builder builder; - auto block = builder - .send () - .previous (0) - .destination (1) - .balance (2) - .sign (nano::keypair ().prv, 4) - .work (5) - .build_shared (); - // Asserts the block wasn't added yet to the unchecked table - auto block_listing1 = unchecked.get (store->tx_begin_read (), block->previous ()); - ASSERT_TRUE (block_listing1.empty ()); - // Enqueues a block to be saved on the unchecked table - unchecked.put (block->previous (), nano::unchecked_info (block)); - // Waits for the block to get written in the database - auto check_block_is_listed = [&] (nano::transaction const & transaction_a, nano::block_hash const & block_hash_a) { - return unchecked.get (transaction_a, block_hash_a).size () > 0; - }; - ASSERT_TIMELY (5s, check_block_is_listed (store->tx_begin_read (), block->previous ())); - auto transaction = store->tx_begin_write (); - // Retrieves the block from the database - auto block_listing2 = unchecked.get (transaction, block->previous ()); - ASSERT_FALSE (block_listing2.empty ()); - // Asserts the added block is equal to the retrieved one - ASSERT_EQ (*block, *(block_listing2[0].block)); - // Deletes the block from the database - unchecked.del (transaction, nano::unchecked_key (block->previous (), block->hash ())); - // Asserts the block is deleted - auto block_listing3 = unchecked.get (transaction, block->previous ()); - ASSERT_TRUE (block_listing3.empty ()); -} - -// This test ensures the unchecked table is able to receive more than one block -TEST (unchecked, multiple) -{ - nano::test::system system{}; - if (nano::rocksdb_config::using_rocksdb_in_tests ()) - { - // Don't test this in rocksdb mode - return; - } - nano::logger_mt logger{}; - auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - nano::unchecked_map unchecked{ *store, false }; - ASSERT_TRUE (!store->init_error ()); - nano::block_builder builder; - auto block = builder - .send () - .previous (4) - .destination (1) - .balance (2) - .sign (nano::keypair ().prv, 4) - .work (5) - .build_shared (); - // Asserts the block wasn't added yet to the unchecked table - auto block_listing1 = unchecked.get (store->tx_begin_read (), block->previous ()); - ASSERT_TRUE (block_listing1.empty ()); - // Enqueues the first block - unchecked.put (block->previous (), nano::unchecked_info (block)); - // Enqueues a second block - unchecked.put (block->source (), nano::unchecked_info (block)); - auto check_block_is_listed = [&] (nano::transaction const & transaction_a, nano::block_hash const & block_hash_a) { - return unchecked.get (transaction_a, block_hash_a).size () > 0; - }; - // Waits for and asserts the first block gets saved in the database - ASSERT_TIMELY (5s, check_block_is_listed (store->tx_begin_read (), block->previous ())); - // Waits for and asserts the second block gets saved in the database - ASSERT_TIMELY (5s, check_block_is_listed (store->tx_begin_read (), block->source ())); -} - -// This test ensures that a block can't occur twice in the unchecked table. -TEST (unchecked, double_put) -{ - nano::test::system system{}; - nano::logger_mt logger{}; - auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - nano::unchecked_map unchecked{ *store, false }; - ASSERT_TRUE (!store->init_error ()); - nano::block_builder builder; - auto block = builder - .send () - .previous (4) - .destination (1) - .balance (2) - .sign (nano::keypair ().prv, 4) - .work (5) - .build_shared (); - // Asserts the block wasn't added yet to the unchecked table - auto block_listing1 = unchecked.get (store->tx_begin_read (), block->previous ()); - ASSERT_TRUE (block_listing1.empty ()); - // Enqueues the block to be saved in the unchecked table - unchecked.put (block->previous (), nano::unchecked_info (block)); - // Enqueues the block again in an attempt to have it there twice - unchecked.put (block->previous (), nano::unchecked_info (block)); - auto check_block_is_listed = [&] (nano::transaction const & transaction_a, nano::block_hash const & block_hash_a) { - return unchecked.get (transaction_a, block_hash_a).size () > 0; - }; - // Waits for and asserts the block was added at least once - ASSERT_TIMELY (5s, check_block_is_listed (store->tx_begin_read (), block->previous ())); - // Asserts the block was added at most once -- this is objective of this test. - auto block_listing2 = unchecked.get (store->tx_begin_read (), block->previous ()); - ASSERT_EQ (block_listing2.size (), 1); -} - -// Tests that recurrent get calls return the correct values -TEST (unchecked, multiple_get) -{ - nano::test::system system{}; - nano::logger_mt logger{}; - auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - nano::unchecked_map unchecked{ *store, false }; - ASSERT_TRUE (!store->init_error ()); - // Instantiates three blocks - nano::block_builder builder; - auto block1 = builder - .send () - .previous (4) - .destination (1) - .balance (2) - .sign (nano::keypair ().prv, 4) - .work (5) - .build_shared (); - auto block2 = builder - .send () - .previous (3) - .destination (1) - .balance (2) - .sign (nano::keypair ().prv, 4) - .work (5) - .build_shared (); - auto block3 = builder - .send () - .previous (5) - .destination (1) - .balance (2) - .sign (nano::keypair ().prv, 4) - .work (5) - .build_shared (); - // Add the blocks' info to the unchecked table - unchecked.put (block1->previous (), nano::unchecked_info (block1)); // unchecked1 - unchecked.put (block1->hash (), nano::unchecked_info (block1)); // unchecked2 - unchecked.put (block2->previous (), nano::unchecked_info (block2)); // unchecked3 - unchecked.put (block1->previous (), nano::unchecked_info (block2)); // unchecked1 - unchecked.put (block1->hash (), nano::unchecked_info (block2)); // unchecked2 - unchecked.put (block3->previous (), nano::unchecked_info (block3)); - unchecked.put (block3->hash (), nano::unchecked_info (block3)); // unchecked4 - unchecked.put (block1->previous (), nano::unchecked_info (block3)); // unchecked1 - - // count the number of blocks in the unchecked table by counting them one by one - // we cannot trust the count() method if the backend is rocksdb - auto count_unchecked_blocks_one_by_one = [&store, &unchecked] () { - size_t count = 0; - auto transaction = store->tx_begin_read (); - unchecked.for_each (transaction, [&count] (nano::unchecked_key const & key, nano::unchecked_info const & info) { - ++count; - }); - return count; - }; - - // Waits for the blocks to get saved in the database - ASSERT_TIMELY (5s, 8 == count_unchecked_blocks_one_by_one ()); - - std::vector unchecked1; - // Asserts the entries will be found for the provided key - auto transaction = store->tx_begin_read (); - auto unchecked1_blocks = unchecked.get (transaction, block1->previous ()); - ASSERT_EQ (unchecked1_blocks.size (), 3); - for (auto & i : unchecked1_blocks) - { - unchecked1.push_back (i.block->hash ()); - } - // Asserts the payloads where correclty saved - ASSERT_TRUE (std::find (unchecked1.begin (), unchecked1.end (), block1->hash ()) != unchecked1.end ()); - ASSERT_TRUE (std::find (unchecked1.begin (), unchecked1.end (), block2->hash ()) != unchecked1.end ()); - ASSERT_TRUE (std::find (unchecked1.begin (), unchecked1.end (), block3->hash ()) != unchecked1.end ()); - std::vector unchecked2; - // Asserts the entries will be found for the provided key - auto unchecked2_blocks = unchecked.get (transaction, block1->hash ()); - ASSERT_EQ (unchecked2_blocks.size (), 2); - for (auto & i : unchecked2_blocks) - { - unchecked2.push_back (i.block->hash ()); - } - // Asserts the payloads where correctly saved - ASSERT_TRUE (std::find (unchecked2.begin (), unchecked2.end (), block1->hash ()) != unchecked2.end ()); - ASSERT_TRUE (std::find (unchecked2.begin (), unchecked2.end (), block2->hash ()) != unchecked2.end ()); - // Asserts the entry is found by the key and the payload is saved - auto unchecked3 = unchecked.get (transaction, block2->previous ()); - ASSERT_EQ (unchecked3.size (), 1); - ASSERT_EQ (unchecked3[0].block->hash (), block2->hash ()); - // Asserts the entry is found by the key and the payload is saved - auto unchecked4 = unchecked.get (transaction, block3->hash ()); - ASSERT_EQ (unchecked4.size (), 1); - ASSERT_EQ (unchecked4[0].block->hash (), block3->hash ()); - // Asserts no entry is found for a block that wasn't added - auto unchecked5 = unchecked.get (transaction, block2->hash ()); - ASSERT_EQ (unchecked5.size (), 0); -} - TEST (block_store, empty_accounts) { nano::logger_mt logger; @@ -653,9 +445,10 @@ TEST (block_store, one_block) TEST (block_store, empty_bootstrap) { + nano::test::system system{}; nano::logger_mt logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - nano::unchecked_map unchecked{ *store, false }; + nano::unchecked_map unchecked{ *store, system.stats, false }; ASSERT_TRUE (!store->init_error ()); auto transaction (store->tx_begin_read ()); size_t count = 0; @@ -1176,10 +969,11 @@ namespace lmdb // Databases need to be dropped in order to convert to dupsort compatible TEST (block_store, DISABLED_change_dupsort) // Unchecked is no longer dupsort table { + nano::test::system system{}; auto path (nano::unique_path ()); nano::logger_mt logger{}; nano::lmdb::store store{ logger, path, nano::dev::constants }; - nano::unchecked_map unchecked{ store, false }; + nano::unchecked_map unchecked{ store, system.stats, false }; auto transaction (store.tx_begin_write ()); ASSERT_EQ (0, mdb_drop (store.env.tx (transaction), store.unchecked_store.unchecked_handle, 1)); ASSERT_EQ (0, mdb_dbi_open (store.env.tx (transaction), "unchecked", MDB_CREATE, &store.unchecked_store.unchecked_handle)); diff --git a/nano/core_test/ledger.cpp b/nano/core_test/ledger.cpp index 6ee3fd27d..b6f8024fd 100644 --- a/nano/core_test/ledger.cpp +++ b/nano/core_test/ledger.cpp @@ -5535,12 +5535,13 @@ TEST (ledger, hash_root_random) TEST (ledger, migrate_lmdb_to_rocksdb) { + nano::test::system system{}; auto path = nano::unique_path (); nano::logger_mt logger{}; boost::asio::ip::address_v6 address (boost::asio::ip::make_address_v6 ("::ffff:127.0.0.1")); uint16_t port = 100; nano::lmdb::store store{ logger, path / "data.ldb", nano::dev::constants }; - nano::unchecked_map unchecked{ store, false }; + nano::unchecked_map unchecked{ store, system.stats, false }; nano::stats stats{}; nano::ledger ledger{ store, stats, nano::dev::constants }; nano::work_pool pool{ nano::dev::network_params.network, std::numeric_limits::max () }; @@ -5582,7 +5583,7 @@ TEST (ledger, migrate_lmdb_to_rocksdb) ASSERT_FALSE (error); nano::rocksdb::store rocksdb_store{ logger, path / "rocksdb", nano::dev::constants }; - nano::unchecked_map rocksdb_unchecked{ rocksdb_store, false }; + nano::unchecked_map rocksdb_unchecked{ rocksdb_store, system.stats, false }; auto rocksdb_transaction (rocksdb_store.tx_begin_read ()); nano::pending_info pending_info{}; diff --git a/nano/core_test/unchecked_map.cpp b/nano/core_test/unchecked_map.cpp index 895c199f6..b47141318 100644 --- a/nano/core_test/unchecked_map.cpp +++ b/nano/core_test/unchecked_map.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -19,10 +20,11 @@ class context public: context () : store{ nano::make_store (logger, nano::unique_path (), nano::dev::constants) }, - unchecked{ *store, false } + unchecked{ *store, stats, false } { } nano::logger_mt logger; + nano::stats stats; std::unique_ptr store; nano::unchecked_map unchecked; }; @@ -58,7 +60,7 @@ TEST (block_store, one_bootstrap) nano::test::system system{}; nano::logger_mt logger{}; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); - nano::unchecked_map unchecked{ *store, false }; + nano::unchecked_map unchecked{ *store, system.stats, false }; ASSERT_TRUE (!store->init_error ()); nano::block_builder builder; auto block1 = builder @@ -87,3 +89,211 @@ TEST (block_store, one_bootstrap) auto block2 = blocks[0].block; ASSERT_EQ (*block1, *block2); } + +// This test checks for basic operations in the unchecked table such as putting a new block, retrieving it, and +// deleting it from the database +TEST (unchecked, simple) +{ + nano::test::system system{}; + nano::logger_mt logger{}; + auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); + nano::unchecked_map unchecked{ *store, system.stats, false }; + ASSERT_TRUE (!store->init_error ()); + nano::block_builder builder; + auto block = builder + .send () + .previous (0) + .destination (1) + .balance (2) + .sign (nano::keypair ().prv, 4) + .work (5) + .build_shared (); + // Asserts the block wasn't added yet to the unchecked table + auto block_listing1 = unchecked.get (store->tx_begin_read (), block->previous ()); + ASSERT_TRUE (block_listing1.empty ()); + // Enqueues a block to be saved on the unchecked table + unchecked.put (block->previous (), nano::unchecked_info (block)); + // Waits for the block to get written in the database + auto check_block_is_listed = [&] (nano::transaction const & transaction_a, nano::block_hash const & block_hash_a) { + return unchecked.get (transaction_a, block_hash_a).size () > 0; + }; + ASSERT_TIMELY (5s, check_block_is_listed (store->tx_begin_read (), block->previous ())); + auto transaction = store->tx_begin_write (); + // Retrieves the block from the database + auto block_listing2 = unchecked.get (transaction, block->previous ()); + ASSERT_FALSE (block_listing2.empty ()); + // Asserts the added block is equal to the retrieved one + ASSERT_EQ (*block, *(block_listing2[0].block)); + // Deletes the block from the database + unchecked.del (transaction, nano::unchecked_key (block->previous (), block->hash ())); + // Asserts the block is deleted + auto block_listing3 = unchecked.get (transaction, block->previous ()); + ASSERT_TRUE (block_listing3.empty ()); +} + +// This test ensures the unchecked table is able to receive more than one block +TEST (unchecked, multiple) +{ + nano::test::system system{}; + if (nano::rocksdb_config::using_rocksdb_in_tests ()) + { + // Don't test this in rocksdb mode + return; + } + nano::logger_mt logger{}; + auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); + nano::unchecked_map unchecked{ *store, system.stats, false }; + ASSERT_TRUE (!store->init_error ()); + nano::block_builder builder; + auto block = builder + .send () + .previous (4) + .destination (1) + .balance (2) + .sign (nano::keypair ().prv, 4) + .work (5) + .build_shared (); + // Asserts the block wasn't added yet to the unchecked table + auto block_listing1 = unchecked.get (store->tx_begin_read (), block->previous ()); + ASSERT_TRUE (block_listing1.empty ()); + // Enqueues the first block + unchecked.put (block->previous (), nano::unchecked_info (block)); + // Enqueues a second block + unchecked.put (block->source (), nano::unchecked_info (block)); + auto check_block_is_listed = [&] (nano::transaction const & transaction_a, nano::block_hash const & block_hash_a) { + return unchecked.get (transaction_a, block_hash_a).size () > 0; + }; + // Waits for and asserts the first block gets saved in the database + ASSERT_TIMELY (5s, check_block_is_listed (store->tx_begin_read (), block->previous ())); + // Waits for and asserts the second block gets saved in the database + ASSERT_TIMELY (5s, check_block_is_listed (store->tx_begin_read (), block->source ())); +} + +// This test ensures that a block can't occur twice in the unchecked table. +TEST (unchecked, double_put) +{ + nano::test::system system{}; + nano::logger_mt logger{}; + auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); + nano::unchecked_map unchecked{ *store, system.stats, false }; + ASSERT_TRUE (!store->init_error ()); + nano::block_builder builder; + auto block = builder + .send () + .previous (4) + .destination (1) + .balance (2) + .sign (nano::keypair ().prv, 4) + .work (5) + .build_shared (); + // Asserts the block wasn't added yet to the unchecked table + auto block_listing1 = unchecked.get (store->tx_begin_read (), block->previous ()); + ASSERT_TRUE (block_listing1.empty ()); + // Enqueues the block to be saved in the unchecked table + unchecked.put (block->previous (), nano::unchecked_info (block)); + // Enqueues the block again in an attempt to have it there twice + unchecked.put (block->previous (), nano::unchecked_info (block)); + auto check_block_is_listed = [&] (nano::transaction const & transaction_a, nano::block_hash const & block_hash_a) { + return unchecked.get (transaction_a, block_hash_a).size () > 0; + }; + // Waits for and asserts the block was added at least once + ASSERT_TIMELY (5s, check_block_is_listed (store->tx_begin_read (), block->previous ())); + // Asserts the block was added at most once -- this is objective of this test. + auto block_listing2 = unchecked.get (store->tx_begin_read (), block->previous ()); + ASSERT_EQ (block_listing2.size (), 1); +} + +// Tests that recurrent get calls return the correct values +TEST (unchecked, multiple_get) +{ + nano::test::system system{}; + nano::logger_mt logger{}; + auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); + nano::unchecked_map unchecked{ *store, system.stats, false }; + ASSERT_TRUE (!store->init_error ()); + // Instantiates three blocks + nano::block_builder builder; + auto block1 = builder + .send () + .previous (4) + .destination (1) + .balance (2) + .sign (nano::keypair ().prv, 4) + .work (5) + .build_shared (); + auto block2 = builder + .send () + .previous (3) + .destination (1) + .balance (2) + .sign (nano::keypair ().prv, 4) + .work (5) + .build_shared (); + auto block3 = builder + .send () + .previous (5) + .destination (1) + .balance (2) + .sign (nano::keypair ().prv, 4) + .work (5) + .build_shared (); + // Add the blocks' info to the unchecked table + unchecked.put (block1->previous (), nano::unchecked_info (block1)); // unchecked1 + unchecked.put (block1->hash (), nano::unchecked_info (block1)); // unchecked2 + unchecked.put (block2->previous (), nano::unchecked_info (block2)); // unchecked3 + unchecked.put (block1->previous (), nano::unchecked_info (block2)); // unchecked1 + unchecked.put (block1->hash (), nano::unchecked_info (block2)); // unchecked2 + unchecked.put (block3->previous (), nano::unchecked_info (block3)); + unchecked.put (block3->hash (), nano::unchecked_info (block3)); // unchecked4 + unchecked.put (block1->previous (), nano::unchecked_info (block3)); // unchecked1 + + // count the number of blocks in the unchecked table by counting them one by one + // we cannot trust the count() method if the backend is rocksdb + auto count_unchecked_blocks_one_by_one = [&store, &unchecked] () { + size_t count = 0; + auto transaction = store->tx_begin_read (); + unchecked.for_each (transaction, [&count] (nano::unchecked_key const & key, nano::unchecked_info const & info) { + ++count; + }); + return count; + }; + + // Waits for the blocks to get saved in the database + ASSERT_TIMELY (5s, 8 == count_unchecked_blocks_one_by_one ()); + + std::vector unchecked1; + // Asserts the entries will be found for the provided key + auto transaction = store->tx_begin_read (); + auto unchecked1_blocks = unchecked.get (transaction, block1->previous ()); + ASSERT_EQ (unchecked1_blocks.size (), 3); + for (auto & i : unchecked1_blocks) + { + unchecked1.push_back (i.block->hash ()); + } + // Asserts the payloads where correclty saved + ASSERT_TRUE (std::find (unchecked1.begin (), unchecked1.end (), block1->hash ()) != unchecked1.end ()); + ASSERT_TRUE (std::find (unchecked1.begin (), unchecked1.end (), block2->hash ()) != unchecked1.end ()); + ASSERT_TRUE (std::find (unchecked1.begin (), unchecked1.end (), block3->hash ()) != unchecked1.end ()); + std::vector unchecked2; + // Asserts the entries will be found for the provided key + auto unchecked2_blocks = unchecked.get (transaction, block1->hash ()); + ASSERT_EQ (unchecked2_blocks.size (), 2); + for (auto & i : unchecked2_blocks) + { + unchecked2.push_back (i.block->hash ()); + } + // Asserts the payloads where correctly saved + ASSERT_TRUE (std::find (unchecked2.begin (), unchecked2.end (), block1->hash ()) != unchecked2.end ()); + ASSERT_TRUE (std::find (unchecked2.begin (), unchecked2.end (), block2->hash ()) != unchecked2.end ()); + // Asserts the entry is found by the key and the payload is saved + auto unchecked3 = unchecked.get (transaction, block2->previous ()); + ASSERT_EQ (unchecked3.size (), 1); + ASSERT_EQ (unchecked3[0].block->hash (), block2->hash ()); + // Asserts the entry is found by the key and the payload is saved + auto unchecked4 = unchecked.get (transaction, block3->hash ()); + ASSERT_EQ (unchecked4.size (), 1); + ASSERT_EQ (unchecked4[0].block->hash (), block3->hash ()); + // Asserts no entry is found for a block that wasn't added + auto unchecked5 = unchecked.get (transaction, block2->hash ()); + ASSERT_EQ (unchecked5.size (), 0); +} diff --git a/nano/lib/stats_enums.hpp b/nano/lib/stats_enums.hpp index bea21b629..41bac781a 100644 --- a/nano/lib/stats_enums.hpp +++ b/nano/lib/stats_enums.hpp @@ -36,6 +36,7 @@ enum class type : uint8_t bootstrap_server, active, backlog, + unchecked, _last // Must be the last enum }; @@ -257,6 +258,11 @@ enum class detail : uint8_t // backlog activated, + // unchecked + put, + satisfied, + trigger, + _last // Must be the last enum }; @@ -275,4 +281,4 @@ namespace nano std::string_view to_string (stat::type type); std::string_view to_string (stat::detail detail); std::string_view to_string (stat::dir dir); -} \ No newline at end of file +} diff --git a/nano/node/node.cpp b/nano/node/node.cpp index a7d0b6a7e..7b96066c5 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -159,7 +159,7 @@ nano::node::node (boost::asio::io_context & io_ctx_a, boost::filesystem::path co logger (config_a.logging.min_time_between_log_output), store_impl (nano::make_store (logger, application_path_a, network_params.ledger, flags.read_only, true, config_a.rocksdb_config, config_a.diagnostics_config.txn_tracking, config_a.block_processor_batch_max_time, config_a.lmdb_config, config_a.backup_before_upgrade)), store (*store_impl), - unchecked{ store, flags.disable_block_processor_unchecked_deletion }, + unchecked{ store, stats, flags.disable_block_processor_unchecked_deletion }, wallets_store_impl (std::make_unique (application_path_a / "wallets.ldb", config_a.lmdb_config)), wallets_store (*wallets_store_impl), gap_cache (*this), diff --git a/nano/node/unchecked_map.cpp b/nano/node/unchecked_map.cpp index 8f2921415..1a4ea8230 100644 --- a/nano/node/unchecked_map.cpp +++ b/nano/node/unchecked_map.cpp @@ -1,11 +1,14 @@ #include +#include +#include #include #include #include #include -nano::unchecked_map::unchecked_map (nano::store & store, bool const & disable_delete) : +nano::unchecked_map::unchecked_map (nano::store & store, nano::stats & stats, bool const & disable_delete) : store{ store }, + stats{ stats }, disable_delete{ disable_delete }, thread{ [this] () { run (); } } { @@ -22,6 +25,7 @@ void nano::unchecked_map::put (nano::hash_or_account const & dependency, nano::u nano::unique_lock lock{ mutex }; buffer.push_back (std::make_pair (dependency, info)); lock.unlock (); + stats.inc (nano::stat::type::unchecked, nano::stat::detail::put); condition.notify_all (); // Notify run () } @@ -151,6 +155,7 @@ void nano::unchecked_map::trigger (nano::hash_or_account const & dependency) buffer.push_back (dependency); debug_assert (buffer.back ().which () == 1); // which stands for "query". lock.unlock (); + stats.inc (nano::stat::type::unchecked, nano::stat::detail::trigger); condition.notify_all (); // Notify run () } @@ -247,6 +252,7 @@ void nano::unchecked_map::query_impl (nano::write_transaction const & transactio std::deque delete_queue; for_each (transaction, hash, [this, &delete_queue] (nano::unchecked_key const & key, nano::unchecked_info const & info) { delete_queue.push_back (key); + stats.inc (nano::stat::type::unchecked, nano::stat::detail::satisfied); satisfied (info); }); if (!disable_delete) diff --git a/nano/node/unchecked_map.hpp b/nano/node/unchecked_map.hpp index 30fc3e96f..3042cdc63 100644 --- a/nano/node/unchecked_map.hpp +++ b/nano/node/unchecked_map.hpp @@ -16,15 +16,17 @@ namespace mi = boost::multi_index; namespace nano { +class stats; class store; class transaction; class unchecked_info; class unchecked_key; class write_transaction; + class unchecked_map { public: - unchecked_map (nano::store & store, bool const & do_delete); + unchecked_map (nano::store &, nano::stats &, bool const & do_delete); ~unchecked_map (); void put (nano::hash_or_account const & dependency, nano::unchecked_info const & info); @@ -62,6 +64,9 @@ private: void insert_impl (nano::write_transaction const & transaction, nano::hash_or_account const & dependency, nano::unchecked_info const & info); void query_impl (nano::write_transaction const & transaction, nano::block_hash const & hash); nano::store & store; + nano::stats & stats; + +private: bool const & disable_delete; std::deque> buffer; std::deque> back_buffer;