Skip to content

Commit

Permalink
Squash merge PR nanocurrency#4656: Overhaul of online_reps class
Browse files Browse the repository at this point in the history
  • Loading branch information
gr0vity committed Jun 26, 2024
1 parent 4e2a06b commit 9bcbb1d
Show file tree
Hide file tree
Showing 29 changed files with 392 additions and 193 deletions.
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 @@ -1688,71 +1689,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 @@ -83,6 +83,7 @@ enum class type
message_processor,
message_processor_overfill,
message_processor_type,
online_reps,

bootstrap_ascending,
bootstrap_ascending_accounts,
Expand Down Expand Up @@ -476,6 +477,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

0 comments on commit 9bcbb1d

Please sign in to comment.