diff --git a/nano/node/active_elections.cpp b/nano/node/active_elections.cpp index 2f04243f..a8fb6469 100644 --- a/nano/node/active_elections.cpp +++ b/nano/node/active_elections.cpp @@ -32,7 +32,7 @@ nano::active_elections::active_elections (nano::node & node_a, nano::confirming_ confirming_set.batch_cemented.add ([this] (auto const & cemented) { auto transaction = node.ledger.tx_begin_read (); - for (auto const & [block, confirmation_root] : cemented) + for (auto const & [block, confirmation_root, election] : cemented) { transaction.refresh_if_needed (); block_cemented_callback (transaction, block, confirmation_root); diff --git a/nano/node/confirming_set.cpp b/nano/node/confirming_set.cpp index 1d2aa2fa..f7a01253 100644 --- a/nano/node/confirming_set.cpp +++ b/nano/node/confirming_set.cpp @@ -13,9 +13,9 @@ nano::confirming_set::confirming_set (confirming_set_config const & config_a, na notification_workers{ 1, nano::thread_role::name::confirmation_height_notifications } { batch_cemented.add ([this] (auto const & cemented) { - for (auto const & [block, confirmation_root] : cemented) + for (auto const & context : cemented) { - cemented_observers.notify (block); + cemented_observers.notify (context.block); } }); } @@ -25,12 +25,12 @@ nano::confirming_set::~confirming_set () debug_assert (!thread.joinable ()); } -void nano::confirming_set::add (nano::block_hash const & hash) +void nano::confirming_set::add (nano::block_hash const & hash, std::shared_ptr const & election) { bool added = false; { std::lock_guard lock{ mutex }; - auto [it, inserted] = set.insert (hash); + auto [it, inserted] = set.push_back ({ hash, election }); added = inserted; } if (added) @@ -71,7 +71,7 @@ void nano::confirming_set::stop () bool nano::confirming_set::exists (nano::block_hash const & hash) const { std::lock_guard lock{ mutex }; - return set.count (hash) != 0; + return set.get ().contains (hash); } std::size_t nano::confirming_set::size () const @@ -100,17 +100,16 @@ void nano::confirming_set::run () } } -std::deque nano::confirming_set::next_batch (size_t max_count) +auto nano::confirming_set::next_batch (size_t max_count) -> std::deque { debug_assert (!mutex.try_lock ()); debug_assert (!set.empty ()); - std::deque results; + std::deque results; while (!set.empty () && results.size () < max_count) { - auto it = set.begin (); - results.push_back (*it); - set.erase (it); + results.push_back (set.front ()); + set.pop_front (); } return results; } @@ -121,7 +120,7 @@ void nano::confirming_set::run_batch (std::unique_lock & lock) debug_assert (!mutex.try_lock ()); debug_assert (!set.empty ()); - std::deque cemented; + std::deque cemented; std::deque already; auto batch = next_batch (batch_size); @@ -129,7 +128,7 @@ void nano::confirming_set::run_batch (std::unique_lock & lock) lock.unlock (); auto notify = [this, &cemented] () { - std::deque batch; + std::deque batch; batch.swap (cemented); std::unique_lock lock{ mutex }; @@ -164,7 +163,7 @@ void nano::confirming_set::run_batch (std::unique_lock & lock) { auto transaction = ledger.tx_begin_write (nano::store::writer::confirmation_height); - for (auto const & hash : batch) + for (auto const & [hash, election] : batch) { do { @@ -195,7 +194,7 @@ void nano::confirming_set::run_batch (std::unique_lock & lock) stats.add (nano::stat::type::confirming_set, nano::stat::detail::cemented, added.size ()); for (auto & block : added) { - cemented.emplace_back (block, hash); + cemented.push_back ({ block, hash, election }); } } else diff --git a/nano/node/confirming_set.hpp b/nano/node/confirming_set.hpp index b9e568db..5eb42967 100644 --- a/nano/node/confirming_set.hpp +++ b/nano/node/confirming_set.hpp @@ -4,6 +4,13 @@ #include #include #include +#include + +#include +#include +#include +#include +#include #include #include @@ -11,6 +18,8 @@ #include #include +namespace mi = boost::multi_index; + namespace nano { class confirming_set_config final @@ -40,7 +49,7 @@ public: void stop (); // Adds a block to the set of blocks to be confirmed - void add (nano::block_hash const & hash); + void add (nano::block_hash const & hash, std::shared_ptr const & election = nullptr); // Added blocks will remain in this set until after ledger has them marked as confirmed. bool exists (nano::block_hash const & hash) const; std::size_t size () const; @@ -48,8 +57,14 @@ public: nano::container_info container_info () const; public: // Events - using cemented_t = std::pair, nano::block_hash>; // - nano::observer_set const &> batch_cemented; + struct context + { + std::shared_ptr block; + nano::block_hash confirmation_root; + std::shared_ptr election; + }; + + nano::observer_set const &> batch_cemented; nano::observer_set const &> already_cemented; nano::observer_set> cemented_observers; @@ -60,12 +75,30 @@ private: // Dependencies nano::stats & stats; private: + struct entry + { + nano::block_hash hash; + std::shared_ptr election; + }; + void run (); void run_batch (std::unique_lock &); - std::deque next_batch (size_t max_count); + std::deque next_batch (size_t max_count); private: - std::unordered_set set; + // clang-format off + class tag_hash {}; + class tag_sequenced {}; + + using ordered_entries = boost::multi_index_container>, + mi::hashed_unique, + mi::member> + >>; + // clang-format on + + ordered_entries set; nano::thread_pool notification_workers;