Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overhaul of online_reps class #4656

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions nano/core_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ add_executable(
network_functions.cpp
node.cpp
object_stream.cpp
online_reps.cpp
optimistic_scheduler.cpp
processing_queue.cpp
processor_service.cpp
Expand Down
1 change: 1 addition & 0 deletions nano/core_test/active_elections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <nano/node/active_elections.hpp>
#include <nano/node/confirming_set.hpp>
#include <nano/node/election.hpp>
#include <nano/node/online_reps.hpp>
#include <nano/node/scheduler/component.hpp>
#include <nano/node/scheduler/manual.hpp>
#include <nano/node/scheduler/priority.hpp>
Expand Down
9 changes: 4 additions & 5 deletions nano/core_test/election.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <nano/lib/blocks.hpp>
#include <nano/node/active_elections.hpp>
#include <nano/node/election.hpp>
#include <nano/node/online_reps.hpp>
#include <nano/node/scheduler/component.hpp>
#include <nano/node/scheduler/priority.hpp>
#include <nano/node/vote_router.hpp>
Expand Down Expand Up @@ -259,11 +260,9 @@ TEST (election, quorum_minimum_update_weight_before_quorum_checks)
node1.rep_crawler.force_process (vote2, channel);

ASSERT_FALSE (election->confirmed ());
{
nano::lock_guard<nano::mutex> guard (node1.online_reps.mutex);
// Modify online_m for online_reps to more than is available, this checks that voting below updates it to current online reps.
node1.online_reps.online_m = node_config.online_weight_minimum.number () + 20;
}

// Modify online_m for online_reps to more than is available, this checks that voting below updates it to current online reps.
node1.online_reps.force_online_weight (node_config.online_weight_minimum.number () + 20);
ASSERT_EQ (nano::vote_code::vote, node1.vote_router.vote (vote2).at (send1->hash ()));
ASSERT_TIMELY (5s, election->confirmed ());
ASSERT_NE (nullptr, node1.block (send1->hash ()));
Expand Down
1 change: 1 addition & 0 deletions nano/core_test/ledger_confirm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <nano/node/active_elections.hpp>
#include <nano/node/election.hpp>
#include <nano/node/make_store.hpp>
#include <nano/node/online_reps.hpp>
#include <nano/secure/ledger.hpp>
#include <nano/secure/ledger_set_any.hpp>
#include <nano/secure/ledger_set_confirmed.hpp>
Expand Down
66 changes: 1 addition & 65 deletions nano/core_test/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <nano/node/inactive_node.hpp>
#include <nano/node/local_vote_history.hpp>
#include <nano/node/make_store.hpp>
#include <nano/node/online_reps.hpp>
#include <nano/node/scheduler/component.hpp>
#include <nano/node/scheduler/manual.hpp>
#include <nano/node/scheduler/priority.hpp>
Expand Down Expand Up @@ -1691,71 +1692,6 @@ TEST (node, bootstrap_connection_scaling)
ASSERT_EQ (1, node1.bootstrap_initiator.connections->target_connections (50000, 1));
}

TEST (node, online_reps)
{
nano::test::system system (1);
auto & node1 (*system.nodes[0]);
// 1 sample of minimum weight
ASSERT_EQ (node1.config.online_weight_minimum, node1.online_reps.trended ());
auto vote (std::make_shared<nano::vote> ());
ASSERT_EQ (0, node1.online_reps.online ());
node1.online_reps.observe (nano::dev::genesis_key.pub);
ASSERT_EQ (nano::dev::constants.genesis_amount, node1.online_reps.online ());
// 1 minimum, 1 maximum
ASSERT_EQ (node1.config.online_weight_minimum, node1.online_reps.trended ());
node1.online_reps.sample ();
ASSERT_EQ (nano::dev::constants.genesis_amount, node1.online_reps.trended ());
node1.online_reps.clear ();
// 2 minimum, 1 maximum
node1.online_reps.sample ();
ASSERT_EQ (node1.config.online_weight_minimum, node1.online_reps.trended ());
}

