Improve use of boost::multi_index_container (#2430)
Change from ordered_non_unique to sequence where applicable, and general improvements.
This commit is contained in:
parent
6db7592bb8
commit
55f4bcbe17
17 changed files with 246 additions and 183 deletions
|
@ -2295,7 +2295,7 @@ TEST (node, block_arrival_size)
|
|||
nano::block_hash hash (0);
|
||||
for (auto i (0); i < nano::block_arrival::arrival_size_min * 2; ++i)
|
||||
{
|
||||
node.block_arrival.arrival.insert (nano::block_arrival_info{ time, hash });
|
||||
node.block_arrival.arrival.push_back (nano::block_arrival_info{ time, hash });
|
||||
++hash.qwords[0];
|
||||
}
|
||||
ASSERT_EQ (nano::block_arrival::arrival_size_min * 2, node.block_arrival.arrival.size ());
|
||||
|
@ -2311,7 +2311,7 @@ TEST (node, block_arrival_time)
|
|||
nano::block_hash hash (0);
|
||||
for (auto i (0); i < nano::block_arrival::arrival_size_min * 2; ++i)
|
||||
{
|
||||
node.block_arrival.arrival.insert (nano::block_arrival_info{ time, hash });
|
||||
node.block_arrival.arrival.push_back (nano::block_arrival_info{ time, hash });
|
||||
++hash.qwords[0];
|
||||
}
|
||||
ASSERT_EQ (nano::block_arrival::arrival_size_min * 2, node.block_arrival.arrival.size ());
|
||||
|
|
|
@ -71,9 +71,9 @@ void nano::active_transactions::search_frontiers (nano::transaction const & tran
|
|||
auto start_elections_for_prioritized_frontiers = [&transaction_a, &elections_count, max_elections, &lk, &representative, this](prioritize_num_uncemented & cementable_frontiers) {
|
||||
while (!cementable_frontiers.empty () && !this->stopped && elections_count < max_elections)
|
||||
{
|
||||
auto cementable_account_front_it = cementable_frontiers.get<1> ().begin ();
|
||||
auto cementable_account_front_it = cementable_frontiers.get<tag_uncemented> ().begin ();
|
||||
auto cementable_account = *cementable_account_front_it;
|
||||
cementable_frontiers.get<1> ().erase (cementable_account_front_it);
|
||||
cementable_frontiers.get<tag_uncemented> ().erase (cementable_account_front_it);
|
||||
lk.unlock ();
|
||||
nano::account_info info;
|
||||
auto error = node.store.account_get (transaction_a, cementable_account.account, info);
|
||||
|
@ -331,7 +331,7 @@ void nano::active_transactions::request_confirm (nano::unique_lock<std::mutex> &
|
|||
|
||||
auto const representatives_l (node.rep_crawler.representatives (std::numeric_limits<size_t>::max ()));
|
||||
auto roots_size_l (roots.size ());
|
||||
auto & sorted_roots_l = roots.get<1> ();
|
||||
auto & sorted_roots_l = roots.get<tag_difficulty> ();
|
||||
size_t count_l{ 0 };
|
||||
|
||||
/*
|
||||
|
@ -434,12 +434,12 @@ void nano::active_transactions::request_confirm (nano::unique_lock<std::mutex> &
|
|||
// Erase inactive elections
|
||||
for (auto i (inactive_l.begin ()), n (inactive_l.end ()); i != n; ++i)
|
||||
{
|
||||
auto root_it (roots.find (*i));
|
||||
if (root_it != roots.end ())
|
||||
auto root_it (roots.get<tag_root> ().find (*i));
|
||||
if (root_it != roots.get<tag_root> ().end ())
|
||||
{
|
||||
root_it->election->clear_blocks ();
|
||||
root_it->election->clear_dependent ();
|
||||
roots.erase (root_it);
|
||||
roots.get<tag_root> ().erase (root_it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -485,13 +485,13 @@ void nano::active_transactions::prioritize_account_for_confirmation (nano::activ
|
|||
{
|
||||
auto num_uncemented = info_a.block_count - confirmation_height;
|
||||
nano::lock_guard<std::mutex> guard (mutex);
|
||||
auto it = cementable_frontiers_a.find (account_a);
|
||||
if (it != cementable_frontiers_a.end ())
|
||||
auto it = cementable_frontiers_a.get<tag_account> ().find (account_a);
|
||||
if (it != cementable_frontiers_a.get<tag_account> ().end ())
|
||||
{
|
||||
if (it->blocks_uncemented != num_uncemented)
|
||||
{
|
||||
// Account already exists and there is now a different uncemented block count so update it in the container
|
||||
cementable_frontiers_a.modify (it, [num_uncemented](nano::cementable_account & info) {
|
||||
cementable_frontiers_a.get<tag_account> ().modify (it, [num_uncemented](nano::cementable_account & info) {
|
||||
info.blocks_uncemented = num_uncemented;
|
||||
});
|
||||
}
|
||||
|
@ -503,17 +503,17 @@ void nano::active_transactions::prioritize_account_for_confirmation (nano::activ
|
|||
{
|
||||
// The maximum amount of frontiers stored has been reached. Check if the current frontier
|
||||
// has more uncemented blocks than the lowest uncemented frontier in the collection if so replace it.
|
||||
auto least_uncemented_frontier_it = cementable_frontiers_a.get<1> ().end ();
|
||||
auto least_uncemented_frontier_it = cementable_frontiers_a.get<tag_uncemented> ().end ();
|
||||
--least_uncemented_frontier_it;
|
||||
if (num_uncemented > least_uncemented_frontier_it->blocks_uncemented)
|
||||
{
|
||||
cementable_frontiers_a.get<1> ().erase (least_uncemented_frontier_it);
|
||||
cementable_frontiers_a.emplace (account_a, num_uncemented);
|
||||
cementable_frontiers_a.get<tag_uncemented> ().erase (least_uncemented_frontier_it);
|
||||
cementable_frontiers_a.get<tag_account> ().emplace (account_a, num_uncemented);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cementable_frontiers_a.emplace (account_a, num_uncemented);
|
||||
cementable_frontiers_a.get<tag_account> ().emplace (account_a, num_uncemented);
|
||||
}
|
||||
}
|
||||
cementable_frontiers_size_a = cementable_frontiers_a.size ();
|
||||
|
@ -666,15 +666,15 @@ bool nano::active_transactions::add (std::shared_ptr<nano::block> block_a, bool
|
|||
if (!stopped)
|
||||
{
|
||||
auto root (block_a->qualified_root ());
|
||||
auto existing (roots.find (root));
|
||||
if (existing == roots.end () && confirmed_set.get<1> ().find (root) == confirmed_set.get<1> ().end ())
|
||||
auto existing (roots.get<tag_root> ().find (root));
|
||||
if (existing == roots.get<tag_root> ().end () && confirmed_set.get<tag_root> ().find (root) == confirmed_set.get<tag_root> ().end ())
|
||||
{
|
||||
auto hash (block_a->hash ());
|
||||
auto election (nano::make_shared<nano::election> (node, block_a, skip_delay_a, confirmation_action_a));
|
||||
uint64_t difficulty (0);
|
||||
error = nano::work_validate (*block_a, &difficulty);
|
||||
release_assert (!error);
|
||||
roots.insert (nano::conflict_info{ root, difficulty, difficulty, election });
|
||||
roots.get<tag_root> ().emplace (nano::conflict_info{ root, difficulty, difficulty, election });
|
||||
blocks.insert (std::make_pair (hash, election));
|
||||
adjust_difficulty (hash);
|
||||
election->insert_inactive_votes_cache ();
|
||||
|
@ -714,8 +714,8 @@ bool nano::active_transactions::vote (std::shared_ptr<nano::vote> vote_a, bool s
|
|||
else
|
||||
{
|
||||
auto block (boost::get<std::shared_ptr<nano::block>> (vote_block));
|
||||
auto existing (roots.find (block->qualified_root ()));
|
||||
if (existing != roots.end ())
|
||||
auto existing (roots.get<tag_root> ().find (block->qualified_root ()));
|
||||
if (existing != roots.get<tag_root> ().end ())
|
||||
{
|
||||
result = existing->election->vote (vote_a->account, vote_a->sequence, block->hash ());
|
||||
}
|
||||
|
@ -738,7 +738,7 @@ bool nano::active_transactions::vote (std::shared_ptr<nano::vote> vote_a, bool s
|
|||
bool nano::active_transactions::active (nano::qualified_root const & root_a)
|
||||
{
|
||||
nano::lock_guard<std::mutex> lock (mutex);
|
||||
return roots.find (root_a) != roots.end ();
|
||||
return roots.get<tag_root> ().find (root_a) != roots.get<tag_root> ().end ();
|
||||
}
|
||||
|
||||
bool nano::active_transactions::active (nano::block const & block_a)
|
||||
|
@ -749,8 +749,8 @@ bool nano::active_transactions::active (nano::block const & block_a)
|
|||
void nano::active_transactions::update_difficulty (std::shared_ptr<nano::block> block_a, boost::optional<nano::write_transaction const &> opt_transaction_a)
|
||||
{
|
||||
nano::unique_lock<std::mutex> lock (mutex);
|
||||
auto existing_election (roots.find (block_a->qualified_root ()));
|
||||
if (existing_election != roots.end ())
|
||||
auto existing_election (roots.get<tag_root> ().find (block_a->qualified_root ()));
|
||||
if (existing_election != roots.get<tag_root> ().end ())
|
||||
{
|
||||
uint64_t difficulty;
|
||||
auto error (nano::work_validate (*block_a, &difficulty));
|
||||
|
@ -762,7 +762,7 @@ void nano::active_transactions::update_difficulty (std::shared_ptr<nano::block>
|
|||
{
|
||||
node.logger.try_log (boost::str (boost::format ("Block %1% was updated from difficulty %2% to %3%") % block_a->hash ().to_string () % nano::to_string_hex (existing_election->difficulty) % nano::to_string_hex (difficulty)));
|
||||
}
|
||||
roots.modify (existing_election, [difficulty](nano::conflict_info & info_a) {
|
||||
roots.get<tag_root> ().modify (existing_election, [difficulty](nano::conflict_info & info_a) {
|
||||
info_a.difficulty = difficulty;
|
||||
});
|
||||
adjust_difficulty (block_a->hash ());
|
||||
|
@ -846,8 +846,8 @@ void nano::active_transactions::adjust_difficulty (nano::block_hash const & hash
|
|||
}
|
||||
processed_blocks.insert (hash);
|
||||
nano::qualified_root root (previous, existing->second->status.winner->root ());
|
||||
auto existing_root (roots.find (root));
|
||||
if (existing_root != roots.end ())
|
||||
auto existing_root (roots.get<tag_root> ().find (root));
|
||||
if (existing_root != roots.get<tag_root> ().end ())
|
||||
{
|
||||
sum += nano::difficulty::to_multiplier (existing_root->difficulty, node.network_params.network.publish_threshold);
|
||||
elections_list.emplace_back (root, level);
|
||||
|
@ -886,9 +886,9 @@ void nano::active_transactions::adjust_difficulty (nano::block_hash const & hash
|
|||
// Set adjusted difficulty
|
||||
for (auto & item : elections_list)
|
||||
{
|
||||
auto existing_root (roots.find (item.first));
|
||||
auto existing_root (roots.get<tag_root> ().find (item.first));
|
||||
uint64_t difficulty_a = average + item.second - limiter;
|
||||
roots.modify (existing_root, [difficulty_a](nano::conflict_info & info_a) {
|
||||
roots.get<tag_root> ().modify (existing_root, [difficulty_a](nano::conflict_info & info_a) {
|
||||
info_a.adjusted_difficulty = difficulty_a;
|
||||
});
|
||||
}
|
||||
|
@ -901,9 +901,9 @@ void nano::active_transactions::update_active_difficulty (nano::unique_lock<std:
|
|||
double multiplier (1.);
|
||||
if (!roots.empty ())
|
||||
{
|
||||
auto & sorted_roots = roots.get<1> ();
|
||||
auto & sorted_roots = roots.get<tag_difficulty> ();
|
||||
std::vector<uint64_t> active_root_difficulties;
|
||||
active_root_difficulties.reserve (std::min (roots.size (), node.config.active_elections_size));
|
||||
active_root_difficulties.reserve (std::min (sorted_roots.size (), node.config.active_elections_size));
|
||||
size_t count (0);
|
||||
auto cutoff (std::chrono::steady_clock::now () - election_request_delay - 1s);
|
||||
for (auto it (sorted_roots.begin ()), end (sorted_roots.end ()); it != end && count++ < node.config.active_elections_size; ++it)
|
||||
|
@ -948,9 +948,9 @@ std::deque<std::shared_ptr<nano::block>> nano::active_transactions::list_blocks
|
|||
{
|
||||
lock = nano::unique_lock<std::mutex> (mutex);
|
||||
}
|
||||
for (auto i (roots.begin ()), n (roots.end ()); i != n; ++i)
|
||||
for (auto & root : roots)
|
||||
{
|
||||
result.push_back (i->election->status.winner);
|
||||
result.push_back (root.election->status.winner);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -964,13 +964,13 @@ std::deque<nano::election_status> nano::active_transactions::list_confirmed ()
|
|||
void nano::active_transactions::add_confirmed (nano::election_status const & status_a, nano::qualified_root const & root_a)
|
||||
{
|
||||
confirmed.push_back (status_a);
|
||||
auto inserted (confirmed_set.insert (nano::election_timepoint{ std::chrono::steady_clock::now (), root_a }));
|
||||
auto inserted (confirmed_set.get<tag_sequence> ().push_back (root_a));
|
||||
if (confirmed.size () > node.config.confirmation_history_size)
|
||||
{
|
||||
confirmed.pop_front ();
|
||||
if (inserted.second)
|
||||
{
|
||||
confirmed_set.erase (confirmed_set.begin ());
|
||||
confirmed_set.get<tag_sequence> ().pop_front ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -978,13 +978,13 @@ void nano::active_transactions::add_confirmed (nano::election_status const & sta
|
|||
void nano::active_transactions::erase (nano::block const & block_a)
|
||||
{
|
||||
nano::lock_guard<std::mutex> lock (mutex);
|
||||
auto root_it (roots.find (block_a.qualified_root ()));
|
||||
if (root_it != roots.end ())
|
||||
auto root_it (roots.get<tag_root> ().find (block_a.qualified_root ()));
|
||||
if (root_it != roots.get<tag_root> ().end ())
|
||||
{
|
||||
root_it->election->stop ();
|
||||
root_it->election->clear_blocks ();
|
||||
root_it->election->clear_dependent ();
|
||||
roots.erase (root_it);
|
||||
roots.get<tag_root> ().erase (root_it);
|
||||
node.logger.try_log (boost::str (boost::format ("Election erased for block block %1% root %2%") % block_a.hash ().to_string () % block_a.root ().to_string ()));
|
||||
}
|
||||
}
|
||||
|
@ -1004,9 +1004,9 @@ size_t nano::active_transactions::size ()
|
|||
bool nano::active_transactions::publish (std::shared_ptr<nano::block> block_a)
|
||||
{
|
||||
nano::lock_guard<std::mutex> lock (mutex);
|
||||
auto existing (roots.find (block_a->qualified_root ()));
|
||||
auto existing (roots.get<tag_root> ().find (block_a->qualified_root ()));
|
||||
auto result (true);
|
||||
if (existing != roots.end ())
|
||||
if (existing != roots.get<tag_root> ().end ())
|
||||
{
|
||||
auto election (existing->election);
|
||||
result = election->publish (block_a);
|
||||
|
@ -1077,11 +1077,11 @@ void nano::active_transactions::add_inactive_votes_cache (nano::block_hash const
|
|||
// Check principal representative status
|
||||
if (node.ledger.weight (representative_a) > node.minimum_principal_weight ())
|
||||
{
|
||||
auto existing (inactive_votes_cache.get<1> ().find (hash_a));
|
||||
if (existing != inactive_votes_cache.get<1> ().end () && !existing->confirmed)
|
||||
auto existing (inactive_votes_cache.get<nano::gap_cache::tag_hash> ().find (hash_a));
|
||||
if (existing != inactive_votes_cache.get<nano::gap_cache::tag_hash> ().end () && !existing->confirmed)
|
||||
{
|
||||
auto is_new (false);
|
||||
inactive_votes_cache.get<1> ().modify (existing, [representative_a, &is_new](nano::gap_information & info) {
|
||||
inactive_votes_cache.get<nano::gap_cache::tag_hash> ().modify (existing, [representative_a, &is_new](nano::gap_information & info) {
|
||||
auto it = std::find (info.voters.begin (), info.voters.end (), representative_a);
|
||||
is_new = (it == info.voters.end ());
|
||||
if (is_new)
|
||||
|
@ -1095,7 +1095,7 @@ void nano::active_transactions::add_inactive_votes_cache (nano::block_hash const
|
|||
{
|
||||
if (node.gap_cache.bootstrap_check (existing->voters, hash_a))
|
||||
{
|
||||
inactive_votes_cache.get<1> ().modify (existing, [](nano::gap_information & info) {
|
||||
inactive_votes_cache.get<nano::gap_cache::tag_hash> ().modify (existing, [](nano::gap_information & info) {
|
||||
info.confirmed = true;
|
||||
});
|
||||
}
|
||||
|
@ -1103,10 +1103,10 @@ void nano::active_transactions::add_inactive_votes_cache (nano::block_hash const
|
|||
}
|
||||
else
|
||||
{
|
||||
inactive_votes_cache.insert ({ std::chrono::steady_clock::now (), hash_a, std::vector<nano::account> (1, representative_a) });
|
||||
inactive_votes_cache.get<nano::gap_cache::tag_arrival> ().emplace (nano::gap_information{ std::chrono::steady_clock::now (), hash_a, std::vector<nano::account> (1, representative_a) });
|
||||
if (inactive_votes_cache.size () > inactive_votes_cache_max)
|
||||
{
|
||||
inactive_votes_cache.get<0> ().erase (inactive_votes_cache.get<0> ().begin ());
|
||||
inactive_votes_cache.get<nano::gap_cache::tag_arrival> ().erase (inactive_votes_cache.get<nano::gap_cache::tag_arrival> ().begin ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1114,8 +1114,8 @@ void nano::active_transactions::add_inactive_votes_cache (nano::block_hash const
|
|||
|
||||
nano::gap_information nano::active_transactions::find_inactive_votes_cache (nano::block_hash const & hash_a)
|
||||
{
|
||||
auto existing (inactive_votes_cache.get<1> ().find (hash_a));
|
||||
if (existing != inactive_votes_cache.get<1> ().end ())
|
||||
auto existing (inactive_votes_cache.get<nano::gap_cache::tag_hash> ().find (hash_a));
|
||||
if (existing != inactive_votes_cache.get<nano::gap_cache::tag_hash> ().end ())
|
||||
{
|
||||
return *existing;
|
||||
}
|
||||
|
@ -1134,18 +1134,18 @@ size_t nano::active_transactions::dropped_elections_cache_size ()
|
|||
void nano::active_transactions::add_dropped_elections_cache (nano::qualified_root const & root_a)
|
||||
{
|
||||
assert (!mutex.try_lock ());
|
||||
dropped_elections_cache.insert (nano::election_timepoint{ std::chrono::steady_clock::now (), root_a });
|
||||
dropped_elections_cache.get<tag_sequence> ().emplace_back (nano::election_timepoint{ std::chrono::steady_clock::now (), root_a });
|
||||
if (dropped_elections_cache.size () > dropped_elections_cache_max)
|
||||
{
|
||||
dropped_elections_cache.get<0> ().erase (dropped_elections_cache.get<0> ().begin ());
|
||||
dropped_elections_cache.get<tag_sequence> ().pop_front ();
|
||||
}
|
||||
}
|
||||
|
||||
std::chrono::steady_clock::time_point nano::active_transactions::find_dropped_elections_cache (nano::qualified_root const & root_a)
|
||||
{
|
||||
assert (!mutex.try_lock ());
|
||||
auto existing (dropped_elections_cache.get<1> ().find (root_a));
|
||||
if (existing != dropped_elections_cache.get<1> ().end ())
|
||||
auto existing (dropped_elections_cache.get<tag_root> ().find (root_a));
|
||||
if (existing != dropped_elections_cache.get<tag_root> ().end ())
|
||||
{
|
||||
return existing->time;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#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 <boost/thread/thread.hpp>
|
||||
|
||||
|
@ -21,6 +22,8 @@
|
|||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace mi = boost::multi_index;
|
||||
|
||||
namespace nano
|
||||
{
|
||||
class node;
|
||||
|
@ -80,6 +83,14 @@ public:
|
|||
// Holds all active blocks i.e. recently added blocks that need confirmation
|
||||
class active_transactions final
|
||||
{
|
||||
// clang-format off
|
||||
class tag_account {};
|
||||
class tag_difficulty {};
|
||||
class tag_root {};
|
||||
class tag_sequence {};
|
||||
class tag_uncemented {};
|
||||
// clang-format on
|
||||
|
||||
public:
|
||||
explicit active_transactions (nano::node &);
|
||||
~active_transactions ();
|
||||
|
@ -107,15 +118,16 @@ public:
|
|||
bool publish (std::shared_ptr<nano::block> block_a);
|
||||
boost::optional<nano::election_status_type> confirm_block (nano::transaction const &, std::shared_ptr<nano::block>);
|
||||
void post_confirmation_height_set (nano::transaction const & transaction_a, std::shared_ptr<nano::block> block_a, nano::block_sideband const & sideband_a, nano::election_status_type election_status_type_a);
|
||||
boost::multi_index_container<
|
||||
nano::conflict_info,
|
||||
boost::multi_index::indexed_by<
|
||||
boost::multi_index::hashed_unique<
|
||||
boost::multi_index::member<nano::conflict_info, nano::qualified_root, &nano::conflict_info::root>>,
|
||||
boost::multi_index::ordered_non_unique<
|
||||
boost::multi_index::member<nano::conflict_info, uint64_t, &nano::conflict_info::adjusted_difficulty>,
|
||||
std::greater<uint64_t>>>>
|
||||
// clang-format off
|
||||
boost::multi_index_container<nano::conflict_info,
|
||||
mi::indexed_by<
|
||||
mi::hashed_unique<mi::tag<tag_root>,
|
||||
mi::member<nano::conflict_info, nano::qualified_root, &nano::conflict_info::root>>,
|
||||
mi::ordered_non_unique<mi::tag<tag_difficulty>,
|
||||
mi::member<nano::conflict_info, uint64_t, &nano::conflict_info::adjusted_difficulty>,
|
||||
std::greater<uint64_t>>>>
|
||||
roots;
|
||||
// clang-format on
|
||||
std::unordered_map<nano::block_hash, std::shared_ptr<nano::election>> blocks;
|
||||
std::deque<nano::election_status> list_confirmed ();
|
||||
std::deque<nano::election_status> confirmed;
|
||||
|
@ -164,37 +176,40 @@ private:
|
|||
bool started{ false };
|
||||
std::atomic<bool> stopped{ false };
|
||||
unsigned ongoing_broadcasts{ 0 };
|
||||
using ordered_elections_timepoint = boost::multi_index_container<
|
||||
nano::election_timepoint,
|
||||
boost::multi_index::indexed_by<
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::member<nano::election_timepoint, std::chrono::steady_clock::time_point, &nano::election_timepoint::time>>,
|
||||
boost::multi_index::hashed_unique<boost::multi_index::member<nano::election_timepoint, nano::qualified_root, &nano::election_timepoint::root>>>>;
|
||||
ordered_elections_timepoint confirmed_set;
|
||||
void prioritize_frontiers_for_confirmation (nano::transaction const &, std::chrono::milliseconds, std::chrono::milliseconds);
|
||||
using prioritize_num_uncemented = boost::multi_index_container<
|
||||
nano::cementable_account,
|
||||
boost::multi_index::indexed_by<
|
||||
boost::multi_index::hashed_unique<
|
||||
boost::multi_index::member<nano::cementable_account, nano::account, &nano::cementable_account::account>>,
|
||||
boost::multi_index::ordered_non_unique<
|
||||
boost::multi_index::member<nano::cementable_account, uint64_t, &nano::cementable_account::blocks_uncemented>,
|
||||
std::greater<uint64_t>>>>;
|
||||
// clang-format off
|
||||
boost::multi_index_container<nano::qualified_root,
|
||||
mi::indexed_by<
|
||||
mi::sequenced<mi::tag<tag_sequence>>,
|
||||
mi::hashed_unique<mi::tag<tag_root>,
|
||||
mi::identity<nano::qualified_root>>>>
|
||||
confirmed_set;
|
||||
using prioritize_num_uncemented = boost::multi_index_container<nano::cementable_account,
|
||||
mi::indexed_by<
|
||||
mi::hashed_unique<mi::tag<tag_account>,
|
||||
mi::member<nano::cementable_account, nano::account, &nano::cementable_account::account>>,
|
||||
mi::ordered_non_unique<mi::tag<tag_uncemented>,
|
||||
mi::member<nano::cementable_account, uint64_t, &nano::cementable_account::blocks_uncemented>,
|
||||
std::greater<uint64_t>>>>;
|
||||
// clang-format on
|
||||
prioritize_num_uncemented priority_wallet_cementable_frontiers;
|
||||
prioritize_num_uncemented priority_cementable_frontiers;
|
||||
void prioritize_frontiers_for_confirmation (nano::transaction const &, std::chrono::milliseconds, std::chrono::milliseconds);
|
||||
std::unordered_set<nano::wallet_id> wallet_ids_already_iterated;
|
||||
std::unordered_map<nano::wallet_id, nano::account> next_wallet_id_accounts;
|
||||
bool skip_wallets{ false };
|
||||
void prioritize_account_for_confirmation (prioritize_num_uncemented &, size_t &, nano::account const &, nano::account_info const &, uint64_t);
|
||||
static size_t constexpr max_priority_cementable_frontiers{ 100000 };
|
||||
static size_t constexpr confirmed_frontiers_max_pending_cut_off{ 1000 };
|
||||
boost::multi_index_container<
|
||||
nano::gap_information,
|
||||
boost::multi_index::indexed_by<
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::member<nano::gap_information, std::chrono::steady_clock::time_point, &nano::gap_information::arrival>>,
|
||||
boost::multi_index::hashed_unique<boost::multi_index::member<nano::gap_information, nano::block_hash, &nano::gap_information::hash>>>>
|
||||
inactive_votes_cache;
|
||||
nano::gap_cache::ordered_gaps inactive_votes_cache;
|
||||
static size_t constexpr inactive_votes_cache_max{ 16 * 1024 };
|
||||
ordered_elections_timepoint dropped_elections_cache;
|
||||
// clang-format off
|
||||
boost::multi_index_container<nano::election_timepoint,
|
||||
mi::indexed_by<
|
||||
mi::sequenced<mi::tag<tag_sequence>>,
|
||||
mi::hashed_unique<mi::tag<tag_root>,
|
||||
mi::member<nano::election_timepoint, nano::qualified_root, &nano::election_timepoint::root>>>>
|
||||
dropped_elections_cache;
|
||||
// clang-format on
|
||||
static size_t constexpr dropped_elections_cache_max{ 32 * 1024 };
|
||||
boost::thread thread;
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ void nano::block_processor::add (nano::unchecked_info const & info_a)
|
|||
auto hash (info_a.block->hash ());
|
||||
auto filter_hash (filter_item (hash, info_a.block->block_signature ()));
|
||||
nano::lock_guard<std::mutex> lock (mutex);
|
||||
if (blocks_filter.find (filter_hash) == blocks_filter.end () && rolled_back.get<1> ().find (hash) == rolled_back.get<1> ().end ())
|
||||
if (blocks_filter.find (filter_hash) == blocks_filter.end () && rolled_back.get<tag_hash> ().find (hash) == rolled_back.get<tag_hash> ().end ())
|
||||
{
|
||||
if (info_a.verified == nano::signature_verification::unknown && (info_a.block->type () == nano::block_type::state || info_a.block->type () == nano::block_type::open || !info_a.account.is_zero ()))
|
||||
{
|
||||
|
@ -328,15 +328,15 @@ void nano::block_processor::process_batch (nano::unique_lock<std::mutex> & lock_
|
|||
}
|
||||
lock_a.lock ();
|
||||
// Prevent rolled back blocks second insertion
|
||||
auto inserted (rolled_back.insert (nano::rolled_hash{ std::chrono::steady_clock::now (), successor->hash () }));
|
||||
auto inserted (rolled_back.get<tag_sequence> ().push_back (successor->hash ()));
|
||||
if (inserted.second)
|
||||
{
|
||||
// Possible election winner change
|
||||
rolled_back.get<1> ().erase (hash);
|
||||
rolled_back.get<tag_hash> ().erase (hash);
|
||||
// Prevent overflow
|
||||
if (rolled_back.size () > rolled_back_max)
|
||||
{
|
||||
rolled_back.erase (rolled_back.begin ());
|
||||
rolled_back.get<tag_sequence> ().pop_front ();
|
||||
}
|
||||
}
|
||||
lock_a.unlock ();
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#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 <chrono>
|
||||
|
@ -20,12 +21,6 @@ class transaction;
|
|||
class write_transaction;
|
||||
class write_database_queue;
|
||||
|
||||
class rolled_hash
|
||||
{
|
||||
public:
|
||||
std::chrono::steady_clock::time_point time;
|
||||
nano::block_hash hash;
|
||||
};
|
||||
/**
|
||||
* Processing blocks is a potentially long IO operation.
|
||||
* This class isolates block insertion from other operations like servicing network operations
|
||||
|
@ -68,12 +63,16 @@ private:
|
|||
std::deque<std::shared_ptr<nano::block>> forced;
|
||||
nano::block_hash filter_item (nano::block_hash const &, nano::signature const &);
|
||||
std::unordered_set<nano::block_hash> blocks_filter;
|
||||
boost::multi_index_container<
|
||||
nano::rolled_hash,
|
||||
// clang-format off
|
||||
class tag_sequence {};
|
||||
class tag_hash {};
|
||||
boost::multi_index_container<nano::block_hash,
|
||||
boost::multi_index::indexed_by<
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::member<nano::rolled_hash, std::chrono::steady_clock::time_point, &nano::rolled_hash::time>>,
|
||||
boost::multi_index::hashed_unique<boost::multi_index::member<nano::rolled_hash, nano::block_hash, &nano::rolled_hash::hash>>>>
|
||||
boost::multi_index::sequenced<boost::multi_index::tag<tag_sequence>>,
|
||||
boost::multi_index::hashed_unique<boost::multi_index::tag<tag_hash>,
|
||||
boost::multi_index::identity<nano::block_hash>>>>
|
||||
rolled_back;
|
||||
// clang-format on
|
||||
static size_t const rolled_back_max = 1024;
|
||||
nano::condition_variable condition;
|
||||
nano::node & node;
|
||||
|
|
|
@ -1209,7 +1209,7 @@ void nano::bootstrap_attempt::lazy_destinations_increment (nano::account const &
|
|||
}
|
||||
else
|
||||
{
|
||||
lazy_destinations.insert (nano::lazy_destinations_item{ destination_a, 1 });
|
||||
lazy_destinations.emplace (nano::lazy_destinations_item{ destination_a, 1 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1547,7 +1547,7 @@ void nano::pulls_cache::add (nano::pull_info const & pull_a)
|
|||
if (existing == cache.get<account_head_tag> ().end ())
|
||||
{
|
||||
// Insert new pull
|
||||
auto inserted (cache.insert (nano::cached_pulls{ std::chrono::steady_clock::now (), head_512, pull_a.head }));
|
||||
auto inserted (cache.emplace (nano::cached_pulls{ std::chrono::steady_clock::now (), head_512, pull_a.head }));
|
||||
(void)inserted;
|
||||
assert (inserted.second);
|
||||
}
|
||||
|
@ -1594,7 +1594,7 @@ uint64_t nano::bootstrap_excluded_peers::add (nano::tcp_endpoint const & endpoin
|
|||
if (existing == peers.get<endpoint_tag> ().end ())
|
||||
{
|
||||
// Insert new endpoint
|
||||
auto inserted (peers.insert (nano::excluded_peers_item{ std::chrono::steady_clock::steady_clock::now () + exclude_time_hours, endpoint_a, 1 }));
|
||||
auto inserted (peers.emplace (nano::excluded_peers_item{ std::chrono::steady_clock::steady_clock::now () + exclude_time_hours, endpoint_a, 1 }));
|
||||
(void)inserted;
|
||||
assert (inserted.second);
|
||||
result = 1;
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include <boost/multi_index/hashed_index.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/multi_index/random_access_index.hpp>
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
|
@ -18,6 +17,8 @@
|
|||
#include <queue>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace mi = boost::multi_index;
|
||||
|
||||
namespace nano
|
||||
{
|
||||
class bootstrap_attempt;
|
||||
|
@ -146,12 +147,16 @@ public:
|
|||
class count_tag
|
||||
{
|
||||
};
|
||||
boost::multi_index_container<
|
||||
lazy_destinations_item,
|
||||
boost::multi_index::indexed_by<
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::tag<count_tag>, boost::multi_index::member<lazy_destinations_item, uint64_t, &lazy_destinations_item::count>, std::greater<uint64_t>>,
|
||||
boost::multi_index::hashed_unique<boost::multi_index::tag<account_tag>, boost::multi_index::member<lazy_destinations_item, nano::account, &lazy_destinations_item::account>>>>
|
||||
// clang-format off
|
||||
boost::multi_index_container<lazy_destinations_item,
|
||||
mi::indexed_by<
|
||||
mi::ordered_non_unique<mi::tag<count_tag>,
|
||||
mi::member<lazy_destinations_item, uint64_t, &lazy_destinations_item::count>,
|
||||
std::greater<uint64_t>>,
|
||||
mi::hashed_unique<mi::tag<account_tag>,
|
||||
mi::member<lazy_destinations_item, nano::account, &lazy_destinations_item::account>>>>
|
||||
lazy_destinations;
|
||||
// clang-format on
|
||||
std::atomic<size_t> lazy_blocks_count{ 0 };
|
||||
std::atomic<bool> lazy_destinations_flushed{ false };
|
||||
std::mutex lazy_mutex;
|
||||
|
@ -194,12 +199,15 @@ public:
|
|||
class account_head_tag
|
||||
{
|
||||
};
|
||||
boost::multi_index_container<
|
||||
nano::cached_pulls,
|
||||
boost::multi_index::indexed_by<
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::member<nano::cached_pulls, std::chrono::steady_clock::time_point, &nano::cached_pulls::time>>,
|
||||
boost::multi_index::hashed_unique<boost::multi_index::tag<account_head_tag>, boost::multi_index::member<nano::cached_pulls, nano::uint512_union, &nano::cached_pulls::account_head>>>>
|
||||
// clang-format off
|
||||
boost::multi_index_container<nano::cached_pulls,
|
||||
mi::indexed_by<
|
||||
mi::ordered_non_unique<
|
||||
mi::member<nano::cached_pulls, std::chrono::steady_clock::time_point, &nano::cached_pulls::time>>,
|
||||
mi::hashed_unique<mi::tag<account_head_tag>,
|
||||
mi::member<nano::cached_pulls, nano::uint512_union, &nano::cached_pulls::account_head>>>>
|
||||
cache;
|
||||
// clang-format on
|
||||
constexpr static size_t cache_size_max = 10000;
|
||||
};
|
||||
class excluded_peers_item final
|
||||
|
@ -219,12 +227,15 @@ public:
|
|||
class endpoint_tag
|
||||
{
|
||||
};
|
||||
boost::multi_index_container<
|
||||
nano::excluded_peers_item,
|
||||
boost::multi_index::indexed_by<
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::member<nano::excluded_peers_item, std::chrono::steady_clock::time_point, &nano::excluded_peers_item::exclude_until>>,
|
||||
boost::multi_index::hashed_unique<boost::multi_index::tag<endpoint_tag>, boost::multi_index::member<nano::excluded_peers_item, nano::tcp_endpoint, &nano::excluded_peers_item::endpoint>>>>
|
||||
// clang-format off
|
||||
boost::multi_index_container<nano::excluded_peers_item,
|
||||
mi::indexed_by<
|
||||
mi::ordered_non_unique<
|
||||
mi::member<nano::excluded_peers_item, std::chrono::steady_clock::time_point, &nano::excluded_peers_item::exclude_until>>,
|
||||
mi::hashed_unique<mi::tag<endpoint_tag>,
|
||||
mi::member<nano::excluded_peers_item, nano::tcp_endpoint, &nano::excluded_peers_item::endpoint>>>>
|
||||
peers;
|
||||
// clang-format on
|
||||
constexpr static size_t excluded_peers_size_max = 5000;
|
||||
constexpr static double excluded_peers_percentage_limit = 0.5;
|
||||
constexpr static uint64_t score_limit = 2;
|
||||
|
|
|
@ -12,19 +12,19 @@ node (node_a)
|
|||
void nano::gap_cache::add (nano::block_hash const & hash_a, std::chrono::steady_clock::time_point time_point_a)
|
||||
{
|
||||
nano::lock_guard<std::mutex> lock (mutex);
|
||||
auto existing (blocks.get<1> ().find (hash_a));
|
||||
if (existing != blocks.get<1> ().end ())
|
||||
auto existing (blocks.get<tag_hash> ().find (hash_a));
|
||||
if (existing != blocks.get<tag_hash> ().end ())
|
||||
{
|
||||
blocks.get<1> ().modify (existing, [time_point_a](nano::gap_information & info) {
|
||||
blocks.get<tag_hash> ().modify (existing, [time_point_a](nano::gap_information & info) {
|
||||
info.arrival = time_point_a;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
blocks.insert ({ time_point_a, hash_a, std::vector<nano::account> () });
|
||||
if (blocks.size () > max)
|
||||
blocks.get<tag_arrival> ().emplace (nano::gap_information{ time_point_a, hash_a, std::vector<nano::account> () });
|
||||
if (blocks.get<tag_arrival> ().size () > max)
|
||||
{
|
||||
blocks.get<0> ().erase (blocks.get<0> ().begin ());
|
||||
blocks.get<tag_arrival> ().erase (blocks.get<tag_arrival> ().begin ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ void nano::gap_cache::add (nano::block_hash const & hash_a, std::chrono::steady_
|
|||
void nano::gap_cache::erase (nano::block_hash const & hash_a)
|
||||
{
|
||||
nano::lock_guard<std::mutex> lock (mutex);
|
||||
blocks.get<1> ().erase (hash_a);
|
||||
blocks.get<tag_hash> ().erase (hash_a);
|
||||
}
|
||||
|
||||
void nano::gap_cache::vote (std::shared_ptr<nano::vote> vote_a)
|
||||
|
@ -40,11 +40,11 @@ void nano::gap_cache::vote (std::shared_ptr<nano::vote> vote_a)
|
|||
nano::lock_guard<std::mutex> lock (mutex);
|
||||
for (auto hash : *vote_a)
|
||||
{
|
||||
auto existing (blocks.get<1> ().find (hash));
|
||||
if (existing != blocks.get<1> ().end () && !existing->confirmed)
|
||||
auto existing (blocks.get<tag_hash> ().find (hash));
|
||||
if (existing != blocks.get<tag_hash> ().end () && !existing->confirmed)
|
||||
{
|
||||
auto is_new (false);
|
||||
blocks.get<1> ().modify (existing, [&is_new, &vote_a](nano::gap_information & info) {
|
||||
blocks.get<tag_hash> ().modify (existing, [&is_new, &vote_a](nano::gap_information & info) {
|
||||
auto it = std::find (info.voters.begin (), info.voters.end (), vote_a->account);
|
||||
is_new = (it == info.voters.end ());
|
||||
if (is_new)
|
||||
|
@ -57,7 +57,7 @@ void nano::gap_cache::vote (std::shared_ptr<nano::vote> vote_a)
|
|||
{
|
||||
if (bootstrap_check (existing->voters, hash))
|
||||
{
|
||||
blocks.get<1> ().modify (existing, [](nano::gap_information & info) {
|
||||
blocks.get<tag_hash> ().modify (existing, [](nano::gap_information & info) {
|
||||
info.confirmed = true;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#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 <chrono>
|
||||
|
@ -40,12 +41,17 @@ public:
|
|||
bool bootstrap_check (std::vector<nano::account> const &, nano::block_hash const &);
|
||||
nano::uint128_t bootstrap_threshold ();
|
||||
size_t size ();
|
||||
boost::multi_index_container<
|
||||
nano::gap_information,
|
||||
// clang-format off
|
||||
class tag_arrival {};
|
||||
class tag_hash {};
|
||||
using ordered_gaps = boost::multi_index_container<nano::gap_information,
|
||||
boost::multi_index::indexed_by<
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::member<gap_information, std::chrono::steady_clock::time_point, &gap_information::arrival>>,
|
||||
boost::multi_index::hashed_unique<boost::multi_index::member<gap_information, nano::block_hash, &gap_information::hash>>>>
|
||||
blocks;
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::tag<tag_arrival>,
|
||||
boost::multi_index::member<gap_information, std::chrono::steady_clock::time_point, &gap_information::arrival>>,
|
||||
boost::multi_index::hashed_unique<boost::multi_index::tag<tag_hash>,
|
||||
boost::multi_index::member<gap_information, nano::block_hash, &gap_information::hash>>>>;
|
||||
ordered_gaps blocks;
|
||||
// clang-format on
|
||||
size_t const max = 256;
|
||||
std::mutex mutex;
|
||||
nano::node & node;
|
||||
|
|
|
@ -2063,12 +2063,16 @@ void epoch_upgrader (std::shared_ptr<nano::node> node_a, nano::private_key const
|
|||
class modified_tag
|
||||
{
|
||||
};
|
||||
boost::multi_index_container<
|
||||
account_upgrade_item,
|
||||
// clang-format off
|
||||
boost::multi_index_container<account_upgrade_item,
|
||||
boost::multi_index::indexed_by<
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::tag<modified_tag>, boost::multi_index::member<account_upgrade_item, uint64_t, &account_upgrade_item::modified>, std::greater<uint64_t>>,
|
||||
boost::multi_index::hashed_unique<boost::multi_index::tag<account_tag>, boost::multi_index::member<account_upgrade_item, nano::account, &account_upgrade_item::account>>>>
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::tag<modified_tag>,
|
||||
boost::multi_index::member<account_upgrade_item, uint64_t, &account_upgrade_item::modified>,
|
||||
std::greater<uint64_t>>,
|
||||
boost::multi_index::hashed_unique<boost::multi_index::tag<account_tag>,
|
||||
boost::multi_index::member<account_upgrade_item, nano::account, &account_upgrade_item::account>>>>
|
||||
accounts_list;
|
||||
// clang-format on
|
||||
|
||||
bool finished_upgrade (false);
|
||||
|
||||
|
@ -2088,7 +2092,7 @@ void epoch_upgrader (std::shared_ptr<nano::node> node_a, nano::private_key const
|
|||
if (info.epoch () < epoch_a)
|
||||
{
|
||||
release_assert (nano::epochs::is_sequential (info.epoch (), epoch_a));
|
||||
accounts_list.insert (account_upgrade_item{ account, info.modified });
|
||||
accounts_list.emplace (account_upgrade_item{ account, info.modified });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1241,7 +1241,7 @@ bool nano::block_arrival::add (nano::block_hash const & hash_a)
|
|||
{
|
||||
nano::lock_guard<std::mutex> lock (mutex);
|
||||
auto now (std::chrono::steady_clock::now ());
|
||||
auto inserted (arrival.insert (nano::block_arrival_info{ now, hash_a }));
|
||||
auto inserted (arrival.get<tag_sequence> ().emplace_back (nano::block_arrival_info{ now, hash_a }));
|
||||
auto result (!inserted.second);
|
||||
return result;
|
||||
}
|
||||
|
@ -1250,11 +1250,11 @@ bool nano::block_arrival::recent (nano::block_hash const & hash_a)
|
|||
{
|
||||
nano::lock_guard<std::mutex> lock (mutex);
|
||||
auto now (std::chrono::steady_clock::now ());
|
||||
while (arrival.size () > arrival_size_min && arrival.begin ()->arrival + arrival_time_min < now)
|
||||
while (arrival.size () > arrival_size_min && arrival.get<tag_sequence> ().front ().arrival + arrival_time_min < now)
|
||||
{
|
||||
arrival.erase (arrival.begin ());
|
||||
arrival.get<tag_sequence> ().pop_front ();
|
||||
}
|
||||
return arrival.get<1> ().find (hash_a) != arrival.get<1> ().end ();
|
||||
return arrival.get<tag_hash> ().find (hash_a) != arrival.get<tag_hash> ().end ();
|
||||
}
|
||||
|
||||
namespace nano
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#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 <boost/thread/latch.hpp>
|
||||
|
||||
|
@ -61,12 +62,16 @@ public:
|
|||
// Return `true' to indicated an error if the block has already been inserted
|
||||
bool add (nano::block_hash const &);
|
||||
bool recent (nano::block_hash const &);
|
||||
boost::multi_index_container<
|
||||
nano::block_arrival_info,
|
||||
boost::multi_index::indexed_by<
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::member<nano::block_arrival_info, std::chrono::steady_clock::time_point, &nano::block_arrival_info::arrival>>,
|
||||
boost::multi_index::hashed_unique<boost::multi_index::member<nano::block_arrival_info, nano::block_hash, &nano::block_arrival_info::hash>>>>
|
||||
// clang-format off
|
||||
class tag_sequence {};
|
||||
class tag_hash {};
|
||||
boost::multi_index_container<nano::block_arrival_info,
|
||||
boost::multi_index::indexed_by<
|
||||
boost::multi_index::sequenced<boost::multi_index::tag<tag_sequence>>,
|
||||
boost::multi_index::hashed_unique<boost::multi_index::tag<tag_hash>,
|
||||
boost::multi_index::member<nano::block_arrival_info, nano::block_hash, &nano::block_arrival_info::hash>>>>
|
||||
arrival;
|
||||
// clang-format on
|
||||
std::mutex mutex;
|
||||
static size_t constexpr arrival_size_min = 8 * 1024;
|
||||
static std::chrono::seconds constexpr arrival_time_min = std::chrono::seconds (300);
|
||||
|
|
|
@ -141,7 +141,7 @@ bool nano::rep_crawler::response (std::shared_ptr<nano::transport::channel> chan
|
|||
}
|
||||
else
|
||||
{
|
||||
probable_reps.insert (nano::representative (rep_account_a, weight_a, channel_a));
|
||||
probable_reps.emplace (nano::representative (rep_account_a, weight_a, channel_a));
|
||||
updated_or_inserted = true;
|
||||
}
|
||||
return updated_or_inserted;
|
||||
|
|
|
@ -9,9 +9,10 @@
|
|||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/multi_index/random_access_index.hpp>
|
||||
#include <boost/multi_index_container.hpp>
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
namespace mi = boost::multi_index;
|
||||
|
||||
namespace nano
|
||||
{
|
||||
class bootstrap_server;
|
||||
|
@ -165,22 +166,29 @@ namespace transport
|
|||
std::chrono::steady_clock::time_point last_attempt;
|
||||
};
|
||||
mutable std::mutex mutex;
|
||||
boost::multi_index_container<
|
||||
channel_tcp_wrapper,
|
||||
boost::multi_index::indexed_by<
|
||||
boost::multi_index::random_access<boost::multi_index::tag<random_access_tag>>,
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::tag<last_bootstrap_attempt_tag>, boost::multi_index::const_mem_fun<channel_tcp_wrapper, std::chrono::steady_clock::time_point, &channel_tcp_wrapper::last_bootstrap_attempt>>,
|
||||
boost::multi_index::hashed_unique<boost::multi_index::tag<endpoint_tag>, boost::multi_index::const_mem_fun<channel_tcp_wrapper, nano::tcp_endpoint, &channel_tcp_wrapper::endpoint>>,
|
||||
boost::multi_index::hashed_non_unique<boost::multi_index::tag<node_id_tag>, boost::multi_index::const_mem_fun<channel_tcp_wrapper, nano::account, &channel_tcp_wrapper::node_id>>,
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::tag<last_packet_sent_tag>, boost::multi_index::const_mem_fun<channel_tcp_wrapper, std::chrono::steady_clock::time_point, &channel_tcp_wrapper::last_packet_sent>>,
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::tag<ip_address_tag>, boost::multi_index::const_mem_fun<channel_tcp_wrapper, boost::asio::ip::address, &channel_tcp_wrapper::ip_address>>>>
|
||||
// clang-format off
|
||||
boost::multi_index_container<channel_tcp_wrapper,
|
||||
mi::indexed_by<
|
||||
mi::random_access<mi::tag<random_access_tag>>,
|
||||
mi::ordered_non_unique<mi::tag<last_bootstrap_attempt_tag>,
|
||||
mi::const_mem_fun<channel_tcp_wrapper, std::chrono::steady_clock::time_point, &channel_tcp_wrapper::last_bootstrap_attempt>>,
|
||||
mi::hashed_unique<mi::tag<endpoint_tag>,
|
||||
mi::const_mem_fun<channel_tcp_wrapper, nano::tcp_endpoint, &channel_tcp_wrapper::endpoint>>,
|
||||
mi::hashed_non_unique<mi::tag<node_id_tag>,
|
||||
mi::const_mem_fun<channel_tcp_wrapper, nano::account, &channel_tcp_wrapper::node_id>>,
|
||||
mi::ordered_non_unique<mi::tag<last_packet_sent_tag>,
|
||||
mi::const_mem_fun<channel_tcp_wrapper, std::chrono::steady_clock::time_point, &channel_tcp_wrapper::last_packet_sent>>,
|
||||
mi::hashed_non_unique<mi::tag<ip_address_tag>,
|
||||
mi::const_mem_fun<channel_tcp_wrapper, boost::asio::ip::address, &channel_tcp_wrapper::ip_address>>>>
|
||||
channels;
|
||||
boost::multi_index_container<
|
||||
tcp_endpoint_attempt,
|
||||
boost::multi_index::indexed_by<
|
||||
boost::multi_index::hashed_unique<boost::multi_index::member<tcp_endpoint_attempt, nano::tcp_endpoint, &tcp_endpoint_attempt::endpoint>>,
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::member<tcp_endpoint_attempt, std::chrono::steady_clock::time_point, &tcp_endpoint_attempt::last_attempt>>>>
|
||||
boost::multi_index_container<tcp_endpoint_attempt,
|
||||
mi::indexed_by<
|
||||
mi::hashed_unique<
|
||||
mi::member<tcp_endpoint_attempt, nano::tcp_endpoint, &tcp_endpoint_attempt::endpoint>>,
|
||||
mi::ordered_non_unique<
|
||||
mi::member<tcp_endpoint_attempt, std::chrono::steady_clock::time_point, &tcp_endpoint_attempt::last_attempt>>>>
|
||||
attempts;
|
||||
// clang-format on
|
||||
// This owns the sockets until the node_id_handshake has been completed. Needed to prevent self referencing callbacks, they are periodically removed if any are dangling.
|
||||
std::vector<std::shared_ptr<nano::socket>> node_id_handshake_sockets;
|
||||
std::atomic<bool> stopped{ false };
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include <mutex>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace mi = boost::multi_index;
|
||||
|
||||
namespace nano
|
||||
{
|
||||
class message_buffer;
|
||||
|
@ -144,22 +146,31 @@ namespace transport
|
|||
std::chrono::steady_clock::time_point last_attempt;
|
||||
};
|
||||
mutable std::mutex mutex;
|
||||
// clang-format off
|
||||
boost::multi_index_container<
|
||||
channel_udp_wrapper,
|
||||
boost::multi_index::indexed_by<
|
||||
boost::multi_index::random_access<boost::multi_index::tag<random_access_tag>>,
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::tag<last_bootstrap_attempt_tag>, boost::multi_index::const_mem_fun<channel_udp_wrapper, std::chrono::steady_clock::time_point, &channel_udp_wrapper::last_bootstrap_attempt>>,
|
||||
boost::multi_index::hashed_unique<boost::multi_index::tag<endpoint_tag>, boost::multi_index::const_mem_fun<channel_udp_wrapper, nano::endpoint, &channel_udp_wrapper::endpoint>>,
|
||||
boost::multi_index::hashed_non_unique<boost::multi_index::tag<node_id_tag>, boost::multi_index::const_mem_fun<channel_udp_wrapper, nano::account, &channel_udp_wrapper::node_id>>,
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::tag<last_packet_received_tag>, boost::multi_index::const_mem_fun<channel_udp_wrapper, std::chrono::steady_clock::time_point, &channel_udp_wrapper::last_packet_received>>,
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::tag<ip_address_tag>, boost::multi_index::const_mem_fun<channel_udp_wrapper, boost::asio::ip::address, &channel_udp_wrapper::ip_address>>>>
|
||||
mi::indexed_by<
|
||||
mi::random_access<mi::tag<random_access_tag>>,
|
||||
mi::ordered_non_unique<mi::tag<last_bootstrap_attempt_tag>,
|
||||
mi::const_mem_fun<channel_udp_wrapper, std::chrono::steady_clock::time_point, &channel_udp_wrapper::last_bootstrap_attempt>>,
|
||||
mi::hashed_unique<mi::tag<endpoint_tag>,
|
||||
mi::const_mem_fun<channel_udp_wrapper, nano::endpoint, &channel_udp_wrapper::endpoint>>,
|
||||
mi::hashed_non_unique<mi::tag<node_id_tag>,
|
||||
mi::const_mem_fun<channel_udp_wrapper, nano::account, &channel_udp_wrapper::node_id>>,
|
||||
mi::ordered_non_unique<mi::tag<last_packet_received_tag>,
|
||||
mi::const_mem_fun<channel_udp_wrapper, std::chrono::steady_clock::time_point, &channel_udp_wrapper::last_packet_received>>,
|
||||
mi::hashed_non_unique<mi::tag<ip_address_tag>,
|
||||
mi::const_mem_fun<channel_udp_wrapper, boost::asio::ip::address, &channel_udp_wrapper::ip_address>>>>
|
||||
channels;
|
||||
boost::multi_index_container<
|
||||
endpoint_attempt,
|
||||
boost::multi_index::indexed_by<
|
||||
boost::multi_index::hashed_unique<boost::multi_index::member<endpoint_attempt, nano::endpoint, &endpoint_attempt::endpoint>>,
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::member<endpoint_attempt, std::chrono::steady_clock::time_point, &endpoint_attempt::last_attempt>>>>
|
||||
mi::indexed_by<
|
||||
mi::hashed_unique<
|
||||
mi::member<endpoint_attempt, nano::endpoint, &endpoint_attempt::endpoint>>,
|
||||
mi::ordered_non_unique<
|
||||
mi::member<endpoint_attempt, std::chrono::steady_clock::time_point, &endpoint_attempt::last_attempt>>>>
|
||||
attempts;
|
||||
// clang-format on
|
||||
boost::asio::strand<boost::asio::io_context::executor_type> strand;
|
||||
boost::asio::ip::udp::socket socket;
|
||||
nano::endpoint local_endpoint;
|
||||
|
|
|
@ -106,23 +106,23 @@ void nano::votes_cache::add (std::shared_ptr<nano::vote> const & vote_a)
|
|||
for (auto & block : vote_a->blocks)
|
||||
{
|
||||
auto hash (boost::get<nano::block_hash> (block));
|
||||
auto existing (cache.get<1> ().find (hash));
|
||||
if (existing == cache.get<1> ().end ())
|
||||
auto existing (cache.get<tag_hash> ().find (hash));
|
||||
if (existing == cache.get<tag_hash> ().end ())
|
||||
{
|
||||
// Clean old votes
|
||||
if (cache.size () >= network_params.voting.max_cache)
|
||||
{
|
||||
cache.erase (cache.begin ());
|
||||
cache.get<tag_sequence> ().pop_front ();
|
||||
}
|
||||
// Insert new votes (new hash)
|
||||
auto inserted (cache.insert (nano::cached_votes{ std::chrono::steady_clock::now (), hash, std::vector<std::shared_ptr<nano::vote>> (1, vote_a) }));
|
||||
auto inserted (cache.get<tag_sequence> ().emplace_back (nano::cached_votes{ hash, std::vector<std::shared_ptr<nano::vote>> (1, vote_a) }));
|
||||
(void)inserted;
|
||||
assert (inserted.second);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Insert new votes (old hash)
|
||||
cache.get<1> ().modify (existing, [vote_a](nano::cached_votes & cache_a) {
|
||||
cache.get<tag_hash> ().modify (existing, [vote_a](nano::cached_votes & cache_a) {
|
||||
// Replace old vote for same representative & hash
|
||||
bool replaced (false);
|
||||
for (auto i (cache_a.votes.begin ()), n (cache_a.votes.end ()); i != n && !replaced; ++i)
|
||||
|
@ -147,8 +147,8 @@ std::vector<std::shared_ptr<nano::vote>> nano::votes_cache::find (nano::block_ha
|
|||
{
|
||||
std::vector<std::shared_ptr<nano::vote>> result;
|
||||
nano::lock_guard<std::mutex> lock (cache_mutex);
|
||||
auto existing (cache.get<1> ().find (hash_a));
|
||||
if (existing != cache.get<1> ().end ())
|
||||
auto existing (cache.get<tag_hash> ().find (hash_a));
|
||||
if (existing != cache.get<tag_hash> ().end ())
|
||||
{
|
||||
result = existing->votes;
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ std::vector<std::shared_ptr<nano::vote>> nano::votes_cache::find (nano::block_ha
|
|||
void nano::votes_cache::remove (nano::block_hash const & hash_a)
|
||||
{
|
||||
nano::lock_guard<std::mutex> lock (cache_mutex);
|
||||
cache.get<1> ().erase (hash_a);
|
||||
cache.get<tag_hash> ().erase (hash_a);
|
||||
}
|
||||
|
||||
namespace nano
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#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>
|
||||
|
@ -55,7 +56,6 @@ std::unique_ptr<seq_con_info_component> collect_seq_con_info (vote_generator & v
|
|||
class cached_votes final
|
||||
{
|
||||
public:
|
||||
std::chrono::steady_clock::time_point time;
|
||||
nano::block_hash hash;
|
||||
std::vector<std::shared_ptr<nano::vote>> votes;
|
||||
};
|
||||
|
@ -68,12 +68,16 @@ public:
|
|||
|
||||
private:
|
||||
std::mutex cache_mutex;
|
||||
boost::multi_index_container<
|
||||
nano::cached_votes,
|
||||
// clang-format off
|
||||
class tag_sequence {};
|
||||
class tag_hash {};
|
||||
boost::multi_index_container<nano::cached_votes,
|
||||
boost::multi_index::indexed_by<
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::member<nano::cached_votes, std::chrono::steady_clock::time_point, &nano::cached_votes::time>>,
|
||||
boost::multi_index::hashed_unique<boost::multi_index::member<nano::cached_votes, nano::block_hash, &nano::cached_votes::hash>>>>
|
||||
boost::multi_index::sequenced<boost::multi_index::tag<tag_sequence>>,
|
||||
boost::multi_index::hashed_unique<boost::multi_index::tag<tag_hash>,
|
||||
boost::multi_index::member<nano::cached_votes, nano::block_hash, &nano::cached_votes::hash>>>>
|
||||
cache;
|
||||
// clang-format on
|
||||
nano::network_params network_params;
|
||||
friend std::unique_ptr<seq_con_info_component> collect_seq_con_info (votes_cache & votes_cache, const std::string & name);
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue