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

Remove elections difficulty sorting #3260

Merged
merged 13 commits into from
May 4, 2021
Merged
Show file tree
Hide file tree
Changes from all 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: 0 additions & 1 deletion nano/core_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ add_executable(
wallet.cpp
wallets.cpp
websocket.cpp
work_watcher.cpp
work_pool.cpp)

target_compile_definitions(
Expand Down
476 changes: 2 additions & 474 deletions nano/core_test/active_transactions.cpp

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions nano/core_test/confirmation_solicitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ TEST (confirmation_solicitor, batches)
nano::lock_guard<nano::mutex> guard (node2.active.mutex);
for (size_t i (0); i < nano::network::confirm_req_hashes_max; ++i)
{
auto election (std::make_shared<nano::election> (node2, send, nullptr, nullptr, false, nano::election_behavior::normal));
auto election (std::make_shared<nano::election> (node2, send, nullptr, nullptr, nano::election_behavior::normal));
ASSERT_FALSE (solicitor.add (*election));
}
// Reached the maximum amount of requests for the channel
auto election (std::make_shared<nano::election> (node2, send, nullptr, nullptr, false, nano::election_behavior::normal));
auto election (std::make_shared<nano::election> (node2, send, nullptr, nullptr, nano::election_behavior::normal));
ASSERT_TRUE (solicitor.add (*election));
// Broadcasting should be immediate
ASSERT_EQ (0, node2.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::out));
Expand Down Expand Up @@ -74,7 +74,7 @@ TEST (confirmation_solicitor, different_hash)
ASSERT_TIMELY (3s, node2.network.size () == 1);
auto send (std::make_shared<nano::send_block> (nano::genesis_hash, nano::keypair ().pub, nano::genesis_amount - 100, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (nano::genesis_hash)));
send->sideband_set ({});
auto election (std::make_shared<nano::election> (node2, send, nullptr, nullptr, false, nano::election_behavior::normal));
auto election (std::make_shared<nano::election> (node2, send, nullptr, nullptr, nano::election_behavior::normal));
// Add a vote for something else, not the winner
election->last_votes[representative.account] = { std::chrono::steady_clock::now (), 1, 1 };
// Ensure the request and broadcast goes through
Expand Down Expand Up @@ -110,7 +110,7 @@ TEST (confirmation_solicitor, bypass_max_requests_cap)
ASSERT_TIMELY (3s, node2.network.size () == 1);
auto send (std::make_shared<nano::send_block> (nano::genesis_hash, nano::keypair ().pub, nano::genesis_amount - 100, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (nano::genesis_hash)));
send->sideband_set ({});
auto election (std::make_shared<nano::election> (node2, send, nullptr, nullptr, false, nano::election_behavior::normal));
auto election (std::make_shared<nano::election> (node2, send, nullptr, nullptr, nano::election_behavior::normal));
// Add a vote for something else, not the winner
for (auto const & rep : representatives)
{
Expand All @@ -124,7 +124,7 @@ TEST (confirmation_solicitor, bypass_max_requests_cap)
ASSERT_EQ (max_representatives + 1, node2.stats.count (nano::stat::type::message, nano::stat::detail::confirm_req, nano::stat::dir::out));

solicitor.prepare (representatives);
auto election2 (std::make_shared<nano::election> (node2, send, nullptr, nullptr, false, nano::election_behavior::normal));
auto election2 (std::make_shared<nano::election> (node2, send, nullptr, nullptr, nano::election_behavior::normal));
ASSERT_FALSE (solicitor.add (*election2));
ASSERT_FALSE (solicitor.broadcast (*election2));

Expand Down
33 changes: 0 additions & 33 deletions nano/core_test/conflicts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,36 +156,3 @@ TEST (vote_uniquer, cleanup)
ASSERT_LT (iterations++, 200);
}
}

TEST (conflicts, reprioritize)
{
nano::system system (1);
auto & node1 (*system.nodes[0]);
nano::genesis genesis;
nano::keypair key1;
auto send1 (std::make_shared<nano::send_block> (genesis.hash (), key1.pub, 0, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0));
node1.work_generate_blocking (*send1);
auto difficulty1 (send1->difficulty ());
auto multiplier1 (nano::normalized_multiplier (nano::difficulty::to_multiplier (difficulty1, nano::work_threshold (send1->work_version (), nano::block_details (nano::epoch::epoch_0, false /* unused */, false /* unused */, false /* unused */))), node1.network_params.network.publish_thresholds.epoch_1));
nano::send_block send1_copy (*send1);
node1.process_active (send1);
node1.block_processor.flush ();
node1.scheduler.flush ();
{
nano::lock_guard<nano::mutex> guard (node1.active.mutex);
auto existing1 (node1.active.roots.find (send1->qualified_root ()));
ASSERT_NE (node1.active.roots.end (), existing1);
ASSERT_EQ (multiplier1, existing1->multiplier);
}
node1.work_generate_blocking (send1_copy, difficulty1);
auto difficulty2 (send1_copy.difficulty ());
auto multiplier2 (nano::normalized_multiplier (nano::difficulty::to_multiplier (difficulty2, nano::work_threshold (send1_copy.work_version (), nano::block_details (nano::epoch::epoch_0, false /* unused */, false /* unused */, false /* unused */))), node1.network_params.network.publish_thresholds.epoch_1));
node1.process_active (std::make_shared<nano::send_block> (send1_copy));
node1.block_processor.flush ();
{
nano::lock_guard<nano::mutex> guard (node1.active.mutex);
auto existing2 (node1.active.roots.find (send1->qualified_root ()));
ASSERT_NE (node1.active.roots.end (), existing2);
ASSERT_EQ (multiplier2, existing2->multiplier);
}
}
58 changes: 9 additions & 49 deletions nano/core_test/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -779,29 +779,25 @@ TEST (node_config, v18_values)
tree.put ("active_elections_size", 10000);
tree.put ("vote_generator_delay", 100);
tree.put ("backup_before_upgrade", true);
tree.put ("work_watcher_period", 5);
}

config.deserialize_json (upgraded, tree);
ASSERT_FALSE (upgraded);
ASSERT_EQ (config.active_elections_size, 10000);
ASSERT_EQ (config.vote_generator_delay.count (), 100);
ASSERT_EQ (config.backup_before_upgrade, true);
ASSERT_EQ (config.work_watcher_period.count (), 5);

// Check config is correct with other values
tree.put ("active_elections_size", 5);
tree.put ("vote_generator_delay", std::numeric_limits<unsigned long>::max () - 100);
tree.put ("backup_before_upgrade", false);
tree.put ("work_watcher_period", 999);

upgraded = false;
config.deserialize_json (upgraded, tree);
ASSERT_FALSE (upgraded);
ASSERT_EQ (config.active_elections_size, 5);
ASSERT_EQ (config.vote_generator_delay.count (), std::numeric_limits<unsigned long>::max () - 100);
ASSERT_EQ (config.backup_before_upgrade, false);
ASSERT_EQ (config.work_watcher_period.count (), 999);
}

// Regression test to ensure that deserializing includes changes node via get_required_child
Expand Down Expand Up @@ -2659,7 +2655,7 @@ TEST (node, confirm_quorum)
.build_shared ();
ASSERT_EQ (nano::process_result::progress, node1.process (*send1).code);
system.wallet (0)->send_action (nano::dev_genesis_key.pub, nano::dev_genesis_key.pub, new_balance.number ());
ASSERT_TIMELY (1s, node1.active.election (send1->qualified_root ()));
ASSERT_TIMELY (2s, node1.active.election (send1->qualified_root ()));
auto election = node1.active.election (send1->qualified_root ());
ASSERT_NE (nullptr, election);
ASSERT_FALSE (election->confirmed ());
Expand Down Expand Up @@ -3920,7 +3916,7 @@ TEST (node, aggressive_flooding)
.build ();
}
// Processing locally goes through the aggressive block flooding path
node1.process_local (block, false);
node1.process_local (block);