TEST (node, online_reps_rep_crawler)
{
nano::test::system system;
nano::node_flags flags;
flags.disable_rep_crawler = true;
auto & node1 = *system.add_node (flags);
auto vote = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::milliseconds_since_epoch (), 0, std::vector<nano::block_hash>{ nano::dev::genesis->hash () });
ASSERT_EQ (0, node1.online_reps.online ());
// Without rep crawler
node1.vote_processor.vote_blocking (vote, std::make_shared<nano::transport::fake::channel> (node1));
ASSERT_EQ (0, node1.online_reps.online ());
// After inserting to rep crawler
auto channel = std::make_shared<nano::transport::fake::channel> (node1);
node1.rep_crawler.force_query (nano::dev::genesis->hash (), channel);
node1.vote_processor.vote_blocking (vote, channel);
ASSERT_EQ (nano::dev::constants.genesis_amount, node1.online_reps.online ());
}

TEST (node, online_reps_election)
{
nano::test::system system;
nano::node_flags flags;
flags.disable_rep_crawler = true;
auto & node1 = *system.add_node (flags);
// Start election
nano::keypair key;
nano::state_block_builder builder;
auto send1 = builder.make_block ()
.account (nano::dev::genesis_key.pub)
.previous (nano::dev::genesis->hash ())
.representative (nano::dev::genesis_key.pub)
.balance (nano::dev::constants.genesis_amount - nano::Gxrb_ratio)
.link (key.pub)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (*node1.work_generate_blocking (nano::dev::genesis->hash ()))
.build ();
node1.process_active (send1);
ASSERT_TIMELY_EQ (5s, 1, node1.active.size ());
// Process vote for ongoing election
auto vote = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::milliseconds_since_epoch (), 0, std::vector<nano::block_hash>{ send1->hash () });
ASSERT_EQ (0, node1.online_reps.online ());
node1.vote_processor.vote_blocking (vote, std::make_shared<nano::transport::fake::channel> (node1));
ASSERT_EQ (nano::dev::constants.genesis_amount - nano::Gxrb_ratio, node1.online_reps.online ());
}

TEST (node, block_confirm)
{
auto type = nano::transport::transport_type::tcp;
Expand Down
70 changes: 70 additions & 0 deletions nano/core_test/online_reps.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include <nano/node/online_reps.hpp>
#include <nano/test_common/system.hpp>
#include <nano/test_common/testutil.hpp>

#include <gtest/gtest.h>

TEST (online_reps, basic)
{
nano::test::system system (1);
auto & node1 (*system.nodes[0]);
// 1 sample of minimum weight
ASSERT_EQ (node1.config.online_weight_minimum, node1.online_reps.trended ());
auto vote (std::make_shared<nano::vote> ());
ASSERT_EQ (0, node1.online_reps.online ());
node1.online_reps.observe (nano::dev::genesis_key.pub);
ASSERT_EQ (nano::dev::constants.genesis_amount, node1.online_reps.online ());
// 1 minimum, 1 maximum
ASSERT_EQ (node1.config.online_weight_minimum, node1.online_reps.trended ());
node1.online_reps.force_sample ();
ASSERT_EQ (nano::dev::constants.genesis_amount, node1.online_reps.trended ());
node1.online_reps.clear ();
// 2 minimum, 1 maximum
node1.online_reps.force_sample ();
ASSERT_EQ (node1.config.online_weight_minimum, node1.online_reps.trended ());
}

TEST (online_reps, rep_crawler)
{
nano::test::system system;
nano::node_flags flags;
flags.disable_rep_crawler = true;
auto & node1 = *system.add_node (flags);
auto vote = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::milliseconds_since_epoch (), 0, std::vector<nano::block_hash>{ nano::dev::genesis->hash () });
ASSERT_EQ (0, node1.online_reps.online ());
// Without rep crawler
node1.vote_processor.vote_blocking (vote, std::make_shared<nano::transport::fake::channel> (node1));
ASSERT_EQ (0, node1.online_reps.online ());
// After inserting to rep crawler
auto channel = std::make_shared<nano::transport::fake::channel> (node1);
node1.rep_crawler.force_query (nano::dev::genesis->hash (), channel);
node1.vote_processor.vote_blocking (vote, channel);
ASSERT_EQ (nano::dev::constants.genesis_amount, node1.online_reps.online ());
}

TEST (online_reps, election)
{
nano::test::system system;
nano::node_flags flags;
flags.disable_rep_crawler = true;
auto & node1 = *system.add_node (flags);
// Start election
nano::keypair key;
nano::state_block_builder builder;
auto send1 = builder.make_block ()
.account (nano::dev::genesis_key.pub)
.previous (nano::dev::genesis->hash ())
.representative (nano::dev::genesis_key.pub)
.balance (nano::dev::constants.genesis_amount - nano::Gxrb_ratio)
.link (key.pub)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (*node1.work_generate_blocking (nano::dev::genesis->hash ()))
.build ();
node1.process_active (send1);
ASSERT_TIMELY_EQ (5s, 1, node1.active.size ());
// Process vote for ongoing election
auto vote = std::make_shared<nano::vote> (nano::dev::genesis_key.pub, nano::dev::genesis_key.prv, nano::milliseconds_since_epoch (), 0, std::vector<nano::block_hash>{ send1->hash () });
ASSERT_EQ (0, node1.online_reps.online ());
node1.vote_processor.vote_blocking (vote, std::make_shared<nano::transport::fake::channel> (node1));
ASSERT_EQ (nano::dev::constants.genesis_amount - nano::Gxrb_ratio, node1.online_reps.online ());
}
11 changes: 5 additions & 6 deletions nano/core_test/vote_processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,7 @@ TEST (vote_processor, weights)
auto & node (*system.nodes[0]);

// Create representatives of different weight levels
// FIXME: Using `online_weight_minimum` because calculation of trended and online weight is broken when running tests
auto const stake = node.config.online_weight_minimum.number ();
auto const stake = node.balance (nano::dev::genesis_key.pub);
auto const level0 = stake / 5000; // 0.02%
auto const level1 = stake / 500; // 0.2%
auto const level2 = stake / 50; // 2%
Expand All @@ -140,10 +139,10 @@ TEST (vote_processor, weights)
node.stats.clear ();
ASSERT_TIMELY (5s, node.stats.count (nano::stat::type::rep_tiers, nano::stat::detail::updated) >= 2);

ASSERT_EQ (node.rep_tiers.tier (key0.pub), nano::rep_tier::none);
ASSERT_EQ (node.rep_tiers.tier (key1.pub), nano::rep_tier::tier_1);
ASSERT_EQ (node.rep_tiers.tier (key2.pub), nano::rep_tier::tier_2);
ASSERT_EQ (node.rep_tiers.tier (nano::dev::genesis_key.pub), nano::rep_tier::tier_3);
ASSERT_TIMELY_EQ (5s, node.rep_tiers.tier (key0.pub), nano::rep_tier::none);
ASSERT_TIMELY_EQ (5s, node.rep_tiers.tier (key1.pub), nano::rep_tier::tier_1);
ASSERT_TIMELY_EQ (5s, node.rep_tiers.tier (key2.pub), nano::rep_tier::tier_2);
ASSERT_TIMELY_EQ (5s, node.rep_tiers.tier (nano::dev::genesis_key.pub), nano::rep_tier::tier_3);
}

// Issue that tracks last changes on this test: https://github.com/nanocurrency/nano-node/issues/3485
Expand Down
1 change: 1 addition & 0 deletions nano/core_test/websocket.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <nano/core_test/fakes/websocket_client.hpp>
#include <nano/lib/blocks.hpp>
#include <nano/node/active_elections.hpp>
#include <nano/node/online_reps.hpp>
#include <nano/node/transport/fake.hpp>
#include <nano/node/vote_router.hpp>
#include <nano/node/websocket.hpp>
Expand Down
5 changes: 5 additions & 0 deletions nano/lib/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,11 @@ void force_nano_dev_network ()
nano::network_constants::set_active_network (nano::networks::nano_dev_network);
}

bool is_dev_run ()
{
return nano::network_constants::get_active_network () == nano::networks::nano_dev_network;
}

bool running_within_valgrind ()
{
return (RUNNING_ON_VALGRIND > 0);
Expand Down
12 changes: 10 additions & 2 deletions nano/lib/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ consteval bool is_asan_build ()
#else
return false;
#endif
// GCC builds
// GCC builds
#elif defined(__SANITIZE_ADDRESS__)
return true;
#else
Expand All @@ -57,7 +57,7 @@ consteval bool is_tsan_build ()
#else
return false;
#endif
// GCC builds
// GCC builds
#elif defined(__SANITIZE_THREAD__)
return true;
#else
Expand Down Expand Up @@ -297,6 +297,11 @@ class network_constants
active_network = network_a;
}

static nano::networks get_active_network ()
{
return active_network;
}

/**
* Optionally called on startup to override the global active network.
* If not called, the compile-time option will be used.
Expand Down Expand Up @@ -384,6 +389,9 @@ bool slow_instrumentation ();
/** Set the active network to the dev network */
void force_nano_dev_network ();

/** Checks that we are running in test mode */
bool is_dev_run ();

/**
* Attempt to read a configuration file from specified directory. Returns empty tomlconfig if nothing is found.
* @throws std::runtime_error with error code if the file or overrides are not valid toml
Expand Down
1 change: 1 addition & 0 deletions nano/lib/logging_enums.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ enum class type
signal_manager,
peer_history,
message_processor,
online_reps,

// bootstrap
bulk_pull_client,
Expand Down
10 changes: 10 additions & 0 deletions nano/lib/stats_enums.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ enum class type
message_processor,
message_processor_overfill,
message_processor_type,
online_reps,

bootstrap_ascending,
bootstrap_ascending_accounts,
Expand Down Expand Up @@ -469,6 +470,15 @@ enum class detail
active_confirmation_height,
inactive_confirmation_height,

// online_reps
trim_trend,
sanitize_old,
sanitize_future,
sample,
rep_new,
rep_update,
update_online,

_last // Must be the last enum
};

Expand Down
3 changes: 3 additions & 0 deletions nano/lib/thread_roles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ std::string nano::thread_role::get_string (nano::thread_role::name role)
case nano::thread_role::name::vote_router:
thread_role_name_string = "Vote router";
break;
case nano::thread_role::name::online_reps:
thread_role_name_string = "Online reps";
break;
default:
debug_assert (false && "nano::thread_role::get_string unhandled thread role");
}
Expand Down
1 change: 1 addition & 0 deletions nano/lib/thread_roles.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ enum class name
port_mapping,
stats,
vote_router,
online_reps,
};

std::string_view to_string (name);
Expand Down
1 change: 1 addition & 0 deletions nano/nano_node/entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <nano/node/ipc/ipc_server.hpp>
#include <nano/node/json_handler.hpp>
#include <nano/node/node.hpp>
#include <nano/node/online_reps.hpp>
#include <nano/node/transport/inproc.hpp>
#include <nano/secure/ledger.hpp>
#include <nano/secure/ledger_set_any.hpp>
Expand Down
2 changes: 2 additions & 0 deletions nano/node/active_elections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <nano/node/confirming_set.hpp>
#include <nano/node/election.hpp>
#include <nano/node/node.hpp>
#include <nano/node/online_reps.hpp>
#include <nano/node/repcrawler.hpp>
#include <nano/node/scheduler/component.hpp>
#include <nano/node/scheduler/priority.hpp>
Expand Down Expand Up @@ -409,6 +410,7 @@ nano::election_insertion_result nano::active_elections::insert (std::shared_ptr<
{
result.inserted = true;
auto observe_rep_cb = [&node = node] (auto const & rep_a) {
// TODO: Is this neccessary? Move this outside of the election class
// Representative is defined as online if replying to live votes or rep_crawler queries
node.online_reps.observe (rep_a);
};
Expand Down
1 change: 1 addition & 0 deletions nano/node/election.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <nano/node/local_vote_history.hpp>
#include <nano/node/network.hpp>
#include <nano/node/node.hpp>
#include <nano/node/online_reps.hpp>
#include <nano/node/vote_generator.hpp>
#include <nano/node/vote_router.hpp>
#include <nano/secure/ledger.hpp>
Expand Down
1 change: 1 addition & 0 deletions nano/node/json_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <nano/node/json_handler.hpp>
#include <nano/node/node.hpp>
#include <nano/node/node_rpc_config.hpp>
#include <nano/node/online_reps.hpp>
#include <nano/node/telemetry.hpp>
#include <nano/secure/ledger.hpp>
#include <nano/secure/ledger_set_any.hpp>
Expand Down
Loading
Loading