From fc286e6e2ce12bef20014e6de8dfb43fd9d33461 Mon Sep 17 00:00:00 2001 From: Sergey Kroshnin Date: Wed, 4 Sep 2019 20:22:55 +0300 Subject: [PATCH] Enhance block processor filter (#2282) --- nano/node/blockprocessor.cpp | 29 +++++++++++++++++++++++++---- nano/node/blockprocessor.hpp | 3 ++- nano/node/node.cpp | 6 +++--- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/nano/node/blockprocessor.cpp b/nano/node/blockprocessor.cpp index 15efe46e..a429984e 100644 --- a/nano/node/blockprocessor.cpp +++ b/nano/node/blockprocessor.cpp @@ -40,6 +40,7 @@ void nano::block_processor::flush () { condition.wait (lock); } + blocks_filter.clear (); } size_t nano::block_processor::size () @@ -70,8 +71,9 @@ void nano::block_processor::add (nano::unchecked_info const & info_a) { { auto hash (info_a.block->hash ()); + auto filter_hash (filter_item (hash, info_a.block->block_signature ())); nano::lock_guard lock (mutex); - if (blocks_hashes.find (hash) == blocks_hashes.end () && rolled_back.get<1> ().find (hash) == rolled_back.get<1> ().end ()) + if (blocks_filter.find (filter_hash) == blocks_filter.end () && rolled_back.get<1> ().find (hash) == rolled_back.get<1> ().end ()) { if (info_a.verified == nano::signature_verification::unknown && (info_a.block->type () == nano::block_type::state || info_a.block->type () == nano::block_type::open || !info_a.account.is_zero ())) { @@ -81,7 +83,7 @@ void nano::block_processor::add (nano::unchecked_info const & info_a) { blocks.push_back (info_a); } - blocks_hashes.insert (hash); + blocks_filter.insert (filter_hash); } } condition.notify_all (); @@ -221,6 +223,10 @@ void nano::block_processor::verify_state_blocks (nano::unique_lock & item.verified = nano::signature_verification::valid; blocks.push_back (std::move (item)); } + else + { + blocks_filter.erase (filter_item (hashes[i], blocks_signatures[i])); + } items.pop_front (); } if (node.config.logging.timing_logging ()) @@ -283,22 +289,24 @@ void nano::block_processor::process_batch (nano::unique_lock & lock_ node.logger.always_log (boost::str (boost::format ("%1% blocks (+ %2% state blocks) (+ %3% forced) in processing queue") % blocks.size () % state_blocks.size () % forced.size ())); } nano::unchecked_info info; + nano::block_hash hash (0); bool force (false); if (forced.empty ()) { info = blocks.front (); blocks.pop_front (); - blocks_hashes.erase (info.block->hash ()); + hash = info.block->hash (); + blocks_filter.erase (filter_item (hash, info.block->block_signature ())); } else { info = nano::unchecked_info (forced.front (), 0, nano::seconds_since_epoch (), nano::signature_verification::unknown); forced.pop_front (); + hash = info.block->hash (); force = true; number_of_forced_processed++; } lock_a.unlock (); - auto hash (info.block->hash ()); if (force) { auto successor (node.ledger.successor (transaction, info.block->qualified_root ())); @@ -550,3 +558,16 @@ void nano::block_processor::queue_unchecked (nano::write_transaction const & tra } node.gap_cache.erase (hash_a); } + +nano::block_hash nano::block_processor::filter_item (nano::block_hash const & hash_a, nano::signature const & signature_a) +{ + static nano::random_constants constants; + nano::block_hash result; + blake2b_state state; + blake2b_init (&state, sizeof (result.bytes)); + blake2b_update (&state, constants.not_an_account.bytes.data (), constants.not_an_account.bytes.size ()); + blake2b_update (&state, signature_a.bytes.data (), signature_a.bytes.size ()); + blake2b_update (&state, hash_a.bytes.data (), hash_a.bytes.size ()); + blake2b_final (&state, result.bytes.data (), sizeof (result.bytes)); + return result; +} diff --git a/nano/node/blockprocessor.hpp b/nano/node/blockprocessor.hpp index 2ed0b5fd..772c50ad 100644 --- a/nano/node/blockprocessor.hpp +++ b/nano/node/blockprocessor.hpp @@ -65,8 +65,9 @@ private: std::chrono::steady_clock::time_point next_log; std::deque state_blocks; std::deque blocks; - std::unordered_set blocks_hashes; std::deque> forced; + nano::block_hash filter_item (nano::block_hash const &, nano::signature const &); + std::unordered_set blocks_filter; boost::multi_index_container< nano::rolled_hash, boost::multi_index::indexed_by< diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 0fa0c936..65664dd7 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -84,7 +84,7 @@ std::unique_ptr collect_seq_con_info (block_processor & { size_t state_blocks_count = 0; size_t blocks_count = 0; - size_t blocks_hashes_count = 0; + size_t blocks_filter_count = 0; size_t forced_count = 0; size_t rolled_back_count = 0; @@ -92,7 +92,7 @@ std::unique_ptr collect_seq_con_info (block_processor & nano::lock_guard guard (block_processor.mutex); state_blocks_count = block_processor.state_blocks.size (); blocks_count = block_processor.blocks.size (); - blocks_hashes_count = block_processor.blocks_hashes.size (); + blocks_filter_count = block_processor.blocks_filter.size (); forced_count = block_processor.forced.size (); rolled_back_count = block_processor.rolled_back.size (); } @@ -100,7 +100,7 @@ std::unique_ptr collect_seq_con_info (block_processor & auto composite = std::make_unique (name); composite->add_component (std::make_unique (seq_con_info{ "state_blocks", state_blocks_count, sizeof (decltype (block_processor.state_blocks)::value_type) })); composite->add_component (std::make_unique (seq_con_info{ "blocks", blocks_count, sizeof (decltype (block_processor.blocks)::value_type) })); - composite->add_component (std::make_unique (seq_con_info{ "blocks_hashes", blocks_hashes_count, sizeof (decltype (block_processor.blocks_hashes)::value_type) })); + composite->add_component (std::make_unique (seq_con_info{ "blocks_filter", blocks_filter_count, sizeof (decltype (block_processor.blocks_filter)::value_type) })); composite->add_component (std::make_unique (seq_con_info{ "forced", forced_count, sizeof (decltype (block_processor.forced)::value_type) })); composite->add_component (std::make_unique (seq_con_info{ "rolled_back", rolled_back_count, sizeof (decltype (block_processor.rolled_back)::value_type) })); composite->add_component (collect_seq_con_info (block_processor.generator, "generator"));