auto all_have_block = [&nodes_wallets] (nano::block_hash const & hash_a) {
return std::all_of (nodes_wallets.begin (), nodes_wallets.end (), [hash = hash_a] (auto const & node_wallet) {
Expand All @@ -3939,42 +3935,6 @@ TEST (node, aggressive_flooding)
ASSERT_EQ (1 + 2 * nodes_wallets.size () + 2, node1.ledger.cache.block_count);
}

TEST (active_difficulty, recalculate_work)
{
nano::system system;
nano::node_config node_config (nano::get_available_port (), system.logging);
node_config.enable_voting = false;
auto & node1 = *system.add_node (node_config);
nano::genesis genesis;
nano::keypair key1;
ASSERT_EQ (node1.network_params.network.publish_thresholds.epoch_2, node1.active.active_difficulty ());
auto send1 = nano::send_block_builder ()
.previous (genesis.hash ())
.destination (key1.pub)
.balance (0)
.sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub)
.work (*system.work.generate (genesis.hash ()))
.build_shared ();
auto multiplier1 = nano::difficulty::to_multiplier (send1->difficulty (), node1.network_params.network.publish_thresholds.epoch_2);
// Process as local block
node1.process_active (send1);
ASSERT_TIMELY (2s, !node1.active.empty ());
auto sum (std::accumulate (node1.active.multipliers_cb.begin (), node1.active.multipliers_cb.end (), double (0)));
ASSERT_EQ (node1.active.active_difficulty (), nano::difficulty::from_multiplier (sum / node1.active.multipliers_cb.size (), node1.network_params.network.publish_thresholds.epoch_2));
nano::unique_lock<nano::mutex> lock (node1.active.mutex);
// Fake history records to force work recalculation
for (auto i (0); i < node1.active.multipliers_cb.size (); i++)
{
node1.active.multipliers_cb.push_back (multiplier1 * (1 + i / 100.));
}
node1.work_generate_blocking (*send1);
node1.process_active (send1);
node1.active.update_active_multiplier (lock);
sum = std::accumulate (node1.active.multipliers_cb.begin (), node1.active.multipliers_cb.end (), double (0));
ASSERT_EQ (node1.active.trended_active_multiplier.load (), sum / node1.active.multipliers_cb.size ());
lock.unlock ();
}

TEST (node, node_sequence)
{
nano::system system (3);
Expand Down Expand Up @@ -4497,8 +4457,8 @@ TEST (node, deferred_dependent_elections)
ASSERT_NE (nullptr, election_send1);

// Should process and republish but not start an election for any dependent blocks
node.process_local (open, false);
node.process_local (send2, false);
node.process_local (open);
node.process_local (send2);
node.block_processor.flush ();
ASSERT_TRUE (node.block (open->hash ()));
ASSERT_TRUE (node.block (send2->hash ()));
Expand All @@ -4509,7 +4469,7 @@ TEST (node, deferred_dependent_elections)

// Re-processing older blocks with updated work also does not start an election
node.work_generate_blocking (*open, open->difficulty () + 1);
node.process_local (open, false);
node.process_local (open);
node.block_processor.flush ();
ASSERT_FALSE (node.active.active (open->qualified_root ()));
/// However, work is still updated
Expand All @@ -4524,7 +4484,7 @@ TEST (node, deferred_dependent_elections)
/// The election was dropped but it's still not possible to restart it
node.work_generate_blocking (*open, open->difficulty () + 1);
ASSERT_FALSE (node.active.active (open->qualified_root ()));
node.process_local (open, false);
node.process_local (open);
node.block_processor.flush ();
ASSERT_FALSE (node.active.active (open->qualified_root ()));
/// However, work is still updated
Expand Down Expand Up @@ -4563,14 +4523,14 @@ TEST (node, deferred_dependent_elections)
ASSERT_FALSE (node.active.active (receive->qualified_root ()));
ASSERT_FALSE (node.ledger.rollback (node.store.tx_begin_write (), receive->hash ()));
ASSERT_FALSE (node.block (receive->hash ()));
node.process_local (receive, false);
node.process_local (receive);
node.block_processor.flush ();
ASSERT_TRUE (node.block (receive->hash ()));
ASSERT_FALSE (node.active.active (receive->qualified_root ()));

// Processing a fork will also not start an election
ASSERT_EQ (nano::process_result::fork, node.process (*fork).code);
node.process_local (fork, false);
node.process_local (fork);
node.block_processor.flush ();
ASSERT_FALSE (node.active.active (receive->qualified_root ()));

Expand All @@ -4581,7 +4541,7 @@ TEST (node, deferred_dependent_elections)
node.active.erase (*receive);
ASSERT_FALSE (node.active.active (receive->qualified_root ()));
node.work_generate_blocking (*receive, receive->difficulty () + 1);
node.process_local (receive, false);
node.process_local (receive);
node.block_processor.flush ();
ASSERT_TRUE (node.active.active (receive->qualified_root ()));
}
Expand Down
10 changes: 5 additions & 5 deletions nano/core_test/telemetry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ TEST (telemetry, basic)
}

