dncurrency/nano/node/vote_generator.hpp
2024-10-21 16:19:40 +02:00

92 lines
3.4 KiB
C++

#pragma once
#include <nano/lib/locks.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/numbers.hpp>
#include <nano/lib/processing_queue.hpp>
#include <nano/lib/utility.hpp>
#include <nano/node/fwd.hpp>
#include <nano/node/wallet.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>
#include <thread>
#include <variant>
namespace mi = boost::multi_index;
namespace nano
{
class vote_generator final
{
private:
using candidate_t = std::pair<nano::root, nano::block_hash>;
using request_t = std::pair<std::vector<candidate_t>, std::shared_ptr<nano::transport::channel>>;
using queue_entry_t = std::pair<nano::root, nano::block_hash>;
std::chrono::steady_clock::time_point next_broadcast = { std::chrono::steady_clock::now () };
public:
vote_generator (nano::node_config const &, nano::node &, nano::ledger &, nano::wallets &, nano::vote_processor &, nano::local_vote_history &, nano::network &, nano::stats &, nano::logger &, bool is_final);
~vote_generator ();
/** Queue items for vote generation, or broadcast votes already in cache */
void add (nano::root const &, nano::block_hash const &);
/** Queue blocks for vote generation, returning the number of successful candidates.*/
std::size_t generate (std::vector<std::shared_ptr<nano::block>> const & blocks_a, std::shared_ptr<nano::transport::channel> const & channel_a);
void set_reply_action (std::function<void (std::shared_ptr<nano::vote> const &, std::shared_ptr<nano::transport::channel> const &)>);
void start ();
void stop ();
nano::container_info container_info () const;
private:
using transaction_variant_t = std::variant<nano::secure::read_transaction, nano::secure::write_transaction>;
void run ();
void broadcast (nano::unique_lock<nano::mutex> &);
void reply (nano::unique_lock<nano::mutex> &, request_t &&);
void vote (std::vector<nano::block_hash> const &, std::vector<nano::root> const &, std::function<void (std::shared_ptr<nano::vote> const &)> const &);
void broadcast_action (std::shared_ptr<nano::vote> const &) const;
void process_batch (std::deque<queue_entry_t> & batch);
bool should_vote (transaction_variant_t const &, nano::root const &, nano::block_hash const &) const;
bool broadcast_predicate () const;
private:
std::function<void (std::shared_ptr<nano::vote> const &, std::shared_ptr<nano::transport::channel> &)> reply_action; // must be set only during initialization by using set_reply_action
private: // Dependencies
nano::node_config const & config;
nano::node & node;
nano::ledger & ledger;
nano::wallets & wallets;
nano::vote_processor & vote_processor;
nano::local_vote_history & history;
std::unique_ptr<nano::vote_spacing> spacing_impl;
nano::vote_spacing & spacing;
nano::network & network;
nano::stats & stats;
nano::logger & logger;
private:
nano::processing_queue<queue_entry_t> vote_generation_queue;
private:
const bool is_final;
mutable nano::mutex mutex;
nano::condition_variable condition;
static std::size_t constexpr max_requests{ 2048 };
std::deque<request_t> requests;
std::deque<candidate_t> candidates;
std::atomic<bool> stopped{ false };
std::thread thread;
std::shared_ptr<nano::transport::channel> inproc_channel;
};
}