Keep election in confirming set

This commit is contained in:
Piotr Wójcik 2024-10-15 16:18:53 +02:00
commit 155cb1c252
3 changed files with 52 additions and 20 deletions

View file

@ -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);

View file

@ -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<nano::election> 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<tag_hash> ().contains (hash);
}
std::size_t nano::confirming_set::size () const
@ -100,17 +100,16 @@ void nano::confirming_set::run ()
}
}
std::deque<nano::block_hash> nano::confirming_set::next_batch (size_t max_count)
auto nano::confirming_set::next_batch (size_t max_count) -> std::deque<entry>
{
debug_assert (!mutex.try_lock ());
debug_assert (!set.empty ());
std::deque<nano::block_hash> results;
std::deque<entry> 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<std::mutex> & lock)
debug_assert (!mutex.try_lock ());
debug_assert (!set.empty ());
std::deque<cemented_t> cemented;
std::deque<context> cemented;
std::deque<nano::block_hash> already;
auto batch = next_batch (batch_size);
@ -129,7 +128,7 @@ void nano::confirming_set::run_batch (std::unique_lock<std::mutex> & lock)
lock.unlock ();
auto notify = [this, &cemented] () {
std::deque<cemented_t> batch;
std::deque<context> batch;
batch.swap (cemented);
std::unique_lock lock{ mutex };
@ -164,7 +163,7 @@ void nano::confirming_set::run_batch (std::unique_lock<std::mutex> & 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<std::mutex> & 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

View file

@ -4,6 +4,13 @@
#include <nano/lib/observer_set.hpp>
#include <nano/lib/thread_pool.hpp>
#include <nano/node/fwd.hpp>
#include <nano/secure/common.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index_container.hpp>
#include <condition_variable>
#include <deque>
@ -11,6 +18,8 @@
#include <thread>
#include <unordered_set>
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<nano::election> 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<std::shared_ptr<nano::block>, nano::block_hash>; // <block, confirmation root>
nano::observer_set<std::deque<cemented_t> const &> batch_cemented;
struct context
{
std::shared_ptr<nano::block> block;
nano::block_hash confirmation_root;
std::shared_ptr<nano::election> election;
};
nano::observer_set<std::deque<context> const &> batch_cemented;
nano::observer_set<std::deque<nano::block_hash> const &> already_cemented;
nano::observer_set<std::shared_ptr<nano::block>> cemented_observers;
@ -60,12 +75,30 @@ private: // Dependencies
nano::stats & stats;
private:
struct entry
{
nano::block_hash hash;
std::shared_ptr<nano::election> election;
};
void run ();
void run_batch (std::unique_lock<std::mutex> &);
std::deque<nano::block_hash> next_batch (size_t max_count);
std::deque<entry> next_batch (size_t max_count);
private:
std::unordered_set<nano::block_hash> set;
// clang-format off
class tag_hash {};
class tag_sequenced {};
using ordered_entries = boost::multi_index_container<entry,
mi::indexed_by<
mi::sequenced<mi::tag<tag_sequenced>>,
mi::hashed_unique<mi::tag<tag_hash>,
mi::member<entry, nano::block_hash, &entry::hash>>
>>;
// clang-format on
ordered_entries set;
nano::thread_pool notification_workers;