// Check the metrics are correct
nano::compare_default_telemetry_response_data (telemetry_data, node_server->network_params, node_server->config.bandwidth_limit, node_server->active.active_difficulty (), node_server->node_id);
nano::compare_default_telemetry_response_data (telemetry_data, node_server->network_params, node_server->config.bandwidth_limit, node_server->default_difficulty (nano::work_version::work_1), node_server->node_id);

// Call again straight away. It should use the cache
{
Expand Down Expand Up @@ -305,7 +305,7 @@ TEST (telemetry, over_udp)
auto channel = node_client->network.find_channel (node_server->network.endpoint ());
node_client->telemetry->get_metrics_single_peer_async (channel, [&done, &node_server] (nano::telemetry_data_response const & response_a) {
ASSERT_FALSE (response_a.error);
nano::compare_default_telemetry_response_data (response_a.telemetry_data, node_server->network_params, node_server->config.bandwidth_limit, node_server->active.active_difficulty (), node_server->node_id);
nano::compare_default_telemetry_response_data (response_a.telemetry_data, node_server->network_params, node_server->config.bandwidth_limit, node_server->default_difficulty (nano::work_version::work_1), node_server->node_id);
done = true;
});

Expand Down Expand Up @@ -370,7 +370,7 @@ TEST (telemetry, blocking_request)
// Now try single request metric
auto telemetry_data_response = node_client->telemetry->get_metrics_single_peer (node_client->network.find_channel (node_server->network.endpoint ()));
ASSERT_FALSE (telemetry_data_response.error);
nano::compare_default_telemetry_response_data (telemetry_data_response.telemetry_data, node_server->network_params, node_server->config.bandwidth_limit, node_server->active.active_difficulty (), node_server->node_id);
nano::compare_default_telemetry_response_data (telemetry_data_response.telemetry_data, node_server->network_params, node_server->config.bandwidth_limit, node_server->default_difficulty (nano::work_version::work_1), node_server->node_id);

done = true;
promise.get_future ().wait ();
Expand Down Expand Up @@ -513,7 +513,7 @@ TEST (telemetry, disable_metrics)
auto channel1 = node_server->network.find_channel (node_client->network.endpoint ());
node_server->telemetry->get_metrics_single_peer_async (channel1, [&done, node_client] (nano::telemetry_data_response const & response_a) {
ASSERT_FALSE (response_a.error);
nano::compare_default_telemetry_response_data (response_a.telemetry_data, node_client->network_params, node_client->config.bandwidth_limit, node_client->active.active_difficulty (), node_client->node_id);
nano::compare_default_telemetry_response_data (response_a.telemetry_data, node_client->network_params, node_client->config.bandwidth_limit, node_client->default_difficulty (nano::work_version::work_1), node_client->node_id);
done = true;
});

Expand Down Expand Up @@ -628,7 +628,7 @@ TEST (telemetry, remove_peer_invalid_signature)
// (Implementation detail) So that messages are not just discarded when requests were not sent.
node->telemetry->recent_or_initial_request_telemetry_data.emplace (channel->get_endpoint (), nano::telemetry_data (), std::chrono::steady_clock::now (), true);

auto telemetry_data = nano::local_telemetry_data (node->ledger, node->network, node->config.bandwidth_limit, node->network_params, node->startup_time, node->active.active_difficulty (), node->node_id);
auto telemetry_data = nano::local_telemetry_data (node->ledger, node->network, node->config.bandwidth_limit, node->network_params, node->startup_time, node->default_difficulty (nano::work_version::work_1), node->node_id);
// Change anything so that the signed message is incorrect
telemetry_data.block_count = 0;
auto telemetry_ack = nano::telemetry_ack (telemetry_data);
Expand Down
3 changes: 0 additions & 3 deletions nano/core_test/toml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,6 @@ TEST (toml, daemon_config_deserialize_defaults)
ASSERT_EQ (conf.node.max_work_generate_multiplier, defaults.node.max_work_generate_multiplier);
ASSERT_EQ (conf.node.network_threads, defaults.node.network_threads);
ASSERT_EQ (conf.node.secondary_work_peers, defaults.node.secondary_work_peers);
ASSERT_EQ (conf.node.work_watcher_period, defaults.node.work_watcher_period);
ASSERT_EQ (conf.node.online_weight_minimum, defaults.node.online_weight_minimum);
ASSERT_EQ (conf.node.election_hint_weight_percent, defaults.node.election_hint_weight_percent);
ASSERT_EQ (conf.node.password_fanout, defaults.node.password_fanout);
Expand Down Expand Up @@ -423,7 +422,6 @@ TEST (toml, daemon_config_deserialize_no_defaults)
vote_minimum = "999"
work_peers = ["dev.org:999"]
work_threads = 999
work_watcher_period = 999
max_work_generate_multiplier = 1.0
max_queued_requests = 999
frontiers_confirmation = "always"
Expand Down Expand Up @@ -573,7 +571,6 @@ TEST (toml, daemon_config_deserialize_no_defaults)
ASSERT_NE (conf.node.secondary_work_peers, defaults.node.secondary_work_peers);
ASSERT_NE (conf.node.max_pruning_age, defaults.node.max_pruning_age);
ASSERT_NE (conf.node.max_pruning_depth, defaults.node.max_pruning_depth);
ASSERT_NE (conf.node.work_watcher_period, defaults.node.work_watcher_period);
ASSERT_NE (conf.node.online_weight_minimum, defaults.node.online_weight_minimum);
ASSERT_NE (conf.node.election_hint_weight_percent, defaults.node.election_hint_weight_percent);
ASSERT_NE (conf.node.password_fanout, defaults.node.password_fanout);
Expand Down
38 changes: 0 additions & 38 deletions nano/core_test/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -996,34 +996,6 @@ TEST (wallet, deterministic_restore)
ASSERT_TRUE (wallet->exists (pub));
}

