diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index 4f81bf23..0fc6d35b 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -72,11 +72,20 @@ TEST (node_DeathTest, DISABLED_readonly_block_store_not_exist) TEST (node_DeathTest, readonly_block_store_not_exist) #endif { - // For ASSERT_DEATH_IF_SUPPORTED - testing::FLAGS_gtest_death_test_style = "threadsafe"; - // This is a read-only node with no ledger file - ASSERT_EXIT (nano::inactive_node (nano::unique_path (), nano::inactive_node_flag_defaults ()), ::testing::ExitedWithCode (1), ""); +#if NANO_ROCKSDB + if (nano::using_rocksdb_in_tests ()) + { + nano::inactive_node node (nano::unique_path (), nano::inactive_node_flag_defaults ()); + ASSERT_TRUE (node.node->init_error ()); + } + else + { + ASSERT_EXIT (nano::inactive_node node (nano::unique_path (), nano::inactive_node_flag_defaults ()), ::testing::ExitedWithCode (1), ""); + } +#else + ASSERT_EXIT (nano::inactive_node node (nano::unique_path (), nano::inactive_node_flag_defaults ()), ::testing::ExitedWithCode (1), ""); +#endif } TEST (node, password_fanout) @@ -3358,6 +3367,7 @@ TEST (node, block_processor_full) { nano::system system; nano::node_flags node_flags; + node_flags.force_use_write_database_queue = true; node_flags.block_processor_full_size = 3; auto & node = *system.add_node (nano::node_config (nano::get_available_port (), system.logging), node_flags); nano::genesis genesis; @@ -3405,6 +3415,7 @@ TEST (node, block_processor_half_full) nano::system system; nano::node_flags node_flags; node_flags.block_processor_full_size = 6; + node_flags.force_use_write_database_queue = true; auto & node = *system.add_node (nano::node_config (nano::get_available_port (), system.logging), node_flags); nano::genesis genesis; nano::state_block_builder builder; diff --git a/nano/node/blockprocessor.cpp b/nano/node/blockprocessor.cpp index 0b854af2..12811c46 100644 --- a/nano/node/blockprocessor.cpp +++ b/nano/node/blockprocessor.cpp @@ -220,7 +220,7 @@ void nano::block_processor::process_batch (nano::unique_lock & lock_ timer_l.start (); // Processing blocks unsigned number_of_blocks_processed (0), number_of_forced_processed (0); - while ((!blocks.empty () || !forced.empty ()) && (timer_l.before_deadline (node.config.block_processor_batch_max_time) || (number_of_blocks_processed < node.flags.block_processor_batch_size)) && !awaiting_write) + while ((!blocks.empty () || !forced.empty ()) && (timer_l.before_deadline (node.config.block_processor_batch_max_time) || (number_of_blocks_processed < node.flags.block_processor_batch_size)) && !awaiting_write && number_of_blocks_processed < node.store.max_block_write_batch_num ()) { if ((blocks.size () + state_block_signature_verification.size () + forced.size () > 64) && should_log ()) { diff --git a/nano/node/lmdb/lmdb.cpp b/nano/node/lmdb/lmdb.cpp index 405eeb96..23984212 100644 --- a/nano/node/lmdb/lmdb.cpp +++ b/nano/node/lmdb/lmdb.cpp @@ -1153,5 +1153,10 @@ bool nano::mdb_store::upgrade_counters::are_equal () const return (before_v0 == after_v0) && (before_v1 == after_v1); } +unsigned nano::mdb_store::max_block_write_batch_num () const +{ + return std::numeric_limits::max (); +} + // Explicitly instantiate template class nano::block_store_partial; diff --git a/nano/node/lmdb/lmdb.hpp b/nano/node/lmdb/lmdb.hpp index d8ccee80..47f2ed35 100644 --- a/nano/node/lmdb/lmdb.hpp +++ b/nano/node/lmdb/lmdb.hpp @@ -51,6 +51,8 @@ public: void serialize_memory_stats (boost::property_tree::ptree &) override; + unsigned max_block_write_batch_num () const override; + private: nano::logger_mt & logger; bool error{ false }; diff --git a/nano/node/rocksdb/rocksdb.cpp b/nano/node/rocksdb/rocksdb.cpp index d4613c83..444dfaa7 100644 --- a/nano/node/rocksdb/rocksdb.cpp +++ b/nano/node/rocksdb/rocksdb.cpp @@ -66,7 +66,8 @@ void rocksdb_val::convert_buffer_to_value () nano::rocksdb_store::rocksdb_store (nano::logger_mt & logger_a, boost::filesystem::path const & path_a, nano::rocksdb_config const & rocksdb_config_a, bool open_read_only_a) : logger (logger_a), rocksdb_config (rocksdb_config_a), -cf_name_table_map (create_cf_name_table_map ()) +cf_name_table_map (create_cf_name_table_map ()), +max_block_write_batch_num_m (nano::narrow_cast (blocks_memtable_size_bytes () / (2 * (sizeof (nano::block_type) + nano::state_block::size + nano::block_sideband::size (nano::block_type::state))))) { boost::system::error_code error_mkdir, error_chmod; boost::filesystem::create_directories (path_a, error_mkdir); @@ -99,7 +100,7 @@ std::unordered_map nano::rocksdb_store::create_cf_na { "peers", tables::peers }, { "confirmation_height", tables::confirmation_height } }; - debug_assert (map.size () == all_tables ().size ()); + debug_assert (map.size () == all_tables ().size () + 1); return map; } @@ -157,7 +158,7 @@ void nano::rocksdb_store::generate_tombstone_map () rocksdb::ColumnFamilyOptions nano::rocksdb_store::get_cf_options (std::string const & cf_name_a) const { rocksdb::ColumnFamilyOptions cf_options; - auto const memtable_size_bytes = 1024ULL * 1024 * rocksdb_config.memory_multiplier * base_memtable_size; + auto const memtable_size_bytes = base_memtable_size_bytes (); auto const block_cache_size_bytes = 1024ULL * 1024 * rocksdb_config.memory_multiplier * base_block_cache_size; if (cf_name_a == "unchecked") { @@ -180,7 +181,7 @@ rocksdb::ColumnFamilyOptions nano::rocksdb_store::get_cf_options (std::string co else if (cf_name_a == "blocks") { std::shared_ptr table_factory (rocksdb::NewBlockBasedTableFactory (get_active_table_options (block_cache_size_bytes * 4))); - cf_options = get_active_cf_options (table_factory, memtable_size_bytes); + cf_options = get_active_cf_options (table_factory, blocks_memtable_size_bytes ()); } else if (cf_name_a == "confirmation_height") { @@ -241,6 +242,7 @@ std::vector nano::rocksdb_store::create_column_ std::vector column_families; for (auto & [cf_name, table] : cf_name_table_map) { + (void)table; column_families.emplace_back (cf_name, get_cf_options (cf_name)); } return column_families; @@ -462,6 +464,14 @@ uint64_t nano::rocksdb_store::count (nano::transaction const & transaction_a, ta ++sum; } } + else if (table_a == tables::confirmation_height) + { + debug_assert (network_constants ().is_dev_network ()); + for (auto i (confirmation_height_begin (transaction_a)), n (confirmation_height_end ()); i != n; ++i) + { + ++sum; + } + } else { debug_assert (false); @@ -821,6 +831,22 @@ void nano::rocksdb_store::serialize_memory_stats (boost::property_tree::ptree & json.put ("block-cache-usage", val); } +unsigned long long nano::rocksdb_store::blocks_memtable_size_bytes () const +{ + return base_memtable_size_bytes (); +} + +unsigned long long nano::rocksdb_store::base_memtable_size_bytes () const +{ + return 1024ULL * 1024 * rocksdb_config.memory_multiplier * base_memtable_size; +} + +// This is a ratio of the blocks memtable size to keep total write transaction commit size down. +unsigned nano::rocksdb_store::max_block_write_batch_num () const +{ + return max_block_write_batch_num_m; +} + nano::rocksdb_store::tombstone_info::tombstone_info (uint64_t num_since_last_flush_a, uint64_t const max_a) : num_since_last_flush (num_since_last_flush_a), max (max_a) diff --git a/nano/node/rocksdb/rocksdb.hpp b/nano/node/rocksdb/rocksdb.hpp index 8ae2eae3..861f775b 100644 --- a/nano/node/rocksdb/rocksdb.hpp +++ b/nano/node/rocksdb/rocksdb.hpp @@ -46,6 +46,8 @@ public: bool copy_db (boost::filesystem::path const & destination) override; void rebuild_db (nano::write_transaction const & transaction_a) override; + unsigned max_block_write_batch_num () const override; + template nano::store_iterator make_iterator (nano::transaction const & transaction_a, tables table_a) const { @@ -70,6 +72,7 @@ private: std::shared_ptr small_table_factory; std::unordered_map write_lock_mutexes; nano::rocksdb_config rocksdb_config; + unsigned const max_block_write_batch_num_m; class tombstone_info { @@ -110,6 +113,8 @@ private: std::unordered_map create_cf_name_table_map () const; std::vector create_column_families (); + unsigned long long base_memtable_size_bytes () const; + unsigned long long blocks_memtable_size_bytes () const; constexpr static int base_memtable_size = 16; constexpr static int base_block_cache_size = 8; diff --git a/nano/secure/blockstore.hpp b/nano/secure/blockstore.hpp index 80fe5603..bb9f3863 100644 --- a/nano/secure/blockstore.hpp +++ b/nano/secure/blockstore.hpp @@ -675,9 +675,9 @@ public: virtual bool confirmation_height_exists (nano::transaction const & transaction_a, nano::account const & account_a) const = 0; virtual void confirmation_height_del (nano::write_transaction const & transaction_a, nano::account const & account_a) = 0; virtual uint64_t confirmation_height_count (nano::transaction const & transaction_a) = 0; - virtual nano::store_iterator confirmation_height_begin (nano::transaction const & transaction_a, nano::account const & account_a) = 0; - virtual nano::store_iterator confirmation_height_begin (nano::transaction const & transaction_a) = 0; - virtual nano::store_iterator confirmation_height_end () = 0; + virtual nano::store_iterator confirmation_height_begin (nano::transaction const & transaction_a, nano::account const & account_a) const = 0; + virtual nano::store_iterator confirmation_height_begin (nano::transaction const & transaction_a) const = 0; + virtual nano::store_iterator confirmation_height_end () const = 0; virtual nano::store_iterator> blocks_begin (nano::transaction const & transaction_a) const = 0; virtual nano::store_iterator> blocks_end () const = 0; @@ -685,6 +685,8 @@ public: virtual uint64_t block_account_height (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const = 0; virtual std::mutex & get_cache_mutex () = 0; + virtual unsigned max_block_write_batch_num () const = 0; + virtual bool copy_db (boost::filesystem::path const & destination) = 0; virtual void rebuild_db (nano::write_transaction const & transaction_a) = 0; diff --git a/nano/secure/blockstore_partial.hpp b/nano/secure/blockstore_partial.hpp index 5084901f..200c5280 100644 --- a/nano/secure/blockstore_partial.hpp +++ b/nano/secure/blockstore_partial.hpp @@ -331,7 +331,7 @@ public: return nano::store_iterator> (nullptr); } - nano::store_iterator confirmation_height_end () override + nano::store_iterator confirmation_height_end () const override { return nano::store_iterator (nullptr); } @@ -686,12 +686,12 @@ public: return make_iterator (transaction_a, tables::peers); } - nano::store_iterator confirmation_height_begin (nano::transaction const & transaction_a, nano::account const & account_a) override + nano::store_iterator confirmation_height_begin (nano::transaction const & transaction_a, nano::account const & account_a) const override { return make_iterator (transaction_a, tables::confirmation_height, nano::db_val (account_a)); } - nano::store_iterator confirmation_height_begin (nano::transaction const & transaction_a) override + nano::store_iterator confirmation_height_begin (nano::transaction const & transaction_a) const override { return make_iterator (transaction_a, tables::confirmation_height); }