Skip to content

Commit

Permalink
Replace election::insert_inactive_votes_cache by election::vote (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
pwojcikdev authored Aug 2, 2022
1 parent 23bc00d commit 5c01068
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 44 deletions.
4 changes: 2 additions & 2 deletions nano/core_test/active_transactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand Down
4 changes: 2 additions & 2 deletions nano/node/active_transactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 ();
Expand Down Expand Up @@ -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);
}
}
Expand Down
1 change: 1 addition & 0 deletions nano/node/active_transactions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ class active_transactions final
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;
Expand Down
54 changes: 17 additions & 37 deletions nano/node/election.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
12 changes: 9 additions & 3 deletions nano/node/election.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -108,9 +116,8 @@ class election final : public std::enable_shared_from_this<nano::election>
* 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> &);

Expand Down Expand Up @@ -150,7 +157,6 @@ class election final : public std::enable_shared_from_this<nano::election>
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;
Expand Down
15 changes: 15 additions & 0 deletions nano/node/inactive_cache_information.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <nano/node/election.hpp>
#include <nano/node/inactive_cache_information.hpp>

using namespace std::chrono;
Expand All @@ -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;
}
6 changes: 6 additions & 0 deletions nano/node/inactive_cache_information.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ class inactive_cache_information final
}

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;
};

}

0 comments on commit 5c01068

Please sign in to comment.