// Ensure the minimum limited difficulty is enough for the highest threshold
TEST (wallet, limited_difficulty)
{
nano::system system;
nano::genesis genesis;
nano::node_config node_config (nano::get_available_port (), system.logging);
node_config.max_work_generate_multiplier = 1;
nano::node_flags node_flags;
node_flags.disable_request_loop = true;
auto & node = *system.add_node (node_config, node_flags);
auto & wallet (*system.wallet (0));
// Upgrade the genesis account to epoch 2
ASSERT_NE (nullptr, system.upgrade_genesis_epoch (node, nano::epoch::epoch_1));
ASSERT_NE (nullptr, system.upgrade_genesis_epoch (node, nano::epoch::epoch_2));
ASSERT_EQ (nano::epoch::epoch_2, node.store.block_version (node.store.tx_begin_read (), node.latest (nano::dev_genesis_key.pub)));
wallet.insert_adhoc (nano::dev_genesis_key.prv, false);
{
// Force active difficulty to an impossibly high value
nano::lock_guard<nano::mutex> guard (node.active.mutex);
node.active.trended_active_multiplier = 1024 * 1024 * 1024;
}
ASSERT_EQ (node.max_work_generate_difficulty (nano::work_version::work_1), node.active.limited_active_difficulty (*genesis.open));
auto send = wallet.send_action (nano::dev_genesis_key.pub, nano::keypair ().pub, 1, 1);
ASSERT_NE (nullptr, send);
ASSERT_EQ (nano::epoch::epoch_2, send->sideband ().details.epoch);
ASSERT_EQ (nano::epoch::epoch_0, send->sideband ().source_epoch); // Not used for send state blocks
}

TEST (wallet, epoch_2_validation)
{
nano::system system (1);
Expand Down Expand Up @@ -1100,11 +1072,6 @@ TEST (wallet, epoch_2_receive_propagation)
auto send2 = wallet.send_action (nano::dev_genesis_key.pub, key.pub, amount, 1);
ASSERT_NE (nullptr, send2);

// Receiving should use the lower difficulty
{
nano::lock_guard<nano::mutex> guard (node.active.mutex);
node.active.trended_active_multiplier = 1.0;
}
auto receive2 = wallet.receive_action (send2->hash (), key.pub, amount, send2->link ().as_account (), 1);
ASSERT_NE (nullptr, receive2);
if (receive2->difficulty () < node.network_params.network.publish_thresholds.base)
Expand Down Expand Up @@ -1150,11 +1117,6 @@ TEST (wallet, epoch_2_receive_unopened)

wallet.insert_adhoc (key.prv, false);

// Receiving should use the lower difficulty
{
nano::lock_guard<nano::mutex> guard (node.active.mutex);
node.active.trended_active_multiplier = 1.0;
}
auto receive1 = wallet.receive_action (send1->hash (), key.pub, amount, send1->link ().as_account (), 1);
ASSERT_NE (nullptr, receive1);
if (receive1->difficulty () < node.network_params.network.publish_thresholds.base)
Expand Down
Loading