Move local_vote_history in to its own file.
This commit is contained in:
parent
c5b24e8000
commit
f430d8fb15
17 changed files with 222 additions and 177 deletions
|
@ -2,6 +2,7 @@
|
|||
#include <nano/lib/config.hpp>
|
||||
#include <nano/lib/logging.hpp>
|
||||
#include <nano/node/election.hpp>
|
||||
#include <nano/node/local_vote_history.hpp>
|
||||
#include <nano/node/make_store.hpp>
|
||||
#include <nano/node/scheduler/component.hpp>
|
||||
#include <nano/node/scheduler/manual.hpp>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <nano/lib/blocks.hpp>
|
||||
#include <nano/lib/jsonconfig.hpp>
|
||||
#include <nano/node/election.hpp>
|
||||
#include <nano/node/local_vote_history.hpp>
|
||||
#include <nano/node/request_aggregator.hpp>
|
||||
#include <nano/node/transport/inproc.hpp>
|
||||
#include <nano/secure/ledger.hpp>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <nano/lib/blocks.hpp>
|
||||
#include <nano/node/common.hpp>
|
||||
#include <nano/node/local_vote_history.hpp>
|
||||
#include <nano/node/voting.hpp>
|
||||
#include <nano/secure/ledger.hpp>
|
||||
#include <nano/test_common/system.hpp>
|
||||
|
|
|
@ -389,4 +389,12 @@ struct hash<std::reference_wrapper<::nano::block_hash const>>
|
|||
return hash (hash_a);
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct hash<::nano::root>
|
||||
{
|
||||
size_t operator() (::nano::root const & value_a) const
|
||||
{
|
||||
return std::hash<::nano::root> () (value_a);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -98,6 +98,8 @@ add_library(
|
|||
json_handler.cpp
|
||||
local_block_broadcaster.cpp
|
||||
local_block_broadcaster.hpp
|
||||
local_vote_history.cpp
|
||||
local_vote_history.hpp
|
||||
make_store.hpp
|
||||
make_store.cpp
|
||||
network.hpp
|
||||
|
|
|
@ -53,8 +53,9 @@ public: // Tests
|
|||
|
||||
private:
|
||||
// clang-format off
|
||||
class tag_root {};
|
||||
class tag_hash {};
|
||||
class tag_root {};
|
||||
class tag_sequence {};
|
||||
|
||||
using ordered_recent_confirmations = boost::multi_index_container<entry_t,
|
||||
mi::indexed_by<
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <nano/lib/threading.hpp>
|
||||
#include <nano/lib/timer.hpp>
|
||||
#include <nano/node/blockprocessor.hpp>
|
||||
#include <nano/node/local_vote_history.hpp>
|
||||
#include <nano/node/node.hpp>
|
||||
#include <nano/secure/ledger.hpp>
|
||||
#include <nano/store/component.hpp>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <nano/lib/blocks.hpp>
|
||||
#include <nano/node/confirmation_solicitor.hpp>
|
||||
#include <nano/node/election.hpp>
|
||||
#include <nano/node/local_vote_history.hpp>
|
||||
#include <nano/node/network.hpp>
|
||||
#include <nano/node/node.hpp>
|
||||
#include <nano/secure/ledger.hpp>
|
||||
|
|
115
nano/node/local_vote_history.cpp
Normal file
115
nano/node/local_vote_history.cpp
Normal file
|
@ -0,0 +1,115 @@
|
|||
#include <nano/node/local_vote_history.hpp>
|
||||
#include <nano/secure/common.hpp>
|
||||
#include <nano/secure/vote.hpp>
|
||||
|
||||
bool nano::local_vote_history::consistency_check (nano::root const & root_a) const
|
||||
{
|
||||
auto & history_by_root (history.get<tag_root> ());
|
||||
auto const range (history_by_root.equal_range (root_a));
|
||||
// All cached votes for a root must be for the same hash, this is actively enforced in local_vote_history::add
|
||||
auto consistent_same = std::all_of (range.first, range.second, [hash = range.first->hash] (auto const & info_a) { return info_a.hash == hash; });
|
||||
std::vector<nano::account> accounts;
|
||||
std::transform (range.first, range.second, std::back_inserter (accounts), [] (auto const & info_a) { return info_a.vote->account; });
|
||||
std::sort (accounts.begin (), accounts.end ());
|
||||
// All cached votes must be unique by account, this is actively enforced in local_vote_history::add
|
||||
auto consistent_unique = accounts.size () == std::unique (accounts.begin (), accounts.end ()) - accounts.begin ();
|
||||
auto result = consistent_same && consistent_unique;
|
||||
debug_assert (result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void nano::local_vote_history::add (nano::root const & root_a, nano::block_hash const & hash_a, std::shared_ptr<nano::vote> const & vote_a)
|
||||
{
|
||||
nano::lock_guard<nano::mutex> guard{ mutex };
|
||||
clean ();
|
||||
auto add_vote (true);
|
||||
auto & history_by_root (history.get<tag_root> ());
|
||||
// Erase any vote that is not for this hash, or duplicate by account, and if new timestamp is higher
|
||||
auto range (history_by_root.equal_range (root_a));
|
||||
for (auto i (range.first); i != range.second;)
|
||||
{
|
||||
if (i->hash != hash_a || (vote_a->account == i->vote->account && i->vote->timestamp () <= vote_a->timestamp ()))
|
||||
{
|
||||
i = history_by_root.erase (i);
|
||||
}
|
||||
else if (vote_a->account == i->vote->account && i->vote->timestamp () > vote_a->timestamp ())
|
||||
{
|
||||
add_vote = false;
|
||||
++i;
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
// Do not add new vote to cache if representative account is same and timestamp is lower
|
||||
if (add_vote)
|
||||
{
|
||||
auto result (history_by_root.emplace (root_a, hash_a, vote_a));
|
||||
(void)result;
|
||||
debug_assert (result.second);
|
||||
}
|
||||
debug_assert (consistency_check (root_a));
|
||||
}
|
||||
|
||||
void nano::local_vote_history::erase (nano::root const & root_a)
|
||||
{
|
||||
nano::lock_guard<nano::mutex> guard{ mutex };
|
||||
auto & history_by_root (history.get<tag_root> ());
|
||||
auto range (history_by_root.equal_range (root_a));
|
||||
history_by_root.erase (range.first, range.second);
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<nano::vote>> nano::local_vote_history::votes (nano::root const & root_a) const
|
||||
{
|
||||
nano::lock_guard<nano::mutex> guard{ mutex };
|
||||
std::vector<std::shared_ptr<nano::vote>> result;
|
||||
auto range (history.get<tag_root> ().equal_range (root_a));
|
||||
std::transform (range.first, range.second, std::back_inserter (result), [] (auto const & entry) { return entry.vote; });
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<nano::vote>> nano::local_vote_history::votes (nano::root const & root_a, nano::block_hash const & hash_a, bool const is_final_a) const
|
||||
{
|
||||
nano::lock_guard<nano::mutex> guard{ mutex };
|
||||
std::vector<std::shared_ptr<nano::vote>> result;
|
||||
auto range (history.get<tag_root> ().equal_range (root_a));
|
||||
// clang-format off
|
||||
nano::transform_if (range.first, range.second, std::back_inserter (result),
|
||||
[&hash_a, is_final_a](auto const & entry) { return entry.hash == hash_a && (!is_final_a || entry.vote->timestamp () == std::numeric_limits<uint64_t>::max ()); },
|
||||
[](auto const & entry) { return entry.vote; });
|
||||
// clang-format on
|
||||
return result;
|
||||
}
|
||||
|
||||
bool nano::local_vote_history::exists (nano::root const & root_a) const
|
||||
{
|
||||
nano::lock_guard<nano::mutex> guard{ mutex };
|
||||
return history.get<tag_root> ().find (root_a) != history.get<tag_root> ().end ();
|
||||
}
|
||||
|
||||
void nano::local_vote_history::clean ()
|
||||
{
|
||||
debug_assert (constants.max_cache > 0);
|
||||
auto & history_by_sequence (history.get<tag_sequence> ());
|
||||
while (history_by_sequence.size () > constants.max_cache)
|
||||
{
|
||||
history_by_sequence.erase (history_by_sequence.begin ());
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t nano::local_vote_history::size () const
|
||||
{
|
||||
nano::lock_guard<nano::mutex> guard{ mutex };
|
||||
return history.size ();
|
||||
}
|
||||
|
||||
std::unique_ptr<nano::container_info_component> nano::local_vote_history::collect_container_info (std::string const & name) const
|
||||
{
|
||||
std::size_t history_count = size ();
|
||||
auto sizeof_element = sizeof (decltype (history)::value_type);
|
||||
auto composite = std::make_unique<container_info_composite> (name);
|
||||
/* This does not currently loop over each element inside the cache to get the sizes of the votes inside history*/
|
||||
composite->add_component (std::make_unique<container_info_leaf> (container_info{ "history", history_count, sizeof_element }));
|
||||
return composite;
|
||||
}
|
74
nano/node/local_vote_history.hpp
Normal file
74
nano/node/local_vote_history.hpp
Normal file
|
@ -0,0 +1,74 @@
|
|||
#pragma once
|
||||
|
||||
#include <nano/lib/locks.hpp>
|
||||
#include <nano/lib/numbers.hpp>
|
||||
|
||||
#include <boost/multi_index/hashed_index.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
#include <boost/multi_index/sequenced_index.hpp>
|
||||
#include <boost/multi_index_container.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace mi = boost::multi_index;
|
||||
|
||||
namespace nano
|
||||
{
|
||||
class container_info_component;
|
||||
class vote;
|
||||
class voting_constants;
|
||||
}
|
||||
|
||||
namespace nano
|
||||
{
|
||||
class local_vote_history final
|
||||
{
|
||||
class local_vote final
|
||||
{
|
||||
public:
|
||||
local_vote (nano::root const & root_a, nano::block_hash const & hash_a, std::shared_ptr<nano::vote> const & vote_a) :
|
||||
root (root_a),
|
||||
hash (hash_a),
|
||||
vote (vote_a)
|
||||
{
|
||||
}
|
||||
nano::root root;
|
||||
nano::block_hash hash;
|
||||
std::shared_ptr<nano::vote> vote;
|
||||
};
|
||||
|
||||
public:
|
||||
local_vote_history (nano::voting_constants const & constants) :
|
||||
constants{ constants }
|
||||
{
|
||||
}
|
||||
void add (nano::root const & root_a, nano::block_hash const & hash_a, std::shared_ptr<nano::vote> const & vote_a);
|
||||
void erase (nano::root const & root_a);
|
||||
|
||||
std::vector<std::shared_ptr<nano::vote>> votes (nano::root const & root_a, nano::block_hash const & hash_a, bool const is_final_a = false) const;
|
||||
bool exists (nano::root const &) const;
|
||||
std::size_t size () const;
|
||||
|
||||
std::unique_ptr<container_info_component> collect_container_info (std::string const & name) const;
|
||||
|
||||
private:
|
||||
// clang-format off
|
||||
boost::multi_index_container<local_vote,
|
||||
mi::indexed_by<
|
||||
mi::hashed_non_unique<mi::tag<class tag_root>,
|
||||
mi::member<local_vote, nano::root, &local_vote::root>>,
|
||||
mi::sequenced<mi::tag<class tag_sequence>>>>
|
||||
history;
|
||||
// clang-format on
|
||||
|
||||
nano::voting_constants const & constants;
|
||||
void clean ();
|
||||
std::vector<std::shared_ptr<nano::vote>> votes (nano::root const & root_a) const;
|
||||
// Only used in Debug
|
||||
bool consistency_check (nano::root const &) const;
|
||||
mutable nano::mutex mutex;
|
||||
|
||||
friend class local_vote_history_basic_Test;
|
||||
};
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
#include <nano/node/common.hpp>
|
||||
#include <nano/node/daemonconfig.hpp>
|
||||
#include <nano/node/make_store.hpp>
|
||||
#include <nano/node/local_vote_history.hpp>
|
||||
#include <nano/node/node.hpp>
|
||||
#include <nano/node/scheduler/component.hpp>
|
||||
#include <nano/node/scheduler/hinted.hpp>
|
||||
|
@ -171,7 +172,8 @@ nano::node::node (std::shared_ptr<boost::asio::io_context> io_ctx_a, std::filesy
|
|||
warmed_up (0),
|
||||
block_processor (*this, write_database_queue),
|
||||
online_reps (ledger, config),
|
||||
history{ config.network_params.voting },
|
||||
history_impl{ std::make_unique<nano::local_vote_history> (config.network_params.voting) },
|
||||
history{ *history_impl },
|
||||
vote_uniquer{},
|
||||
confirmation_height_processor (ledger, write_database_queue, config.conf_height_processor_batch_min_time, logger, node_initialized_latch, flags.confirmation_height_processor_mode),
|
||||
vote_cache{ config.vote_cache, stats },
|
||||
|
@ -537,7 +539,7 @@ std::unique_ptr<nano::container_info_component> nano::collect_container_info (no
|
|||
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 (collect_container_info (node.online_reps, "online_reps"));
|
||||
composite->add_component (collect_container_info (node.history, "history"));
|
||||
composite->add_component (node.history.collect_container_info ("history"));
|
||||
composite->add_component (node.block_uniquer.collect_container_info ("block_uniquer"));
|
||||
composite->add_component (node.vote_uniquer.collect_container_info ("vote_uniquer"));
|
||||
composite->add_component (collect_container_info (node.confirmation_height_processor, "confirmation_height_processor"));
|
||||
|
|
|
@ -166,7 +166,8 @@ public:
|
|||
nano::vote_processor vote_processor;
|
||||
unsigned warmed_up;
|
||||
nano::block_processor block_processor;
|
||||
nano::local_vote_history history;
|
||||
std::unique_ptr<nano::local_vote_history> history_impl;
|
||||
nano::local_vote_history & history;
|
||||
nano::block_uniquer block_uniquer;
|
||||
nano::vote_uniquer vote_uniquer;
|
||||
nano::confirmation_height_processor confirmation_height_processor;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <nano/lib/stats.hpp>
|
||||
#include <nano/node/active_transactions.hpp>
|
||||
#include <nano/node/common.hpp>
|
||||
#include <nano/node/local_vote_history.hpp>
|
||||
#include <nano/node/network.hpp>
|
||||
#include <nano/node/nodeconfig.hpp>
|
||||
#include <nano/node/request_aggregator.hpp>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <nano/lib/blocks.hpp>
|
||||
#include <nano/lib/stats.hpp>
|
||||
#include <nano/lib/utility.hpp>
|
||||
#include <nano/node/local_vote_history.hpp>
|
||||
#include <nano/node/network.hpp>
|
||||
#include <nano/node/nodeconfig.hpp>
|
||||
#include <nano/node/transport/inproc.hpp>
|
||||
|
@ -50,118 +51,6 @@ std::size_t nano::vote_spacing::size () const
|
|||
return recent.size ();
|
||||
}
|
||||
|
||||
bool nano::local_vote_history::consistency_check (nano::root const & root_a) const
|
||||
{
|
||||
auto & history_by_root (history.get<tag_root> ());
|
||||
auto const range (history_by_root.equal_range (root_a));
|
||||
// All cached votes for a root must be for the same hash, this is actively enforced in local_vote_history::add
|
||||
auto consistent_same = std::all_of (range.first, range.second, [hash = range.first->hash] (auto const & info_a) { return info_a.hash == hash; });
|
||||
std::vector<nano::account> accounts;
|
||||
std::transform (range.first, range.second, std::back_inserter (accounts), [] (auto const & info_a) { return info_a.vote->account; });
|
||||
std::sort (accounts.begin (), accounts.end ());
|
||||
// All cached votes must be unique by account, this is actively enforced in local_vote_history::add
|
||||
auto consistent_unique = accounts.size () == std::unique (accounts.begin (), accounts.end ()) - accounts.begin ();
|
||||
auto result = consistent_same && consistent_unique;
|
||||
debug_assert (result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void nano::local_vote_history::add (nano::root const & root_a, nano::block_hash const & hash_a, std::shared_ptr<nano::vote> const & vote_a)
|
||||
{
|
||||
nano::lock_guard<nano::mutex> guard{ mutex };
|
||||
clean ();
|
||||
auto add_vote (true);
|
||||
auto & history_by_root (history.get<tag_root> ());
|
||||
// Erase any vote that is not for this hash, or duplicate by account, and if new timestamp is higher
|
||||
auto range (history_by_root.equal_range (root_a));
|
||||
for (auto i (range.first); i != range.second;)
|
||||
{
|
||||
if (i->hash != hash_a || (vote_a->account == i->vote->account && i->vote->timestamp () <= vote_a->timestamp ()))
|
||||
{
|
||||
i = history_by_root.erase (i);
|
||||
}
|
||||
else if (vote_a->account == i->vote->account && i->vote->timestamp () > vote_a->timestamp ())
|
||||
{
|
||||
add_vote = false;
|
||||
++i;
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
// Do not add new vote to cache if representative account is same and timestamp is lower
|
||||
if (add_vote)
|
||||
{
|
||||
auto result (history_by_root.emplace (root_a, hash_a, vote_a));
|
||||
(void)result;
|
||||
debug_assert (result.second);
|
||||
}
|
||||
debug_assert (consistency_check (root_a));
|
||||
}
|
||||
|
||||
void nano::local_vote_history::erase (nano::root const & root_a)
|
||||
{
|
||||
nano::lock_guard<nano::mutex> guard{ mutex };
|
||||
auto & history_by_root (history.get<tag_root> ());
|
||||
auto range (history_by_root.equal_range (root_a));
|
||||
history_by_root.erase (range.first, range.second);
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<nano::vote>> nano::local_vote_history::votes (nano::root const & root_a) const
|
||||
{
|
||||
nano::lock_guard<nano::mutex> guard{ mutex };
|
||||
std::vector<std::shared_ptr<nano::vote>> result;
|
||||
auto range (history.get<tag_root> ().equal_range (root_a));
|
||||
std::transform (range.first, range.second, std::back_inserter (result), [] (auto const & entry) { return entry.vote; });
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<nano::vote>> nano::local_vote_history::votes (nano::root const & root_a, nano::block_hash const & hash_a, bool const is_final_a) const
|
||||
{
|
||||
nano::lock_guard<nano::mutex> guard{ mutex };
|
||||
std::vector<std::shared_ptr<nano::vote>> result;
|
||||
auto range (history.get<tag_root> ().equal_range (root_a));
|
||||
// clang-format off
|
||||
nano::transform_if (range.first, range.second, std::back_inserter (result),
|
||||
[&hash_a, is_final_a](auto const & entry) { return entry.hash == hash_a && (!is_final_a || entry.vote->timestamp () == std::numeric_limits<uint64_t>::max ()); },
|
||||
[](auto const & entry) { return entry.vote; });
|
||||
// clang-format on
|
||||
return result;
|
||||
}
|
||||
|
||||
bool nano::local_vote_history::exists (nano::root const & root_a) const
|
||||
{
|
||||
nano::lock_guard<nano::mutex> guard{ mutex };
|
||||
return history.get<tag_root> ().find (root_a) != history.get<tag_root> ().end ();
|
||||
}
|
||||
|
||||
void nano::local_vote_history::clean ()
|
||||
{
|
||||
debug_assert (constants.max_cache > 0);
|
||||
auto & history_by_sequence (history.get<tag_sequence> ());
|
||||
while (history_by_sequence.size () > constants.max_cache)
|
||||
{
|
||||
history_by_sequence.erase (history_by_sequence.begin ());
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t nano::local_vote_history::size () const
|
||||
{
|
||||
nano::lock_guard<nano::mutex> guard{ mutex };
|
||||
return history.size ();
|
||||
}
|
||||
|
||||
std::unique_ptr<nano::container_info_component> nano::collect_container_info (nano::local_vote_history & history, std::string const & name)
|
||||
{
|
||||
std::size_t history_count = history.size ();
|
||||
auto sizeof_element = sizeof (decltype (history.history)::value_type);
|
||||
auto composite = std::make_unique<container_info_composite> (name);
|
||||
/* This does not currently loop over each element inside the cache to get the sizes of the votes inside history*/
|
||||
composite->add_component (std::make_unique<container_info_leaf> (container_info{ "history", history_count, sizeof_element }));
|
||||
return composite;
|
||||
}
|
||||
|
||||
nano::vote_generator::vote_generator (nano::node_config const & config_a, nano::node & node_a, nano::ledger & ledger_a, nano::wallets & wallets_a, nano::vote_processor & vote_processor_a, nano::local_vote_history & history_a, nano::network & network_a, nano::stats & stats_a, nano::logger & logger_a, bool is_final_a) :
|
||||
config (config_a),
|
||||
node (node_a),
|
||||
|
|
|
@ -22,9 +22,10 @@ namespace mi = boost::multi_index;
|
|||
|
||||
namespace nano
|
||||
{
|
||||
class node;
|
||||
class ledger;
|
||||
class local_vote_history;
|
||||
class network;
|
||||
class node;
|
||||
class node_config;
|
||||
class stats;
|
||||
class vote_processor;
|
||||
|
@ -64,57 +65,6 @@ public:
|
|||
std::size_t size () const;
|
||||
};
|
||||
|
||||
class local_vote_history final
|
||||
{
|
||||
class local_vote final
|
||||
{
|
||||
public:
|
||||
local_vote (nano::root const & root_a, nano::block_hash const & hash_a, std::shared_ptr<nano::vote> const & vote_a) :
|
||||
root (root_a),
|
||||
hash (hash_a),
|
||||
vote (vote_a)
|
||||
{
|
||||
}
|
||||
nano::root root;
|
||||
nano::block_hash hash;
|
||||
std::shared_ptr<nano::vote> vote;
|
||||
};
|
||||
|
||||
public:
|
||||
local_vote_history (nano::voting_constants const & constants) :
|
||||
constants{ constants }
|
||||
{
|
||||
}
|
||||
void add (nano::root const & root_a, nano::block_hash const & hash_a, std::shared_ptr<nano::vote> const & vote_a);
|
||||
void erase (nano::root const & root_a);
|
||||
|
||||
std::vector<std::shared_ptr<nano::vote>> votes (nano::root const & root_a, nano::block_hash const & hash_a, bool const is_final_a = false) const;
|
||||
bool exists (nano::root const &) const;
|
||||
std::size_t size () const;
|
||||
|
||||
private:
|
||||
// clang-format off
|
||||
boost::multi_index_container<local_vote,
|
||||
mi::indexed_by<
|
||||
mi::hashed_non_unique<mi::tag<class tag_root>,
|
||||
mi::member<local_vote, nano::root, &local_vote::root>>,
|
||||
mi::sequenced<mi::tag<class tag_sequence>>>>
|
||||
history;
|
||||
// clang-format on
|
||||
|
||||
nano::voting_constants const & constants;
|
||||
void clean ();
|
||||
std::vector<std::shared_ptr<nano::vote>> votes (nano::root const & root_a) const;
|
||||
// Only used in Debug
|
||||
bool consistency_check (nano::root const &) const;
|
||||
mutable nano::mutex mutex;
|
||||
|
||||
friend std::unique_ptr<container_info_component> collect_container_info (local_vote_history & history, std::string const & name);
|
||||
friend class local_vote_history_basic_Test;
|
||||
};
|
||||
|
||||
std::unique_ptr<container_info_component> collect_container_info (local_vote_history & history, std::string const & name);
|
||||
|
||||
class vote_generator final
|
||||
{
|
||||
private:
|
||||
|
|
|
@ -73,14 +73,6 @@ struct hash<::nano::qualified_root>
|
|||
return std::hash<::nano::qualified_root> () (value_a);
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct hash<::nano::root>
|
||||
{
|
||||
size_t operator() (::nano::root const & value_a) const
|
||||
{
|
||||
return std::hash<::nano::root> () (value_a);
|
||||
}
|
||||
};
|
||||
}
|
||||
namespace nano
|
||||
{
|
||||
|
|
|
@ -10,6 +10,11 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
namespace nano
|
||||
{
|
||||
class object_stream;
|
||||
}
|
||||
|
||||
namespace nano
|
||||
{
|
||||
class vote final
|
||||
|
@ -77,4 +82,4 @@ public: // Logging
|
|||
};
|
||||
|
||||
using vote_uniquer = nano::uniquer<nano::block_hash, nano::vote>;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue