Replace election::insert_inactive_votes_cache
by election::vote
(#3874)
This commit is contained in:
parent
23bc00db85
commit
5c0106823f
7 changed files with 52 additions and 44 deletions
|
@ -337,10 +337,10 @@ TEST (active_transactions, inactive_votes_cache_existing_vote)
|
|||
nano::unique_lock<nano::mutex> active_lock (node.active.mutex);
|
||||
node.active.add_inactive_votes_cache (active_lock, send->hash (), key.pub, 0);
|
||||
active_lock.unlock ();
|
||||
auto cache (node.active.find_inactive_votes_cache (send->hash ()));
|
||||
const auto cache (node.active.find_inactive_votes_cache (send->hash ()));
|
||||
active_lock.lock ();
|
||||
ASSERT_EQ (1, cache.voters.size ());
|
||||
election->insert_inactive_votes_cache (cache);
|
||||
cache.fill (election);
|
||||
// Check that election data is not changed
|
||||
ASSERT_EQ (2, election->votes ().size ());
|
||||
auto last_vote2 (election->votes ()[key.pub]);
|
||||
|
|
|
@ -391,7 +391,7 @@ nano::election_insertion_result nano::active_transactions::insert_impl (nano::un
|
|||
}
|
||||
auto const cache = find_inactive_votes_cache_impl (hash);
|
||||
lock_a.unlock ();
|
||||
result.election->insert_inactive_votes_cache (cache);
|
||||
cache.fill (result.election);
|
||||
node.observers.active_started.notify (hash);
|
||||
node.stats.inc (nano::stat::type::election, nano::stat::detail::election_start);
|
||||
vacancy_update ();
|
||||
|
@ -624,7 +624,7 @@ bool nano::active_transactions::publish (std::shared_ptr<nano::block> const & bl
|
|||
blocks.emplace (block_a->hash (), election);
|
||||
auto const cache = find_inactive_votes_cache_impl (block_a->hash ());
|
||||
lock.unlock ();
|
||||
election->insert_inactive_votes_cache (cache);
|
||||
cache.fill (election);
|
||||
node.stats.inc (nano::stat::type::election, nano::stat::detail::election_block_conflict);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -197,6 +197,7 @@ private:
|
|||
nano::inactive_cache_status inactive_votes_bootstrap_check (nano::unique_lock<nano::mutex> &, nano::account const &, nano::block_hash const &, nano::inactive_cache_status const &);
|
||||
nano::inactive_cache_status inactive_votes_bootstrap_check_impl (nano::unique_lock<nano::mutex> &, nano::uint128_t const &, std::size_t, nano::block_hash const &, nano::inactive_cache_status const &);
|
||||
nano::inactive_cache_information find_inactive_votes_cache_impl (nano::block_hash const &);
|
||||
|
||||
boost::thread thread;
|
||||
|
||||
friend class election;
|
||||
|
|
|
@ -364,15 +364,13 @@ std::shared_ptr<nano::block> nano::election::find (nano::block_hash const & hash
|
|||
return result;
|
||||
}
|
||||
|
||||
nano::election_vote_result nano::election::vote (nano::account const & rep, uint64_t timestamp_a, nano::block_hash const & block_hash_a)
|
||||
nano::election_vote_result nano::election::vote (nano::account const & rep, uint64_t timestamp_a, nano::block_hash const & block_hash_a, vote_source vote_source_a)
|
||||
{
|
||||
auto replay = false;
|
||||
auto weight = node.ledger.weight (rep);
|
||||
auto should_process = false;
|
||||
if (node.network_params.network.is_dev_network () || weight > node.minimum_principal_weight ())
|
||||
{
|
||||
const auto cooldown = cooldown_time (weight);
|
||||
|
||||
nano::unique_lock<nano::mutex> lock (mutex);
|
||||
|
||||
auto last_vote_it (last_votes.find (rep));
|
||||
|
@ -386,7 +384,15 @@ nano::election_vote_result nano::election::vote (nano::account const & rep, uint
|
|||
if (last_vote_l.timestamp < timestamp_a || (last_vote_l.timestamp == timestamp_a && last_vote_l.hash < block_hash_a))
|
||||
{
|
||||
auto max_vote = timestamp_a == std::numeric_limits<uint64_t>::max () && last_vote_l.timestamp < timestamp_a;
|
||||
auto past_cooldown = last_vote_l.time <= std::chrono::steady_clock::now () - std::chrono::seconds (cooldown);
|
||||
|
||||
bool past_cooldown = true;
|
||||
// Only cooldown live votes
|
||||
if (vote_source_a == vote_source::live)
|
||||
{
|
||||
const auto cooldown = cooldown_time (weight);
|
||||
past_cooldown = last_vote_l.time <= std::chrono::steady_clock::now () - cooldown;
|
||||
}
|
||||
|
||||
should_process = max_vote || past_cooldown;
|
||||
}
|
||||
else
|
||||
|
@ -396,9 +402,14 @@ nano::election_vote_result nano::election::vote (nano::account const & rep, uint
|
|||
}
|
||||
if (should_process)
|
||||
{
|
||||
node.stats.inc (nano::stat::type::election, nano::stat::detail::vote_new);
|
||||
last_votes[rep] = { std::chrono::steady_clock::now (), timestamp_a, block_hash_a };
|
||||
live_vote_action (rep);
|
||||
if (vote_source_a == vote_source::live)
|
||||
{
|
||||
live_vote_action (rep);
|
||||
}
|
||||
|
||||
node.stats.inc (nano::stat::type::election, vote_source_a == vote_source::live ? nano::stat::detail::vote_new : nano::stat::detail::vote_cached);
|
||||
|
||||
if (!confirmed ())
|
||||
{
|
||||
confirm_if_quorum (lock);
|
||||
|
@ -450,37 +461,6 @@ bool nano::election::publish (std::shared_ptr<nano::block> const & block_a)
|
|||
return result;
|
||||
}
|
||||
|
||||
std::size_t nano::election::insert_inactive_votes_cache (nano::inactive_cache_information const & cache_a)
|
||||
{
|
||||
nano::unique_lock<nano::mutex> lock (mutex);
|
||||
for (auto const & [rep, timestamp] : cache_a.voters)
|
||||
{
|
||||
auto inserted (last_votes.emplace (rep, nano::vote_info{ std::chrono::steady_clock::time_point::min (), timestamp, cache_a.hash }));
|
||||
if (inserted.second)
|
||||
{
|
||||
node.stats.inc (nano::stat::type::election, nano::stat::detail::vote_cached);
|
||||
}
|
||||
}
|
||||
if (!confirmed ())
|
||||
{
|
||||
if (!cache_a.voters.empty ())
|
||||
{
|
||||
auto delay (std::chrono::duration_cast<std::chrono::seconds> (std::chrono::steady_clock::now () - cache_a.arrival));
|
||||
if (delay > late_blocks_delay)
|
||||
{
|
||||
node.stats.inc (nano::stat::type::election, nano::stat::detail::late_block);
|
||||
node.stats.add (nano::stat::type::election, nano::stat::detail::late_block_seconds, nano::stat::dir::in, delay.count (), true);
|
||||
}
|
||||
}
|
||||
if (last_votes.size () > 1) // null account
|
||||
{
|
||||
// Even if no votes were in cache, they could be in the election
|
||||
confirm_if_quorum (lock);
|
||||
}
|
||||
}
|
||||
return cache_a.voters.size ();
|
||||
}
|
||||
|
||||
nano::election_extended_status nano::election::current_status () const
|
||||
{
|
||||
nano::lock_guard<nano::mutex> guard (mutex);
|
||||
|
|
|
@ -53,6 +53,14 @@ struct election_extended_status final
|
|||
};
|
||||
class election final : public std::enable_shared_from_this<nano::election>
|
||||
{
|
||||
public:
|
||||
enum class vote_source
|
||||
{
|
||||
live,
|
||||
cache,
|
||||
};
|
||||
|
||||
private:
|
||||
// Minimum time between broadcasts of the current winner of an election, as a backup to requesting confirmations
|
||||
std::chrono::milliseconds base_latency () const;
|
||||
std::function<void (std::shared_ptr<nano::block> const &)> confirmation_action;
|
||||
|
@ -108,9 +116,8 @@ public: // Interface
|
|||
* Process vote. Internally uses cooldown to throttle non-final votes
|
||||
* If the election reaches consensus, it will be confirmed
|
||||
*/
|
||||
nano::election_vote_result vote (nano::account const & representative, uint64_t timestamp, nano::block_hash const & block_hash);
|
||||
nano::election_vote_result vote (nano::account const & representative, uint64_t timestamp, nano::block_hash const & block_hash, vote_source = vote_source::live);
|
||||
bool publish (std::shared_ptr<nano::block> const & block_a);
|
||||
std::size_t insert_inactive_votes_cache (nano::inactive_cache_information const &);
|
||||
// Confirm this block if quorum is met
|
||||
void confirm_if_quorum (nano::unique_lock<nano::mutex> &);
|
||||
|
||||
|
@ -150,7 +157,6 @@ private:
|
|||
nano::node & node;
|
||||
mutable nano::mutex mutex;
|
||||
|
||||
static std::chrono::seconds constexpr late_blocks_delay{ 5 };
|
||||
static std::size_t constexpr max_blocks{ 10 };
|
||||
|
||||
friend class active_transactions;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include <nano/node/election.hpp>
|
||||
#include <nano/node/inactive_cache_information.hpp>
|
||||
|
||||
using namespace std::chrono;
|
||||
|
@ -15,3 +16,17 @@ std::string nano::inactive_cache_information::to_string () const
|
|||
}
|
||||
return ss.str ();
|
||||
}
|
||||
|
||||
std::size_t nano::inactive_cache_information::fill (std::shared_ptr<nano::election> election) const
|
||||
{
|
||||
std::size_t inserted = 0;
|
||||
for (auto const & [rep, timestamp] : voters)
|
||||
{
|
||||
auto [is_replay, processed] = election->vote (rep, timestamp, hash, nano::election::vote_source::cache);
|
||||
if (processed)
|
||||
{
|
||||
inserted++;
|
||||
}
|
||||
}
|
||||
return inserted;
|
||||
}
|
|
@ -31,6 +31,12 @@ public:
|
|||
}
|
||||
|
||||
std::string to_string () const;
|
||||
|
||||
/**
|
||||
* Inserts votes stored in this entry into an election
|
||||
* @return number of votes inserted
|
||||
*/
|
||||
std::size_t fill (std::shared_ptr<nano::election> election) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue