Vote cache processor (#4631)
This commit is contained in:
parent
360ef3d564
commit
30f2de0439
11 changed files with 198 additions and 42 deletions
|
|
@ -48,6 +48,7 @@ enum class type
|
||||||
telemetry,
|
telemetry,
|
||||||
vote_generator,
|
vote_generator,
|
||||||
vote_cache,
|
vote_cache,
|
||||||
|
vote_cache_processor,
|
||||||
hinting,
|
hinting,
|
||||||
blockprocessor,
|
blockprocessor,
|
||||||
blockprocessor_source,
|
blockprocessor_source,
|
||||||
|
|
@ -112,6 +113,7 @@ enum class detail
|
||||||
cache,
|
cache,
|
||||||
rebroadcast,
|
rebroadcast,
|
||||||
queue_overflow,
|
queue_overflow,
|
||||||
|
triggered,
|
||||||
|
|
||||||
// processing queue
|
// processing queue
|
||||||
queue,
|
queue,
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,9 @@ std::string nano::thread_role::get_string (nano::thread_role::name role)
|
||||||
case nano::thread_role::name::vote_processing:
|
case nano::thread_role::name::vote_processing:
|
||||||
thread_role_name_string = "Vote processing";
|
thread_role_name_string = "Vote processing";
|
||||||
break;
|
break;
|
||||||
|
case nano::thread_role::name::vote_cache_processing:
|
||||||
|
thread_role_name_string = "Vote cache proc";
|
||||||
|
break;
|
||||||
case nano::thread_role::name::block_processing:
|
case nano::thread_role::name::block_processing:
|
||||||
thread_role_name_string = "Blck processing";
|
thread_role_name_string = "Blck processing";
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ enum class name
|
||||||
work,
|
work,
|
||||||
message_processing,
|
message_processing,
|
||||||
vote_processing,
|
vote_processing,
|
||||||
|
vote_cache_processing,
|
||||||
block_processing,
|
block_processing,
|
||||||
request_loop,
|
request_loop,
|
||||||
wallet_actions,
|
wallet_actions,
|
||||||
|
|
|
||||||
|
|
@ -440,7 +440,7 @@ nano::election_insertion_result nano::active_elections::insert (std::shared_ptr<
|
||||||
{
|
{
|
||||||
debug_assert (result.election);
|
debug_assert (result.election);
|
||||||
|
|
||||||
node.vote_router.trigger_vote_cache (hash);
|
node.vote_cache_processor.trigger (hash);
|
||||||
node.observers.active_started.notify (hash);
|
node.observers.active_started.notify (hash);
|
||||||
vacancy_update ();
|
vacancy_update ();
|
||||||
}
|
}
|
||||||
|
|
@ -523,7 +523,7 @@ bool nano::active_elections::publish (std::shared_ptr<nano::block> const & block
|
||||||
node.vote_router.connect (block_a->hash (), election);
|
node.vote_router.connect (block_a->hash (), election);
|
||||||
lock.unlock ();
|
lock.unlock ();
|
||||||
|
|
||||||
node.vote_router.trigger_vote_cache (block_a->hash ());
|
node.vote_cache_processor.trigger (block_a->hash ());
|
||||||
|
|
||||||
node.stats.inc (nano::stat::type::active, nano::stat::detail::election_block_conflict);
|
node.stats.inc (nano::stat::type::active, nano::stat::detail::election_block_conflict);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,20 @@ class ledger;
|
||||||
class local_vote_history;
|
class local_vote_history;
|
||||||
class logger;
|
class logger;
|
||||||
class network;
|
class network;
|
||||||
|
class network_params;
|
||||||
class node;
|
class node;
|
||||||
class node_config;
|
class node_config;
|
||||||
|
class node_flags;
|
||||||
|
class node_observers;
|
||||||
|
class online_reps;
|
||||||
|
class rep_crawler;
|
||||||
|
class rep_tiers;
|
||||||
class stats;
|
class stats;
|
||||||
|
class vote_cache;
|
||||||
class vote_generator;
|
class vote_generator;
|
||||||
|
class vote_processor;
|
||||||
class vote_router;
|
class vote_router;
|
||||||
class wallets;
|
class wallets;
|
||||||
|
|
||||||
|
enum class vote_code;
|
||||||
}
|
}
|
||||||
|
|
@ -200,6 +200,8 @@ nano::node::node (std::shared_ptr<boost::asio::io_context> io_ctx_a, std::filesy
|
||||||
vote_router{ *vote_router_impl },
|
vote_router{ *vote_router_impl },
|
||||||
vote_processor_impl{ std::make_unique<nano::vote_processor> (config.vote_processor, vote_router, observers, stats, flags, logger, online_reps, rep_crawler, ledger, network_params, rep_tiers) },
|
vote_processor_impl{ std::make_unique<nano::vote_processor> (config.vote_processor, vote_router, observers, stats, flags, logger, online_reps, rep_crawler, ledger, network_params, rep_tiers) },
|
||||||
vote_processor{ *vote_processor_impl },
|
vote_processor{ *vote_processor_impl },
|
||||||
|
vote_cache_processor_impl{ std::make_unique<nano::vote_cache_processor> (config.vote_processor, vote_router, vote_cache, stats, logger) },
|
||||||
|
vote_cache_processor{ *vote_cache_processor_impl },
|
||||||
generator_impl{ std::make_unique<nano::vote_generator> (config, *this, ledger, wallets, vote_processor, history, network, stats, logger, /* non-final */ false) },
|
generator_impl{ std::make_unique<nano::vote_generator> (config, *this, ledger, wallets, vote_processor, history, network, stats, logger, /* non-final */ false) },
|
||||||
generator{ *generator_impl },
|
generator{ *generator_impl },
|
||||||
final_generator_impl{ std::make_unique<nano::vote_generator> (config, *this, ledger, wallets, vote_processor, history, network, stats, logger, /* final */ true) },
|
final_generator_impl{ std::make_unique<nano::vote_generator> (config, *this, ledger, wallets, vote_processor, history, network, stats, logger, /* final */ true) },
|
||||||
|
|
@ -572,6 +574,7 @@ std::unique_ptr<nano::container_info_component> nano::collect_container_info (no
|
||||||
composite->add_component (collect_container_info (node.observers, "observers"));
|
composite->add_component (collect_container_info (node.observers, "observers"));
|
||||||
composite->add_component (collect_container_info (node.wallets, "wallets"));
|
composite->add_component (collect_container_info (node.wallets, "wallets"));
|
||||||
composite->add_component (node.vote_processor.collect_container_info ("vote_processor"));
|
composite->add_component (node.vote_processor.collect_container_info ("vote_processor"));
|
||||||
|
composite->add_component (node.vote_cache_processor.collect_container_info ("vote_cache_processor"));
|
||||||
composite->add_component (node.rep_crawler.collect_container_info ("rep_crawler"));
|
composite->add_component (node.rep_crawler.collect_container_info ("rep_crawler"));
|
||||||
composite->add_component (node.block_processor.collect_container_info ("block_processor"));
|
composite->add_component (node.block_processor.collect_container_info ("block_processor"));
|
||||||
composite->add_component (collect_container_info (node.online_reps, "online_reps"));
|
composite->add_component (collect_container_info (node.online_reps, "online_reps"));
|
||||||
|
|
@ -690,6 +693,7 @@ void nano::node::start ()
|
||||||
wallets.start ();
|
wallets.start ();
|
||||||
rep_tiers.start ();
|
rep_tiers.start ();
|
||||||
vote_processor.start ();
|
vote_processor.start ();
|
||||||
|
vote_cache_processor.start ();
|
||||||
block_processor.start ();
|
block_processor.start ();
|
||||||
active.start ();
|
active.start ();
|
||||||
generator.start ();
|
generator.start ();
|
||||||
|
|
@ -734,6 +738,7 @@ void nano::node::stop ()
|
||||||
unchecked.stop ();
|
unchecked.stop ();
|
||||||
block_processor.stop ();
|
block_processor.stop ();
|
||||||
aggregator.stop ();
|
aggregator.stop ();
|
||||||
|
vote_cache_processor.stop ();
|
||||||
vote_processor.stop ();
|
vote_processor.stop ();
|
||||||
rep_tiers.stop ();
|
rep_tiers.stop ();
|
||||||
scheduler.stop ();
|
scheduler.stop ();
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ class confirming_set;
|
||||||
class message_processor;
|
class message_processor;
|
||||||
class node;
|
class node;
|
||||||
class vote_processor;
|
class vote_processor;
|
||||||
|
class vote_cache_processor;
|
||||||
class vote_router;
|
class vote_router;
|
||||||
class work_pool;
|
class work_pool;
|
||||||
class peer_history;
|
class peer_history;
|
||||||
|
|
@ -194,6 +195,8 @@ public:
|
||||||
nano::vote_router & vote_router;
|
nano::vote_router & vote_router;
|
||||||
std::unique_ptr<nano::vote_processor> vote_processor_impl;
|
std::unique_ptr<nano::vote_processor> vote_processor_impl;
|
||||||
nano::vote_processor & vote_processor;
|
nano::vote_processor & vote_processor;
|
||||||
|
std::unique_ptr<nano::vote_cache_processor> vote_cache_processor_impl;
|
||||||
|
nano::vote_cache_processor & vote_cache_processor;
|
||||||
std::unique_ptr<nano::vote_generator> generator_impl;
|
std::unique_ptr<nano::vote_generator> generator_impl;
|
||||||
nano::vote_generator & generator;
|
nano::vote_generator & generator;
|
||||||
std::unique_ptr<nano::vote_generator> final_generator_impl;
|
std::unique_ptr<nano::vote_generator> final_generator_impl;
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,10 @@
|
||||||
|
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vote_processor
|
||||||
|
*/
|
||||||
|
|
||||||
nano::vote_processor::vote_processor (vote_processor_config const & config_a, nano::vote_router & vote_router, nano::node_observers & observers_a, nano::stats & stats_a, nano::node_flags & flags_a, nano::logger & logger_a, nano::online_reps & online_reps_a, nano::rep_crawler & rep_crawler_a, nano::ledger & ledger_a, nano::network_params & network_params_a, nano::rep_tiers & rep_tiers_a) :
|
nano::vote_processor::vote_processor (vote_processor_config const & config_a, nano::vote_router & vote_router, nano::node_observers & observers_a, nano::stats & stats_a, nano::node_flags & flags_a, nano::logger & logger_a, nano::online_reps & online_reps_a, nano::rep_crawler & rep_crawler_a, nano::ledger & ledger_a, nano::network_params & network_params_a, nano::rep_tiers & rep_tiers_a) :
|
||||||
config{ config_a },
|
config{ config_a },
|
||||||
vote_router{ vote_router },
|
vote_router{ vote_router },
|
||||||
|
|
@ -218,6 +222,129 @@ std::unique_ptr<nano::container_info_component> nano::vote_processor::collect_co
|
||||||
return composite;
|
return composite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vote_cache_processor
|
||||||
|
*/
|
||||||
|
|
||||||
|
nano::vote_cache_processor::vote_cache_processor (vote_processor_config const & config_a, nano::vote_router & vote_router_a, nano::vote_cache & vote_cache_a, nano::stats & stats_a, nano::logger & logger_a) :
|
||||||
|
config{ config_a },
|
||||||
|
vote_router{ vote_router_a },
|
||||||
|
vote_cache{ vote_cache_a },
|
||||||
|
stats{ stats_a },
|
||||||
|
logger{ logger_a }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
nano::vote_cache_processor::~vote_cache_processor ()
|
||||||
|
{
|
||||||
|
debug_assert (!thread.joinable ());
|
||||||
|
}
|
||||||
|
|
||||||
|
void nano::vote_cache_processor::start ()
|
||||||
|
{
|
||||||
|
debug_assert (!thread.joinable ());
|
||||||
|
|
||||||
|
thread = std::thread ([this] () {
|
||||||
|
nano::thread_role::set (nano::thread_role::name::vote_cache_processing);
|
||||||
|
run ();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void nano::vote_cache_processor::stop ()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
nano::lock_guard<nano::mutex> guard{ mutex };
|
||||||
|
stopped = true;
|
||||||
|
}
|
||||||
|
condition.notify_all ();
|
||||||
|
if (thread.joinable ())
|
||||||
|
{
|
||||||
|
thread.join ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void nano::vote_cache_processor::trigger (nano::block_hash const & hash)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
nano::lock_guard<nano::mutex> guard{ mutex };
|
||||||
|
if (triggered.size () >= config.max_triggered)
|
||||||
|
{
|
||||||
|
triggered.pop_front ();
|
||||||
|
stats.inc (nano::stat::type::vote_cache_processor, nano::stat::detail::overfill);
|
||||||
|
}
|
||||||
|
triggered.push_back (hash);
|
||||||
|
}
|
||||||
|
condition.notify_all ();
|
||||||
|
stats.inc (nano::stat::type::vote_cache_processor, nano::stat::detail::triggered);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nano::vote_cache_processor::run ()
|
||||||
|
{
|
||||||
|
nano::unique_lock<nano::mutex> lock{ mutex };
|
||||||
|
while (!stopped)
|
||||||
|
{
|
||||||
|
stats.inc (nano::stat::type::vote_cache_processor, nano::stat::detail::loop);
|
||||||
|
|
||||||
|
if (!triggered.empty ())
|
||||||
|
{
|
||||||
|
run_batch (lock);
|
||||||
|
debug_assert (!lock.owns_lock ());
|
||||||
|
lock.lock ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
condition.wait (lock, [&] { return stopped || !triggered.empty (); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void nano::vote_cache_processor::run_batch (nano::unique_lock<nano::mutex> & lock)
|
||||||
|
{
|
||||||
|
debug_assert (lock.owns_lock ());
|
||||||
|
debug_assert (!mutex.try_lock ());
|
||||||
|
debug_assert (!triggered.empty ());
|
||||||
|
|
||||||
|
// Swap and deduplicate
|
||||||
|
decltype (triggered) triggered_l;
|
||||||
|
swap (triggered_l, triggered);
|
||||||
|
|
||||||
|
lock.unlock ();
|
||||||
|
|
||||||
|
std::unordered_set<nano::block_hash> hashes;
|
||||||
|
hashes.reserve (triggered_l.size ());
|
||||||
|
hashes.insert (triggered_l.begin (), triggered_l.end ());
|
||||||
|
|
||||||
|
stats.add (nano::stat::type::vote_cache_processor, nano::stat::detail::processed, hashes.size ());
|
||||||
|
|
||||||
|
for (auto const & hash : hashes)
|
||||||
|
{
|
||||||
|
auto cached = vote_cache.find (hash);
|
||||||
|
for (auto const & cached_vote : cached)
|
||||||
|
{
|
||||||
|
vote_router.vote (cached_vote, nano::vote_source::cache, hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t nano::vote_cache_processor::size () const
|
||||||
|
{
|
||||||
|
nano::lock_guard<nano::mutex> guard{ mutex };
|
||||||
|
return triggered.size ();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nano::vote_cache_processor::empty () const
|
||||||
|
{
|
||||||
|
return size () == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<nano::container_info_component> nano::vote_cache_processor::collect_container_info (std::string const & name) const
|
||||||
|
{
|
||||||
|
nano::lock_guard<nano::mutex> guard{ mutex };
|
||||||
|
auto composite = std::make_unique<container_info_composite> (name);
|
||||||
|
composite->add_component (std::make_unique<container_info_leaf> (container_info{ "triggered", triggered.size (), sizeof (decltype (triggered)::value_type) }));
|
||||||
|
return composite;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vote_processor_config
|
* vote_processor_config
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include <nano/lib/threading.hpp>
|
#include <nano/lib/threading.hpp>
|
||||||
#include <nano/lib/utility.hpp>
|
#include <nano/lib/utility.hpp>
|
||||||
#include <nano/node/fair_queue.hpp>
|
#include <nano/node/fair_queue.hpp>
|
||||||
|
#include <nano/node/fwd.hpp>
|
||||||
#include <nano/node/rep_tiers.hpp>
|
#include <nano/node/rep_tiers.hpp>
|
||||||
#include <nano/node/vote_router.hpp>
|
#include <nano/node/vote_router.hpp>
|
||||||
#include <nano/secure/common.hpp>
|
#include <nano/secure/common.hpp>
|
||||||
|
|
@ -13,32 +14,6 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
namespace nano
|
|
||||||
{
|
|
||||||
namespace store
|
|
||||||
{
|
|
||||||
class component;
|
|
||||||
}
|
|
||||||
class node_observers;
|
|
||||||
class stats;
|
|
||||||
class node_config;
|
|
||||||
class logger;
|
|
||||||
class online_reps;
|
|
||||||
class rep_crawler;
|
|
||||||
class ledger;
|
|
||||||
class network_params;
|
|
||||||
class node_flags;
|
|
||||||
class stats;
|
|
||||||
class rep_tiers;
|
|
||||||
enum class vote_code;
|
|
||||||
class vote_router;
|
|
||||||
|
|
||||||
namespace transport
|
|
||||||
{
|
|
||||||
class channel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace nano
|
namespace nano
|
||||||
{
|
{
|
||||||
class vote_processor_config final
|
class vote_processor_config final
|
||||||
|
|
@ -53,21 +28,25 @@ public:
|
||||||
size_t pr_priority{ 3 };
|
size_t pr_priority{ 3 };
|
||||||
size_t threads{ std::clamp (nano::hardware_concurrency () / 2, 1u, 4u) };
|
size_t threads{ std::clamp (nano::hardware_concurrency () / 2, 1u, 4u) };
|
||||||
size_t batch_size{ 1024 };
|
size_t batch_size{ 1024 };
|
||||||
|
size_t max_triggered{ 16384 };
|
||||||
};
|
};
|
||||||
|
|
||||||
class vote_processor final
|
class vote_processor final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
vote_processor (vote_processor_config const &, nano::vote_router & vote_router, nano::node_observers &, nano::stats &, nano::node_flags &, nano::logger &, nano::online_reps &, nano::rep_crawler &, nano::ledger &, nano::network_params &, nano::rep_tiers &);
|
vote_processor (vote_processor_config const &, nano::vote_router &, nano::node_observers &, nano::stats &, nano::node_flags &, nano::logger &, nano::online_reps &, nano::rep_crawler &, nano::ledger &, nano::network_params &, nano::rep_tiers &);
|
||||||
~vote_processor ();
|
~vote_processor ();
|
||||||
|
|
||||||
void start ();
|
void start ();
|
||||||
void stop ();
|
void stop ();
|
||||||
|
|
||||||
/** @returns true if the vote was queued for processing */
|
/** Queue vote for processing. @returns true if the vote was queued */
|
||||||
bool vote (std::shared_ptr<nano::vote> const &, std::shared_ptr<nano::transport::channel> const &, nano::vote_source = nano::vote_source::live);
|
bool vote (std::shared_ptr<nano::vote> const &, std::shared_ptr<nano::transport::channel> const &, nano::vote_source = nano::vote_source::live);
|
||||||
nano::vote_code vote_blocking (std::shared_ptr<nano::vote> const &, std::shared_ptr<nano::transport::channel> const &, nano::vote_source = nano::vote_source::live);
|
nano::vote_code vote_blocking (std::shared_ptr<nano::vote> const &, std::shared_ptr<nano::transport::channel> const &, nano::vote_source = nano::vote_source::live);
|
||||||
|
|
||||||
|
/** Queue hash for vote cache lookup and processing. */
|
||||||
|
void trigger (nano::block_hash const & hash);
|
||||||
|
|
||||||
std::size_t size () const;
|
std::size_t size () const;
|
||||||
bool empty () const;
|
bool empty () const;
|
||||||
|
|
||||||
|
|
@ -101,4 +80,41 @@ private:
|
||||||
mutable nano::mutex mutex{ mutex_identifier (mutexes::vote_processor) };
|
mutable nano::mutex mutex{ mutex_identifier (mutexes::vote_processor) };
|
||||||
std::vector<std::thread> threads;
|
std::vector<std::thread> threads;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class vote_cache_processor final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
vote_cache_processor (vote_processor_config const &, nano::vote_router &, nano::vote_cache &, nano::stats &, nano::logger &);
|
||||||
|
~vote_cache_processor ();
|
||||||
|
|
||||||
|
void start ();
|
||||||
|
void stop ();
|
||||||
|
|
||||||
|
/** Queue hash for vote cache lookup and processing. */
|
||||||
|
void trigger (nano::block_hash const & hash);
|
||||||
|
|
||||||
|
std::size_t size () const;
|
||||||
|
bool empty () const;
|
||||||
|
|
||||||
|
std::unique_ptr<container_info_component> collect_container_info (std::string const & name) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void run ();
|
||||||
|
void run_batch (nano::unique_lock<nano::mutex> &);
|
||||||
|
|
||||||
|
private: // Dependencies
|
||||||
|
vote_processor_config const & config;
|
||||||
|
nano::vote_router & vote_router;
|
||||||
|
nano::vote_cache & vote_cache;
|
||||||
|
nano::stats & stats;
|
||||||
|
nano::logger & logger;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::deque<nano::block_hash> triggered;
|
||||||
|
|
||||||
|
bool stopped{ false };
|
||||||
|
nano::condition_variable condition;
|
||||||
|
mutable nano::mutex mutex;
|
||||||
|
std::thread thread;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -123,16 +123,6 @@ std::unordered_map<nano::block_hash, nano::vote_code> nano::vote_router::vote (s
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nano::vote_router::trigger_vote_cache (nano::block_hash const & hash)
|
|
||||||
{
|
|
||||||
auto cached = cache.find (hash);
|
|
||||||
for (auto const & cached_vote : cached)
|
|
||||||
{
|
|
||||||
vote (cached_vote, nano::vote_source::cache, hash);
|
|
||||||
}
|
|
||||||
return !cached.empty ();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nano::vote_router::active (nano::block_hash const & hash) const
|
bool nano::vote_router::active (nano::block_hash const & hash) const
|
||||||
{
|
{
|
||||||
std::shared_lock lock{ mutex };
|
std::shared_lock lock{ mutex };
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,6 @@ public:
|
||||||
// If 'filter' parameter is non-zero, only elections for the specified hash are notified.
|
// If 'filter' parameter is non-zero, only elections for the specified hash are notified.
|
||||||
// This eliminates duplicate processing when triggering votes from the vote_cache as the result of a specific election being created.
|
// This eliminates duplicate processing when triggering votes from the vote_cache as the result of a specific election being created.
|
||||||
std::unordered_map<nano::block_hash, nano::vote_code> vote (std::shared_ptr<nano::vote> const &, nano::vote_source = nano::vote_source::live, nano::block_hash filter = { 0 });
|
std::unordered_map<nano::block_hash, nano::vote_code> vote (std::shared_ptr<nano::vote> const &, nano::vote_source = nano::vote_source::live, nano::block_hash filter = { 0 });
|
||||||
bool trigger_vote_cache (nano::block_hash const & hash);
|
|
||||||
bool active (nano::block_hash const & hash) const;
|
bool active (nano::block_hash const & hash) const;
|
||||||
std::shared_ptr<nano::election> election (nano::block_hash const & hash) const;
|
std::shared_ptr<nano::election> election (nano::block_hash const & hash) const;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue