dncurrency/nano/node/online_reps.cpp
Thiago Silva 7a052d440d
Disambiguity of all the implemented locks (#4045)
* Apply uniform initialization to the mutexes (vote_processor.cpp)

* Apply uniform initialization to the mutexes (blockprocessor.cpp)

* Apply uniform initialization to the mutexes (voting.cpp)

* Apply uniform initialization to the mutexes (active_transaction.cpp)

* Apply uniform initialization to the mutexes (network.cpp)

* Apply uniform initialization to the mutexes (election.cpp)

* Apply uniform initialization to the mutexes (tcp.cpp)

* Apply uniform initialization to the mutexes (udp.cpp)

* Apply uniform initialization to the mutexes (bootstrap_legacy.cpp)

* Apply uniform initialization to the mutexes (bootstrap.cpp)

* Apply uniform initialization to the mutexes (boostrap_lazy.cpp)

* Apply uniform initialization to the mutexes (bootstrap_connections.cpp)

* Apply uniform initialization to the mutexes (online_reps.cpp)

* Apply uniform initialization to the mutexes (ipc)

* Apply uniform initialization to the mutexes (repcrawler.cpp)

* Apply uniform initialization to the mutexes (node.cpp)

* Apply uniform initialization to the mutexes (request_aggregator.cpp)

* Apply uniform initialization to the mutexes (gap_cache.cpp)

* Apply uniform initialization to the mutexes (ledger.cpp)

* Apply uniform initialization to the mutexes (node.cpp)

* Apply uniform initialization to the mutexes (locks.cpp)

* Apply uniform initialization to the mutexes (utility.cpp)

* Apply uniform initialization to the mutexes (blocks.cpp)

* Apply uniform initialization to the mutexes (observer_set.hpp)

* Apply uniform initialization to the mutexes (stats.cpp)

* Apply uniform initialization to the mutexes (work.cpp)

* Apply uniform initialization to the mutexes (entry.cpp)

* Apply uniform initialization to the mutexes (block_arrival.cpp)

* Apply uniform initialization to the mutexes (bootstrap_attempt.cpp)

* Apply uniform initialization to the mutexes (cli.cpp)

* Apply uniform initialization to the mutexes (distributed_work.cpp)

* Apply uniform initialization to the mutexes (gap_cache.cpp)

* Apply uniform initialization to the mutexes (openclwork.cpp)

* Apply uniform initialization to the mutexes (node.cpp)

* Apply uniform initialization to the mutexes (tcp_server.cpp)

* Apply uniform initialization to the mutexes (wallet.cpp)

* Apply uniform initialization to the mutexes (rpc_request_processor.cpp)

* Apply uniform initialization to the mutexes (common.cpp)

* Apply uniform initialization to the mutexes (network_filter.cpp)

* Apply uniform initialization to the mutexes (testutil.hpp)
2023-01-13 15:02:34 -03:00

131 lines
4.1 KiB
C++

#include <nano/node/nodeconfig.hpp>
#include <nano/node/online_reps.hpp>
#include <nano/secure/ledger.hpp>
#include <nano/secure/store.hpp>
nano::online_reps::online_reps (nano::ledger & ledger_a, nano::node_config const & config_a) :
ledger{ ledger_a },
config{ config_a }
{
if (!ledger.store.init_error ())
{
auto transaction (ledger.store.tx_begin_read ());
trended_m = calculate_trend (transaction);
}
}
void nano::online_reps::observe (nano::account const & rep_a)
{
if (ledger.weight (rep_a) > 0)
{
nano::lock_guard<nano::mutex> lock{ mutex };
auto now = std::chrono::steady_clock::now ();
auto new_insert = reps.get<tag_account> ().erase (rep_a) == 0;
reps.insert ({ now, rep_a });
auto cutoff = reps.get<tag_time> ().lower_bound (now - std::chrono::seconds (config.network_params.node.weight_period));
auto trimmed = reps.get<tag_time> ().begin () != cutoff;
reps.get<tag_time> ().erase (reps.get<tag_time> ().begin (), cutoff);
if (new_insert || trimmed)
{
online_m = calculate_online ();
}
}
}
void nano::online_reps::sample ()
{
nano::unique_lock<nano::mutex> lock{ mutex };
nano::uint128_t online_l = online_m;
lock.unlock ();
nano::uint128_t trend_l;
{
auto transaction (ledger.store.tx_begin_write ({ tables::online_weight }));
// Discard oldest entries
while (ledger.store.online_weight.count (transaction) >= config.network_params.node.max_weight_samples)
{
auto oldest (ledger.store.online_weight.begin (transaction));
debug_assert (oldest != ledger.store.online_weight.end ());
ledger.store.online_weight.del (transaction, oldest->first);
}
ledger.store.online_weight.put (transaction, std::chrono::system_clock::now ().time_since_epoch ().count (), online_l);
trend_l = calculate_trend (transaction);
}
lock.lock ();
trended_m = trend_l;
}
nano::uint128_t nano::online_reps::calculate_online () const
{
nano::uint128_t current;
for (auto & i : reps)
{
current += ledger.weight (i.account);
}
return current;
}
nano::uint128_t nano::online_reps::calculate_trend (nano::transaction & transaction_a) const
{
std::vector<nano::uint128_t> items;
items.reserve (config.network_params.node.max_weight_samples + 1);
items.push_back (config.online_weight_minimum.number ());
for (auto i (ledger.store.online_weight.begin (transaction_a)), n (ledger.store.online_weight.end ()); i != n; ++i)
{
items.push_back (i->second.number ());
}
nano::uint128_t result;
// Pick median value for our target vote weight
auto median_idx = items.size () / 2;
nth_element (items.begin (), items.begin () + median_idx, items.end ());
result = items[median_idx];
return result;
}
nano::uint128_t nano::online_reps::trended () const
{
nano::lock_guard<nano::mutex> lock{ mutex };
return trended_m;
}
nano::uint128_t nano::online_reps::online () const
{
nano::lock_guard<nano::mutex> lock{ mutex };
return online_m;
}
nano::uint128_t nano::online_reps::delta () const
{
nano::lock_guard<nano::mutex> lock{ mutex };
// Using a larger container to ensure maximum precision
auto weight = static_cast<nano::uint256_t> (std::max ({ online_m, trended_m, config.online_weight_minimum.number () }));
return ((weight * online_weight_quorum) / 100).convert_to<nano::uint128_t> ();
}
std::vector<nano::account> nano::online_reps::list ()
{
std::vector<nano::account> result;
nano::lock_guard<nano::mutex> lock{ mutex };
std::for_each (reps.begin (), reps.end (), [&result] (rep_info const & info_a) { result.push_back (info_a.account); });
return result;
}
void nano::online_reps::clear ()
{
nano::lock_guard<nano::mutex> lock{ mutex };
reps.clear ();
online_m = 0;
}
std::unique_ptr<nano::container_info_component> nano::collect_container_info (online_reps & online_reps, std::string const & name)
{
std::size_t count;
{
nano::lock_guard<nano::mutex> guard{ online_reps.mutex };
count = online_reps.reps.size ();
}
auto sizeof_element = sizeof (decltype (online_reps.reps)::value_type);
auto composite = std::make_unique<container_info_composite> (name);
composite->add_component (std::make_unique<container_info_leaf> (container_info{ "reps", count, sizeof_element }));
return composite;
}