* 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)
131 lines
4.1 KiB
C++
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;
|
|
}
|