From 70461758f778d6cf9dcdf2747466b1156959c6b3 Mon Sep 17 00:00:00 2001 From: clemahieu Date: Sun, 18 Apr 2021 15:09:18 +0200 Subject: [PATCH 01/10] This change replaces PoW-difficulty based prioritization with balance * time_since_use based prioritization. The scheduler currently manages two queues. A priority queue where live traffic is managed and scheduled according to vacancy in the active_transactions container and prioritized by the prioritization container. A manual queue where requests that have come through RPCs are enqueued and bypass prioritization. --- nano/core_test/CMakeLists.txt | 1 + nano/core_test/active_transactions.cpp | 113 +++++++++++++--------- nano/core_test/bootstrap.cpp | 2 + nano/core_test/confirmation_height.cpp | 2 + nano/core_test/conflicts.cpp | 26 +++-- nano/core_test/election.cpp | 60 ++++++------ nano/core_test/election_scheduler.cpp | 126 ++++++++++++++++++++++++ nano/core_test/ledger.cpp | 86 ++++++++++------- nano/core_test/network.cpp | 4 +- nano/core_test/node.cpp | 86 +++++++++-------- nano/core_test/vote_processor.cpp | 22 +++-- nano/core_test/wallet.cpp | 10 +- nano/core_test/websocket.cpp | 1 + nano/core_test/work_watcher.cpp | 22 +++-- nano/node/CMakeLists.txt | 2 + nano/node/active_transactions.cpp | 62 +++--------- nano/node/active_transactions.hpp | 10 +- nano/node/blockprocessor.cpp | 3 +- nano/node/election_scheduler.cpp | 128 +++++++++++++++++++++++++ nano/node/election_scheduler.hpp | 47 +++++++++ nano/node/node.cpp | 50 +++++++++- nano/node/node.hpp | 4 + nano/node/wallet.cpp | 13 +-- nano/rpc_test/rpc.cpp | 20 ++-- nano/secure/ledger.cpp | 22 ++--- nano/secure/ledger.hpp | 1 - nano/slow_test/node.cpp | 33 +++---- 27 files changed, 658 insertions(+), 298 deletions(-) create mode 100644 nano/core_test/election_scheduler.cpp create mode 100644 nano/node/election_scheduler.cpp create mode 100644 nano/node/election_scheduler.hpp diff --git a/nano/core_test/CMakeLists.txt b/nano/core_test/CMakeLists.txt index 276829df62..a212078412 100644 --- a/nano/core_test/CMakeLists.txt +++ b/nano/core_test/CMakeLists.txt @@ -14,6 +14,7 @@ add_executable( difficulty.cpp distributed_work.cpp election.cpp + election_scheduler.cpp epochs.cpp frontiers_confirmation.cpp gap_cache.cpp diff --git a/nano/core_test/active_transactions.cpp b/nano/core_test/active_transactions.cpp index 48ce985ba1..d43d870166 100644 --- a/nano/core_test/active_transactions.cpp +++ b/nano/core_test/active_transactions.cpp @@ -133,9 +133,10 @@ TEST (active_transactions, keep_local) auto send5 (wallet.send_action (nano::dev_genesis_key.pub, key5.pub, node.config.receive_minimum.number ())); auto send6 (wallet.send_action (nano::dev_genesis_key.pub, key6.pub, node.config.receive_minimum.number ())); // should not drop wallet created transactions - ASSERT_TIMELY (5s, node.active.size () == 6); + ASSERT_TIMELY (5s, node.active.size () == 1); for (auto const & block : { send1, send2, send3, send4, send5, send6 }) { + ASSERT_TIMELY (1s, node.active.election (block->qualified_root ())); auto election = node.active.election (block->qualified_root ()); ASSERT_NE (nullptr, election); election->force_confirm (); @@ -174,8 +175,8 @@ TEST (active_transactions, keep_local) node.process_active (open3); node.block_processor.flush (); // bound elections, should drop after one loop - ASSERT_TIMELY (5s, node.active.size () == node_config.active_elections_size); - ASSERT_EQ (1, node.stats.count (nano::stat::type::election, nano::stat::detail::election_drop)); + ASSERT_TIMELY (1s, node.active.size () == node_config.active_elections_size); + ASSERT_EQ (1, node.scheduler.size ()); } TEST (active_transactions, inactive_votes_cache) @@ -342,7 +343,10 @@ TEST (active_transactions, inactive_votes_cache_multiple_votes) ASSERT_TIMELY (5s, node.active.find_inactive_votes_cache (send1->hash ()).voters.size () == 2); ASSERT_EQ (1, node.active.inactive_votes_cache_size ()); // Start election - auto election = node.active.insert (send1).election; + node.scheduler.activate (nano::dev_genesis_key.pub, node.store.tx_begin_read ()); + node.scheduler.flush (); + auto election = node.active.election (send1->qualified_root ()); + ASSERT_NE (nullptr, election); ASSERT_EQ (3, election->votes ().size ()); // 2 votes and 1 default not_an_acount ASSERT_EQ (2, node.stats.count (nano::stat::type::election, nano::stat::detail::vote_cached)); } @@ -508,7 +512,7 @@ TEST (active_transactions, inactive_votes_cache_election_start) ASSERT_TIMELY (5s, 13 == node.ledger.cache.cemented_count); } -TEST (active_transactions, update_difficulty) +TEST (active_transactions, DISABLED_update_difficulty) { nano::system system (2); auto & node1 = *system.nodes[0]; @@ -555,6 +559,7 @@ TEST (active_transactions, update_difficulty) node1.process_active (send1); node1.process_active (send2); node1.block_processor.flush (); + node1.scheduler.flush (); // Share the updated blocks node1.network.flood_block (send1); node1.network.flood_block (send2); @@ -699,7 +704,9 @@ TEST (active_transactions, dropped_cleanup) ASSERT_FALSE (node.network.publish_filter.apply (block_bytes.data (), block_bytes.size ())); ASSERT_TRUE (node.network.publish_filter.apply (block_bytes.data (), block_bytes.size ())); - auto election (node.active.insert (block).election); + node.block_confirm (block); + node.scheduler.flush (); + auto election = node.active.election (block->qualified_root ()); ASSERT_NE (nullptr, election); // Not yet removed @@ -721,7 +728,9 @@ TEST (active_transactions, dropped_cleanup) // Repeat test for a confirmed election ASSERT_TRUE (node.network.publish_filter.apply (block_bytes.data (), block_bytes.size ())); - election = node.active.insert (block).election; + node.block_confirm (block); + node.scheduler.flush (); + election = node.active.election (block->qualified_root ()); ASSERT_NE (nullptr, election); election->force_confirm (); ASSERT_TRUE (election->confirmed ()); @@ -843,9 +852,10 @@ TEST (active_transactions, fork_filter_cleanup) .work (*system.work.generate (genesis.hash ())) .build_shared (); node1.process_active (fork); + node1.block_processor.flush (); + node1.scheduler.flush (); } - node1.block_processor.flush (); - ASSERT_TIMELY (3s, !node1.active.empty ()); + ASSERT_EQ (1, node1.active.size ()); // Process correct block node_config.peering_port = nano::get_available_port (); @@ -1024,7 +1034,7 @@ TEST (active_transactions, confirmation_consistency) system.deadline_set (5s); while (!node.ledger.block_confirmed (node.store.tx_begin_read (), block->hash ())) { - ASSERT_FALSE (node.active.insert (block).inserted); + node.scheduler.activate (nano::dev_genesis_key.pub, node.store.tx_begin_read ()); ASSERT_NO_ERROR (system.poll (5ms)); } ASSERT_NO_ERROR (system.poll_until_true (1s, [&node, &block, i] { @@ -1123,19 +1133,33 @@ TEST (active_transactions, insertion_prioritization) node.active.update_active_multiplier (lock); }; - ASSERT_TRUE (node.active.insert (blocks[2]).election->prioritized ()); + node.block_confirm (blocks[2]); + node.scheduler.flush (); + ASSERT_TRUE (node.active.election (blocks[2]->qualified_root ())->prioritized ()); update_active_multiplier (); - ASSERT_FALSE (node.active.insert (blocks[3]).election->prioritized ()); + node.block_confirm (blocks[3]); + node.scheduler.flush (); + ASSERT_FALSE (node.active.election (blocks[3]->qualified_root ())->prioritized ()); update_active_multiplier (); - ASSERT_TRUE (node.active.insert (blocks[1]).election->prioritized ()); + node.block_confirm (blocks[1]); + node.scheduler.flush (); + ASSERT_TRUE (node.active.election (blocks[1]->qualified_root ())->prioritized ()); update_active_multiplier (); - ASSERT_FALSE (node.active.insert (blocks[4]).election->prioritized ()); + node.block_confirm (blocks[4]); + node.scheduler.flush (); + ASSERT_FALSE (node.active.election (blocks[4]->qualified_root ())->prioritized ()); update_active_multiplier (); - ASSERT_TRUE (node.active.insert (blocks[0]).election->prioritized ()); + node.block_confirm (blocks[0]); + node.scheduler.flush (); + ASSERT_TRUE (node.active.election (blocks[0]->qualified_root ())->prioritized ()); update_active_multiplier (); - ASSERT_FALSE (node.active.insert (blocks[5]).election->prioritized ()); + node.block_confirm (blocks[5]); + node.scheduler.flush (); + ASSERT_FALSE (node.active.election (blocks[5]->qualified_root ())->prioritized ()); update_active_multiplier (); - ASSERT_FALSE (node.active.insert (blocks[6]).election->prioritized ()); + node.block_confirm (blocks[6]); + node.scheduler.flush (); + ASSERT_FALSE (node.active.election (blocks[6]->qualified_root ())->prioritized ()); ASSERT_EQ (4, node.stats.count (nano::stat::type::election, nano::stat::detail::election_non_priority)); ASSERT_EQ (3, node.stats.count (nano::stat::type::election, nano::stat::detail::election_priority)); @@ -1251,6 +1275,7 @@ TEST (active_transactions, election_difficulty_update_old) auto send1_copy = builder.make_block ().from (*send1).build_shared (); node.process_active (send1); node.block_processor.flush (); + node.scheduler.flush (); ASSERT_EQ (1, node.active.size ()); auto multiplier = node.active.roots.begin ()->multiplier; { @@ -1362,6 +1387,7 @@ TEST (active_transactions, election_difficulty_update_fork) node.process_active (fork_change); node.block_processor.flush (); + node.scheduler.flush (); ASSERT_EQ (1, node.active.size ()); auto multiplier_change = node.active.roots.begin ()->multiplier; node.process_active (fork_send); @@ -1410,6 +1436,7 @@ TEST (active_transactions, confirm_new) .build_shared (); node1.process_active (send); node1.block_processor.flush (); + node1.scheduler.flush (); ASSERT_EQ (1, node1.active.size ()); auto & node2 = *system.add_node (); // Add key to node2 @@ -1505,6 +1532,7 @@ TEST (active_transactions, conflicting_block_vote_existing_election) auto vote_fork (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, std::numeric_limits::max (), fork)); ASSERT_EQ (nano::process_result::progress, node.process_local (send).code); + node.scheduler.flush (); ASSERT_EQ (1, node.active.size ()); // Vote for conflicting block, but the block does not yet exist in the ledger @@ -1580,42 +1608,41 @@ TEST (active_transactions, activate_account_chain) ASSERT_EQ (nano::process_result::progress, node.process (*open).code); ASSERT_EQ (nano::process_result::progress, node.process (*receive).code); - auto result = node.active.activate (nano::dev_genesis_key.pub); - ASSERT_TRUE (result.inserted); + node.scheduler.activate (nano::dev_genesis_key.pub, node.store.tx_begin_read ()); + node.scheduler.flush (); + auto election1 = node.active.election (send->qualified_root ()); ASSERT_EQ (1, node.active.size ()); - ASSERT_EQ (1, result.election->blocks ().count (send->hash ())); - auto result2 = node.active.activate (nano::dev_genesis_key.pub); - ASSERT_FALSE (result2.inserted); - ASSERT_EQ (result2.election, result.election); - result.election->force_confirm (); + ASSERT_EQ (1, election1->blocks ().count (send->hash ())); + node.scheduler.activate (nano::dev_genesis_key.pub, node.store.tx_begin_read ()); + auto election2 = node.active.election (send->qualified_root ()); + ASSERT_EQ (election2, election1); + election1->force_confirm (); ASSERT_TIMELY (3s, node.block_confirmed (send->hash ())); // On cementing, the next election is started ASSERT_TIMELY (3s, node.active.active (send2->qualified_root ())); - auto result3 = node.active.activate (nano::dev_genesis_key.pub); - ASSERT_FALSE (result3.inserted); - ASSERT_NE (nullptr, result3.election); - ASSERT_EQ (1, result3.election->blocks ().count (send2->hash ())); - result3.election->force_confirm (); + node.scheduler.activate (nano::dev_genesis_key.pub, node.store.tx_begin_read ()); + auto election3 = node.active.election (send2->qualified_root ()); + ASSERT_NE (nullptr, election3); + ASSERT_EQ (1, election3->blocks ().count (send2->hash ())); + election3->force_confirm (); ASSERT_TIMELY (3s, node.block_confirmed (send2->hash ())); // On cementing, the next election is started ASSERT_TIMELY (3s, node.active.active (open->qualified_root ())); ASSERT_TIMELY (3s, node.active.active (send3->qualified_root ())); - auto result4 = node.active.activate (nano::dev_genesis_key.pub); - ASSERT_FALSE (result4.inserted); - ASSERT_NE (nullptr, result4.election); - ASSERT_EQ (1, result4.election->blocks ().count (send3->hash ())); - auto result5 = node.active.activate (key.pub); - ASSERT_FALSE (result5.inserted); - ASSERT_NE (nullptr, result5.election); - ASSERT_EQ (1, result5.election->blocks ().count (open->hash ())); - result5.election->force_confirm (); + node.scheduler.activate (nano::dev_genesis_key.pub, node.store.tx_begin_read ()); + auto election4 = node.active.election (send3->qualified_root ()); + ASSERT_NE (nullptr, election4); + ASSERT_EQ (1, election4->blocks ().count (send3->hash ())); + node.scheduler.activate (key.pub, node.store.tx_begin_read ()); + auto election5 = node.active.election (open->qualified_root ()); + ASSERT_NE (nullptr, election5); + ASSERT_EQ (1, election5->blocks ().count (open->hash ())); + election5->force_confirm (); ASSERT_TIMELY (3s, node.block_confirmed (open->hash ())); // Until send3 is also confirmed, the receive block should not activate std::this_thread::sleep_for (200ms); - auto result6 = node.active.activate (key.pub); - ASSERT_FALSE (result6.inserted); - ASSERT_EQ (nullptr, result6.election); - result4.election->force_confirm (); + node.scheduler.activate (key.pub, node.store.tx_begin_read ()); + election4->force_confirm (); ASSERT_TIMELY (3s, node.block_confirmed (send3->hash ())); ASSERT_TIMELY (3s, node.active.active (receive->qualified_root ())); } @@ -1917,7 +1944,7 @@ TEST (active_transactions, vacancy) ASSERT_EQ (nano::process_result::progress, node.process (*send).code); ASSERT_EQ (1, node.active.vacancy ()); ASSERT_EQ (0, node.active.size ()); - node.active.activate (nano::dev_genesis_key.pub); + node.scheduler.activate (nano::dev_genesis_key.pub, node.store.tx_begin_read ()); ASSERT_TIMELY (1s, updated); updated = false; ASSERT_EQ (0, node.active.vacancy ()); diff --git a/nano/core_test/bootstrap.cpp b/nano/core_test/bootstrap.cpp index b1c32f8f32..e00c8ebd56 100644 --- a/nano/core_test/bootstrap.cpp +++ b/nano/core_test/bootstrap.cpp @@ -1224,6 +1224,8 @@ TEST (bulk, offline_send) auto send1 (system.wallet (0)->send_action (nano::dev_genesis_key.pub, key2.pub, node1->config.receive_minimum.number ())); ASSERT_NE (nullptr, send1); ASSERT_NE (std::numeric_limits::max (), node1->balance (nano::dev_genesis_key.pub)); + node1->block_processor.flush (); + node1->scheduler.flush (); // Wait to finish election background tasks ASSERT_TIMELY (10s, node1->active.empty ()); ASSERT_TRUE (node1->block_confirmed (send1->hash ())); diff --git a/nano/core_test/confirmation_height.cpp b/nano/core_test/confirmation_height.cpp index 2f65418246..890c285440 100644 --- a/nano/core_test/confirmation_height.cpp +++ b/nano/core_test/confirmation_height.cpp @@ -663,9 +663,11 @@ TEST (confirmation_height, conflict_rollback_cemented) auto channel1 (node1->network.udp_channels.create (node1->network.endpoint ())); node1->network.process_message (publish1, channel1); node1->block_processor.flush (); + node1->scheduler.flush (); auto channel2 (node2->network.udp_channels.create (node1->network.endpoint ())); node2->network.process_message (publish2, channel2); node2->block_processor.flush (); + node2->scheduler.flush (); ASSERT_EQ (1, node1->active.size ()); ASSERT_EQ (1, node2->active.size ()); system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv); diff --git a/nano/core_test/conflicts.cpp b/nano/core_test/conflicts.cpp index 6db6315434..a8889d0b6f 100644 --- a/nano/core_test/conflicts.cpp +++ b/nano/core_test/conflicts.cpp @@ -18,10 +18,12 @@ TEST (conflicts, start_stop) node1.work_generate_blocking (*send1); ASSERT_EQ (nano::process_result::progress, node1.process (*send1).code); ASSERT_EQ (0, node1.active.size ()); - auto election1 = node1.active.insert (send1); + node1.scheduler.activate (nano::dev_genesis_key.pub, node1.store.tx_begin_read ()); + node1.scheduler.flush (); + auto election1 = node1.active.election (send1->qualified_root ()); ASSERT_EQ (1, node1.active.size ()); - ASSERT_NE (nullptr, election1.election); - ASSERT_EQ (1, election1.election->votes ().size ()); + ASSERT_NE (nullptr, election1); + ASSERT_EQ (1, election1->votes ().size ()); } TEST (conflicts, add_existing) @@ -33,17 +35,18 @@ TEST (conflicts, add_existing) auto send1 (std::make_shared (genesis.hash (), key1.pub, 0, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); node1.work_generate_blocking (*send1); ASSERT_EQ (nano::process_result::progress, node1.process (*send1).code); - node1.active.insert (send1); + node1.scheduler.activate (nano::dev_genesis_key.pub, node1.store.tx_begin_read ()); nano::keypair key2; auto send2 (std::make_shared (genesis.hash (), key2.pub, 0, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); send2->sideband_set ({}); - auto election1 = node1.active.insert (send2); + node1.scheduler.activate (nano::dev_genesis_key.pub, node1.store.tx_begin_read ()); + auto election1 = node1.active.election (send2->qualified_root ()); ASSERT_EQ (1, node1.active.size ()); auto vote1 (std::make_shared (key2.pub, key2.prv, 0, send2)); node1.active.vote (vote1); - ASSERT_NE (nullptr, election1.election); - ASSERT_EQ (2, election1.election->votes ().size ()); - auto votes (election1.election->votes ()); + ASSERT_NE (nullptr, election1); + ASSERT_EQ (2, election1->votes ().size ()); + auto votes (election1->votes ()); ASSERT_NE (votes.end (), votes.find (key2.pub)); } @@ -56,12 +59,14 @@ TEST (conflicts, add_two) auto send1 (std::make_shared (genesis.hash (), key1.pub, 0, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); node1.work_generate_blocking (*send1); ASSERT_EQ (nano::process_result::progress, node1.process (*send1).code); - node1.active.insert (send1); + node1.block_confirm (send1); + node1.active.election (send1->qualified_root ())->force_confirm (); nano::keypair key2; auto send2 (std::make_shared (send1->hash (), key2.pub, 0, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); node1.work_generate_blocking (*send2); ASSERT_EQ (nano::process_result::progress, node1.process (*send2).code); - node1.active.insert (send2); + node1.scheduler.activate (nano::dev_genesis_key.pub, node1.store.tx_begin_read ()); + node1.scheduler.flush (); ASSERT_EQ (2, node1.active.size ()); } @@ -165,6 +170,7 @@ TEST (conflicts, reprioritize) nano::send_block send1_copy (*send1); node1.process_active (send1); node1.block_processor.flush (); + node1.scheduler.flush (); { nano::lock_guard guard (node1.active.mutex); auto existing1 (node1.active.roots.find (send1->qualified_root ())); diff --git a/nano/core_test/election.cpp b/nano/core_test/election.cpp index 8061f7593c..58d0de0e78 100644 --- a/nano/core_test/election.cpp +++ b/nano/core_test/election.cpp @@ -12,7 +12,9 @@ TEST (election, construction) nano::genesis genesis; auto & node = *system.nodes[0]; genesis.open->sideband_set (nano::block_sideband (nano::genesis_account, 0, nano::genesis_amount, 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false, false, false, nano::epoch::epoch_0)); - auto election = node.active.insert (genesis.open).election; + node.block_confirm (genesis.open); + node.scheduler.flush (); + auto election = node.active.election (genesis.open->qualified_root ()); election->transition_active (); } @@ -47,17 +49,19 @@ TEST (election, quorum_minimum_flip_success) .build_shared (); node1.work_generate_blocking (*send2); node1.process_active (send1); + node1.block_processor.flush (); + node1.scheduler.flush (); node1.process_active (send2); node1.block_processor.flush (); - auto election{ node1.active.insert (send1) }; - ASSERT_FALSE (election.inserted); - ASSERT_NE (nullptr, election.election); - ASSERT_EQ (2, election.election->blocks ().size ()); + node1.scheduler.flush (); + auto election = node1.active.election (send1->qualified_root ()); + ASSERT_NE (nullptr, election); + ASSERT_EQ (2, election->blocks ().size ()); auto vote1 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, std::numeric_limits::max (), send2)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1)); node1.block_processor.flush (); ASSERT_NE (nullptr, node1.block (send2->hash ())); - ASSERT_TRUE (election.election->confirmed ()); + ASSERT_TRUE (election->confirmed ()); } TEST (election, quorum_minimum_flip_fail) @@ -91,17 +95,19 @@ TEST (election, quorum_minimum_flip_fail) .build_shared (); node1.work_generate_blocking (*send2); node1.process_active (send1); + node1.block_processor.flush (); + node1.scheduler.flush (); node1.process_active (send2); node1.block_processor.flush (); - auto election{ node1.active.insert (send1) }; - ASSERT_FALSE (election.inserted); - ASSERT_NE (nullptr, election.election); - ASSERT_EQ (2, election.election->blocks ().size ()); + node1.scheduler.flush (); + auto election = node1.active.election (send1->qualified_root ()); + ASSERT_NE (nullptr, election); + ASSERT_EQ (2, election->blocks ().size ()); auto vote1 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, std::numeric_limits::max (), send2)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1)); node1.block_processor.flush (); ASSERT_NE (nullptr, node1.block (send1->hash ())); - ASSERT_FALSE (election.election->confirmed ()); + ASSERT_FALSE (election->confirmed ()); } TEST (election, quorum_minimum_confirm_success) @@ -125,15 +131,15 @@ TEST (election, quorum_minimum_confirm_success) node1.work_generate_blocking (*send1); node1.process_active (send1); node1.block_processor.flush (); - auto election{ node1.active.insert (send1) }; - ASSERT_FALSE (election.inserted); - ASSERT_NE (nullptr, election.election); - ASSERT_EQ (1, election.election->blocks ().size ()); + node1.scheduler.activate (nano::dev_genesis_key.pub, node1.store.tx_begin_read ()); + auto election = node1.active.election (send1->qualified_root ()); + ASSERT_NE (nullptr, election); + ASSERT_EQ (1, election->blocks ().size ()); auto vote1 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, std::numeric_limits::max (), send1)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1)); node1.block_processor.flush (); ASSERT_NE (nullptr, node1.block (send1->hash ())); - ASSERT_TRUE (election.election->confirmed ()); + ASSERT_TRUE (election->confirmed ()); } TEST (election, quorum_minimum_confirm_fail) @@ -157,15 +163,15 @@ TEST (election, quorum_minimum_confirm_fail) node1.work_generate_blocking (*send1); node1.process_active (send1); node1.block_processor.flush (); - auto election{ node1.active.insert (send1) }; - ASSERT_FALSE (election.inserted); - ASSERT_NE (nullptr, election.election); - ASSERT_EQ (1, election.election->blocks ().size ()); + node1.scheduler.activate (nano::dev_genesis_key.pub, node1.store.tx_begin_read ()); + auto election = node1.active.election (send1->qualified_root ()); + ASSERT_NE (nullptr, election); + ASSERT_EQ (1, election->blocks ().size ()); auto vote1 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, std::numeric_limits::max (), send1)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1)); node1.block_processor.flush (); ASSERT_NE (nullptr, node1.block (send1->hash ())); - ASSERT_FALSE (election.election->confirmed ()); + ASSERT_FALSE (election->confirmed ()); } namespace nano @@ -227,17 +233,17 @@ TEST (election, quorum_minimum_update_weight_before_quorum_checks) node2.block_processor.flush (); ASSERT_EQ (node2.ledger.cache.block_count, 4); - auto election{ node1.active.insert (send1) }; - ASSERT_FALSE (election.inserted); - ASSERT_NE (nullptr, election.election); - ASSERT_EQ (1, election.election->blocks ().size ()); + node1.scheduler.activate (nano::dev_genesis_key.pub, node1.store.tx_begin_read ()); + auto election = node1.active.election (send1->qualified_root ()); + ASSERT_NE (nullptr, election); + ASSERT_EQ (1, election->blocks ().size ()); auto vote1 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, std::numeric_limits::max (), send1)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1)); auto vote2 (std::make_shared (key1.pub, key1.prv, std::numeric_limits::max (), send1)); auto channel = node1.network.find_channel (node2.network.endpoint ()); ASSERT_NE (channel, nullptr); ASSERT_TIMELY (10s, !node1.rep_crawler.response (channel, vote2)); - ASSERT_FALSE (election.election->confirmed ()); + ASSERT_FALSE (election->confirmed ()); { nano::lock_guard 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. @@ -246,6 +252,6 @@ TEST (election, quorum_minimum_update_weight_before_quorum_checks) ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote2)); node1.block_processor.flush (); ASSERT_NE (nullptr, node1.block (send1->hash ())); - ASSERT_TRUE (election.election->confirmed ()); + ASSERT_TRUE (election->confirmed ()); } } diff --git a/nano/core_test/election_scheduler.cpp b/nano/core_test/election_scheduler.cpp new file mode 100644 index 0000000000..08dc077c6a --- /dev/null +++ b/nano/core_test/election_scheduler.cpp @@ -0,0 +1,126 @@ +#include +#include +#include + +#include + +#include + +using namespace std::chrono_literals; + +TEST (election_scheduler, construction) +{ + nano::system system{ 1 }; +} + +TEST (election_scheduler, activate_one_timely) +{ + nano::system system{ 1 }; + nano::state_block_builder builder; + auto send1 = builder.make_block () + .account (nano::dev_genesis_key.pub) + .previous (nano::genesis_hash) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - nano::Gxrb_ratio) + .link (nano::dev_genesis_key.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (nano::genesis_hash)) + .build_shared (); + system.nodes[0]->ledger.process (system.nodes[0]->store.tx_begin_write (), *send1); + system.nodes[0]->scheduler.activate (nano::dev_genesis_key.pub, system.nodes[0]->store.tx_begin_read ()); + ASSERT_TIMELY (1s, system.nodes[0]->active.election (send1->qualified_root ())); +} + +TEST (election_scheduler, activate_one_flush) +{ + nano::system system{ 1 }; + nano::state_block_builder builder; + auto send1 = builder.make_block () + .account (nano::dev_genesis_key.pub) + .previous (nano::genesis_hash) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - nano::Gxrb_ratio) + .link (nano::dev_genesis_key.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (nano::genesis_hash)) + .build_shared (); + system.nodes[0]->ledger.process (system.nodes[0]->store.tx_begin_write (), *send1); + system.nodes[0]->scheduler.activate (nano::dev_genesis_key.pub, system.nodes[0]->store.tx_begin_read ()); + system.nodes[0]->scheduler.flush (); + ASSERT_NE (nullptr, system.nodes[0]->active.election (send1->qualified_root ())); +} + +TEST (election_scheduler, no_vacancy) +{ + nano::system system; + nano::node_config config{ nano::get_available_port (), system.logging }; + config.active_elections_size = 1; + auto & node = *system.add_node (config); + ; + nano::state_block_builder builder; + nano::keypair key; + + // Activating accounts depends on confirmed dependencies. First, prepare 2 accounts + auto send = builder.make_block () + .account (nano::dev_genesis_key.pub) + .previous (nano::genesis_hash) + .representative (nano::dev_genesis_key.pub) + .link (key.pub) + .balance (nano::genesis_amount - nano::Gxrb_ratio) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (nano::genesis_hash)) + .build_shared (); + auto receive = builder.make_block () + .account (key.pub) + .previous (0) + .representative (key.pub) + .link (send->hash ()) + .balance (nano::Gxrb_ratio) + .sign (key.prv, key.pub) + .work (*system.work.generate (key.pub)) + .build_shared (); + ASSERT_EQ (nano::process_result::progress, node.process (*send).code); + ASSERT_EQ (nano::process_result::progress, node.process (*receive).code); + node.block_confirm (send); + auto election1 = node.active.election (send->qualified_root ()); + election1->force_confirm (); + node.block_confirm (receive); + auto election2 = node.active.election (receive->qualified_root ()); + election2->force_confirm (); + + // Second, process two eligble transactions + auto block0 = builder.make_block () + .account (nano::dev_genesis_key.pub) + .previous (send->hash ()) + .representative (nano::dev_genesis_key.pub) + .link (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - 2 * nano::Gxrb_ratio) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (send->hash ())) + .build_shared (); + auto block1 = builder.make_block () + .account (key.pub) + .previous (receive->hash ()) + .representative (key.pub) + .link (key.pub) + .balance (0) + .sign (key.prv, key.pub) + .work (*system.work.generate (receive->hash ())) + .build_shared (); + ASSERT_EQ (nano::process_result::progress, node.process (*block0).code); + ASSERT_EQ (nano::process_result::progress, node.process (*block1).code); + node.scheduler.activate (nano::dev_genesis_key.pub, node.store.tx_begin_read ()); + // There is vacancy so it should be inserted + ASSERT_TIMELY (1s, node.active.size () == 1); + node.scheduler.activate (key.pub, node.store.tx_begin_read ()); + // There is no vacancy so it should stay queued + ASSERT_TIMELY (1s, node.scheduler.size () == 1); + auto election3 = node.active.election (block0->qualified_root ()); + ASSERT_NE (nullptr, election3); + election3->force_confirm (); + // Election completed, next in queue should begin + ASSERT_TIMELY (1s, node.scheduler.size () == 0); + ASSERT_TIMELY (1s, node.active.size () == 1); + auto election4 = node.active.election (block1->qualified_root ()); + ASSERT_NE (nullptr, election4); +} diff --git a/nano/core_test/ledger.cpp b/nano/core_test/ledger.cpp index 3c2641cbd5..187f1d1993 100644 --- a/nano/core_test/ledger.cpp +++ b/nano/core_test/ledger.cpp @@ -767,8 +767,10 @@ TEST (votes, check_signature) auto transaction (node1.store.tx_begin_write ()); ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code); } - auto election1 = node1.active.insert (send1); - ASSERT_EQ (1, election1.election->votes ().size ()); + node1.scheduler.activate (nano::dev_genesis_key.pub, node1.store.tx_begin_read ()); + node1.scheduler.flush (); + auto election1 = node1.active.election (send1->qualified_root ()); + ASSERT_EQ (1, election1->votes ().size ()); auto vote1 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 1, send1)); vote1->signature.bytes[0] ^= 1; ASSERT_EQ (nano::vote_code::invalid, node1.vote_processor.vote_blocking (vote1, std::make_shared (node1))); @@ -787,47 +789,51 @@ TEST (votes, add_one) node1.work_generate_blocking (*send1); auto transaction (node1.store.tx_begin_write ()); ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code); - auto election1 = node1.active.insert (send1); - ASSERT_EQ (1, election1.election->votes ().size ()); + node1.block_confirm (send1); + node1.scheduler.flush (); + auto election1 = node1.active.election (send1->qualified_root ()); + ASSERT_EQ (1, election1->votes ().size ()); auto vote1 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 1, send1)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1)); auto vote2 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 2, send1)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote2)); - ASSERT_EQ (2, election1.election->votes ().size ()); - auto votes1 (election1.election->votes ()); + ASSERT_EQ (2, election1->votes ().size ()); + auto votes1 (election1->votes ()); auto existing1 (votes1.find (nano::dev_genesis_key.pub)); ASSERT_NE (votes1.end (), existing1); ASSERT_EQ (send1->hash (), existing1->second.hash); nano::lock_guard guard (node1.active.mutex); - auto winner (*election1.election->tally ().begin ()); + auto winner (*election1->tally ().begin ()); ASSERT_EQ (*send1, *winner.second); ASSERT_EQ (nano::genesis_amount - 100, winner.first); } TEST (votes, add_two) { - nano::system system (1); - auto & node1 (*system.nodes[0]); + nano::system system{ 1 }; + auto & node1 = *system.nodes[0]; nano::genesis genesis; nano::keypair key1; - auto send1 (std::make_shared (genesis.hash (), key1.pub, nano::genesis_amount - 100, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); + auto send1 = std::make_shared (genesis.hash (), key1.pub, nano::genesis_amount - 100, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0); node1.work_generate_blocking (*send1); - auto transaction (node1.store.tx_begin_write ()); + auto transaction = node1.store.tx_begin_write (); ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code); - auto election1 = node1.active.insert (send1); + node1.block_confirm (send1); + node1.scheduler.flush (); + auto election1 = node1.active.election (send1->qualified_root ()); nano::keypair key2; - auto send2 (std::make_shared (genesis.hash (), key2.pub, 0, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); - auto vote2 (std::make_shared (key2.pub, key2.prv, 1, send2)); + auto send2 = std::make_shared (genesis.hash (), key2.pub, 0, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0); + auto vote2 = std::make_shared (key2.pub, key2.prv, 1, send2); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote2)); - auto vote1 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 1, send1)); + auto vote1 = std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 1, send1); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1)); - ASSERT_EQ (3, election1.election->votes ().size ()); - auto votes1 (election1.election->votes ()); + ASSERT_EQ (3, election1->votes ().size ()); + auto votes1 = election1->votes (); ASSERT_NE (votes1.end (), votes1.find (nano::dev_genesis_key.pub)); ASSERT_EQ (send1->hash (), votes1[nano::dev_genesis_key.pub].hash); ASSERT_NE (votes1.end (), votes1.find (key2.pub)); ASSERT_EQ (send2->hash (), votes1[key2.pub].hash); - ASSERT_EQ (*send1, *election1.election->winner ()); + ASSERT_EQ (*send1, *election1->winner ()); } namespace nano @@ -853,12 +859,14 @@ TEST (votes, add_existing) .build (); node1.work_generate_blocking (*send1); ASSERT_EQ (nano::process_result::progress, node1.ledger.process (node1.store.tx_begin_write (), *send1).code); - auto election1 = node1.active.insert (send1); + node1.scheduler.activate (nano::dev_genesis_key.pub, node1.store.tx_begin_read ()); + node1.scheduler.flush (); + auto election1 = node1.active.election (send1->qualified_root ()); auto vote1 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 1, send1)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1)); // Block is already processed from vote ASSERT_TRUE (node1.active.publish (send1)); - ASSERT_EQ (1, election1.election->last_votes[nano::dev_genesis_key.pub].timestamp); + ASSERT_EQ (1, election1->last_votes[nano::dev_genesis_key.pub].timestamp); nano::keypair key2; std::shared_ptr send2 = builder.state () .account (nano::dev_genesis_key.pub) @@ -872,23 +880,23 @@ TEST (votes, add_existing) node1.work_generate_blocking (*send2); auto vote2 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 2, send2)); // Pretend we've waited the timeout - nano::unique_lock lock (election1.election->mutex); - election1.election->last_votes[nano::dev_genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20); + nano::unique_lock lock (election1->mutex); + election1->last_votes[nano::dev_genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20); lock.unlock (); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote2)); ASSERT_FALSE (node1.active.publish (send2)); - ASSERT_EQ (2, election1.election->last_votes[nano::dev_genesis_key.pub].timestamp); + ASSERT_EQ (2, election1->last_votes[nano::dev_genesis_key.pub].timestamp); // Also resend the old vote, and see if we respect the timestamp lock.lock (); - election1.election->last_votes[nano::dev_genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20); + election1->last_votes[nano::dev_genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20); lock.unlock (); ASSERT_EQ (nano::vote_code::replay, node1.active.vote (vote1)); - ASSERT_EQ (2, election1.election->votes ()[nano::dev_genesis_key.pub].timestamp); - auto votes (election1.election->votes ()); + ASSERT_EQ (2, election1->votes ()[nano::dev_genesis_key.pub].timestamp); + auto votes (election1->votes ()); ASSERT_EQ (2, votes.size ()); ASSERT_NE (votes.end (), votes.find (nano::dev_genesis_key.pub)); ASSERT_EQ (send2->hash (), votes[nano::dev_genesis_key.pub].hash); - ASSERT_EQ (*send2, *election1.election->tally ().begin ()->second); + ASSERT_EQ (*send2, *election1->tally ().begin ()->second); } // Lower timestamps are ignored @@ -902,7 +910,9 @@ TEST (votes, add_old) node1.work_generate_blocking (*send1); auto transaction (node1.store.tx_begin_write ()); ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code); - auto election1 = node1.active.insert (send1); + node1.block_confirm (send1); + node1.scheduler.flush (); + auto election1 = node1.active.election (send1->qualified_root ()); auto vote1 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 2, send1)); auto channel (std::make_shared (node1)); node1.vote_processor.vote_blocking (vote1, channel); @@ -911,15 +921,15 @@ TEST (votes, add_old) node1.work_generate_blocking (*send2); auto vote2 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 1, send2)); { - nano::lock_guard lock (election1.election->mutex); - election1.election->last_votes[nano::dev_genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20); + nano::lock_guard lock (election1->mutex); + election1->last_votes[nano::dev_genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20); } node1.vote_processor.vote_blocking (vote2, channel); - ASSERT_EQ (2, election1.election->votes ().size ()); - auto votes (election1.election->votes ()); + ASSERT_EQ (2, election1->votes ().size ()); + auto votes (election1->votes ()); ASSERT_NE (votes.end (), votes.find (nano::dev_genesis_key.pub)); ASSERT_EQ (send1->hash (), votes[nano::dev_genesis_key.pub].hash); - ASSERT_EQ (*send1, *election1.election->winner ()); + ASSERT_EQ (*send1, *election1->winner ()); } } @@ -975,7 +985,9 @@ TEST (votes, add_cooldown) node1.work_generate_blocking (*send1); auto transaction (node1.store.tx_begin_write ()); ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code); - auto election1 = node1.active.insert (send1); + node1.block_confirm (send1); + node1.scheduler.flush (); + auto election1 = node1.active.election (send1->qualified_root ()); auto vote1 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 1, send1)); auto channel (std::make_shared (node1)); node1.vote_processor.vote_blocking (vote1, channel); @@ -984,11 +996,11 @@ TEST (votes, add_cooldown) node1.work_generate_blocking (*send2); auto vote2 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 2, send2)); node1.vote_processor.vote_blocking (vote2, channel); - ASSERT_EQ (2, election1.election->votes ().size ()); - auto votes (election1.election->votes ()); + ASSERT_EQ (2, election1->votes ().size ()); + auto votes (election1->votes ()); ASSERT_NE (votes.end (), votes.find (nano::dev_genesis_key.pub)); ASSERT_EQ (send1->hash (), votes[nano::dev_genesis_key.pub].hash); - ASSERT_EQ (*send1, *election1.election->winner ()); + ASSERT_EQ (*send1, *election1->winner ()); } // Query for block successor diff --git a/nano/core_test/network.cpp b/nano/core_test/network.cpp index c03515637c..2226dbc7a9 100644 --- a/nano/core_test/network.cpp +++ b/nano/core_test/network.cpp @@ -332,7 +332,7 @@ TEST (receivable_processor, confirm_insufficient_pos) auto block1 (std::make_shared (genesis.hash (), 0, 0, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); node1.work_generate_blocking (*block1); ASSERT_EQ (nano::process_result::progress, node1.process (*block1).code); - node1.active.insert (block1); + node1.scheduler.activate (nano::dev_genesis_key.pub, node1.store.tx_begin_read ()); nano::keypair key1; auto vote (std::make_shared (key1.pub, key1.prv, 0, block1)); nano::confirm_ack con1 (vote); @@ -347,7 +347,7 @@ TEST (receivable_processor, confirm_sufficient_pos) auto block1 (std::make_shared (genesis.hash (), 0, 0, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); node1.work_generate_blocking (*block1); ASSERT_EQ (nano::process_result::progress, node1.process (*block1).code); - node1.active.insert (block1); + node1.scheduler.activate (nano::dev_genesis_key.pub, node1.store.tx_begin_read ()); auto vote (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 0, block1)); nano::confirm_ack con1 (vote); node1.network.process_message (con1, node1.network.udp_channels.create (node1.network.endpoint ())); diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index b74182eaaa..c11f570972 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -1079,6 +1079,7 @@ TEST (node, fork_publish) node1.work_generate_blocking (*send2); node1.process_active (send1); node1.block_processor.flush (); + node1.scheduler.flush (); ASSERT_EQ (1, node1.active.size ()); auto election (node1.active.election (send1->qualified_root ())); ASSERT_NE (nullptr, election); @@ -1159,8 +1160,10 @@ TEST (node, fork_keep) .build_shared (); node1.process_active (send1); node1.block_processor.flush (); + node1.scheduler.flush (); node2.process_active (send1); node2.block_processor.flush (); + node2.scheduler.flush (); ASSERT_EQ (1, node1.active.size ()); ASSERT_EQ (1, node2.active.size ()); system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv); @@ -1214,9 +1217,11 @@ TEST (node, fork_flip) auto channel1 (node1.network.udp_channels.create (node1.network.endpoint ())); node1.network.process_message (publish1, channel1); node1.block_processor.flush (); + node1.scheduler.flush (); auto channel2 (node2.network.udp_channels.create (node1.network.endpoint ())); node2.network.process_message (publish2, channel2); node2.block_processor.flush (); + node2.scheduler.flush (); ASSERT_EQ (1, node1.active.size ()); ASSERT_EQ (1, node2.active.size ()); system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv); @@ -1289,7 +1294,9 @@ TEST (node, fork_multi_flip) node2.network.process_message (publish2, node2.network.udp_channels.create (node2.network.endpoint ())); node2.network.process_message (publish3, node2.network.udp_channels.create (node2.network.endpoint ())); node1.block_processor.flush (); + node1.scheduler.flush (); node2.block_processor.flush (); + node2.scheduler.flush (); ASSERT_EQ (1, node1.active.size ()); ASSERT_EQ (1, node2.active.size ()); system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv); @@ -1380,6 +1387,7 @@ TEST (node, fork_open) auto channel1 (node1.network.udp_channels.create (node1.network.endpoint ())); node1.network.process_message (publish1, channel1); node1.block_processor.flush (); + node1.scheduler.flush (); auto election = node1.active.election (publish1.block->qualified_root ()); ASSERT_NE (nullptr, election); election->force_confirm (); @@ -1395,6 +1403,7 @@ TEST (node, fork_open) nano::publish publish2 (open1); node1.network.process_message (publish2, channel1); node1.block_processor.flush (); + node1.scheduler.flush (); ASSERT_EQ (1, node1.active.size ()); auto open2 = builder.make_block () .source (publish1.block->hash ()) @@ -1407,6 +1416,7 @@ TEST (node, fork_open) system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv); node1.network.process_message (publish3, channel1); node1.block_processor.flush (); + node1.scheduler.flush (); election = node1.active.election (publish3.block->qualified_root ()); ASSERT_EQ (2, election->blocks ().size ()); ASSERT_EQ (publish2.block->hash (), election->winner ()->hash ()); @@ -1866,11 +1876,15 @@ TEST (node, rep_self_vote) .work (*system.work.generate (fund_big.hash ())) .build_shared (); ASSERT_EQ (nano::process_result::progress, node0->process (*block0).code); - auto & active (node0->active); - auto election1 = active.insert (block0); + auto & active = node0->active; + auto & scheduler = node0->scheduler; + scheduler.activate (nano::dev_genesis_key.pub, node0->store.tx_begin_read ()); + scheduler.flush (); + auto election1 = active.election (block0->qualified_root ()); + ASSERT_NE (nullptr, election1); // Wait until representatives are activated & make vote - ASSERT_TIMELY (1s, election1.election->votes ().size () == 3); - auto rep_votes (election1.election->votes ()); + ASSERT_TIMELY (1s, election1->votes ().size () == 3); + auto rep_votes (election1->votes ()); ASSERT_NE (rep_votes.end (), rep_votes.find (nano::dev_genesis_key.pub)); ASSERT_NE (rep_votes.end (), rep_votes.find (rep_big.pub)); } @@ -1953,7 +1967,6 @@ TEST (node, bootstrap_fork_open) auto node0 = system.add_node (node_config); node_config.peering_port = nano::get_available_port (); auto node1 = system.add_node (node_config); - system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv); nano::keypair key0; nano::block_builder builder; auto send0 = *builder.send () @@ -1984,6 +1997,7 @@ TEST (node, bootstrap_fork_open) for (auto node : system.nodes) { node->block_confirm (node->block (node->latest (nano::dev_genesis_key.pub))); + ASSERT_TIMELY (1s, node->active.election (send0.qualified_root ())); auto election = node->active.election (send0.qualified_root ()); ASSERT_NE (nullptr, election); election->force_confirm (); @@ -1993,10 +2007,11 @@ TEST (node, bootstrap_fork_open) // They disagree about open0/open1 ASSERT_EQ (nano::process_result::progress, node0->process (open0).code); ASSERT_EQ (nano::process_result::progress, node1->process (open1).code); + system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv); ASSERT_FALSE (node1->ledger.block_exists (open0.hash ())); ASSERT_FALSE (node1->bootstrap_initiator.in_progress ()); node1->bootstrap_initiator.bootstrap (node0->network.endpoint (), false); - ASSERT_TRUE (node1->active.empty ()); + ASSERT_TIMELY (1s, node1->active.empty ()); ASSERT_TIMELY (10s, !node1->ledger.block_exists (open1.hash ()) && node1->ledger.block_exists (open0.hash ())); } @@ -2525,6 +2540,7 @@ TEST (node, online_reps_election) .build_shared (); node1.process_active (send1); node1.block_processor.flush (); + node1.scheduler.flush (); ASSERT_EQ (1, node1.active.size ()); // Process vote for ongoing election auto vote = std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, nano::milliseconds_since_epoch (), std::vector{ send1->hash () }); @@ -2551,6 +2567,7 @@ TEST (node, block_confirm) nano::genesis genesis; nano::keypair key; nano::state_block_builder builder; + system.wallet (1)->insert_adhoc (nano::dev_genesis_key.prv); auto send1 = builder.make_block () .account (nano::dev_genesis_key.pub) .previous (genesis.hash ()) @@ -2573,21 +2590,7 @@ TEST (node, block_confirm) node2.block_confirm (send1_copy); auto election = node2.active.election (send1_copy->qualified_root ()); ASSERT_NE (nullptr, election); - election->force_confirm (); - ASSERT_TIMELY (3s, node2.block_confirmed (send1_copy->hash ()) && node2.active.empty ()); - system.wallet (1)->insert_adhoc (nano::dev_genesis_key.prv); - auto send2 (std::make_shared (nano::dev_genesis_key.pub, send1->hash (), nano::dev_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio * 2, key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node1.work_generate_blocking (send1->hash ()))); - { - auto transaction (node1.store.tx_begin_write ()); - ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send2).code); - } - { - auto transaction (node2.store.tx_begin_write ()); - ASSERT_EQ (nano::process_result::progress, node2.ledger.process (transaction, *send2).code); - } - ASSERT_TRUE (node1.active.list_recently_cemented ().empty ()); - node1.block_confirm (send2); - ASSERT_TIMELY (10s, node1.active.list_recently_cemented ().size () == 2); + ASSERT_TIMELY (10s, node1.active.list_recently_cemented ().size () == 1); } } @@ -2641,11 +2644,11 @@ TEST (node, block_arrival_time) TEST (node, confirm_quorum) { nano::system system (1); - auto & node1 (*system.nodes[0]); + auto & node1 = *system.nodes[0]; nano::genesis genesis; system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv); // Put greater than node.delta () in pending so quorum can't be reached - nano::amount new_balance (node1.online_reps.delta () - nano::Gxrb_ratio); + nano::amount new_balance = node1.online_reps.delta () - nano::Gxrb_ratio; auto send1 = nano::state_block_builder () .account (nano::dev_genesis_key.pub) .previous (genesis.hash ()) @@ -2657,8 +2660,8 @@ 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 (10s, !node1.active.empty ()); - auto election (node1.active.election (nano::qualified_root (send1->hash (), send1->hash ()))); + ASSERT_TIMELY (1s, node1.active.election (send1->qualified_root ())); + auto election = node1.active.election (send1->qualified_root ()); ASSERT_NE (nullptr, election); ASSERT_FALSE (election->confirmed ()); ASSERT_EQ (1, election->votes ().size ()); @@ -2982,10 +2985,10 @@ TEST (node, vote_by_hash_bundle) blocks.push_back (block); ASSERT_EQ (nano::process_result::progress, node.ledger.process (node.store.tx_begin_write (), *blocks.back ()).code); } - auto election_insertion_result = node.active.insert (blocks.back ()); - ASSERT_TRUE (election_insertion_result.inserted); - ASSERT_NE (nullptr, election_insertion_result.election); - election_insertion_result.election->force_confirm (); + node.block_confirm (blocks.back ()); + auto election = node.active.election (blocks.back ()->qualified_root ()); + ASSERT_NE (nullptr, election); + election->force_confirm (); system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv); nano::keypair key1; system.wallet (0)->insert_adhoc (key1.prv); @@ -4032,8 +4035,11 @@ TEST (node, rollback_vote_self) ASSERT_TIMELY (5s, node.ledger.cache.cemented_count == 3); ASSERT_EQ (weight, node.weight (key.pub)); node.process_active (send2); + node.block_processor.flush (); + node.scheduler.flush (); node.process_active (fork); node.block_processor.flush (); + node.scheduler.flush (); election = node.active.election (send2->qualified_root ()); ASSERT_NE (nullptr, election); ASSERT_EQ (2, election->blocks ().size ()); @@ -4487,6 +4493,7 @@ TEST (node, deferred_dependent_elections) .build_shared (); node.process_local (send1); node.block_processor.flush (); + node.scheduler.flush (); auto election_send1 = node.active.election (send1->qualified_root ()); ASSERT_NE (nullptr, election_send1); @@ -4645,6 +4652,7 @@ TEST (node, pruning_automatic) node1.process_active (send1); node1.process_active (send2); node1.block_processor.flush (); + node1.scheduler.flush (); // Confirm last block to prune previous { auto election = node1.active.election (send1->qualified_root ()); @@ -4698,6 +4706,7 @@ TEST (node, pruning_age) node1.process_active (send1); node1.process_active (send2); node1.block_processor.flush (); + node1.scheduler.flush (); // Confirm last block to prune previous { auto election = node1.active.election (send1->qualified_root ()); @@ -4730,7 +4739,7 @@ TEST (node, pruning_age) TEST (node, pruning_depth) { nano::system system; - nano::node_config node_config (nano::get_available_port (), system.logging); + nano::node_config node_config{ nano::get_available_port (), system.logging }; node_config.enable_voting = false; // Remove after allowing pruned voting nano::node_flags node_flags; node_flags.enable_pruning = true; @@ -4755,19 +4764,16 @@ TEST (node, pruning_depth) node1.process_active (send1); node1.process_active (send2); node1.block_processor.flush (); + node1.scheduler.flush (); // Confirm last block to prune previous - { - auto election = node1.active.election (send1->qualified_root ()); - ASSERT_NE (nullptr, election); - election->force_confirm (); - } + auto election1 = node1.active.election (send1->qualified_root ()); + ASSERT_NE (nullptr, election1); + election1->force_confirm (); ASSERT_TIMELY (2s, node1.block_confirmed (send1->hash ()) && node1.active.active (send2->qualified_root ())); ASSERT_EQ (0, node1.ledger.cache.pruned_count); - { - auto election = node1.active.election (send2->qualified_root ()); - ASSERT_NE (nullptr, election); - election->force_confirm (); - } + auto election2 = node1.active.election (send2->qualified_root ()); + ASSERT_NE (nullptr, election2); + election2->force_confirm (); ASSERT_TIMELY (2s, node1.active.empty () && node1.block_confirmed (send2->hash ())); // Pruning with default depth (unlimited) node1.ledger_pruning (1, true, false); diff --git a/nano/core_test/vote_processor.cpp b/nano/core_test/vote_processor.cpp index 8fe35965f2..4fce89606a 100644 --- a/nano/core_test/vote_processor.cpp +++ b/nano/core_test/vote_processor.cpp @@ -29,7 +29,8 @@ TEST (vote_processor, codes) // First vote from an account for an ongoing election genesis.open->sideband_set (nano::block_sideband (nano::genesis_account, 0, nano::genesis_amount, 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false, false, false, nano::epoch::epoch_0)); - ASSERT_TRUE (node.active.insert (genesis.open).inserted); + node.block_confirm (genesis.open); + ASSERT_NE (nullptr, node.active.election (genesis.open->qualified_root ())); ASSERT_EQ (nano::vote_code::vote, node.vote_processor.vote_blocking (vote, channel)); // Processing the same vote is a replay @@ -68,25 +69,26 @@ TEST (vote_processor, flush) TEST (vote_processor, invalid_signature) { - nano::system system (1); - auto & node (*system.nodes[0]); + nano::system system{ 1 }; + auto & node = *system.nodes[0]; nano::genesis genesis; nano::keypair key; - auto vote (std::make_shared (key.pub, key.prv, 1, std::vector{ genesis.open->hash () })); + auto vote = std::make_shared (key.pub, key.prv, 1, std::vector{ genesis.open->hash () }); auto vote_invalid = std::make_shared (*vote); vote_invalid->signature.bytes[0] ^= 1; - auto channel (std::make_shared (node)); + auto channel = std::make_shared (node); genesis.open->sideband_set (nano::block_sideband (nano::genesis_account, 0, nano::genesis_amount, 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false, false, false, nano::epoch::epoch_0)); - auto election (node.active.insert (genesis.open)); - ASSERT_TRUE (election.election && election.inserted); - ASSERT_EQ (1, election.election->votes ().size ()); + node.block_confirm (genesis.open); + auto election = node.active.election (genesis.open->qualified_root ()); + ASSERT_TRUE (election); + ASSERT_EQ (1, election->votes ().size ()); node.vote_processor.vote (vote_invalid, channel); node.vote_processor.flush (); - ASSERT_EQ (1, election.election->votes ().size ()); + ASSERT_EQ (1, election->votes ().size ()); node.vote_processor.vote (vote, channel); node.vote_processor.flush (); - ASSERT_EQ (2, election.election->votes ().size ()); + ASSERT_EQ (2, election->votes ().size ()); } TEST (vote_processor, no_capacity) diff --git a/nano/core_test/wallet.cpp b/nano/core_test/wallet.cpp index 65ea109fce..545da24802 100644 --- a/nano/core_test/wallet.cpp +++ b/nano/core_test/wallet.cpp @@ -1244,14 +1244,14 @@ TEST (wallet, receive_pruned) nano::system system; nano::node_flags node_flags; node_flags.disable_request_loop = true; - auto & node1 (*system.add_node (node_flags)); + auto & node1 = *system.add_node (node_flags); node_flags.enable_pruning = true; nano::node_config config (nano::get_available_port (), system.logging); config.enable_voting = false; // Remove after allowing pruned voting - auto & node2 (*system.add_node (config, node_flags)); + auto & node2 = *system.add_node (config, node_flags); - auto & wallet1 (*system.wallet (0)); - auto & wallet2 (*system.wallet (1)); + auto & wallet1 = *system.wallet (0); + auto & wallet2 = *system.wallet (1); nano::keypair key; nano::state_block_builder builder; @@ -1265,7 +1265,7 @@ TEST (wallet, receive_pruned) // Pruning ASSERT_TIMELY (5s, node2.ledger.cache.cemented_count == 3); { - auto transaction (node2.store.tx_begin_write ()); + auto transaction = node2.store.tx_begin_write (); ASSERT_EQ (1, node2.ledger.pruning_action (transaction, send1->hash (), 2)); } ASSERT_EQ (1, node2.ledger.cache.pruned_count); diff --git a/nano/core_test/websocket.cpp b/nano/core_test/websocket.cpp index 9a15dc97dc..be1fef9e84 100644 --- a/nano/core_test/websocket.cpp +++ b/nano/core_test/websocket.cpp @@ -206,6 +206,7 @@ TEST (websocket, stopped_election) auto channel1 (node1->network.udp_channels.create (node1->network.endpoint ())); node1->network.process_message (publish1, channel1); node1->block_processor.flush (); + ASSERT_TIMELY (1s, node1->active.election (send1->qualified_root ())); node1->active.erase (*send1); ASSERT_TIMELY (5s, future.wait_for (0s) == std::future_status::ready); diff --git a/nano/core_test/work_watcher.cpp b/nano/core_test/work_watcher.cpp index 37e79df87b..3b3e815b0d 100644 --- a/nano/core_test/work_watcher.cpp +++ b/nano/core_test/work_watcher.cpp @@ -5,7 +5,7 @@ using namespace std::chrono_literals; -TEST (work_watcher, update) +TEST (work_watcher, DISABLED_update) { nano::system system; nano::node_config node_config (nano::get_available_port (), system.logging); @@ -15,15 +15,17 @@ TEST (work_watcher, update) 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)); + auto & wallet = *system.wallet (0); wallet.insert_adhoc (nano::dev_genesis_key.prv); nano::keypair key; - auto const block1 (wallet.send_action (nano::dev_genesis_key.pub, key.pub, 100)); - auto difficulty1 (block1->difficulty ()); - auto multiplier1 (nano::normalized_multiplier (nano::difficulty::to_multiplier (difficulty1, nano::work_threshold (block1->work_version (), nano::block_details (nano::epoch::epoch_0, true, false, false))), node.network_params.network.publish_thresholds.epoch_1)); - auto const block2 (wallet.send_action (nano::dev_genesis_key.pub, key.pub, 200)); - auto difficulty2 (block2->difficulty ()); - auto multiplier2 (nano::normalized_multiplier (nano::difficulty::to_multiplier (difficulty2, nano::work_threshold (block2->work_version (), nano::block_details (nano::epoch::epoch_0, true, false, false))), node.network_params.network.publish_thresholds.epoch_1)); + auto const block1 = wallet.send_action (nano::dev_genesis_key.pub, key.pub, 100); + auto difficulty1 = block1->difficulty (); + auto multiplier1 = nano::normalized_multiplier (nano::difficulty::to_multiplier (difficulty1, nano::work_threshold (block1->work_version (), nano::block_details (nano::epoch::epoch_0, true, false, false))), node.network_params.network.publish_thresholds.epoch_1); + auto const block2 = wallet.send_action (nano::dev_genesis_key.pub, key.pub, 200); + auto difficulty2 = block2->difficulty (); + auto multiplier2 = nano::normalized_multiplier (nano::difficulty::to_multiplier (difficulty2, nano::work_threshold (block2->work_version (), nano::block_details (nano::epoch::epoch_0, true, false, false))), node.network_params.network.publish_thresholds.epoch_1); + node.block_processor.flush (); + node.scheduler.flush (); double updated_multiplier1{ multiplier1 }, updated_multiplier2{ multiplier2 }, target_multiplier{ std::max (multiplier1, multiplier2) + 1e-6 }; { nano::lock_guard guard (node.active.mutex); @@ -35,13 +37,13 @@ TEST (work_watcher, update) { nano::lock_guard guard (node.active.mutex); { - auto const existing (node.active.roots.find (block1->qualified_root ())); + auto const existing = node.active.roots.find (block1->qualified_root ()); //if existing is junk the block has been confirmed already ASSERT_NE (existing, node.active.roots.end ()); updated_multiplier1 = existing->multiplier; } { - auto const existing (node.active.roots.find (block2->qualified_root ())); + auto const existing = node.active.roots.find (block2->qualified_root ()); //if existing is junk the block has been confirmed already ASSERT_NE (existing, node.active.roots.end ()); updated_multiplier2 = existing->multiplier; diff --git a/nano/node/CMakeLists.txt b/nano/node/CMakeLists.txt index c0dec134b3..dd2d92e12a 100644 --- a/nano/node/CMakeLists.txt +++ b/nano/node/CMakeLists.txt @@ -56,6 +56,8 @@ add_library( distributed_work_factory.cpp election.hpp election.cpp + election_scheduler.hpp + election_scheduler.cpp gap_cache.hpp gap_cache.cpp ipc/action_handler.hpp diff --git a/nano/node/active_transactions.cpp b/nano/node/active_transactions.cpp index 5646cce5f5..fad07ec289 100644 --- a/nano/node/active_transactions.cpp +++ b/nano/node/active_transactions.cpp @@ -19,14 +19,15 @@ size_t constexpr nano::active_transactions::max_active_elections_frontier_insert constexpr std::chrono::minutes nano::active_transactions::expired_optimistic_election_info_cutoff; nano::active_transactions::active_transactions (nano::node & node_a, nano::confirmation_height_processor & confirmation_height_processor_a) : -confirmation_height_processor (confirmation_height_processor_a), -node (node_a), -multipliers_cb (20, 1.), -trended_active_multiplier (1.0), -generator (node_a.config, node_a.ledger, node_a.wallets, node_a.vote_processor, node_a.history, node_a.network, node_a.stats), -check_all_elections_period (node_a.network_params.network.is_dev_network () ? 10ms : 5s), -election_time_to_live (node_a.network_params.network.is_dev_network () ? 0s : 2s), -prioritized_cutoff (std::max (1, node_a.config.active_elections_size / 10)), +scheduler{ node_a.scheduler }, // Move dependencies requiring this circular reference +confirmation_height_processor{ confirmation_height_processor_a }, +node{ node_a }, +multipliers_cb{ 20, 1. }, +trended_active_multiplier{ 1.0 }, +generator{ node_a.config, node_a.ledger, node_a.wallets, node_a.vote_processor, node_a.history, node_a.network, node_a.stats }, +check_all_elections_period{ node_a.network_params.network.is_dev_network () ? 10ms : 5s }, +election_time_to_live{ node_a.network_params.network.is_dev_network () ? 0s : 2s }, +prioritized_cutoff{ std::max (1, node_a.config.active_elections_size / 10) }, thread ([this] () { nano::thread_role::set (nano::thread_role::name::request_loop); request_loop (); @@ -246,13 +247,13 @@ void nano::active_transactions::block_cemented_callback (std::shared_ptr const & block_a, boost::optional const & previous_balance_a, nano::election_behavior election_behavior_a, std::function const &)> const & confirmation_action_a) -{ - nano::unique_lock lock (mutex); - return insert_impl (lock, block_a, previous_balance_a, election_behavior_a, confirmation_action_a); -} - // Validate a vote and apply it to the current election if one exists nano::vote_code nano::active_transactions::vote (std::shared_ptr const & vote_a) { @@ -989,34 +979,6 @@ std::shared_ptr nano::active_transactions::winner (nano::block_hash return result; } -nano::election_insertion_result nano::active_transactions::activate (nano::account const & account_a) -{ - nano::election_insertion_result result; - auto transaction (node.store.tx_begin_read ()); - nano::account_info account_info; - if (!node.store.account_get (transaction, account_a, account_info)) - { - nano::confirmation_height_info conf_info; - node.store.confirmation_height_get (transaction, account_a, conf_info); - if (conf_info.height < account_info.block_count) - { - debug_assert (conf_info.frontier != account_info.head); - auto hash = conf_info.height == 0 ? account_info.open_block : node.store.block_successor (transaction, conf_info.frontier); - auto block = node.store.block_get (transaction, hash); - release_assert (block != nullptr); - if (node.ledger.dependents_confirmed (transaction, *block)) - { - result = insert (block); - if (result.inserted) - { - result.election->transition_active (); - } - } - } - } - return result; -} - bool nano::active_transactions::update_difficulty (std::shared_ptr const & block_a, bool flood_update) { nano::unique_lock lock (mutex); @@ -1072,7 +1034,7 @@ void nano::active_transactions::restart (nano::transaction const & transaction_a auto previous_balance = node.ledger.balance (transaction_a, ledger_block->previous ()); auto block_has_account = ledger_block->type () == nano::block_type::state || ledger_block->type () == nano::block_type::open; auto account = block_has_account ? ledger_block->account () : ledger_block->sideband ().account; - activate (account); + scheduler.activate (account, transaction_a); } } } diff --git a/nano/node/active_transactions.hpp b/nano/node/active_transactions.hpp index 6a0ca47c46..ca3b89b0a3 100644 --- a/nano/node/active_transactions.hpp +++ b/nano/node/active_transactions.hpp @@ -29,6 +29,7 @@ class node; class block; class block_sideband; class election; +class election_scheduler; class vote; class transaction; class confirmation_height_processor; @@ -155,11 +156,6 @@ class active_transactions final explicit active_transactions (nano::node &, nano::confirmation_height_processor &); ~active_transactions (); - // Start an election for a block - // Call action with confirmed block, may be different than what we started with - // clang-format off - nano::election_insertion_result insert (std::shared_ptr const &, boost::optional const & = boost::none, nano::election_behavior = nano::election_behavior::normal, std::function const&)> const & = nullptr); - // clang-format on // Distinguishes replay votes, cannot be determined if the block is not in any election nano::vote_code vote (std::shared_ptr const &); // Is the root of this block in the roots container @@ -167,8 +163,6 @@ class active_transactions final bool active (nano::qualified_root const &); std::shared_ptr election (nano::qualified_root const &) const; std::shared_ptr winner (nano::block_hash const &) const; - // Activates the first unconfirmed block of \p account_a - nano::election_insertion_result activate (nano::account const &); // Returns false if the election difficulty was updated bool update_difficulty (std::shared_ptr const &, bool); // Returns false if the election was restarted @@ -207,6 +201,7 @@ class active_transactions final void trigger_inactive_votes_cache_election (std::shared_ptr const &); nano::inactive_cache_information find_inactive_votes_cache (nano::block_hash const &); void erase_inactive_votes_cache (nano::block_hash const &); + nano::election_scheduler & scheduler; nano::confirmation_height_processor & confirmation_height_processor; nano::node & node; mutable nano::mutex mutex{ mutex_identifier (mutexes::active) }; @@ -333,6 +328,7 @@ class active_transactions final boost::thread thread; friend class election; + friend class election_scheduler; friend std::unique_ptr collect_container_info (active_transactions &, const std::string &); friend class active_transactions_vote_replays_Test; diff --git a/nano/node/blockprocessor.cpp b/nano/node/blockprocessor.cpp index 1a0ca87d19..48cf1f3855 100644 --- a/nano/node/blockprocessor.cpp +++ b/nano/node/blockprocessor.cpp @@ -348,7 +348,8 @@ void nano::block_processor::process_live (nano::transaction const & transaction_ // Start collecting quorum on block if (watch_work_a || node.ledger.dependents_confirmed (transaction_a, *block_a)) { - node.active.insert (block_a, process_return_a.previous_balance.number ()); + auto account = block_a->account ().is_zero () ? block_a->sideband ().account : block_a->account (); + node.scheduler.activate (account, transaction_a); } else { diff --git a/nano/node/election_scheduler.cpp b/nano/node/election_scheduler.cpp new file mode 100644 index 0000000000..342195b285 --- /dev/null +++ b/nano/node/election_scheduler.cpp @@ -0,0 +1,128 @@ +#include +#include + +nano::election_scheduler::election_scheduler (nano::node & node) : +node{ node }, +stopped{ false }, +thread{ [this] () { run (); } } +{ +} + +nano::election_scheduler::~election_scheduler () +{ + stop (); + thread.join (); +} + +void nano::election_scheduler::manual (std::shared_ptr const & block_a, boost::optional const & previous_balance_a, nano::election_behavior election_behavior_a, std::function const &)> const & confirmation_action_a) +{ + std::lock_guard lock{ mutex }; + manual_queue.push_back (std::make_tuple (block_a, previous_balance_a, election_behavior_a, confirmation_action_a)); + observe (); +} + +void nano::election_scheduler::activate (nano::account const & account_a, nano::transaction const & transaction) +{ + debug_assert (!account_a.is_zero ()); + nano::account_info account_info; + if (!node.store.account_get (transaction, account_a, account_info)) + { + nano::confirmation_height_info conf_info; + node.store.confirmation_height_get (transaction, account_a, conf_info); + if (conf_info.height < account_info.block_count) + { + debug_assert (conf_info.frontier != account_info.head); + auto hash = conf_info.height == 0 ? account_info.open_block : node.store.block_successor (transaction, conf_info.frontier); + auto block = node.store.block_get (transaction, hash); + debug_assert (block != nullptr); + if (node.ledger.dependents_confirmed (transaction, *block)) + { + std::lock_guard lock{ mutex }; + priority.push (account_info.modified, block); + observe (); + } + } + } +} + +void nano::election_scheduler::stop () +{ + std::unique_lock lock{ mutex }; + stopped = true; + observe (); +} + +void nano::election_scheduler::flush () +{ + std::unique_lock lock{ mutex }; + auto priority_target = priority_queued + priority.size (); + auto manual_target = manual_queued + manual_queue.size (); + condition.wait (lock, [this, &priority_target, &manual_target] () { + return priority_queued >= priority_target && manual_queued >= manual_target; + }); +} + +void nano::election_scheduler::observe () +{ + condition.notify_all (); +} + +size_t nano::election_scheduler::size () const +{ + std::lock_guard lock{ mutex }; + return priority.size () + manual_queue.size (); +} + +bool nano::election_scheduler::empty () const +{ + std::lock_guard lock{ mutex }; + return priority.empty () && manual_queue.empty (); +} + +size_t nano::election_scheduler::priority_queue_size () const +{ + return priority.size (); +} + +void nano::election_scheduler::run () +{ + std::unique_lock lock{ mutex }; + while (!stopped) + { + condition.wait (lock, [this] () { + auto vacancy = node.active.vacancy (); + auto has_vacancy = vacancy > 0; + auto available = !priority.empty () || !manual_queue.empty (); + return stopped || (has_vacancy && available); + }); + debug_assert ((std::this_thread::yield (), true)); // Introduce some random delay in debug builds + if (!stopped) + { + if (!priority.empty ()) + { + auto block = priority.top (); + lock.unlock (); + manual (block); + lock.lock (); + auto election = node.active.election (block->qualified_root ()); + if (election != nullptr) + { + election->transition_active (); + } + priority.pop (); + ++priority_queued; + } + if (!manual_queue.empty ()) + { + auto const [block, previous_balance, election_behavior, confirmation_action] = manual_queue.front (); + lock.unlock (); + nano::unique_lock lock2 (node.active.mutex); + node.active.insert_impl (lock2, block, previous_balance, election_behavior, confirmation_action); + lock.lock (); + manual_queue.pop_front (); + ++manual_queued; + } + observe (); + } + } +} diff --git a/nano/node/election_scheduler.hpp b/nano/node/election_scheduler.hpp new file mode 100644 index 0000000000..4b9cdd35d8 --- /dev/null +++ b/nano/node/election_scheduler.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include +#include +#include + +#include + +#include +#include +#include +#include + +namespace nano +{ +class block; +class node; +class election_scheduler final +{ +public: + election_scheduler (nano::node & node); + ~election_scheduler (); + // Manualy start an election for a block + // Call action with confirmed block, may be different than what we started with + void manual (std::shared_ptr const &, boost::optional const & = boost::none, nano::election_behavior = nano::election_behavior::normal, std::function const &)> const & = nullptr); + // Activates the first unconfirmed block of \p account_a + void activate (nano::account const &, nano::transaction const &); + void stop (); + void flush (); + void observe (); + size_t size () const; + bool empty () const; + size_t priority_queue_size () const; + +private: + void run (); + nano::prioritization priority; + uint64_t priority_queued{ 0 }; + std::deque, boost::optional, nano::election_behavior, std::function)>>> manual_queue; + uint64_t manual_queued{ 0 }; + nano::node & node; + bool stopped; + std::condition_variable condition; + mutable std::mutex mutex; + std::thread thread; +}; +} diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 9354386a78..45a0ab5f72 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -123,6 +123,7 @@ history{ config.network_params.voting }, vote_uniquer (block_uniquer), confirmation_height_processor (ledger, write_database_queue, config.conf_height_processor_batch_min_time, config.logging, logger, node_initialized_latch, flags.confirmation_height_processor_mode), active (*this, confirmation_height_processor), +scheduler{ *this }, aggregator (network_params.network, config, stats, active.generator, history, ledger, wallets, active), wallets (wallets_store.init_error (), *this), startup_time (std::chrono::steady_clock::now ()), @@ -131,6 +132,8 @@ node_seq (seq) if (!init_error ()) { telemetry->start (); + + active.vacancy_update = [this] () { scheduler.observe (); }; if (config.websocket_config.enabled) { @@ -656,6 +659,12 @@ void nano::node::start () { port_mapping.start (); } + if (config.frontiers_confirmation != nano::frontiers_confirmation_mode::disabled) + { + workers.push_task([this_l = shared ()] () { + this_l->ongoing_backlog_population (); + }); + } } void nano::node::stop () @@ -673,6 +682,7 @@ void nano::node::stop () } aggregator.stop (); vote_processor.stop (); + scheduler.stop (); active.stop (); confirmation_height_processor.stop (); network.stop (); @@ -967,12 +977,20 @@ void nano::node::unchecked_cleanup () void nano::node::ongoing_unchecked_cleanup () { unchecked_cleanup (); - auto this_l (shared ()); - workers.add_timed_task (std::chrono::steady_clock::now () + network_params.node.unchecked_cleaning_interval, [this_l]() { + workers.add_timed_task (std::chrono::steady_clock::now () + network_params.node.unchecked_cleaning_interval, [this_l = shared ()]() { this_l->ongoing_unchecked_cleanup (); }); } +void nano::node::ongoing_backlog_population () +{ + populate_backlog (); + auto delay = config.network_params.network.is_dev_network () ? std::chrono::seconds{ 1 } : std::chrono::duration_cast (std::chrono::minutes{ 5 }); + workers.add_timed_task (std::chrono::steady_clock::now () + delay, [this_l = shared ()] () { + this_l->ongoing_backlog_population (); + }); +} + bool nano::node::collect_ledger_pruning_targets (std::deque & pruning_targets_a, nano::account & last_account_a, uint64_t const batch_read_size_a, uint64_t const max_depth_a, uint64_t const cutoff_time_a) { uint64_t read_operations (0); @@ -1229,10 +1247,12 @@ void nano::node::add_initial_peers () void nano::node::block_confirm (std::shared_ptr const & block_a) { - auto election = active.insert (block_a); - if (election.inserted) + scheduler.manual (block_a); + scheduler.flush (); + auto election = active.election (block_a->qualified_root ()); + if (election != nullptr) { - election.election->transition_active (); + election->transition_active (); } } @@ -1725,6 +1745,26 @@ std::pair nano::node::get_ return { max_blocks, weights }; } +void nano::node::populate_backlog () +{ + auto done = false; + uint64_t const chunk_size = 65536; + nano::account next = 0; + uint64_t total = 0; + while (!stopped && !done) + { + auto transaction = store.tx_begin_read (); + auto count = 0; + for (auto i = store.accounts_begin (transaction, next), n = store.accounts_end (); !stopped && i != n && count < chunk_size; ++i, ++count, ++total) + { + auto const & account = i->first; + scheduler.activate (account, transaction); + next = account.number () + 1; + } + done = store.accounts_begin (transaction, next) == store.accounts_end (); + } +} + nano::node_wrapper::node_wrapper (boost::filesystem::path const & path_a, boost::filesystem::path const & config_path_a, nano::node_flags const & node_flags_a) : io_context (std::make_shared ()), work (1) diff --git a/nano/node/node.hpp b/nano/node/node.hpp index cb1640804b..949c287932 100644 --- a/nano/node/node.hpp +++ b/nano/node/node.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -119,6 +120,7 @@ class node final : public std::enable_shared_from_this void ongoing_bootstrap (); void ongoing_peer_store (); void ongoing_unchecked_cleanup (); + void ongoing_backlog_population (); void backup_wallet (); void search_pending (); void bootstrap_wallet (); @@ -148,6 +150,7 @@ class node final : public std::enable_shared_from_this bool init_error () const; bool epoch_upgrader (nano::raw_key const &, nano::epoch, uint64_t, uint64_t); std::pair get_bootstrap_weights () const; + void populate_backlog (); nano::write_database_queue write_database_queue; boost::asio::io_context & io_ctx; boost::latch node_initialized_latch; @@ -187,6 +190,7 @@ class node final : public std::enable_shared_from_this nano::vote_uniquer vote_uniquer; nano::confirmation_height_processor confirmation_height_processor; nano::active_transactions active; + nano::election_scheduler scheduler; nano::request_aggregator aggregator; nano::wallets wallets; const std::chrono::steady_clock::time_point startup_time; diff --git a/nano/node/wallet.cpp b/nano/node/wallet.cpp index 88ff191580..243b352f7e 100644 --- a/nano/node/wallet.cpp +++ b/nano/node/wallet.cpp @@ -1188,18 +1188,7 @@ bool nano::wallet::search_pending (nano::transaction const & wallet_transaction_ if (wallets.node.config.receive_minimum.number () <= amount) { wallets.node.logger.try_log (boost::str (boost::format ("Found a pending block %1% for account %2%") % hash.to_string () % pending.source.to_account ())); - bool confirmed (wallets.node.ledger.block_confirmed (block_transaction, hash)); - if (confirmed) - { - auto block (wallets.node.store.block_get (block_transaction, hash)); - release_assert (block->type () == nano::block_type::state || block->type () == nano::block_type::send); - } - else if (wallets.node.ledger.pruning) - { - // All pruned blocks should be confirmed - confirmed = wallets.node.store.pruned_exists (block_transaction, hash); - } - if (confirmed) + if (wallets.node.ledger.block_confirmed (block_transaction, hash)) { auto representative = store.representative (wallet_transaction_a); // Receive confirmed block diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index 0e8cb24b31..095bac1d04 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -2127,12 +2127,12 @@ TEST (rpc, process_subtype_open) auto & node2 = *system.add_node (); nano::keypair key; auto latest (node1.latest (nano::dev_genesis_key.pub)); - nano::state_block send (nano::genesis_account, latest, nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node1.work_generate_blocking (latest)); - ASSERT_EQ (nano::process_result::progress, node1.process (send).code); - ASSERT_EQ (nano::process_result::progress, node2.process (send).code); + auto send = std::make_shared (nano::genesis_account, latest, nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node1.work_generate_blocking (latest)); + ASSERT_EQ (nano::process_result::progress, node1.process (*send).code); + ASSERT_EQ (nano::process_result::progress, node2.process (*send).code); scoped_io_thread_name_change scoped_thread_name_io; - node1.active.insert (std::make_shared (send)); - nano::state_block open (key.pub, 0, key.pub, nano::Gxrb_ratio, send.hash (), key.prv, key.pub, *node1.work_generate_blocking (key.pub)); + node1.scheduler.manual (send); + nano::state_block open (key.pub, 0, key.pub, nano::Gxrb_ratio, send->hash (), key.prv, key.pub, *node1.work_generate_blocking (key.pub)); nano::node_rpc_config node_rpc_config; nano::ipc::ipc_server ipc_server (node1, node_rpc_config); nano::rpc_config rpc_config (nano::get_available_port (), true); @@ -2170,12 +2170,12 @@ TEST (rpc, process_subtype_receive) auto & node1 = *add_ipc_enabled_node (system); auto & node2 = *system.add_node (); auto latest (node1.latest (nano::dev_genesis_key.pub)); - nano::state_block send (nano::genesis_account, latest, nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node1.work_generate_blocking (latest)); - ASSERT_EQ (nano::process_result::progress, node1.process (send).code); - ASSERT_EQ (nano::process_result::progress, node2.process (send).code); + auto send = std::make_shared (nano::genesis_account, latest, nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node1.work_generate_blocking (latest)); + ASSERT_EQ (nano::process_result::progress, node1.process (*send).code); + ASSERT_EQ (nano::process_result::progress, node2.process (*send).code); scoped_io_thread_name_change scoped_thread_name_io; - node1.active.insert (std::make_shared (send)); - nano::state_block receive (nano::dev_genesis_key.pub, send.hash (), nano::dev_genesis_key.pub, nano::genesis_amount, send.hash (), nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node1.work_generate_blocking (send.hash ())); + node1.scheduler.manual (send); + nano::state_block receive (nano::dev_genesis_key.pub, send->hash (), nano::dev_genesis_key.pub, nano::genesis_amount, send->hash (), nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node1.work_generate_blocking (send->hash ())); nano::node_rpc_config node_rpc_config; nano::ipc::ipc_server ipc_server (node1, node_rpc_config); nano::rpc_config rpc_config (nano::get_available_port (), true); diff --git a/nano/secure/ledger.cpp b/nano/secure/ledger.cpp index cd18342276..484f4b1784 100644 --- a/nano/secure/ledger.cpp +++ b/nano/secure/ledger.cpp @@ -840,7 +840,7 @@ nano::uint128_t nano::ledger::account_pending (nano::transaction const & transac nano::pending_info const & info (i->second); if (only_confirmed_a) { - if (block_confirmed_or_pruned_exists (transaction_a, i->first.hash)) + if (block_confirmed (transaction_a, i->first.hash)) { result += info.amount.number (); } @@ -894,11 +894,6 @@ bool nano::ledger::block_or_pruned_exists (nano::block_hash const & hash_a) cons return block_or_pruned_exists (store.tx_begin_read (), hash_a); } -bool nano::ledger::block_confirmed_or_pruned_exists (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const -{ - return block_confirmed (transaction_a, hash_a) || (pruning && store.pruned_exists (transaction_a, hash_a)); -} - std::string nano::ledger::block_text (char const * hash_a) { return block_text (nano::block_hash (hash_a)); @@ -1322,13 +1317,16 @@ std::shared_ptr nano::ledger::forked_block (nano::transaction const bool nano::ledger::block_confirmed (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const { - auto confirmed (false); - auto block = store.block_get (transaction_a, hash_a); - if (block) + auto confirmed = store.pruned_exists (transaction_a, hash_a); + if (!confirmed) { - nano::confirmation_height_info confirmation_height_info; - store.confirmation_height_get (transaction_a, block->account ().is_zero () ? block->sideband ().account : block->account (), confirmation_height_info); - confirmed = (confirmation_height_info.height >= block->sideband ().height); + auto block = store.block_get (transaction_a, hash_a); + if (block) + { + nano::confirmation_height_info confirmation_height_info; + store.confirmation_height_get (transaction_a, block->account ().is_zero () ? block->sideband ().account : block->account (), confirmation_height_info); + confirmed = (confirmation_height_info.height >= block->sideband ().height); + } } return confirmed; } diff --git a/nano/secure/ledger.hpp b/nano/secure/ledger.hpp index f04cc580ca..c36ff5b131 100644 --- a/nano/secure/ledger.hpp +++ b/nano/secure/ledger.hpp @@ -48,7 +48,6 @@ class ledger final bool block_exists (nano::block_hash const &) const; bool block_or_pruned_exists (nano::transaction const &, nano::block_hash const &) const; bool block_or_pruned_exists (nano::block_hash const &) const; - bool block_confirmed_or_pruned_exists (nano::transaction const &, nano::block_hash const &) const; std::string block_text (char const *); std::string block_text (nano::block_hash const &); bool is_send (nano::transaction const &, nano::state_block const &) const; diff --git a/nano/slow_test/node.cpp b/nano/slow_test/node.cpp index 45629ca922..08e27c8d6a 100644 --- a/nano/slow_test/node.cpp +++ b/nano/slow_test/node.cpp @@ -535,10 +535,10 @@ TEST (confirmation_height, many_accounts_single_confirmation) { auto block = node->block (last_open_hash); ASSERT_NE (nullptr, block); - auto election_insertion_result (node->active.insert (block)); - ASSERT_TRUE (election_insertion_result.inserted); - ASSERT_NE (nullptr, election_insertion_result.election); - election_insertion_result.election->force_confirm (); + node->scheduler.manual (block); + auto election = node->active.election (block->qualified_root ()); + ASSERT_NE (nullptr, election); + election->force_confirm (); } ASSERT_TIMELY (120s, node->ledger.block_confirmed (node->store.tx_begin_read (), last_open_hash)); @@ -603,10 +603,10 @@ TEST (confirmation_height, many_accounts_many_confirmations) // Confirm all of the accounts for (auto & open_block : open_blocks) { - auto election_insertion_result (node->active.insert (open_block)); - ASSERT_TRUE (election_insertion_result.inserted); - ASSERT_NE (nullptr, election_insertion_result.election); - election_insertion_result.election->force_confirm (); + node->scheduler.manual (open_block); + auto election = node->active.election (open_block->qualified_root ()); + ASSERT_NE (nullptr, election); + election->force_confirm (); } auto const num_blocks_to_confirm = (num_accounts - 1) * 2; @@ -690,10 +690,10 @@ TEST (confirmation_height, long_chains) // Call block confirm on the existing receive block on the genesis account which will confirm everything underneath on both accounts { - auto election_insertion_result (node->active.insert (receive1)); - ASSERT_TRUE (election_insertion_result.inserted); - ASSERT_NE (nullptr, election_insertion_result.election); - election_insertion_result.election->force_confirm (); + node->scheduler.manual (receive1); + auto election = node->active.election (receive1->qualified_root ()); + ASSERT_NE (nullptr, election); + election->force_confirm (); } ASSERT_TIMELY (30s, node->ledger.block_confirmed (node->store.tx_begin_read (), receive1->hash ())); @@ -1852,10 +1852,11 @@ TEST (node, wallet_create_block_confirm_conflicts) // Call block confirm on the top level send block which will confirm everything underneath on both accounts. { - auto election_insertion_result (node->active.insert (node->store.block_get (node->store.tx_begin_read (), latest))); - ASSERT_TRUE (election_insertion_result.inserted); - ASSERT_NE (nullptr, election_insertion_result.election); - election_insertion_result.election->force_confirm (); + auto block = node->store.block_get (node->store.tx_begin_read (), latest); + node->scheduler.manual (block); + auto election = node->active.election (block->qualified_root ()); + ASSERT_NE (nullptr, election); + election->force_confirm (); } ASSERT_TIMELY (120s, node->ledger.block_confirmed (node->store.tx_begin_read (), latest) && node->confirmation_height_processor.current () == 0); From c5fdcc473c9518855da58516343d641d2cb0ddbd Mon Sep 17 00:00:00 2001 From: clemahieu Date: Sun, 18 Apr 2021 15:38:41 +0200 Subject: [PATCH 02/10] Clang formatting. --- nano/core_test/ledger.cpp | 4 +- nano/core_test/network.cpp | 48 +++++++++--------- nano/core_test/node.cpp | 42 ++++++++-------- nano/core_test/wallet.cpp | 14 +++--- nano/core_test/websocket.cpp | 44 ++++++++--------- nano/core_test/work_watcher.cpp | 2 +- nano/node/blockprocessor.cpp | 60 +++++++++-------------- nano/node/blockprocessor.hpp | 2 +- nano/node/election.cpp | 10 ++-- nano/node/node.cpp | 86 ++++++++++++++++----------------- nano/node/node.hpp | 2 +- nano/node/vote_processor.cpp | 4 +- nano/node/wallet.cpp | 63 +++++++++++------------- nano/rpc_test/rpc.cpp | 40 +++++++-------- nano/secure/ledger.cpp | 26 +++++----- nano/slow_test/node.cpp | 42 ++++++++-------- 16 files changed, 235 insertions(+), 254 deletions(-) diff --git a/nano/core_test/ledger.cpp b/nano/core_test/ledger.cpp index 187f1d1993..623cb8a785 100644 --- a/nano/core_test/ledger.cpp +++ b/nano/core_test/ledger.cpp @@ -3093,7 +3093,7 @@ TEST (ledger, work_validation) nano::keypair key; // With random work the block doesn't pass, then modifies the block with sufficient work and ensures a correct result - auto process_block = [&store, &ledger, &pool](nano::block & block_a, nano::block_details const details_a) { + auto process_block = [&store, &ledger, &pool] (nano::block & block_a, nano::block_details const details_a) { auto threshold = nano::work_threshold (block_a.work_version (), details_a); // Rarely failed with random work, so modify until it doesn't have enough difficulty while (block_a.difficulty () >= threshold) @@ -3301,7 +3301,7 @@ TEST (ledger, cache) auto genesis_weight = nano::genesis_amount - i; auto pruned_count = i; - auto cache_check = [&, i](nano::ledger_cache const & cache_a) { + auto cache_check = [&, i] (nano::ledger_cache const & cache_a) { ASSERT_EQ (account_count, cache_a.account_count); ASSERT_EQ (block_count, cache_a.block_count); ASSERT_EQ (cemented_count, cache_a.cemented_count); diff --git a/nano/core_test/network.cpp b/nano/core_test/network.cpp index 2226dbc7a9..71f3d19f64 100644 --- a/nano/core_test/network.cpp +++ b/nano/core_test/network.cpp @@ -25,7 +25,7 @@ TEST (network, tcp_connection) std::atomic done1 (false); std::string message1; acceptor.async_accept (incoming, - [&done1, &message1](boost::system::error_code const & ec_a) { + [&done1, &message1] (boost::system::error_code const & ec_a) { if (ec_a) { message1 = ec_a.message (); @@ -36,7 +36,7 @@ TEST (network, tcp_connection) std::atomic done2 (false); std::string message2; connector.async_connect (boost::asio::ip::tcp::endpoint (boost::asio::ip::address_v4::loopback (), port), - [&done2, &message2](boost::system::error_code const & ec_a) { + [&done2, &message2] (boost::system::error_code const & ec_a) { if (ec_a) { message2 = ec_a.message (); @@ -283,7 +283,7 @@ TEST (network, send_insufficient_work_udp) auto block (std::make_shared (0, 1, 20, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); nano::publish publish (block); nano::transport::channel_udp channel (node1.network.udp_channels, node2.network.endpoint (), node1.network_params.protocol.protocol_version); - channel.send (publish, [](boost::system::error_code const & ec, size_t size) {}); + channel.send (publish, [] (boost::system::error_code const & ec, size_t size) {}); ASSERT_EQ (0, node1.stats.count (nano::stat::type::error, nano::stat::detail::insufficient_work)); ASSERT_TIMELY (10s, node2.stats.count (nano::stat::type::error, nano::stat::detail::insufficient_work) != 0); ASSERT_EQ (1, node2.stats.count (nano::stat::type::error, nano::stat::detail::insufficient_work)); @@ -298,27 +298,27 @@ TEST (network, send_insufficient_work) auto block1 (std::make_shared (0, 1, 20, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); nano::publish publish1 (block1); auto tcp_channel (node1.network.tcp_channels.find_channel (nano::transport::map_endpoint_to_tcp (node2.network.endpoint ()))); - tcp_channel->send (publish1, [](boost::system::error_code const & ec, size_t size) {}); + tcp_channel->send (publish1, [] (boost::system::error_code const & ec, size_t size) {}); ASSERT_EQ (0, node1.stats.count (nano::stat::type::error, nano::stat::detail::insufficient_work)); ASSERT_TIMELY (10s, node2.stats.count (nano::stat::type::error, nano::stat::detail::insufficient_work) != 0); ASSERT_EQ (1, node2.stats.count (nano::stat::type::error, nano::stat::detail::insufficient_work)); // Legacy block work between epoch_2_recieve & epoch_1 auto block2 (std::make_shared (block1->hash (), 1, 20, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, system.work_generate_limited (block1->hash (), node1.network_params.network.publish_thresholds.epoch_2_receive, node1.network_params.network.publish_thresholds.epoch_1 - 1))); nano::publish publish2 (block2); - tcp_channel->send (publish2, [](boost::system::error_code const & ec, size_t size) {}); + tcp_channel->send (publish2, [] (boost::system::error_code const & ec, size_t size) {}); ASSERT_TIMELY (10s, node2.stats.count (nano::stat::type::error, nano::stat::detail::insufficient_work) != 1); ASSERT_EQ (2, node2.stats.count (nano::stat::type::error, nano::stat::detail::insufficient_work)); // Legacy block work epoch_1 auto block3 (std::make_shared (block2->hash (), 1, 20, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (block2->hash (), node1.network_params.network.publish_thresholds.epoch_2))); nano::publish publish3 (block3); - tcp_channel->send (publish3, [](boost::system::error_code const & ec, size_t size) {}); + tcp_channel->send (publish3, [] (boost::system::error_code const & ec, size_t size) {}); ASSERT_EQ (0, node2.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::in)); ASSERT_TIMELY (10s, node2.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::in) != 0); ASSERT_EQ (1, node2.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::in)); // State block work epoch_2_recieve auto block4 (std::make_shared (nano::dev_genesis_key.pub, block1->hash (), nano::dev_genesis_key.pub, 20, 1, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, system.work_generate_limited (block1->hash (), node1.network_params.network.publish_thresholds.epoch_2_receive, node1.network_params.network.publish_thresholds.epoch_1 - 1))); nano::publish publish4 (block4); - tcp_channel->send (publish4, [](boost::system::error_code const & ec, size_t size) {}); + tcp_channel->send (publish4, [] (boost::system::error_code const & ec, size_t size) {}); ASSERT_TIMELY (10s, node2.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::in) != 0); ASSERT_EQ (1, node2.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::in)); ASSERT_EQ (2, node2.stats.count (nano::stat::type::error, nano::stat::detail::insufficient_work)); @@ -405,7 +405,7 @@ TEST (network, receive_weight_change) system.wallet (1)->store.representative_set (transaction, key2.pub); } ASSERT_NE (nullptr, system.wallet (0)->send_action (nano::dev_genesis_key.pub, key2.pub, system.nodes[0]->config.receive_minimum.number ())); - ASSERT_TIMELY (10s, std::all_of (system.nodes.begin (), system.nodes.end (), [&](std::shared_ptr const & node_a) { return node_a->weight (key2.pub) == system.nodes[0]->config.receive_minimum.number (); })); + ASSERT_TIMELY (10s, std::all_of (system.nodes.begin (), system.nodes.end (), [&] (std::shared_ptr const & node_a) { return node_a->weight (key2.pub) == system.nodes[0]->config.receive_minimum.number (); })); } TEST (parse_endpoint, valid) @@ -496,7 +496,7 @@ TEST (network, ipv6_bind_send_ipv4) auto finish1 (false); nano::endpoint endpoint3; boost::asio::ip::udp::socket socket1 (io_ctx, endpoint1); - socket1.async_receive_from (boost::asio::buffer (bytes1.data (), bytes1.size ()), endpoint3, [&finish1](boost::system::error_code const & error, size_t size_a) { + socket1.async_receive_from (boost::asio::buffer (bytes1.data (), bytes1.size ()), endpoint3, [&finish1] (boost::system::error_code const & error, size_t size_a) { ASSERT_FALSE (error); ASSERT_EQ (16, size_a); finish1 = true; @@ -504,7 +504,7 @@ TEST (network, ipv6_bind_send_ipv4) boost::asio::ip::udp::socket socket2 (io_ctx, endpoint2); nano::endpoint endpoint5 (boost::asio::ip::address_v4::loopback (), port1); nano::endpoint endpoint6 (boost::asio::ip::address_v6::v4_mapped (boost::asio::ip::address_v4::loopback ()), port2); - socket2.async_send_to (boost::asio::buffer (std::array{}, 16), endpoint5, [](boost::system::error_code const & error, size_t size_a) { + socket2.async_send_to (boost::asio::buffer (std::array{}, 16), endpoint5, [] (boost::system::error_code const & error, size_t size_a) { ASSERT_FALSE (error); ASSERT_EQ (16, size_a); }); @@ -518,11 +518,11 @@ TEST (network, ipv6_bind_send_ipv4) ASSERT_EQ (endpoint6, endpoint3); std::array bytes2; nano::endpoint endpoint4; - socket2.async_receive_from (boost::asio::buffer (bytes2.data (), bytes2.size ()), endpoint4, [](boost::system::error_code const & error, size_t size_a) { + socket2.async_receive_from (boost::asio::buffer (bytes2.data (), bytes2.size ()), endpoint4, [] (boost::system::error_code const & error, size_t size_a) { ASSERT_FALSE (!error); ASSERT_EQ (16, size_a); }); - socket1.async_send_to (boost::asio::buffer (std::array{}, 16), endpoint6, [](boost::system::error_code const & error, size_t size_a) { + socket1.async_send_to (boost::asio::buffer (std::array{}, 16), endpoint6, [] (boost::system::error_code const & error, size_t size_a) { ASSERT_FALSE (error); ASSERT_EQ (16, size_a); }); @@ -635,7 +635,7 @@ TEST (message_buffer_manager, one_buffer_multithreaded) { nano::stat stats; nano::message_buffer_manager buffer (stats, 512, 1); - boost::thread thread ([&buffer]() { + boost::thread thread ([&buffer] () { auto done (false); while (!done) { @@ -663,7 +663,7 @@ TEST (message_buffer_manager, many_buffers_multithreaded) std::vector threads; for (auto i (0); i < 4; ++i) { - threads.push_back (boost::thread ([&buffer]() { + threads.push_back (boost::thread ([&buffer] () { auto done (false); while (!done) { @@ -679,7 +679,7 @@ TEST (message_buffer_manager, many_buffers_multithreaded) std::atomic_int count (0); for (auto i (0); i < 4; ++i) { - threads.push_back (boost::thread ([&buffer, &count]() { + threads.push_back (boost::thread ([&buffer, &count] () { auto done (false); for (auto i (0); !done && i < 1000; ++i) { @@ -723,9 +723,9 @@ TEST (tcp_listener, tcp_node_id_handshake) nano::node_id_handshake node_id_handshake (cookie, boost::none); auto input (node_id_handshake.to_shared_const_buffer ()); std::atomic write_done (false); - socket->async_connect (bootstrap_endpoint, [&input, socket, &write_done](boost::system::error_code const & ec) { + socket->async_connect (bootstrap_endpoint, [&input, socket, &write_done] (boost::system::error_code const & ec) { ASSERT_FALSE (ec); - socket->async_write (input, [&input, &write_done](boost::system::error_code const & ec, size_t size_a) { + socket->async_write (input, [&input, &write_done] (boost::system::error_code const & ec, size_t size_a) { ASSERT_FALSE (ec); ASSERT_EQ (input.size (), size_a); write_done = true; @@ -738,7 +738,7 @@ TEST (tcp_listener, tcp_node_id_handshake) nano::node_id_handshake node_id_handshake_response (boost::none, response_zero); auto output (node_id_handshake_response.to_bytes ()); std::atomic done (false); - socket->async_read (output, output->size (), [&output, &done](boost::system::error_code const & ec, size_t size_a) { + socket->async_read (output, output->size (), [&output, &done] (boost::system::error_code const & ec, size_t size_a) { ASSERT_FALSE (ec); ASSERT_EQ (output->size (), size_a); done = true; @@ -752,7 +752,7 @@ TEST (tcp_listener, tcp_listener_timeout_empty) auto node0 (system.nodes[0]); auto socket (std::make_shared (*node0)); std::atomic connected (false); - socket->async_connect (node0->bootstrap.endpoint (), [&connected](boost::system::error_code const & ec) { + socket->async_connect (node0->bootstrap.endpoint (), [&connected] (boost::system::error_code const & ec) { ASSERT_FALSE (ec); connected = true; }); @@ -777,9 +777,9 @@ TEST (tcp_listener, tcp_listener_timeout_node_id_handshake) auto cookie (node0->network.syn_cookies.assign (nano::transport::map_tcp_to_endpoint (node0->bootstrap.endpoint ()))); nano::node_id_handshake node_id_handshake (cookie, boost::none); auto input (node_id_handshake.to_shared_const_buffer ()); - socket->async_connect (node0->bootstrap.endpoint (), [&input, socket](boost::system::error_code const & ec) { + socket->async_connect (node0->bootstrap.endpoint (), [&input, socket] (boost::system::error_code const & ec) { ASSERT_FALSE (ec); - socket->async_write (input, [&input](boost::system::error_code const & ec, size_t size_a) { + socket->async_write (input, [&input] (boost::system::error_code const & ec, size_t size_a) { ASSERT_FALSE (ec); ASSERT_EQ (input.size (), size_a); }); @@ -818,7 +818,7 @@ TEST (network, replace_port) auto wrong_endpoint = nano::endpoint (node1->network.endpoint ().address (), nano::get_available_port ()); auto channel0 (node0->network.udp_channels.insert (wrong_endpoint, node1->network_params.protocol.protocol_version)); ASSERT_NE (nullptr, channel0); - node0->network.udp_channels.modify (channel0, [&node1](std::shared_ptr const & channel_a) { + node0->network.udp_channels.modify (channel0, [&node1] (std::shared_ptr const & channel_a) { channel_a->set_node_id (node1->node_id.pub); }); auto peers_list (node0->network.list (std::numeric_limits::max ())); @@ -960,7 +960,7 @@ TEST (peer_exclusion, validate) nano::tcp_endpoint oldest (boost::asio::ip::address_v6::v4_mapped (boost::asio::ip::address_v4 (0x0)), 0); ASSERT_EQ (peers_by_endpoint.end (), peers_by_endpoint.find (oldest.address ())); - auto to_seconds = [](std::chrono::steady_clock::time_point const & timepoint) { + auto to_seconds = [] (std::chrono::steady_clock::time_point const & timepoint) { return static_cast (std::chrono::duration_cast (timepoint.time_since_epoch ()).count ()); }; nano::tcp_endpoint first (boost::asio::ip::address_v6::v4_mapped (boost::asio::ip::address_v4 (0x1)), 0); @@ -1117,7 +1117,7 @@ TEST (network, cleanup_purge) ASSERT_EQ (0, node1.network.size ()); std::weak_ptr node_w = node1.shared (); - node1.network.tcp_channels.start_tcp (node2->network.endpoint (), [node_w](std::shared_ptr const & channel_a) { + node1.network.tcp_channels.start_tcp (node2->network.endpoint (), [node_w] (std::shared_ptr const & channel_a) { if (auto node_l = node_w.lock ()) { node_l->network.send_keepalive (channel_a); diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index c11f570972..c7e9195f0b 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -160,7 +160,7 @@ TEST (node, send_single_observing_peer) ASSERT_NE (nullptr, system.wallet (0)->send_action (nano::dev_genesis_key.pub, key2.pub, system.nodes[0]->config.receive_minimum.number ())); ASSERT_EQ (std::numeric_limits::max () - system.nodes[0]->config.receive_minimum.number (), system.nodes[0]->balance (nano::dev_genesis_key.pub)); ASSERT_TRUE (system.nodes[0]->balance (key2.pub).is_zero ()); - ASSERT_TIMELY (10s, std::all_of (system.nodes.begin (), system.nodes.end (), [&](std::shared_ptr const & node_a) { return !node_a->balance (key2.pub).is_zero (); })); + ASSERT_TIMELY (10s, std::all_of (system.nodes.begin (), system.nodes.end (), [&] (std::shared_ptr const & node_a) { return !node_a->balance (key2.pub).is_zero (); })); } TEST (node, send_single_many_peers) @@ -172,7 +172,7 @@ TEST (node, send_single_many_peers) ASSERT_NE (nullptr, system.wallet (0)->send_action (nano::dev_genesis_key.pub, key2.pub, system.nodes[0]->config.receive_minimum.number ())); ASSERT_EQ (std::numeric_limits::max () - system.nodes[0]->config.receive_minimum.number (), system.nodes[0]->balance (nano::dev_genesis_key.pub)); ASSERT_TRUE (system.nodes[0]->balance (key2.pub).is_zero ()); - ASSERT_TIMELY (3.5min, std::all_of (system.nodes.begin (), system.nodes.end (), [&](std::shared_ptr const & node_a) { return !node_a->balance (key2.pub).is_zero (); })); + ASSERT_TIMELY (3.5min, std::all_of (system.nodes.begin (), system.nodes.end (), [&] (std::shared_ptr const & node_a) { return !node_a->balance (key2.pub).is_zero (); })); system.stop (); for (auto node : system.nodes) { @@ -212,7 +212,7 @@ TEST (node, send_out_of_order) node1.process_active (send3); node1.process_active (send2); node1.process_active (send1); - ASSERT_TIMELY (10s, std::all_of (system.nodes.begin (), system.nodes.end (), [&](std::shared_ptr const & node_a) { return node_a->balance (nano::dev_genesis_key.pub) == nano::genesis_amount - node1.config.receive_minimum.number () * 3; })); + ASSERT_TIMELY (10s, std::all_of (system.nodes.begin (), system.nodes.end (), [&] (std::shared_ptr const & node_a) { return node_a->balance (nano::dev_genesis_key.pub) == nano::genesis_amount - node1.config.receive_minimum.number () * 3; })); } TEST (node, quick_confirm) @@ -539,7 +539,7 @@ TEST (node, connect_after_junk) std::vector junk_buffer; junk_buffer.push_back (0); auto channel1 (std::make_shared (node1->network.udp_channels, node0->network.endpoint (), node1->network_params.protocol.protocol_version)); - channel1->send_buffer (nano::shared_const_buffer (std::move (junk_buffer)), [](boost::system::error_code const &, size_t) {}); + channel1->send_buffer (nano::shared_const_buffer (std::move (junk_buffer)), [] (boost::system::error_code const &, size_t) {}); ASSERT_TIMELY (10s, node0->stats.count (nano::stat::type::error) != 0); node1->start (); system.nodes.push_back (node1); @@ -560,11 +560,11 @@ TEST (node, price) nano::system system (1); auto price1 (system.nodes[0]->price (nano::Gxrb_ratio, 1)); ASSERT_EQ (nano::node::price_max * 100.0, price1); - auto price2 (system.nodes[0]->price (nano::Gxrb_ratio * int(nano::node::free_cutoff + 1), 1)); + auto price2 (system.nodes[0]->price (nano::Gxrb_ratio * int (nano::node::free_cutoff + 1), 1)); ASSERT_EQ (0, price2); - auto price3 (system.nodes[0]->price (nano::Gxrb_ratio * int(nano::node::free_cutoff + 2) / 2, 1)); + auto price3 (system.nodes[0]->price (nano::Gxrb_ratio * int (nano::node::free_cutoff + 2) / 2, 1)); ASSERT_EQ (nano::node::price_max * 100.0 / 2, price3); - auto price4 (system.nodes[0]->price (nano::Gxrb_ratio * int(nano::node::free_cutoff) * 2, 1)); + auto price4 (system.nodes[0]->price (nano::Gxrb_ratio * int (nano::node::free_cutoff) * 2, 1)); ASSERT_EQ (0, price4); } @@ -943,7 +943,7 @@ TEST (json, backup) ASSERT_EQ ("created", object1.text); /** Returns 'dir' if backup file cannot be found */ - auto get_backup_path = [&dir]() { + auto get_backup_path = [&dir] () { for (fs::directory_iterator itr (dir); itr != fs::directory_iterator (); ++itr) { if (itr->path ().filename ().string ().find ("_backup_") != std::string::npos) @@ -954,7 +954,7 @@ TEST (json, backup) return dir; }; - auto get_file_count = [&dir]() { + auto get_file_count = [&dir] () { return std::count_if (boost::filesystem::directory_iterator (dir), boost::filesystem::directory_iterator (), static_cast (boost::filesystem::is_regular_file)); }; @@ -1502,7 +1502,7 @@ TEST (node, coherent_observer) { nano::system system (1); auto & node1 (*system.nodes[0]); - node1.observers.blocks.add ([&node1](nano::election_status const & status_a, std::vector const &, nano::account const &, nano::uint128_t const &, bool) { + node1.observers.blocks.add ([&node1] (nano::election_status const & status_a, std::vector const &, nano::account const &, nano::uint128_t const &, bool) { auto transaction (node1.store.tx_begin_read ()); ASSERT_TRUE (node1.store.block_exists (transaction, status_a.winner->hash ())); }); @@ -2284,7 +2284,7 @@ TEST (node, rep_remove) ASSERT_EQ (*channel0, reps[0].channel_ref ()); // Modify last_packet_received so the channel is removed faster std::chrono::steady_clock::time_point fake_timepoint{}; - node.network.udp_channels.modify (channel_udp, [fake_timepoint](std::shared_ptr const & channel_a) { + node.network.udp_channels.modify (channel_udp, [fake_timepoint] (std::shared_ptr const & channel_a) { channel_a->set_last_packet_received (fake_timepoint); }); // This UDP channel is not reachable and should timeout @@ -2302,7 +2302,7 @@ TEST (node, rep_remove) auto node2 (std::make_shared (system.io_ctx, nano::unique_path (), nano::node_config (nano::get_available_port (), system.logging), system.work)); std::weak_ptr node_w (node.shared ()); auto vote3 = std::make_shared (keypair2.pub, keypair2.prv, 0, genesis.open); - node.network.tcp_channels.start_tcp (node2->network.endpoint (), [node_w, &vote3](std::shared_ptr const & channel2) { + node.network.tcp_channels.start_tcp (node2->network.endpoint (), [node_w, &vote3] (std::shared_ptr const & channel2) { if (auto node_l = node_w.lock ()) { ASSERT_FALSE (node_l->rep_crawler.response (channel2, vote3)); @@ -2373,7 +2373,7 @@ TEST (node, balance_observer) auto & node1 (*system.nodes[0]); std::atomic balances (0); nano::keypair key; - node1.observers.account_balance.add ([&key, &balances](nano::account const & account_a, bool is_pending) { + node1.observers.account_balance.add ([&key, &balances] (nano::account const & account_a, bool is_pending) { if (key.pub == account_a && is_pending) { balances++; @@ -2993,7 +2993,7 @@ TEST (node, vote_by_hash_bundle) nano::keypair key1; system.wallet (0)->insert_adhoc (key1.prv); - system.nodes[0]->observers.vote.add ([&max_hashes](std::shared_ptr const & vote_a, std::shared_ptr const &, nano::vote_code) { + system.nodes[0]->observers.vote.add ([&max_hashes] (std::shared_ptr const & vote_a, std::shared_ptr const &, nano::vote_code) { if (vote_a->blocks.size () > max_hashes) { max_hashes = vote_a->blocks.size (); @@ -3726,7 +3726,7 @@ TEST (node, dont_write_lock_node) std::promise write_lock_held_promise; std::promise finished_promise; - std::thread ([&path, &write_lock_held_promise, &finished_promise]() { + std::thread ([&path, &write_lock_held_promise, &finished_promise] () { nano::logger_mt logger; auto store = nano::make_store (logger, path, false, true); { @@ -3870,7 +3870,7 @@ TEST (node, aggressive_flooding) bool const sanitizer_or_valgrind (is_sanitizer_build || nano::running_within_valgrind ()); nodes_wallets.resize (!sanitizer_or_valgrind ? 5 : 3); - std::generate (nodes_wallets.begin (), nodes_wallets.end (), [&system, node_flags]() { + std::generate (nodes_wallets.begin (), nodes_wallets.end (), [&system, node_flags] () { nano::node_config node_config (nano::get_available_port (), system.logging); auto node (system.add_node (node_config, node_flags)); return std::make_pair (node, system.wallet (system.nodes.size () - 1)); @@ -3923,8 +3923,8 @@ TEST (node, aggressive_flooding) // Processing locally goes through the aggressive block flooding path node1.process_local (block, false); - 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) { + 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) { return node_wallet.first->block (hash) != nullptr; }); }; @@ -3960,7 +3960,7 @@ TEST (active_difficulty, recalculate_work) // 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))); + 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 lock (node1.active.mutex); // Fake history records to force work recalculation @@ -3971,7 +3971,7 @@ TEST (active_difficulty, recalculate_work) 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)); + 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 (); } @@ -4252,7 +4252,7 @@ TEST (node, dependency_graph) nano::lock_guard guard (node.active.mutex); // Ensure that active blocks have their ancestors confirmed - auto error = std::any_of (dependency_graph.cbegin (), dependency_graph.cend (), [&](auto entry) { + auto error = std::any_of (dependency_graph.cbegin (), dependency_graph.cend (), [&] (auto entry) { if (node.active.blocks.count (entry.first)) { for (auto ancestor : entry.second) diff --git a/nano/core_test/wallet.cpp b/nano/core_test/wallet.cpp index 545da24802..66df3fa9a8 100644 --- a/nano/core_test/wallet.cpp +++ b/nano/core_test/wallet.cpp @@ -198,11 +198,11 @@ TEST (wallet, send_async) nano::system system (1); system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv); nano::keypair key2; - std::thread thread ([&system]() { + std::thread thread ([&system] () { ASSERT_TIMELY (10s, system.nodes[0]->balance (nano::dev_genesis_key.pub).is_zero ()); }); std::atomic success (false); - system.wallet (0)->send_async (nano::dev_genesis_key.pub, key2.pub, std::numeric_limits::max (), [&success](std::shared_ptr const & block_a) { ASSERT_NE (nullptr, block_a); success = true; }); + system.wallet (0)->send_async (nano::dev_genesis_key.pub, key2.pub, std::numeric_limits::max (), [&success] (std::shared_ptr const & block_a) { ASSERT_NE (nullptr, block_a); success = true; }); thread.join (); ASSERT_TIMELY (2s, success); } @@ -846,7 +846,7 @@ TEST (wallet, password_race) nano::system system (1); nano::thread_runner runner (system.io_ctx, system.nodes[0]->config.io_threads); auto wallet = system.wallet (0); - std::thread thread ([&wallet]() { + std::thread thread ([&wallet] () { for (int i = 0; i < 100; i++) { auto transaction (wallet->wallets.tx_begin_write ()); @@ -884,21 +884,21 @@ TEST (wallet, password_race_corrupt_seed) std::vector threads; for (int i = 0; i < 100; i++) { - threads.emplace_back ([&wallet]() { + threads.emplace_back ([&wallet] () { for (int i = 0; i < 10; i++) { auto transaction (wallet->wallets.tx_begin_write ()); wallet->store.rekey (transaction, "0000"); } }); - threads.emplace_back ([&wallet]() { + threads.emplace_back ([&wallet] () { for (int i = 0; i < 10; i++) { auto transaction (wallet->wallets.tx_begin_write ()); wallet->store.rekey (transaction, "1234"); } }); - threads.emplace_back ([&wallet]() { + threads.emplace_back ([&wallet] () { for (int i = 0; i < 10; i++) { auto transaction (wallet->wallets.tx_begin_read ()); @@ -1175,7 +1175,7 @@ TEST (wallet, foreach_representative_deadlock) system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv); node.wallets.compute_reps (); ASSERT_EQ (1, node.wallets.reps ().voting); - node.wallets.foreach_representative ([&node](nano::public_key const & pub, nano::raw_key const & prv) { + node.wallets.foreach_representative ([&node] (nano::public_key const & pub, nano::raw_key const & prv) { if (node.wallets.mutex.try_lock ()) { node.wallets.mutex.unlock (); diff --git a/nano/core_test/websocket.cpp b/nano/core_test/websocket.cpp index be1fef9e84..b7fec3e16d 100644 --- a/nano/core_test/websocket.cpp +++ b/nano/core_test/websocket.cpp @@ -28,7 +28,7 @@ TEST (websocket, subscription_edge) ASSERT_EQ (0, node1->websocket_server->subscriber_count (nano::websocket::topic::confirmation)); - auto task = ([config, &node1]() { + auto task = ([config, &node1] () { fake_websocket_client client (config.websocket_config.port); client.send_message (R"json({"action": "subscribe", "topic": "confirmation", "ack": true})json"); client.await_ack (); @@ -65,7 +65,7 @@ TEST (websocket, active_difficulty) ASSERT_EQ (0, node1->websocket_server->subscriber_count (nano::websocket::topic::active_difficulty)); std::atomic ack_ready{ false }; - auto task = ([&ack_ready, config, &node1]() { + auto task = ([&ack_ready, config, &node1] () { fake_websocket_client client (config.websocket_config.port); client.send_message (R"json({"action": "subscribe", "topic": "active_difficulty", "ack": true})json"); client.await_ack (); @@ -129,7 +129,7 @@ TEST (websocket, confirmation) std::atomic ack_ready{ false }; std::atomic unsubscribed{ false }; - auto task = ([&ack_ready, &unsubscribed, config, &node1]() { + auto task = ([&ack_ready, &unsubscribed, config, &node1] () { fake_websocket_client client (config.websocket_config.port); client.send_message (R"json({"action": "subscribe", "topic": "confirmation", "ack": true})json"); client.await_ack (); @@ -186,7 +186,7 @@ TEST (websocket, stopped_election) auto node1 (system.add_node (config)); std::atomic ack_ready{ false }; - auto task = ([&ack_ready, config, &node1]() { + auto task = ([&ack_ready, config, &node1] () { fake_websocket_client client (config.websocket_config.port); client.send_message (R"json({"action": "subscribe", "topic": "stopped_election", "ack": "true"})json"); client.await_ack (); @@ -230,7 +230,7 @@ TEST (websocket, confirmation_options) auto node1 (system.add_node (config)); std::atomic ack_ready{ false }; - auto task1 = ([&ack_ready, config, &node1]() { + auto task1 = ([&ack_ready, config, &node1] () { fake_websocket_client client (config.websocket_config.port); client.send_message (R"json({"action": "subscribe", "topic": "confirmation", "ack": "true", "options": {"confirmation_type": "active_quorum", "accounts": ["xrb_invalid"]}})json"); client.await_ack (); @@ -259,7 +259,7 @@ TEST (websocket, confirmation_options) ASSERT_TIMELY (5s, future1.wait_for (0s) == std::future_status::ready); ack_ready = false; - auto task2 = ([&ack_ready, config, &node1]() { + auto task2 = ([&ack_ready, config, &node1] () { fake_websocket_client client (config.websocket_config.port); client.send_message (R"json({"action": "subscribe", "topic": "confirmation", "ack": "true", "options": {"confirmation_type": "active_quorum", "all_local_accounts": "true", "include_election_info": "true"}})json"); client.await_ack (); @@ -310,7 +310,7 @@ TEST (websocket, confirmation_options) } ack_ready = false; - auto task3 = ([&ack_ready, config, &node1]() { + auto task3 = ([&ack_ready, config, &node1] () { fake_websocket_client client (config.websocket_config.port); client.send_message (R"json({"action": "subscribe", "topic": "confirmation", "ack": "true", "options": {"confirmation_type": "active_quorum", "all_local_accounts": "true"}})json"); client.await_ack (); @@ -344,7 +344,7 @@ TEST (websocket, confirmation_options_votes) auto node1 (system.add_node (config)); std::atomic ack_ready{ false }; - auto task1 = ([&ack_ready, config, &node1]() { + auto task1 = ([&ack_ready, config, &node1] () { fake_websocket_client client (config.websocket_config.port); client.send_message (R"json({"action": "subscribe", "topic": "confirmation", "ack": "true", "options": {"confirmation_type": "active_quorum", "include_election_info_with_votes": "true", "include_block": "false"}})json"); client.await_ack (); @@ -423,7 +423,7 @@ TEST (websocket, confirmation_options_update) std::atomic added{ false }; std::atomic deleted{ false }; - auto task = ([&added, &deleted, config, &node1]() { + auto task = ([&added, &deleted, config, &node1] () { fake_websocket_client client (config.websocket_config.port); // Subscribe initially with empty options, everything will be filtered client.send_message (R"json({"action": "subscribe", "topic": "confirmation", "ack": "true", "options": {}})json"); @@ -478,7 +478,7 @@ TEST (websocket, vote) auto node1 (system.add_node (config)); std::atomic ack_ready{ false }; - auto task = ([&ack_ready, config, &node1]() { + auto task = ([&ack_ready, config, &node1] () { fake_websocket_client client (config.websocket_config.port); client.send_message (R"json({"action": "subscribe", "topic": "vote", "ack": true})json"); client.await_ack (); @@ -518,7 +518,7 @@ TEST (websocket, vote_options_type) auto node1 (system.add_node (config)); std::atomic ack_ready{ false }; - auto task = ([&ack_ready, config, &node1]() { + auto task = ([&ack_ready, config, &node1] () { fake_websocket_client client (config.websocket_config.port); client.send_message (R"json({"action": "subscribe", "topic": "vote", "ack": true, "options": {"include_replays": "true", "include_indeterminate": "false"}})json"); client.await_ack (); @@ -560,7 +560,7 @@ TEST (websocket, vote_options_representatives) auto node1 (system.add_node (config)); std::atomic ack_ready{ false }; - auto task1 = ([&ack_ready, config, &node1]() { + auto task1 = ([&ack_ready, config, &node1] () { fake_websocket_client client (config.websocket_config.port); std::string message = boost::str (boost::format (R"json({"action": "subscribe", "topic": "vote", "ack": "true", "options": {"representatives": ["%1%"]}})json") % nano::dev_genesis_key.pub.to_account ()); client.send_message (message); @@ -584,7 +584,7 @@ TEST (websocket, vote_options_representatives) auto balance = nano::genesis_amount; system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv); auto send_amount = node1->online_reps.delta () + 1; - auto confirm_block = [&]() { + auto confirm_block = [&] () { nano::block_hash previous (node1->latest (nano::dev_genesis_key.pub)); balance -= send_amount; auto send (std::make_shared (nano::dev_genesis_key.pub, previous, nano::dev_genesis_key.pub, balance, key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (previous))); @@ -595,7 +595,7 @@ TEST (websocket, vote_options_representatives) ASSERT_TIMELY (5s, future1.wait_for (0s) == std::future_status::ready); ack_ready = false; - auto task2 = ([&ack_ready, config, &node1]() { + auto task2 = ([&ack_ready, config, &node1] () { fake_websocket_client client (config.websocket_config.port); client.send_message (R"json({"action": "subscribe", "topic": "vote", "ack": "true", "options": {"representatives": ["xrb_invalid"]}})json"); client.await_ack (); @@ -629,7 +629,7 @@ TEST (websocket, work) // Subscribe to work and wait for response asynchronously std::atomic ack_ready{ false }; - auto task = ([&ack_ready, config, &node1]() { + auto task = ([&ack_ready, config, &node1] () { fake_websocket_client client (config.websocket_config.port); client.send_message (R"json({"action": "subscribe", "topic": "work", "ack": true})json"); client.await_ack (); @@ -699,7 +699,7 @@ TEST (websocket, bootstrap) // Subscribe to bootstrap and wait for response asynchronously std::atomic ack_ready{ false }; - auto task = ([&ack_ready, config, &node1]() { + auto task = ([&ack_ready, config, &node1] () { fake_websocket_client client (config.websocket_config.port); client.send_message (R"json({"action": "subscribe", "topic": "bootstrap", "ack": true})json"); client.await_ack (); @@ -748,7 +748,7 @@ TEST (websocket, bootstrap_exited) // Start bootstrap, exit after subscription std::atomic bootstrap_started{ false }; nano::util::counted_completion subscribed_completion (1); - std::thread bootstrap_thread ([node1, &system, &bootstrap_started, &subscribed_completion]() { + std::thread bootstrap_thread ([node1, &system, &bootstrap_started, &subscribed_completion] () { std::shared_ptr attempt; while (attempt == nullptr) { @@ -766,7 +766,7 @@ TEST (websocket, bootstrap_exited) // Subscribe to bootstrap and wait for response asynchronously std::atomic ack_ready{ false }; - auto task = ([&ack_ready, config, &node1]() { + auto task = ([&ack_ready, config, &node1] () { fake_websocket_client client (config.websocket_config.port); client.send_message (R"json({"action": "subscribe", "topic": "bootstrap", "ack": true})json"); client.await_ack (); @@ -810,7 +810,7 @@ TEST (websocket, ws_keepalive) config.websocket_config.port = nano::get_available_port (); auto node1 (system.add_node (config)); - auto task = ([config]() { + auto task = ([config] () { fake_websocket_client client (config.websocket_config.port); client.send_message (R"json({"action": "ping"})json"); client.await_ack (); @@ -839,7 +839,7 @@ TEST (websocket, telemetry) wait_peer_connections (system); std::atomic done{ false }; - auto task = ([config = node1->config, &node1, &done]() { + auto task = ([config = node1->config, &node1, &done] () { fake_websocket_client client (config.websocket_config.port); client.send_message (R"json({"action": "subscribe", "topic": "telemetry", "ack": true})json"); client.await_ack (); @@ -852,7 +852,7 @@ TEST (websocket, telemetry) ASSERT_TIMELY (10s, done); - node1->telemetry->get_metrics_single_peer_async (node1->network.find_channel (node2->network.endpoint ()), [](auto const & response_a) { + node1->telemetry->get_metrics_single_peer_async (node1->network.find_channel (node2->network.endpoint ()), [] (auto const & response_a) { ASSERT_FALSE (response_a.error); }); @@ -889,7 +889,7 @@ TEST (websocket, new_unconfirmed_block) auto node1 (system.add_node (config)); std::atomic ack_ready{ false }; - auto task = ([&ack_ready, config, node1]() { + auto task = ([&ack_ready, config, node1] () { fake_websocket_client client (config.websocket_config.port); client.send_message (R"json({"action": "subscribe", "topic": "new_unconfirmed_block", "ack": "true"})json"); client.await_ack (); diff --git a/nano/core_test/work_watcher.cpp b/nano/core_test/work_watcher.cpp index 3b3e815b0d..e91eb98e8f 100644 --- a/nano/core_test/work_watcher.cpp +++ b/nano/core_test/work_watcher.cpp @@ -256,7 +256,7 @@ TEST (work_watcher, confirm_while_generating) ASSERT_TIMELY (5s, 0 != node.work.size ()); // Attach a callback to work cancellations std::atomic notified{ false }; - node.observers.work_cancel.add ([¬ified, &block1](nano::root const & root_a) { + node.observers.work_cancel.add ([¬ified, &block1] (nano::root const & root_a) { EXPECT_EQ (root_a, block1->root ()); notified = true; }); diff --git a/nano/node/blockprocessor.cpp b/nano/node/blockprocessor.cpp index 48cf1f3855..4718d933a7 100644 --- a/nano/node/blockprocessor.cpp +++ b/nano/node/blockprocessor.cpp @@ -31,10 +31,10 @@ node (node_a), write_database_queue (write_database_queue_a), state_block_signature_verification (node.checker, node.ledger.network_params.ledger.epochs, node.config, node.logger, node.flags.block_processor_verification_size) { - state_block_signature_verification.blocks_verified_callback = [this](std::deque> & items, std::vector const & verifications, std::vector const & hashes, std::vector const & blocks_signatures) { + state_block_signature_verification.blocks_verified_callback = [this] (std::deque> & items, std::vector const & verifications, std::vector const & hashes, std::vector const & blocks_signatures) { this->process_verified_state_blocks (items, verifications, hashes, blocks_signatures); }; - state_block_signature_verification.transition_inactive_callback = [this]() { + state_block_signature_verification.transition_inactive_callback = [this] () { if (this->flushing) { { @@ -242,7 +242,7 @@ void nano::block_processor::process_verified_state_blocks (std::deque & lock_a) { auto scoped_write_guard = write_database_queue.wait (nano::writer::process_batch); - block_post_events post_events ([& store = node.store] { return store.tx_begin_read (); }); + block_post_events post_events ([&store = node.store] { return store.tx_begin_read (); }); auto transaction (node.store.tx_begin_write ({ tables::accounts, tables::blocks, tables::frontiers, tables::pending, tables::unchecked })); nano::timer timer_l; lock_a.lock (); @@ -376,8 +376,7 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction result = node.ledger.process (transaction_a, *block, info_a.verified); switch (result.code) { - case nano::process_result::progress: - { + case nano::process_result::progress: { release_assert (info_a.account.is_zero () || info_a.account == node.store.block_account_calculated (*block)); if (node.config.logging.ledger_logging ()) { @@ -387,7 +386,7 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction } if ((info_a.modified > nano::seconds_since_epoch () - 300 && node.block_arrival.recent (hash)) || forced_a) { - events_a.events.emplace_back ([this, hash, block = info_a.block, result, watch_work_a, origin_a](nano::transaction const & post_event_transaction_a) { process_live (post_event_transaction_a, hash, block, result, watch_work_a, origin_a); }); + events_a.events.emplace_back ([this, hash, block = info_a.block, result, watch_work_a, origin_a] (nano::transaction const & post_event_transaction_a) { process_live (post_event_transaction_a, hash, block, result, watch_work_a, origin_a); }); } queue_unchecked (transaction_a, hash); /* For send blocks check epoch open unchecked (gap pending). @@ -401,8 +400,7 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction } break; } - case nano::process_result::gap_previous: - { + case nano::process_result::gap_previous: { if (node.config.logging.ledger_logging ()) { node.logger.try_log (boost::str (boost::format ("Gap previous for: %1%") % hash.to_string ())); @@ -416,13 +414,12 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction nano::unchecked_key unchecked_key (block->previous (), hash); node.store.unchecked_put (transaction_a, unchecked_key, info_a); - events_a.events.emplace_back ([this, hash](nano::transaction const & /* unused */) { this->node.gap_cache.add (hash); }); + events_a.events.emplace_back ([this, hash] (nano::transaction const & /* unused */) { this->node.gap_cache.add (hash); }); node.stats.inc (nano::stat::type::ledger, nano::stat::detail::gap_previous); break; } - case nano::process_result::gap_source: - { + case nano::process_result::gap_source: { if (node.config.logging.ledger_logging ()) { node.logger.try_log (boost::str (boost::format ("Gap source for: %1%") % hash.to_string ())); @@ -436,13 +433,12 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction nano::unchecked_key unchecked_key (node.ledger.block_source (transaction_a, *(block)), hash); node.store.unchecked_put (transaction_a, unchecked_key, info_a); - events_a.events.emplace_back ([this, hash](nano::transaction const & /* unused */) { this->node.gap_cache.add (hash); }); + events_a.events.emplace_back ([this, hash] (nano::transaction const & /* unused */) { this->node.gap_cache.add (hash); }); node.stats.inc (nano::stat::type::ledger, nano::stat::detail::gap_source); break; } - case nano::process_result::gap_epoch_open_pending: - { + case nano::process_result::gap_epoch_open_pending: { if (node.config.logging.ledger_logging ()) { node.logger.try_log (boost::str (boost::format ("Gap pending entries for epoch open: %1%") % hash.to_string ())); @@ -459,82 +455,72 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction node.stats.inc (nano::stat::type::ledger, nano::stat::detail::gap_source); break; } - case nano::process_result::old: - { + case nano::process_result::old: { if (node.config.logging.ledger_duplicate_logging ()) { node.logger.try_log (boost::str (boost::format ("Old for: %1%") % hash.to_string ())); } - events_a.events.emplace_back ([this, block = info_a.block, origin_a](nano::transaction const & post_event_transaction_a) { process_old (post_event_transaction_a, block, origin_a); }); + events_a.events.emplace_back ([this, block = info_a.block, origin_a] (nano::transaction const & post_event_transaction_a) { process_old (post_event_transaction_a, block, origin_a); }); node.stats.inc (nano::stat::type::ledger, nano::stat::detail::old); break; } - case nano::process_result::bad_signature: - { + case nano::process_result::bad_signature: { if (node.config.logging.ledger_logging ()) { node.logger.try_log (boost::str (boost::format ("Bad signature for: %1%") % hash.to_string ())); } - events_a.events.emplace_back ([this, hash, info_a](nano::transaction const & /* unused */) { requeue_invalid (hash, info_a); }); + events_a.events.emplace_back ([this, hash, info_a] (nano::transaction const & /* unused */) { requeue_invalid (hash, info_a); }); break; } - case nano::process_result::negative_spend: - { + case nano::process_result::negative_spend: { if (node.config.logging.ledger_logging ()) { node.logger.try_log (boost::str (boost::format ("Negative spend for: %1%") % hash.to_string ())); } break; } - case nano::process_result::unreceivable: - { + case nano::process_result::unreceivable: { if (node.config.logging.ledger_logging ()) { node.logger.try_log (boost::str (boost::format ("Unreceivable for: %1%") % hash.to_string ())); } break; } - case nano::process_result::fork: - { + case nano::process_result::fork: { node.stats.inc (nano::stat::type::ledger, nano::stat::detail::fork); - events_a.events.emplace_back ([this, block](nano::transaction const &) { this->node.active.publish (block); }); + events_a.events.emplace_back ([this, block] (nano::transaction const &) { this->node.active.publish (block); }); if (node.config.logging.ledger_logging ()) { node.logger.try_log (boost::str (boost::format ("Fork for: %1% root: %2%") % hash.to_string () % block->root ().to_string ())); } break; } - case nano::process_result::opened_burn_account: - { + case nano::process_result::opened_burn_account: { node.logger.always_log (boost::str (boost::format ("*** Rejecting open block for burn account ***: %1%") % hash.to_string ())); break; } - case nano::process_result::balance_mismatch: - { + case nano::process_result::balance_mismatch: { if (node.config.logging.ledger_logging ()) { node.logger.try_log (boost::str (boost::format ("Balance mismatch for: %1%") % hash.to_string ())); } break; } - case nano::process_result::representative_mismatch: - { + case nano::process_result::representative_mismatch: { if (node.config.logging.ledger_logging ()) { node.logger.try_log (boost::str (boost::format ("Representative mismatch for: %1%") % hash.to_string ())); } break; } - case nano::process_result::block_position: - { + case nano::process_result::block_position: { if (node.config.logging.ledger_logging ()) { node.logger.try_log (boost::str (boost::format ("Block %1% cannot follow predecessor %2%") % hash.to_string () % block->previous ().to_string ())); } break; } - case nano::process_result::insufficient_work: - { + case nano::process_result::insufficient_work: { if (node.config.logging.ledger_logging ()) { node.logger.try_log (boost::str (boost::format ("Insufficient work for %1% : %2% (difficulty %3%)") % hash.to_string () % nano::to_string_hex (block->block_work ()) % nano::to_string_hex (block->difficulty ()))); diff --git a/nano/node/blockprocessor.hpp b/nano/node/blockprocessor.hpp index ad1f4f74ab..27f754592e 100644 --- a/nano/node/blockprocessor.hpp +++ b/nano/node/blockprocessor.hpp @@ -33,7 +33,7 @@ class block_post_events final public: explicit block_post_events (std::function &&); ~block_post_events (); - std::deque> events; + std::deque> events; private: std::function get_transaction; diff --git a/nano/node/election.cpp b/nano/node/election.cpp index 4257d75352..5efb24c6f5 100644 --- a/nano/node/election.cpp +++ b/nano/node/election.cpp @@ -18,7 +18,7 @@ nano::election_vote_result::election_vote_result (bool replay_a, bool processed_ processed = processed_a; } -nano::election::election (nano::node & node_a, std::shared_ptr const & block_a, std::function const &)> const & confirmation_action_a, std::function const & live_vote_action_a, bool prioritized_a, nano::election_behavior election_behavior_a) : +nano::election::election (nano::node & node_a, std::shared_ptr const & block_a, std::function const &)> const & confirmation_action_a, std::function const & live_vote_action_a, bool prioritized_a, nano::election_behavior election_behavior_a) : confirmation_action (confirmation_action_a), live_vote_action (live_vote_action_a), prioritized_m (prioritized_a), @@ -52,7 +52,7 @@ void nano::election::confirm_once (nano::unique_lock & lock_a, nano lock_a.unlock (); node.active.add_recently_confirmed (status_l.winner->qualified_root (), status_l.winner->hash ()); node.process_confirmed (status_l); - node.background ([node_l = node.shared (), status_l, confirmation_action_l = confirmation_action]() { + node.background ([node_l = node.shared (), status_l, confirmation_action_l = confirmation_action] () { if (confirmation_action_l) { confirmation_action_l (status_l.winner); @@ -551,7 +551,7 @@ bool nano::election::replace_by_weight (nano::unique_lock & lock_a, std::copy (last_tally.begin (), last_tally.end (), std::back_inserter (sorted)); lock_a.unlock (); // Sort in ascending order - std::sort (sorted.begin (), sorted.end (), [](auto const & left, auto const & right) { return left.second < right.second; }); + std::sort (sorted.begin (), sorted.end (), [] (auto const & left, auto const & right) { return left.second < right.second; }); // Replace if lowest tally is below inactive cache new block weight auto inactive_existing (node.active.find_inactive_votes_cache (hash_a)); auto inactive_tally (inactive_existing.status.tally); @@ -560,7 +560,7 @@ bool nano::election::replace_by_weight (nano::unique_lock & lock_a, // If count of tally items is less than 10, remove any block without tally for (auto const & [hash, block] : blocks ()) { - if (std::find_if (sorted.begin (), sorted.end (), [& hash = hash](auto const & item_a) { return item_a.first == hash; }) == sorted.end () && hash != winner_hash) + if (std::find_if (sorted.begin (), sorted.end (), [&hash = hash] (auto const & item_a) { return item_a.first == hash; }) == sorted.end () && hash != winner_hash) { replaced_block = hash; break; @@ -630,6 +630,6 @@ std::vector nano::election::votes_with_weight () co } } result.reserve (sorted_votes.size ()); - std::transform (sorted_votes.begin (), sorted_votes.end (), std::back_inserter (result), [](auto const & entry) { return entry.second; }); + std::transform (sorted_votes.begin (), sorted_votes.end (), std::back_inserter (result), [] (auto const & entry) { return entry.second; }); return result; } diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 45a0ab5f72..a44f9963f1 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -35,7 +35,7 @@ extern size_t nano_bootstrap_weights_beta_size; void nano::node::keepalive (std::string const & address_a, uint16_t port_a) { auto node_l (shared_from_this ()); - network.resolver.async_resolve (boost::asio::ip::udp::resolver::query (address_a, std::to_string (port_a)), [node_l, address_a, port_a](boost::system::error_code const & ec, boost::asio::ip::udp::resolver::iterator i_a) { + network.resolver.async_resolve (boost::asio::ip::udp::resolver::query (address_a, std::to_string (port_a)), [node_l, address_a, port_a] (boost::system::error_code const & ec, boost::asio::ip::udp::resolver::iterator i_a) { if (!ec) { for (auto i (i_a), n (boost::asio::ip::udp::resolver::iterator{}); i != n; ++i) @@ -45,7 +45,7 @@ void nano::node::keepalive (std::string const & address_a, uint16_t port_a) auto channel (node_l->network.find_channel (endpoint)); if (!channel) { - node_l->network.tcp_channels.start_tcp (endpoint, [node_w](std::shared_ptr const & channel_a) { + node_l->network.tcp_channels.start_tcp (endpoint, [node_w] (std::shared_ptr const & channel_a) { if (auto node_l = node_w.lock ()) { node_l->network.send_keepalive (channel_a); @@ -132,7 +132,7 @@ node_seq (seq) if (!init_error ()) { telemetry->start (); - + active.vacancy_update = [this] () { scheduler.observe (); }; if (config.websocket_config.enabled) @@ -142,24 +142,24 @@ node_seq (seq) this->websocket_server->run (); } - wallets.observer = [this](bool active) { + wallets.observer = [this] (bool active) { observers.wallet.notify (active); }; - network.channel_observer = [this](std::shared_ptr const & channel_a) { + network.channel_observer = [this] (std::shared_ptr const & channel_a) { debug_assert (channel_a != nullptr); observers.endpoint.notify (channel_a); }; - network.disconnect_observer = [this]() { + network.disconnect_observer = [this] () { observers.disconnect.notify (); }; if (!config.callback_address.empty ()) { - observers.blocks.add ([this](nano::election_status const & status_a, std::vector const & votes_a, nano::account const & account_a, nano::amount const & amount_a, bool is_state_send_a) { + observers.blocks.add ([this] (nano::election_status const & status_a, std::vector const & votes_a, nano::account const & account_a, nano::amount const & amount_a, bool is_state_send_a) { auto block_a (status_a.winner); if ((status_a.type == nano::election_status_type::active_confirmed_quorum || status_a.type == nano::election_status_type::active_confirmation_height) && this->block_arrival.recent (block_a->hash ())) { auto node_l (shared_from_this ()); - background ([node_l, block_a, account_a, amount_a, is_state_send_a]() { + background ([node_l, block_a, account_a, amount_a, is_state_send_a] () { boost::property_tree::ptree event; event.add ("account", account_a.to_account ()); event.add ("hash", block_a->hash ().to_string ()); @@ -196,7 +196,7 @@ node_seq (seq) auto port (node_l->config.callback_port); auto target (std::make_shared (node_l->config.callback_target)); auto resolver (std::make_shared (node_l->io_ctx)); - resolver->async_resolve (boost::asio::ip::tcp::resolver::query (address, std::to_string (port)), [node_l, address, port, target, body, resolver](boost::system::error_code const & ec, boost::asio::ip::tcp::resolver::iterator i_a) { + resolver->async_resolve (boost::asio::ip::tcp::resolver::query (address, std::to_string (port)), [node_l, address, port, target, body, resolver] (boost::system::error_code const & ec, boost::asio::ip::tcp::resolver::iterator i_a) { if (!ec) { node_l->do_rpc_callback (i_a, address, port, target, body, resolver); @@ -216,7 +216,7 @@ node_seq (seq) } if (websocket_server) { - observers.blocks.add ([this](nano::election_status const & status_a, std::vector const & votes_a, nano::account const & account_a, nano::amount const & amount_a, bool is_state_send_a) { + observers.blocks.add ([this] (nano::election_status const & status_a, std::vector const & votes_a, nano::account const & account_a, nano::amount const & amount_a, bool is_state_send_a) { debug_assert (status_a.type != nano::election_status_type::ongoing); if (this->websocket_server->any_subscriber (nano::websocket::topic::confirmation)) @@ -247,7 +247,7 @@ node_seq (seq) } }); - observers.active_stopped.add ([this](nano::block_hash const & hash_a) { + observers.active_stopped.add ([this] (nano::block_hash const & hash_a) { if (this->websocket_server->any_subscriber (nano::websocket::topic::stopped_election)) { nano::websocket::message_builder builder; @@ -255,7 +255,7 @@ node_seq (seq) } }); - observers.difficulty.add ([this](uint64_t active_difficulty) { + observers.difficulty.add ([this] (uint64_t active_difficulty) { if (this->websocket_server->any_subscriber (nano::websocket::topic::active_difficulty)) { nano::websocket::message_builder builder; @@ -264,7 +264,7 @@ node_seq (seq) } }); - observers.telemetry.add ([this](nano::telemetry_data const & telemetry_data, nano::endpoint const & endpoint) { + observers.telemetry.add ([this] (nano::telemetry_data const & telemetry_data, nano::endpoint const & endpoint) { if (this->websocket_server->any_subscriber (nano::websocket::topic::telemetry)) { nano::websocket::message_builder builder; @@ -273,7 +273,7 @@ node_seq (seq) }); } // Add block confirmation type stats regardless of http-callback and websocket subscriptions - observers.blocks.add ([this](nano::election_status const & status_a, std::vector const & votes_a, nano::account const & account_a, nano::amount const & amount_a, bool is_state_send_a) { + observers.blocks.add ([this] (nano::election_status const & status_a, std::vector const & votes_a, nano::account const & account_a, nano::amount const & amount_a, bool is_state_send_a) { debug_assert (status_a.type != nano::election_status_type::ongoing); switch (status_a.type) { @@ -290,7 +290,7 @@ node_seq (seq) break; } }); - observers.endpoint.add ([this](std::shared_ptr const & channel_a) { + observers.endpoint.add ([this] (std::shared_ptr const & channel_a) { if (channel_a->get_type () == nano::transport::transport_type::udp) { this->network.send_keepalive (channel_a); @@ -300,7 +300,7 @@ node_seq (seq) this->network.send_keepalive_self (channel_a); } }); - observers.vote.add ([this](std::shared_ptr vote_a, std::shared_ptr const & channel_a, nano::vote_code code_a) { + observers.vote.add ([this] (std::shared_ptr vote_a, std::shared_ptr const & channel_a, nano::vote_code code_a) { debug_assert (code_a != nano::vote_code::invalid); // The vote_code::vote is handled inside the election if (code_a == nano::vote_code::indeterminate) @@ -316,7 +316,7 @@ node_seq (seq) }); if (websocket_server) { - observers.vote.add ([this](std::shared_ptr vote_a, std::shared_ptr const & channel_a, nano::vote_code code_a) { + observers.vote.add ([this] (std::shared_ptr vote_a, std::shared_ptr const & channel_a, nano::vote_code code_a) { if (this->websocket_server->any_subscriber (nano::websocket::topic::vote)) { nano::websocket::message_builder builder; @@ -326,7 +326,7 @@ node_seq (seq) }); } // Cancelling local work generation - observers.work_cancel.add ([this](nano::root const & root_a) { + observers.work_cancel.add ([this] (nano::root const & root_a) { this->work.cancel (root_a); this->distributed_work.cancel (root_a); }); @@ -464,7 +464,7 @@ void nano::node::do_rpc_callback (boost::asio::ip::tcp::resolver::iterator i_a, { auto node_l (shared_from_this ()); auto sock (std::make_shared (node_l->io_ctx)); - sock->async_connect (i_a->endpoint (), [node_l, target, body, sock, address, port, i_a, resolver](boost::system::error_code const & ec) mutable { + sock->async_connect (i_a->endpoint (), [node_l, target, body, sock, address, port, i_a, resolver] (boost::system::error_code const & ec) mutable { if (!ec) { auto req (std::make_shared> ()); @@ -475,12 +475,12 @@ void nano::node::do_rpc_callback (boost::asio::ip::tcp::resolver::iterator i_a, req->insert (boost::beast::http::field::content_type, "application/json"); req->body () = *body; req->prepare_payload (); - boost::beast::http::async_write (*sock, *req, [node_l, sock, address, port, req, i_a, target, body, resolver](boost::system::error_code const & ec, size_t bytes_transferred) mutable { + boost::beast::http::async_write (*sock, *req, [node_l, sock, address, port, req, i_a, target, body, resolver] (boost::system::error_code const & ec, size_t bytes_transferred) mutable { if (!ec) { auto sb (std::make_shared ()); auto resp (std::make_shared> ()); - boost::beast::http::async_read (*sock, *sb, *resp, [node_l, sb, resp, sock, address, port, i_a, target, body, resolver](boost::system::error_code const & ec, size_t bytes_transferred) mutable { + boost::beast::http::async_read (*sock, *sb, *resp, [node_l, sb, resp, sock, address, port, i_a, target, body, resolver] (boost::system::error_code const & ec, size_t bytes_transferred) mutable { if (!ec) { if (boost::beast::http::to_status_class (resp->result ()) == boost::beast::http::status_class::successful) @@ -588,7 +588,7 @@ nano::process_return nano::node::process_local (std::shared_ptr con // Notify block processor to release write lock block_processor.wait_write (); // Process block - block_post_events post_events ([& store = store] { return store.tx_begin_read (); }); + block_post_events post_events ([&store = store] { return store.tx_begin_read (); }); auto transaction (store.tx_begin_write ({ tables::accounts, tables::blocks, tables::frontiers, tables::pending })); return block_processor.process_one (transaction, post_events, info, work_watcher_a, false, nano::block_origin::local); } @@ -614,14 +614,14 @@ void nano::node::start () if (!flags.disable_unchecked_cleanup) { auto this_l (shared ()); - workers.push_task ([this_l]() { + workers.push_task ([this_l] () { this_l->ongoing_unchecked_cleanup (); }); } if (flags.enable_pruning) { auto this_l (shared ()); - workers.push_task ([this_l]() { + workers.push_task ([this_l] () { this_l->ongoing_ledger_pruning (); }); } @@ -650,7 +650,7 @@ void nano::node::start () { // Delay to start wallet lazy bootstrap auto this_l (shared ()); - workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::minutes (1), [this_l]() { + workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::minutes (1), [this_l] () { this_l->bootstrap_wallet (); }); } @@ -661,7 +661,7 @@ void nano::node::start () } if (config.frontiers_confirmation != nano::frontiers_confirmation_mode::disabled) { - workers.push_task([this_l = shared ()] () { + workers.push_task ([this_l = shared ()] () { this_l->ongoing_backlog_population (); }); } @@ -794,7 +794,7 @@ void nano::node::ongoing_rep_calculation () auto now (std::chrono::steady_clock::now ()); vote_processor.calculate_weights (); std::weak_ptr node_w (shared_from_this ()); - workers.add_timed_task (now + std::chrono::minutes (10), [node_w]() { + workers.add_timed_task (now + std::chrono::minutes (10), [node_w] () { if (auto node_l = node_w.lock ()) { node_l->ongoing_rep_calculation (); @@ -854,7 +854,7 @@ void nano::node::ongoing_bootstrap () // Bootstrap and schedule for next attempt bootstrap_initiator.bootstrap (false, boost::str (boost::format ("auto_bootstrap_%1%") % previous_bootstrap_count), frontiers_age); std::weak_ptr node_w (shared_from_this ()); - workers.add_timed_task (std::chrono::steady_clock::now () + next_wakeup, [node_w]() { + workers.add_timed_task (std::chrono::steady_clock::now () + next_wakeup, [node_w] () { if (auto node_l = node_w.lock ()) { node_l->ongoing_bootstrap (); @@ -867,7 +867,7 @@ void nano::node::ongoing_peer_store () bool stored (network.tcp_channels.store_all (true)); network.udp_channels.store_all (!stored); std::weak_ptr node_w (shared_from_this ()); - workers.add_timed_task (std::chrono::steady_clock::now () + network_params.node.peer_interval, [node_w]() { + workers.add_timed_task (std::chrono::steady_clock::now () + network_params.node.peer_interval, [node_w] () { if (auto node_l = node_w.lock ()) { node_l->ongoing_peer_store (); @@ -888,7 +888,7 @@ void nano::node::backup_wallet () i->second->store.write_backup (transaction, backup_path / (i->first.to_string () + ".json")); } auto this_l (shared ()); - workers.add_timed_task (std::chrono::steady_clock::now () + network_params.node.backup_interval, [this_l]() { + workers.add_timed_task (std::chrono::steady_clock::now () + network_params.node.backup_interval, [this_l] () { this_l->backup_wallet (); }); } @@ -900,7 +900,7 @@ void nano::node::search_pending () // Search pending wallets.search_pending_all (); auto this_l (shared ()); - workers.add_timed_task (std::chrono::steady_clock::now () + network_params.node.search_pending_interval, [this_l]() { + workers.add_timed_task (std::chrono::steady_clock::now () + network_params.node.search_pending_interval, [this_l] () { this_l->search_pending (); }); } @@ -977,7 +977,7 @@ void nano::node::unchecked_cleanup () void nano::node::ongoing_unchecked_cleanup () { unchecked_cleanup (); - workers.add_timed_task (std::chrono::steady_clock::now () + network_params.node.unchecked_cleaning_interval, [this_l = shared ()]() { + workers.add_timed_task (std::chrono::steady_clock::now () + network_params.node.unchecked_cleaning_interval, [this_l = shared ()] () { this_l->ongoing_unchecked_cleanup (); }); } @@ -1102,8 +1102,8 @@ void nano::node::ongoing_ledger_pruning () ledger_pruning (flags.block_processor_batch_size != 0 ? flags.block_processor_batch_size : 2 * 1024, bootstrap_weight_reached, false); auto ledger_pruning_interval (bootstrap_weight_reached ? config.max_pruning_age : std::min (config.max_pruning_age, std::chrono::seconds (15 * 60))); auto this_l (shared ()); - workers.add_timed_task (std::chrono::steady_clock::now () + ledger_pruning_interval, [this_l]() { - this_l->workers.push_task ([this_l]() { + workers.add_timed_task (std::chrono::steady_clock::now () + ledger_pruning_interval, [this_l] () { + this_l->workers.push_task ([this_l] () { this_l->ongoing_ledger_pruning (); }); }); @@ -1183,7 +1183,7 @@ boost::optional nano::node::work_generate_blocking (nano::block & bloc return opt_work_l; } -void nano::node::work_generate (nano::work_version const version_a, nano::root const & root_a, uint64_t difficulty_a, std::function)> callback_a, boost::optional const & account_a, bool secondary_work_peers_a) +void nano::node::work_generate (nano::work_version const version_a, nano::root const & root_a, uint64_t difficulty_a, std::function)> callback_a, boost::optional const & account_a, bool secondary_work_peers_a) { auto const & peers_l (secondary_work_peers_a ? config.secondary_work_peers : config.work_peers); if (distributed_work.make (version_a, root_a, peers_l, difficulty_a, callback_a, account_a)) @@ -1197,7 +1197,7 @@ boost::optional nano::node::work_generate_blocking (nano::work_version { std::promise> promise; work_generate ( - version_a, root_a, difficulty_a, [&promise](boost::optional opt_work_a) { + version_a, root_a, difficulty_a, [&promise] (boost::optional opt_work_a) { promise.set_value (opt_work_a); }, account_a); @@ -1231,7 +1231,7 @@ void nano::node::add_initial_peers () if (!network.reachout (endpoint, config.allow_local_peers)) { std::weak_ptr node_w (shared_from_this ()); - network.tcp_channels.start_tcp (endpoint, [node_w](std::shared_ptr const & channel_a) { + network.tcp_channels.start_tcp (endpoint, [node_w] (std::shared_ptr const & channel_a) { if (auto node_l = node_w.lock ()) { node_l->network.send_keepalive (channel_a); @@ -1270,7 +1270,7 @@ bool nano::node::block_confirmed_or_being_confirmed (nano::transaction const & t void nano::node::ongoing_online_weight_calculation_queue () { std::weak_ptr node_w (shared_from_this ()); - workers.add_timed_task (std::chrono::steady_clock::now () + (std::chrono::seconds (network_params.node.weight_period)), [node_w]() { + workers.add_timed_task (std::chrono::steady_clock::now () + (std::chrono::seconds (network_params.node.weight_period)), [node_w] () { if (auto node_l = node_w.lock ()) { node_l->ongoing_online_weight_calculation (); @@ -1306,7 +1306,7 @@ void nano::node::receive_confirmed (nano::transaction const & block_transaction_ if (!error) { auto amount (pending.amount.number ()); - wallet->receive_async (hash_a, representative, amount, destination_a, [](std::shared_ptr const &) {}); + wallet->receive_async (hash_a, representative, amount, destination_a, [] (std::shared_ptr const &) {}); } else { @@ -1378,7 +1378,7 @@ void nano::node::process_confirmed (nano::election_status const & status_a, uint { iteration_a++; std::weak_ptr node_w (shared ()); - workers.add_timed_task (std::chrono::steady_clock::now () + network_params.node.process_confirmed_interval, [node_w, status_a, iteration_a]() { + workers.add_timed_task (std::chrono::steady_clock::now () + network_params.node.process_confirmed_interval, [node_w, status_a, iteration_a] () { if (auto node_l = node_w.lock ()) { node_l->process_confirmed (status_a, iteration_a); @@ -1460,7 +1460,7 @@ bool nano::node::epoch_upgrader (nano::raw_key const & prv_a, nano::epoch epoch_ void nano::node::epoch_upgrader_impl (nano::raw_key const & prv_a, nano::epoch epoch_a, uint64_t count_limit, uint64_t threads) { nano::thread_role::set (nano::thread_role::name::epoch_upgrader); - auto upgrader_process = [](nano::node & node_a, std::atomic & counter, std::shared_ptr const & epoch, uint64_t difficulty, nano::public_key const & signer_a, nano::root const & root_a, nano::account const & account_a) { + auto upgrader_process = [] (nano::node & node_a, std::atomic & counter, std::shared_ptr const & epoch, uint64_t difficulty, nano::public_key const & signer_a, nano::root const & root_a, nano::account const & account_a) { epoch->block_work_set (node_a.work_generate_blocking (nano::work_version::work_1, root_a, difficulty).value_or (0)); bool valid_signature (!nano::validate_message (signer_a, epoch->hash (), epoch->block_signature ())); bool valid_work (epoch->difficulty () >= difficulty); @@ -1571,7 +1571,7 @@ void nano::node::epoch_upgrader_impl (nano::raw_key const & prv_a, nano::epoch e upgrader_condition.wait (lock); } } - this->workers.push_task ([node_l = shared_from_this (), &upgrader_process, &upgrader_mutex, &upgrader_condition, &upgraded_accounts, &workers, epoch, difficulty, signer, root, account]() { + this->workers.push_task ([node_l = shared_from_this (), &upgrader_process, &upgrader_mutex, &upgrader_condition, &upgraded_accounts, &workers, epoch, difficulty, signer, root, account] () { upgrader_process (*node_l, upgraded_accounts, epoch, difficulty, signer, root, account); { nano::lock_guard lock (upgrader_mutex); @@ -1650,7 +1650,7 @@ void nano::node::epoch_upgrader_impl (nano::raw_key const & prv_a, nano::epoch e upgrader_condition.wait (lock); } } - this->workers.push_task ([node_l = shared_from_this (), &upgrader_process, &upgrader_mutex, &upgrader_condition, &upgraded_pending, &workers, epoch, difficulty, signer, root, account]() { + this->workers.push_task ([node_l = shared_from_this (), &upgrader_process, &upgrader_mutex, &upgrader_condition, &upgraded_pending, &workers, epoch, difficulty, signer, root, account] () { upgrader_process (*node_l, upgraded_pending, epoch, difficulty, signer, root, account); { nano::lock_guard lock (upgrader_mutex); diff --git a/nano/node/node.hpp b/nano/node/node.hpp index 949c287932..184cfb1332 100644 --- a/nano/node/node.hpp +++ b/nano/node/node.hpp @@ -138,7 +138,7 @@ class node final : public std::enable_shared_from_this bool work_generation_enabled (std::vector> const &) const; boost::optional work_generate_blocking (nano::block &, uint64_t); boost::optional work_generate_blocking (nano::work_version const, nano::root const &, uint64_t, boost::optional const & = boost::none); - void work_generate (nano::work_version const, nano::root const &, uint64_t, std::function)>, boost::optional const & = boost::none, bool const = false); + void work_generate (nano::work_version const, nano::root const &, uint64_t, std::function)>, boost::optional const & = boost::none, bool const = false); void add_initial_peers (); void block_confirm (std::shared_ptr const &); bool block_confirmed (nano::block_hash const &); diff --git a/nano/node/vote_processor.cpp b/nano/node/vote_processor.cpp index d0283074ed..bfacd1a2d2 100644 --- a/nano/node/vote_processor.cpp +++ b/nano/node/vote_processor.cpp @@ -30,13 +30,13 @@ max_votes (flags_a.vote_processor_capacity), started (false), stopped (false), is_active (false), -thread ([this]() { +thread ([this] () { nano::thread_role::set (nano::thread_role::name::vote_processing); process_loop (); }) { nano::unique_lock lock (mutex); - condition.wait (lock, [& started = started] { return started; }); + condition.wait (lock, [&started = started] { return started; }); } void nano::vote_processor::process_loop () diff --git a/nano/node/wallet.cpp b/nano/node/wallet.cpp index 243b352f7e..16229c6525 100644 --- a/nano/node/wallet.cpp +++ b/nano/node/wallet.cpp @@ -114,15 +114,13 @@ void nano::wallet_store::deterministic_clear (nano::transaction const & transact { switch (key_type (nano::wallet_value (i->second))) { - case nano::key_type::deterministic: - { + case nano::key_type::deterministic: { auto const & key (i->first); erase (transaction_a, key); i = begin (transaction_a, key); break; } - default: - { + default: { ++i; break; } @@ -486,24 +484,21 @@ bool nano::wallet_store::fetch (nano::transaction const & transaction_a, nano::a { switch (key_type (value)) { - case nano::key_type::deterministic: - { + case nano::key_type::deterministic: { nano::raw_key seed_l; seed (seed_l, transaction_a); uint32_t index (static_cast (value.key.number () & static_cast (-1))); prv = deterministic_key (transaction_a, index); break; } - case nano::key_type::adhoc: - { + case nano::key_type::adhoc: { // Ad-hoc keys nano::raw_key password_l; wallet_key (password_l, transaction_a); prv.decrypt (value.key, password_l, pub.owords[0].number ()); break; } - default: - { + default: { result = true; break; } @@ -659,14 +654,14 @@ void nano::kdf::phs (nano::raw_key & result_a, std::string const & password_a, n } nano::wallet::wallet (bool & init_a, nano::transaction & transaction_a, nano::wallets & wallets_a, std::string const & wallet_a) : -lock_observer ([](bool, bool) {}), +lock_observer ([] (bool, bool) {}), store (init_a, wallets_a.kdf, transaction_a, wallets_a.node.config.random_representative (), wallets_a.node.config.password_fanout, wallet_a), wallets (wallets_a) { } nano::wallet::wallet (bool & init_a, nano::transaction & transaction_a, nano::wallets & wallets_a, std::string const & wallet_a, std::string const & json) : -lock_observer ([](bool, bool) {}), +lock_observer ([] (bool, bool) {}), store (init_a, wallets_a.kdf, transaction_a, wallets_a.node.config.random_representative (), wallets_a.node.config.password_fanout, wallet_a, json), wallets (wallets_a) { @@ -700,7 +695,7 @@ bool nano::wallet::enter_password (nano::transaction const & transaction_a, std: if (!result) { auto this_l (shared_from_this ()); - wallets.node.background ([this_l]() { + wallets.node.background ([this_l] () { this_l->search_pending (this_l->wallets.tx_begin_read ()); }); wallets.node.logger.try_log ("Wallet unlocked"); @@ -942,7 +937,7 @@ std::shared_ptr nano::wallet::send_action (nano::account const & so id_mdb_val = nano::mdb_val (id_a->size (), const_cast (id_a->data ())); } - auto prepare_send = [&id_mdb_val, &wallets = this->wallets, &store = this->store, &source_a, &amount_a, &work_a, &account_a](const auto & transaction) { + auto prepare_send = [&id_mdb_val, &wallets = this->wallets, &store = this->store, &source_a, &amount_a, &work_a, &account_a] (const auto & transaction) { auto block_transaction (wallets.node.store.tx_begin_read ()); auto error (false); auto cached_block (false); @@ -1070,17 +1065,17 @@ bool nano::wallet::change_sync (nano::account const & source_a, nano::account co std::promise result; std::future future = result.get_future (); change_async ( - source_a, representative_a, [&result](std::shared_ptr const & block_a) { + source_a, representative_a, [&result] (std::shared_ptr const & block_a) { result.set_value (block_a == nullptr); }, true); return future.get (); } -void nano::wallet::change_async (nano::account const & source_a, nano::account const & representative_a, std::function const &)> const & action_a, uint64_t work_a, bool generate_work_a) +void nano::wallet::change_async (nano::account const & source_a, nano::account const & representative_a, std::function const &)> const & action_a, uint64_t work_a, bool generate_work_a) { auto this_l (shared_from_this ()); - wallets.node.wallets.queue_wallet_action (nano::wallets::high_priority, this_l, [this_l, source_a, representative_a, action_a, work_a, generate_work_a](nano::wallet & wallet_a) { + wallets.node.wallets.queue_wallet_action (nano::wallets::high_priority, this_l, [this_l, source_a, representative_a, action_a, work_a, generate_work_a] (nano::wallet & wallet_a) { auto block (wallet_a.change_action (source_a, representative_a, work_a, generate_work_a)); action_a (block); }); @@ -1092,17 +1087,17 @@ bool nano::wallet::receive_sync (std::shared_ptr const & block_a, n std::future future = result.get_future (); auto destination (block_a->link ().is_zero () ? block_a->destination () : block_a->link ().as_account ()); receive_async ( - block_a->hash (), representative_a, amount_a, destination, [&result](std::shared_ptr const & block_a) { + block_a->hash (), representative_a, amount_a, destination, [&result] (std::shared_ptr const & block_a) { result.set_value (block_a == nullptr); }, true); return future.get (); } -void nano::wallet::receive_async (nano::block_hash const & hash_a, nano::account const & representative_a, nano::uint128_t const & amount_a, nano::account const & account_a, std::function const &)> const & action_a, uint64_t work_a, bool generate_work_a) +void nano::wallet::receive_async (nano::block_hash const & hash_a, nano::account const & representative_a, nano::uint128_t const & amount_a, nano::account const & account_a, std::function const &)> const & action_a, uint64_t work_a, bool generate_work_a) { auto this_l (shared_from_this ()); - wallets.node.wallets.queue_wallet_action (amount_a, this_l, [this_l, hash_a, representative_a, amount_a, account_a, action_a, work_a, generate_work_a](nano::wallet & wallet_a) { + wallets.node.wallets.queue_wallet_action (amount_a, this_l, [this_l, hash_a, representative_a, amount_a, account_a, action_a, work_a, generate_work_a] (nano::wallet & wallet_a) { auto block (wallet_a.receive_action (hash_a, representative_a, amount_a, account_a, work_a, generate_work_a)); action_a (block); }); @@ -1113,17 +1108,17 @@ nano::block_hash nano::wallet::send_sync (nano::account const & source_a, nano:: std::promise result; std::future future = result.get_future (); send_async ( - source_a, account_a, amount_a, [&result](std::shared_ptr const & block_a) { + source_a, account_a, amount_a, [&result] (std::shared_ptr const & block_a) { result.set_value (block_a->hash ()); }, true); return future.get (); } -void nano::wallet::send_async (nano::account const & source_a, nano::account const & account_a, nano::uint128_t const & amount_a, std::function const &)> const & action_a, uint64_t work_a, bool generate_work_a, boost::optional id_a) +void nano::wallet::send_async (nano::account const & source_a, nano::account const & account_a, nano::uint128_t const & amount_a, std::function const &)> const & action_a, uint64_t work_a, bool generate_work_a, boost::optional id_a) { auto this_l (shared_from_this ()); - wallets.node.wallets.queue_wallet_action (nano::wallets::high_priority, this_l, [this_l, source_a, account_a, amount_a, action_a, work_a, generate_work_a, id_a](nano::wallet & wallet_a) { + wallets.node.wallets.queue_wallet_action (nano::wallets::high_priority, this_l, [this_l, source_a, account_a, amount_a, action_a, work_a, generate_work_a, id_a] (nano::wallet & wallet_a) { auto block (wallet_a.send_action (source_a, account_a, amount_a, work_a, generate_work_a, id_a)); action_a (block); }); @@ -1159,7 +1154,7 @@ void nano::wallet::work_ensure (nano::account const & account_a, nano::root cons if (existing != delayed_work->end () && existing->second == root_a) { delayed_work->erase (existing); - this_l->wallets.queue_wallet_action (nano::wallets::generate_priority, this_l, [account_a, root_a](nano::wallet & wallet_a) { + this_l->wallets.queue_wallet_action (nano::wallets::generate_priority, this_l, [account_a, root_a] (nano::wallet & wallet_a) { wallet_a.work_cache_blocking (account_a, root_a); }); } @@ -1192,7 +1187,7 @@ bool nano::wallet::search_pending (nano::transaction const & wallet_transaction_ { auto representative = store.representative (wallet_transaction_a); // Receive confirmed block - receive_async (hash, representative, amount, account, [](std::shared_ptr const &) {}); + receive_async (hash, representative, amount, account, [] (std::shared_ptr const &) {}); } else if (!wallets.node.confirmation_height_processor.is_processing_block (hash)) { @@ -1312,7 +1307,7 @@ nano::work_watcher::work_watcher (nano::node & node_a) : node (node_a), stopped (false) { - node.observers.blocks.add ([this](nano::election_status const & status_a, std::vector const & votes_a, nano::account const & account_a, nano::amount const & amount_a, bool is_state_send_a) { + node.observers.blocks.add ([this] (nano::election_status const & status_a, std::vector const & votes_a, nano::account const & account_a, nano::amount const & amount_a, bool is_state_send_a) { this->remove (*status_a.winner); }); } @@ -1351,7 +1346,7 @@ void nano::work_watcher::update (nano::qualified_root const & root_a, std::share void nano::work_watcher::watching (nano::qualified_root const & root_a, std::shared_ptr const & block_a) { std::weak_ptr watcher_w (shared_from_this ()); - node.workers.add_timed_task (std::chrono::steady_clock::now () + node.config.work_watcher_period, [block_a, root_a, watcher_w]() { + node.workers.add_timed_task (std::chrono::steady_clock::now () + node.config.work_watcher_period, [block_a, root_a, watcher_w] () { auto watcher_l = watcher_w.lock (); if (watcher_l && !watcher_l->stopped && watcher_l->is_watched (root_a)) { @@ -1363,7 +1358,7 @@ void nano::work_watcher::watching (nano::qualified_root const & root_a, std::sha if (active_difficulty > block_a->difficulty () && watcher_l->node.work_generation_enabled ()) { watcher_l->node.work_generate ( - block_a->work_version (), block_a->root (), active_difficulty, [watcher_l, block_a, root_a](boost::optional work_a) { + block_a->work_version (), block_a->root (), active_difficulty, [watcher_l, block_a, root_a] (boost::optional work_a) { if (watcher_l->is_watched (root_a)) { if (work_a.is_initialized ()) @@ -1451,12 +1446,12 @@ void nano::wallets::do_wallet_actions () } nano::wallets::wallets (bool error_a, nano::node & node_a) : -observer ([](bool) {}), +observer ([] (bool) {}), node (node_a), env (boost::polymorphic_downcast (node_a.wallets_store_impl.get ())->environment), stopped (false), watcher (std::make_shared (node_a)), -thread ([this]() { +thread ([this] () { nano::thread_role::set (nano::thread_role::name::wallet_actions); do_wallet_actions (); }) @@ -1636,7 +1631,7 @@ void nano::wallets::reload () } } -void nano::wallets::queue_wallet_action (nano::uint128_t const & amount_a, std::shared_ptr const & wallet_a, std::function action_a) +void nano::wallets::queue_wallet_action (nano::uint128_t const & amount_a, std::shared_ptr const & wallet_a, std::function action_a) { { nano::lock_guard action_lock (action_mutex); @@ -1645,7 +1640,7 @@ void nano::wallets::queue_wallet_action (nano::uint128_t const & amount_a, std:: condition.notify_all (); } -void nano::wallets::foreach_representative (std::function const & action_a) +void nano::wallets::foreach_representative (std::function const & action_a) { if (node.config.enable_voting) { @@ -1797,7 +1792,7 @@ void nano::wallets::ongoing_compute_reps () compute_reps (); auto & node_l (node); auto compute_delay (network_params.network.is_dev_network () ? std::chrono::milliseconds (10) : std::chrono::milliseconds (15 * 60 * 1000)); // Representation drifts quickly on the test network but very slowly on the live network - node.workers.add_timed_task (std::chrono::steady_clock::now () + compute_delay, [&node_l]() { + node.workers.add_timed_task (std::chrono::steady_clock::now () + compute_delay, [&node_l] () { node_l.wallets.ongoing_compute_reps (); }); } @@ -1812,7 +1807,7 @@ void nano::wallets::split_if_needed (nano::transaction & transaction_destination std::string beginning (nano::uint256_union (0).to_string ()); std::string end ((nano::uint256_union (nano::uint256_t (0) - nano::uint256_t (1))).to_string ()); - auto get_store_it = [& handle = handle](nano::transaction const & transaction_source, std::string const & hash) { + auto get_store_it = [&handle = handle] (nano::transaction const & transaction_source, std::string const & hash) { return nano::store_iterator, nano::no_value> (std::make_unique, nano::no_value>> (transaction_source, handle, nano::mdb_val (hash.size (), const_cast (hash.c_str ())))); }; diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index 095bac1d04..4a41ce14e2 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -40,7 +40,7 @@ class test_response void run (uint16_t port_a) { - sock.async_connect (nano::tcp_endpoint (boost::asio::ip::address_v6::loopback (), port_a), [this](boost::system::error_code const & ec) { + sock.async_connect (nano::tcp_endpoint (boost::asio::ip::address_v6::loopback (), port_a), [this] (boost::system::error_code const & ec) { if (!ec) { std::stringstream ostream; @@ -51,10 +51,10 @@ class test_response ostream.flush (); req.body () = ostream.str (); req.prepare_payload (); - boost::beast::http::async_write (sock, req, [this](boost::system::error_code const & ec, size_t bytes_transferred) { + boost::beast::http::async_write (sock, req, [this] (boost::system::error_code const & ec, size_t bytes_transferred) { if (!ec) { - boost::beast::http::async_read (sock, sb, resp, [this](boost::system::error_code const & ec, size_t bytes_transferred) { + boost::beast::http::async_read (sock, sb, resp, [this] (boost::system::error_code const & ec, size_t bytes_transferred) { if (!ec) { std::stringstream body (resp.body ()); @@ -162,7 +162,7 @@ TEST (rpc, wrapped_task) auto & node = *add_ipc_enabled_node (system); nano::node_rpc_config node_rpc_config; std::atomic response (false); - auto response_handler_l ([&response](std::string const & response_a) { + auto response_handler_l ([&response] (std::string const & response_a) { std::stringstream istream (response_a); boost::property_tree::ptree json_l; ASSERT_NO_THROW (boost::property_tree::read_json (istream, json_l)); @@ -171,7 +171,7 @@ TEST (rpc, wrapped_task) response = true; }); auto handler_l (std::make_shared (node, node_rpc_config, "", response_handler_l)); - auto task (handler_l->create_worker_task ([](std::shared_ptr const &) { + auto task (handler_l->create_worker_task ([] (std::shared_ptr const &) { // Exception should get caught throw std::runtime_error (""); })); @@ -641,7 +641,7 @@ TEST (rpc, send_ipc_random_id) scoped_io_thread_name_change scoped_thread_name_io; nano::node_rpc_config node_rpc_config; std::atomic got_request{ false }; - node_rpc_config.set_request_callback ([&got_request](boost::property_tree::ptree const & request_a) { + node_rpc_config.set_request_callback ([&got_request] (boost::property_tree::ptree const & request_a) { EXPECT_TRUE (request_a.count ("id")); got_request = true; }); @@ -2506,7 +2506,7 @@ TEST (rpc, pending) request.put ("source", "false"); request.put ("min_version", "false"); - auto check_block_response_count = [&system, &request, &rpc](size_t size) { + auto check_block_response_count = [&system, &request, &rpc] (size_t size) { test_response response (request, rpc.config.port, system.io_ctx); ASSERT_TIMELY (5s, response.status != 0); @@ -2676,7 +2676,7 @@ TEST (rpc, work_generate) boost::property_tree::ptree request; request.put ("action", "work_generate"); request.put ("hash", hash.to_string ()); - auto verify_response = [node, &rpc, &system](auto & request, auto & hash) { + auto verify_response = [node, &rpc, &system] (auto & request, auto & hash) { test_response response (request, rpc.config.port, system.io_ctx); ASSERT_TIMELY (5s, response.status != 0); ASSERT_EQ (200, response.status); @@ -2998,7 +2998,7 @@ TEST (rpc, work_cancel) system.deadline_set (10s); while (!done) { - system.work.generate (nano::work_version::work_1, hash1, node1.network_params.network.publish_thresholds.base, [&done](boost::optional work_a) { + system.work.generate (nano::work_version::work_1, hash1, node1.network_params.network.publish_thresholds.base, [&done] (boost::optional work_a) { done = !work_a; }); test_response response1 (request1, rpc.config.port, system.io_ctx); @@ -3030,7 +3030,7 @@ TEST (rpc, work_peer_bad) node2.config.work_peers.push_back (std::make_pair (boost::asio::ip::address_v6::any ().to_string (), 0)); nano::block_hash hash1 (1); std::atomic work (0); - node2.work_generate (nano::work_version::work_1, hash1, node2.network_params.network.publish_thresholds.base, [&work](boost::optional work_a) { + node2.work_generate (nano::work_version::work_1, hash1, node2.network_params.network.publish_thresholds.base, [&work] (boost::optional work_a) { ASSERT_TRUE (work_a.is_initialized ()); work = *work_a; }); @@ -3056,7 +3056,7 @@ TEST (rpc, work_peer_one) node2.config.work_peers.push_back (std::make_pair (node1.network.endpoint ().address ().to_string (), rpc.config.port)); nano::keypair key1; std::atomic work (0); - node2.work_generate (nano::work_version::work_1, key1.pub, node1.network_params.network.publish_thresholds.base, [&work](boost::optional work_a) { + node2.work_generate (nano::work_version::work_1, key1.pub, node1.network_params.network.publish_thresholds.base, [&work] (boost::optional work_a) { ASSERT_TRUE (work_a.is_initialized ()); work = *work_a; }); @@ -3099,7 +3099,7 @@ TEST (rpc, work_peer_many) for (auto i (0); i < works.size (); ++i) { nano::keypair key1; - node1.work_generate (nano::work_version::work_1, key1.pub, node1.network_params.network.publish_thresholds.base, [& work = works[i]](boost::optional work_a) { + node1.work_generate (nano::work_version::work_1, key1.pub, node1.network_params.network.publish_thresholds.base, [&work = works[i]] (boost::optional work_a) { work = *work_a; }); while (nano::work_difficulty (nano::work_version::work_1, key1.pub, works[i]) < nano::work_threshold_base (nano::work_version::work_1)) @@ -4412,7 +4412,7 @@ TEST (rpc, pending_exists) rpc.start (); boost::property_tree::ptree request; - auto pending_exists = [&system, &request, &rpc](const char * exists_a) { + auto pending_exists = [&system, &request, &rpc] (const char * exists_a) { test_response response0 (request, rpc.config.port, system.io_ctx); ASSERT_TIMELY (10s, response0.status != 0); ASSERT_EQ (200, response0.status); @@ -5087,7 +5087,7 @@ TEST (rpc, blocks_info) nano::ipc_rpc_processor ipc_rpc_processor (system.io_ctx, rpc_config); nano::rpc rpc (system.io_ctx, rpc_config, ipc_rpc_processor); rpc.start (); - auto check_blocks = [node](test_response & response) { + auto check_blocks = [node] (test_response & response) { for (auto & blocks : response.json.get_child ("blocks")) { std::string hash_text (blocks.first); @@ -7045,7 +7045,7 @@ TEST (rpc, database_txn_tracker) rpc.start (); boost::property_tree::ptree request; - auto check_not_correct_amount = [&system, &request, &rpc_port = rpc.config.port]() { + auto check_not_correct_amount = [&system, &request, &rpc_port = rpc.config.port] () { test_response response (request, rpc_port, system.io_ctx); ASSERT_TIMELY (5s, response.status != 0); ASSERT_EQ (200, response.status); @@ -7068,7 +7068,7 @@ TEST (rpc, database_txn_tracker) std::promise keep_txn_alive_promise; std::promise txn_created_promise; - std::thread thread ([& store = node->store, &keep_txn_alive_promise, &txn_created_promise]() { + std::thread thread ([&store = node->store, &keep_txn_alive_promise, &txn_created_promise] () { // Use rpc_process_container as a placeholder as this thread is only instantiated by the daemon so won't be used nano::thread_role::set (nano::thread_role::name::rpc_process_container); @@ -7182,7 +7182,7 @@ TEST (rpc, active_difficulty) { // Look for the sequence 4.2, 1.5; we don't know where as the active transaction request loop may prepend values concurrently double values[2]{ 4.2, 1.5 }; - auto it = std::search (trend.begin (), trend.end (), values, values + 2, [](auto a, double b) { + auto it = std::search (trend.begin (), trend.end (), values, values + 2, [] (auto a, double b) { return a.second.template get ("") == b; }); done = it != trend.end (); @@ -7222,7 +7222,7 @@ TEST (rpc, simultaneous_calls) std::atomic count{ num }; for (int i = 0; i < num; ++i) { - std::thread ([&test_responses, &promise, &count, i, port = rpc.config.port]() { + std::thread ([&test_responses, &promise, &count, i, port = rpc.config.port] () { test_responses[i]->run (port); if (--count == 0) { @@ -7234,7 +7234,7 @@ TEST (rpc, simultaneous_calls) promise.get_future ().wait (); - ASSERT_TIMELY (60s, std::all_of (test_responses.begin (), test_responses.end (), [](const auto & test_response) { return test_response->status != 0; })); + ASSERT_TIMELY (60s, std::all_of (test_responses.begin (), test_responses.end (), [] (const auto & test_response) { return test_response->status != 0; })); for (int i = 0; i < num; ++i) { @@ -7918,7 +7918,7 @@ TEST (rpc, telemetry_all) // First need to set up the cached data std::atomic done{ false }; auto node = system.nodes.front (); - node1.telemetry->get_metrics_single_peer_async (node1.network.find_channel (node->network.endpoint ()), [&done](nano::telemetry_data_response const & telemetry_data_response_a) { + node1.telemetry->get_metrics_single_peer_async (node1.network.find_channel (node->network.endpoint ()), [&done] (nano::telemetry_data_response const & telemetry_data_response_a) { ASSERT_FALSE (telemetry_data_response_a.error); done = true; }); diff --git a/nano/secure/ledger.cpp b/nano/secure/ledger.cpp index 484f4b1784..12ce86efa1 100644 --- a/nano/secure/ledger.cpp +++ b/nano/secure/ledger.cpp @@ -752,7 +752,7 @@ void nano::ledger::initialize (nano::generate_cache const & generate_cache_a) if (generate_cache_a.reps || generate_cache_a.account_count || generate_cache_a.block_count) { store.accounts_for_each_par ( - [this](nano::read_transaction const & /*unused*/, nano::store_iterator i, nano::store_iterator n) { + [this] (nano::read_transaction const & /*unused*/, nano::store_iterator i, nano::store_iterator n) { uint64_t block_count_l{ 0 }; uint64_t account_count_l{ 0 }; decltype (this->cache.rep_weights) rep_weights_l; @@ -772,7 +772,7 @@ void nano::ledger::initialize (nano::generate_cache const & generate_cache_a) if (generate_cache_a.cemented_count) { store.confirmation_height_for_each_par ( - [this](nano::read_transaction const & /*unused*/, nano::store_iterator i, nano::store_iterator n) { + [this] (nano::read_transaction const & /*unused*/, nano::store_iterator i, nano::store_iterator n) { uint64_t cemented_count_l (0); for (; i != n; ++i) { @@ -1155,7 +1155,7 @@ void nano::ledger::dump_account_chain (nano::account const & account_a, std::ost bool nano::ledger::could_fit (nano::transaction const & transaction_a, nano::block const & block_a) const { auto dependencies (dependent_blocks (transaction_a, block_a)); - return std::all_of (dependencies.begin (), dependencies.end (), [this, &transaction_a](nano::block_hash const & hash_a) { + return std::all_of (dependencies.begin (), dependencies.end (), [this, &transaction_a] (nano::block_hash const & hash_a) { return hash_a.is_zero () || store.block_exists (transaction_a, hash_a); }); } @@ -1163,7 +1163,7 @@ bool nano::ledger::could_fit (nano::transaction const & transaction_a, nano::blo bool nano::ledger::dependents_confirmed (nano::transaction const & transaction_a, nano::block const & block_a) const { auto dependencies (dependent_blocks (transaction_a, block_a)); - return std::all_of (dependencies.begin (), dependencies.end (), [this, &transaction_a](nano::block_hash const & hash_a) { + return std::all_of (dependencies.begin (), dependencies.end (), [this, &transaction_a] (nano::block_hash const & hash_a) { auto result (hash_a.is_zero ()); if (!result) { @@ -1369,7 +1369,7 @@ std::multimap> nano::ledger::unc nano::locked>> result; using result_t = decltype (result)::value_type; - store.accounts_for_each_par ([this, &result](nano::read_transaction const & transaction_a, nano::store_iterator i, nano::store_iterator n) { + store.accounts_for_each_par ([this, &result] (nano::read_transaction const & transaction_a, nano::store_iterator i, nano::store_iterator n) { result_t unconfirmed_frontiers_l; for (; i != n; ++i) { @@ -1414,7 +1414,7 @@ bool nano::ledger::migrate_lmdb_to_rocksdb (boost::filesystem::path const & data if (!rocksdb_store->init_error ()) { store.blocks_for_each_par ( - [&rocksdb_store](nano::read_transaction const & /*unused*/, auto i, auto n) { + [&rocksdb_store] (nano::read_transaction const & /*unused*/, auto i, auto n) { for (; i != n; ++i) { auto rocksdb_transaction (rocksdb_store->tx_begin_write ({}, { nano::tables::blocks })); @@ -1430,7 +1430,7 @@ bool nano::ledger::migrate_lmdb_to_rocksdb (boost::filesystem::path const & data }); store.unchecked_for_each_par ( - [&rocksdb_store](nano::read_transaction const & /*unused*/, auto i, auto n) { + [&rocksdb_store] (nano::read_transaction const & /*unused*/, auto i, auto n) { for (; i != n; ++i) { auto rocksdb_transaction (rocksdb_store->tx_begin_write ({}, { nano::tables::unchecked })); @@ -1439,7 +1439,7 @@ bool nano::ledger::migrate_lmdb_to_rocksdb (boost::filesystem::path const & data }); store.pending_for_each_par ( - [&rocksdb_store](nano::read_transaction const & /*unused*/, auto i, auto n) { + [&rocksdb_store] (nano::read_transaction const & /*unused*/, auto i, auto n) { for (; i != n; ++i) { auto rocksdb_transaction (rocksdb_store->tx_begin_write ({}, { nano::tables::pending })); @@ -1448,7 +1448,7 @@ bool nano::ledger::migrate_lmdb_to_rocksdb (boost::filesystem::path const & data }); store.confirmation_height_for_each_par ( - [&rocksdb_store](nano::read_transaction const & /*unused*/, auto i, auto n) { + [&rocksdb_store] (nano::read_transaction const & /*unused*/, auto i, auto n) { for (; i != n; ++i) { auto rocksdb_transaction (rocksdb_store->tx_begin_write ({}, { nano::tables::confirmation_height })); @@ -1457,7 +1457,7 @@ bool nano::ledger::migrate_lmdb_to_rocksdb (boost::filesystem::path const & data }); store.accounts_for_each_par ( - [&rocksdb_store](nano::read_transaction const & /*unused*/, auto i, auto n) { + [&rocksdb_store] (nano::read_transaction const & /*unused*/, auto i, auto n) { for (; i != n; ++i) { auto rocksdb_transaction (rocksdb_store->tx_begin_write ({}, { nano::tables::accounts })); @@ -1466,7 +1466,7 @@ bool nano::ledger::migrate_lmdb_to_rocksdb (boost::filesystem::path const & data }); store.frontiers_for_each_par ( - [&rocksdb_store](nano::read_transaction const & /*unused*/, auto i, auto n) { + [&rocksdb_store] (nano::read_transaction const & /*unused*/, auto i, auto n) { for (; i != n; ++i) { auto rocksdb_transaction (rocksdb_store->tx_begin_write ({}, { nano::tables::frontiers })); @@ -1475,7 +1475,7 @@ bool nano::ledger::migrate_lmdb_to_rocksdb (boost::filesystem::path const & data }); store.pruned_for_each_par ( - [&rocksdb_store](nano::read_transaction const & /*unused*/, auto i, auto n) { + [&rocksdb_store] (nano::read_transaction const & /*unused*/, auto i, auto n) { for (; i != n; ++i) { auto rocksdb_transaction (rocksdb_store->tx_begin_write ({}, { nano::tables::pruned })); @@ -1484,7 +1484,7 @@ bool nano::ledger::migrate_lmdb_to_rocksdb (boost::filesystem::path const & data }); store.final_vote_for_each_par ( - [&rocksdb_store](nano::read_transaction const & /*unused*/, auto i, auto n) { + [&rocksdb_store] (nano::read_transaction const & /*unused*/, auto i, auto n) { for (; i != n; ++i) { auto rocksdb_transaction (rocksdb_store->tx_begin_write ({}, { nano::tables::final_votes })); diff --git a/nano/slow_test/node.cpp b/nano/slow_test/node.cpp index 08e27c8d6a..8a8a4f24da 100644 --- a/nano/slow_test/node.cpp +++ b/nano/slow_test/node.cpp @@ -71,7 +71,7 @@ TEST (system, receive_while_synchronizing) node1->start (); system.nodes.push_back (node1); ASSERT_NE (nullptr, nano::establish_tcp (system, *node1, node->network.endpoint ())); - node1->workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::milliseconds (200), ([&system, &key]() { + node1->workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::milliseconds (200), ([&system, &key] () { auto hash (system.wallet (0)->send_sync (nano::dev_genesis_key.pub, key.pub, system.nodes[0]->config.receive_minimum.number ())); auto transaction (system.nodes[0]->store.tx_begin_read ()); auto block (system.nodes[0]->store.block_get (transaction, hash)); @@ -137,10 +137,10 @@ TEST (wallet, multithreaded_send_async) wallet_l->insert_adhoc (key.prv); for (auto i (0); i < 20; ++i) { - threads.push_back (boost::thread ([wallet_l, &key]() { + threads.push_back (boost::thread ([wallet_l, &key] () { for (auto i (0); i < 1000; ++i) { - wallet_l->send_async (nano::dev_genesis_key.pub, key.pub, 1000, [](std::shared_ptr const & block_a) { + wallet_l->send_async (nano::dev_genesis_key.pub, key.pub, 1000, [] (std::shared_ptr const & block_a) { ASSERT_FALSE (block_a == nullptr); ASSERT_FALSE (block_a->hash ().is_zero ()); }); @@ -161,7 +161,7 @@ TEST (store, load) std::vector threads; for (auto i (0); i < 100; ++i) { - threads.push_back (boost::thread ([&system]() { + threads.push_back (boost::thread ([&system] () { for (auto i (0); i != 1000; ++i) { auto transaction (system.nodes[0]->store.tx_begin_write ()); @@ -218,7 +218,7 @@ TEST (node, fork_storm) { auto empty = 0; auto single = 0; - std::for_each (system.nodes.begin (), system.nodes.end (), [&](std::shared_ptr const & node_a) { + std::for_each (system.nodes.begin (), system.nodes.end (), [&] (std::shared_ptr const & node_a) { if (node_a->active.empty ()) { ++empty; @@ -475,7 +475,7 @@ TEST (wallets, rep_scan) } } auto begin (std::chrono::steady_clock::now ()); - node.wallets.foreach_representative ([](nano::public_key const & pub_a, nano::raw_key const & prv_a) { + node.wallets.foreach_representative ([] (nano::public_key const & pub_a, nano::raw_key const & prv_a) { }); ASSERT_LT (std::chrono::steady_clock::now () - begin, std::chrono::milliseconds (5)); } @@ -793,7 +793,7 @@ TEST (confirmation_height, dynamic_algorithm_no_transition_while_pending) std::vector> state_blocks; auto const num_blocks = nano::confirmation_height::unbounded_cutoff - 2; - auto add_block_to_genesis_chain = [&](nano::write_transaction & transaction) { + auto add_block_to_genesis_chain = [&] (nano::write_transaction & transaction) { static int num = 0; auto send (std::make_shared (nano::dev_genesis_key.pub, latest_genesis, nano::dev_genesis_key.pub, nano::genesis_amount - num - 1, key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (latest_genesis))); latest_genesis = send->hash (); @@ -1258,8 +1258,8 @@ namespace transport // The test waits until all telemetry_ack messages have been received. for (int i = 0; i < num_threads; ++i) { - threads.emplace_back ([&node_data, &shared_data]() { - while (std::any_of (node_data.cbegin (), node_data.cend (), [](auto const & data) { return data.keep_requesting_metrics.load (); })) + threads.emplace_back ([&node_data, &shared_data] () { + while (std::any_of (node_data.cbegin (), node_data.cend (), [] (auto const & data) { return data.keep_requesting_metrics.load (); })) { for (auto & data : node_data) { @@ -1270,7 +1270,7 @@ namespace transport // Pick first peer to be consistent auto peer = data.node->network.tcp_channels.channels[0].channel; - data.node->telemetry->get_metrics_single_peer_async (peer, [&shared_data, &data, &node_data](nano::telemetry_data_response const & telemetry_data_response_a) { + data.node->telemetry->get_metrics_single_peer_async (peer, [&shared_data, &data, &node_data] (nano::telemetry_data_response const & telemetry_data_response_a) { ASSERT_FALSE (telemetry_data_response_a.error); callback_process (shared_data, data, node_data, telemetry_data_response_a.telemetry_data.timestamp); }); @@ -1286,7 +1286,7 @@ namespace transport ASSERT_TIMELY (30s, shared_data.done); - ASSERT_TRUE (std::all_of (node_data.begin (), node_data.end (), [](auto const & data) { return !data.keep_requesting_metrics; })); + ASSERT_TRUE (std::all_of (node_data.begin (), node_data.end (), [] (auto const & data) { return !data.keep_requesting_metrics; })); for (auto & thread : threads) { @@ -1320,7 +1320,7 @@ TEST (telemetry, under_load) node->process_active (open); auto latest_key = open->hash (); - auto thread_func = [key1, &system, node, num_blocks](nano::keypair const & keypair, nano::block_hash const & latest, nano::uint128_t const initial_amount) { + auto thread_func = [key1, &system, node, num_blocks] (nano::keypair const & keypair, nano::block_hash const & latest, nano::uint128_t const initial_amount) { auto latest_l = latest; for (int i = 0; i < num_blocks; ++i) { @@ -1363,7 +1363,7 @@ TEST (telemetry, all_peers_use_single_request_cache) { std::atomic done{ false }; auto channel = node_client->network.find_channel (node_server->network.endpoint ()); - node_client->telemetry->get_metrics_single_peer_async (channel, [&done, &telemetry_data](nano::telemetry_data_response const & response_a) { + node_client->telemetry->get_metrics_single_peer_async (channel, [&done, &telemetry_data] (nano::telemetry_data_response const & response_a) { telemetry_data = response_a.telemetry_data; done = true; }); @@ -1391,7 +1391,7 @@ TEST (telemetry, all_peers_use_single_request_cache) { std::atomic done{ false }; auto channel = node_client->network.find_channel (node_server->network.endpoint ()); - node_client->telemetry->get_metrics_single_peer_async (channel, [&done, &telemetry_data](nano::telemetry_data_response const & response_a) { + node_client->telemetry->get_metrics_single_peer_async (channel, [&done, &telemetry_data] (nano::telemetry_data_response const & response_a) { telemetry_data = response_a.telemetry_data; done = true; }); @@ -1464,7 +1464,7 @@ TEST (telemetry, many_nodes) ASSERT_EQ (peers.size (), num_nodes - 1); for (auto const & peer : peers) { - node_client->telemetry->get_metrics_single_peer_async (peer, [&telemetry_datas, &mutex](nano::telemetry_data_response const & response_a) { + node_client->telemetry->get_metrics_single_peer_async (peer, [&telemetry_datas, &mutex] (nano::telemetry_data_response const & response_a) { ASSERT_FALSE (response_a.error); nano::lock_guard guard (mutex); telemetry_datas.push_back (response_a.telemetry_data); @@ -1506,7 +1506,7 @@ TEST (telemetry, many_nodes) // We gave some nodes different bandwidth caps, confirm they are not all the same auto bandwidth_cap = telemetry_datas.front ().bandwidth_cap; telemetry_datas.erase (telemetry_datas.begin ()); - auto all_bandwidth_limits_same = std::all_of (telemetry_datas.begin (), telemetry_datas.end (), [bandwidth_cap](auto & telemetry_data) { + auto all_bandwidth_limits_same = std::all_of (telemetry_datas.begin (), telemetry_datas.end (), [bandwidth_cap] (auto & telemetry_data) { return telemetry_data.bandwidth_cap == bandwidth_cap; }); ASSERT_FALSE (all_bandwidth_limits_same); @@ -1517,7 +1517,7 @@ TEST (signature_checker, mass_boundary_checks) { // sizes container must be in incrementing order std::vector sizes{ 0, 1 }; - auto add_boundary = [&sizes](size_t boundary) { + auto add_boundary = [&sizes] (size_t boundary) { sizes.insert (sizes.end (), { boundary - 1, boundary, boundary + 1 }); }; @@ -1561,7 +1561,7 @@ TEST (signature_checker, mass_boundary_checks) } nano::signature_check_set check = { size, messages.data (), lengths.data (), pub_keys.data (), signatures.data (), verifications.data () }; checker.verify (check); - bool all_valid = std::all_of (verifications.cbegin (), verifications.cend (), [](auto verification) { return verification == 1; }); + bool all_valid = std::all_of (verifications.cbegin (), verifications.cend (), [] (auto verification) { return verification == 1; }); ASSERT_TRUE (all_valid); last_size = size; } @@ -1572,7 +1572,7 @@ TEST (signature_checker, mass_boundary_checks) // Possible to manually add work peers TEST (node, mass_epoch_upgrader) { - auto perform_test = [](size_t const batch_size) { + auto perform_test = [] (size_t const batch_size) { unsigned threads = 5; size_t total_accounts = 2500; @@ -1709,7 +1709,7 @@ TEST (node, mass_block_new) system.upgrade_genesis_epoch (node, nano::epoch::epoch_2); auto next_block_count = num_blocks + 3; - auto process_all = [&](std::vector> const & blocks_a) { + auto process_all = [&] (std::vector> const & blocks_a) { for (auto const & block : blocks_a) { node.process_active (block); @@ -1843,7 +1843,7 @@ TEST (node, wallet_create_block_confirm_conflicts) // Keep creating wallets. This is to check that there is no issues present when confirming blocks at the same time. std::atomic done{ false }; - std::thread t ([node, &done]() { + std::thread t ([node, &done] () { while (!done) { node->wallets.create (nano::random_wallet_id ()); From ff00b6aae6e440de05adbd87a1c978a14719dd86 Mon Sep 17 00:00:00 2001 From: clemahieu Date: Sun, 18 Apr 2021 16:01:10 +0200 Subject: [PATCH 03/10] Using nano:: variants of synchronization classes. --- nano/node/election_scheduler.cpp | 14 +++++++------- nano/node/election_scheduler.hpp | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/nano/node/election_scheduler.cpp b/nano/node/election_scheduler.cpp index 342195b285..da3b13a4c2 100644 --- a/nano/node/election_scheduler.cpp +++ b/nano/node/election_scheduler.cpp @@ -16,7 +16,7 @@ nano::election_scheduler::~election_scheduler () void nano::election_scheduler::manual (std::shared_ptr const & block_a, boost::optional const & previous_balance_a, nano::election_behavior election_behavior_a, std::function const &)> const & confirmation_action_a) { - std::lock_guard lock{ mutex }; + nano::lock_guard lock{ mutex }; manual_queue.push_back (std::make_tuple (block_a, previous_balance_a, election_behavior_a, confirmation_action_a)); observe (); } @@ -37,7 +37,7 @@ void nano::election_scheduler::activate (nano::account const & account_a, nano:: debug_assert (block != nullptr); if (node.ledger.dependents_confirmed (transaction, *block)) { - std::lock_guard lock{ mutex }; + nano::lock_guard lock{ mutex }; priority.push (account_info.modified, block); observe (); } @@ -47,14 +47,14 @@ void nano::election_scheduler::activate (nano::account const & account_a, nano:: void nano::election_scheduler::stop () { - std::unique_lock lock{ mutex }; + nano::unique_lock lock{ mutex }; stopped = true; observe (); } void nano::election_scheduler::flush () { - std::unique_lock lock{ mutex }; + nano::unique_lock lock{ mutex }; auto priority_target = priority_queued + priority.size (); auto manual_target = manual_queued + manual_queue.size (); condition.wait (lock, [this, &priority_target, &manual_target] () { @@ -69,13 +69,13 @@ void nano::election_scheduler::observe () size_t nano::election_scheduler::size () const { - std::lock_guard lock{ mutex }; + nano::lock_guard lock{ mutex }; return priority.size () + manual_queue.size (); } bool nano::election_scheduler::empty () const { - std::lock_guard lock{ mutex }; + nano::lock_guard lock{ mutex }; return priority.empty () && manual_queue.empty (); } @@ -86,7 +86,7 @@ size_t nano::election_scheduler::priority_queue_size () const void nano::election_scheduler::run () { - std::unique_lock lock{ mutex }; + nano::unique_lock lock{ mutex }; while (!stopped) { condition.wait (lock, [this] () { diff --git a/nano/node/election_scheduler.hpp b/nano/node/election_scheduler.hpp index 4b9cdd35d8..02544bfc55 100644 --- a/nano/node/election_scheduler.hpp +++ b/nano/node/election_scheduler.hpp @@ -40,8 +40,8 @@ class election_scheduler final uint64_t manual_queued{ 0 }; nano::node & node; bool stopped; - std::condition_variable condition; - mutable std::mutex mutex; + nano::condition_variable condition; + mutable nano::mutex mutex; std::thread thread; }; } From 8d3a7e23cc5be58827f6a6692fc7af969ca1881d Mon Sep 17 00:00:00 2001 From: clemahieu Date: Sun, 18 Apr 2021 22:07:39 +0200 Subject: [PATCH 04/10] Fixes for CI unit test failures. --- nano/core_test/active_transactions.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/nano/core_test/active_transactions.cpp b/nano/core_test/active_transactions.cpp index d43d870166..414c988a7f 100644 --- a/nano/core_test/active_transactions.cpp +++ b/nano/core_test/active_transactions.cpp @@ -174,6 +174,7 @@ TEST (active_transactions, keep_local) node.process_active (open2); node.process_active (open3); node.block_processor.flush (); + node.scheduler.flush (); // bound elections, should drop after one loop ASSERT_TIMELY (1s, node.active.size () == node_config.active_elections_size); ASSERT_EQ (1, node.scheduler.size ()); @@ -231,12 +232,12 @@ TEST (active_transactions, inactive_votes_cache_fork) ASSERT_NE (nullptr, node.block (send2->hash ())); node.network.process_message (nano::publish (send1), channel1); node.block_processor.flush (); + node.scheduler.flush (); bool confirmed (false); system.deadline_set (5s); while (!confirmed) { - auto transaction (node.store.tx_begin_read ()); - confirmed = node.block (send1->hash ()) != nullptr && node.ledger.block_confirmed (transaction, send1->hash ()) && node.active.empty (); + confirmed = node.block (send1->hash ()) != nullptr && node.ledger.block_confirmed (node.store.tx_begin_read (), send1->hash ()) && node.active.empty (); ASSERT_NO_ERROR (system.poll ()); } ASSERT_EQ (1, node.stats.count (nano::stat::type::election, nano::stat::detail::vote_cached)); @@ -1470,6 +1471,7 @@ TEST (active_transactions, restart_dropped) ASSERT_EQ (0, node.active.size ()); node.process_active (send); node.block_processor.flush (); + node.scheduler.flush (); ASSERT_EQ (1, node.active.size ()); ASSERT_EQ (1, node.stats.count (nano::stat::type::election, nano::stat::detail::election_restart)); auto ledger_block (node.store.block_get (node.store.tx_begin_read (), send->hash ())); From 0f5ee9f149e31c4fb93b5a8b7b062127d3c7f2ea Mon Sep 17 00:00:00 2001 From: clemahieu Date: Mon, 19 Apr 2021 15:59:03 +0200 Subject: [PATCH 05/10] Revert "Fixes for CI unit test failures." This reverts commit 8d3a7e23cc5be58827f6a6692fc7af969ca1881d. --- nano/core_test/active_transactions.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/nano/core_test/active_transactions.cpp b/nano/core_test/active_transactions.cpp index 414c988a7f..d43d870166 100644 --- a/nano/core_test/active_transactions.cpp +++ b/nano/core_test/active_transactions.cpp @@ -174,7 +174,6 @@ TEST (active_transactions, keep_local) node.process_active (open2); node.process_active (open3); node.block_processor.flush (); - node.scheduler.flush (); // bound elections, should drop after one loop ASSERT_TIMELY (1s, node.active.size () == node_config.active_elections_size); ASSERT_EQ (1, node.scheduler.size ()); @@ -232,12 +231,12 @@ TEST (active_transactions, inactive_votes_cache_fork) ASSERT_NE (nullptr, node.block (send2->hash ())); node.network.process_message (nano::publish (send1), channel1); node.block_processor.flush (); - node.scheduler.flush (); bool confirmed (false); system.deadline_set (5s); while (!confirmed) { - confirmed = node.block (send1->hash ()) != nullptr && node.ledger.block_confirmed (node.store.tx_begin_read (), send1->hash ()) && node.active.empty (); + auto transaction (node.store.tx_begin_read ()); + confirmed = node.block (send1->hash ()) != nullptr && node.ledger.block_confirmed (transaction, send1->hash ()) && node.active.empty (); ASSERT_NO_ERROR (system.poll ()); } ASSERT_EQ (1, node.stats.count (nano::stat::type::election, nano::stat::detail::vote_cached)); @@ -1471,7 +1470,6 @@ TEST (active_transactions, restart_dropped) ASSERT_EQ (0, node.active.size ()); node.process_active (send); node.block_processor.flush (); - node.scheduler.flush (); ASSERT_EQ (1, node.active.size ()); ASSERT_EQ (1, node.stats.count (nano::stat::type::election, nano::stat::detail::election_restart)); auto ledger_block (node.store.block_get (node.store.tx_begin_read (), send->hash ())); From a7145414032fbafcf0ff9a1d4823e29695afb7d8 Mon Sep 17 00:00:00 2001 From: clemahieu Date: Tue, 20 Apr 2021 12:39:07 +0200 Subject: [PATCH 06/10] Updating unit tests in preparation for election scheduler changes. This simplifies the election_scheduler commit itself. --- nano/core_test/active_transactions.cpp | 87 ++++++++++++++------------ nano/core_test/bootstrap.cpp | 1 + nano/core_test/conflicts.cpp | 23 ++++--- nano/core_test/election.cpp | 55 ++++++++-------- nano/core_test/ledger.cpp | 66 ++++++++++--------- nano/core_test/network.cpp | 4 +- nano/core_test/node.cpp | 57 +++++++---------- nano/core_test/vote_processor.cpp | 14 +++-- nano/core_test/websocket.cpp | 1 + nano/rpc_test/rpc.cpp | 20 +++--- nano/slow_test/node.cpp | 33 +++++----- 11 files changed, 186 insertions(+), 175 deletions(-) diff --git a/nano/core_test/active_transactions.cpp b/nano/core_test/active_transactions.cpp index 26b19eebbe..3597418c47 100644 --- a/nano/core_test/active_transactions.cpp +++ b/nano/core_test/active_transactions.cpp @@ -136,6 +136,7 @@ TEST (active_transactions, keep_local) ASSERT_TIMELY (5s, node.active.size () == 6); for (auto const & block : { send1, send2, send3, send4, send5, send6 }) { + ASSERT_TIMELY (1s, node.active.election (block->qualified_root ())); auto election = node.active.election (block->qualified_root ()); ASSERT_NE (nullptr, election); election->force_confirm (); @@ -341,8 +342,9 @@ TEST (active_transactions, inactive_votes_cache_multiple_votes) node.vote_processor.vote (vote2, std::make_shared (node)); ASSERT_TIMELY (5s, node.active.find_inactive_votes_cache (send1->hash ()).voters.size () == 2); ASSERT_EQ (1, node.active.inactive_votes_cache_size ()); - // Start election - auto election = node.active.insert (send1).election; + node.active.insert (send1); + auto election = node.active.election (send1->qualified_root ()); + ASSERT_NE (nullptr, election); ASSERT_EQ (3, election->votes ().size ()); // 2 votes and 1 default not_an_acount ASSERT_EQ (2, node.stats.count (nano::stat::type::election, nano::stat::detail::vote_cached)); } @@ -699,7 +701,8 @@ TEST (active_transactions, dropped_cleanup) ASSERT_FALSE (node.network.publish_filter.apply (block_bytes.data (), block_bytes.size ())); ASSERT_TRUE (node.network.publish_filter.apply (block_bytes.data (), block_bytes.size ())); - auto election (node.active.insert (block).election); + node.active.insert (block); + auto election = node.active.election (block->qualified_root ()); ASSERT_NE (nullptr, election); // Not yet removed @@ -721,7 +724,8 @@ TEST (active_transactions, dropped_cleanup) // Repeat test for a confirmed election ASSERT_TRUE (node.network.publish_filter.apply (block_bytes.data (), block_bytes.size ())); - election = node.active.insert (block).election; + node.block_confirm (block); + election = node.active.election (block->qualified_root ()); ASSERT_NE (nullptr, election); election->force_confirm (); ASSERT_TRUE (election->confirmed ()); @@ -843,9 +847,9 @@ TEST (active_transactions, fork_filter_cleanup) .work (*system.work.generate (genesis.hash ())) .build_shared (); node1.process_active (fork); + node1.block_processor.flush (); } - node1.block_processor.flush (); - ASSERT_TIMELY (3s, !node1.active.empty ()); + ASSERT_EQ (1, node1.active.size ()); // Process correct block node_config.peering_port = nano::get_available_port (); @@ -1024,7 +1028,7 @@ TEST (active_transactions, confirmation_consistency) system.deadline_set (5s); while (!node.ledger.block_confirmed (node.store.tx_begin_read (), block->hash ())) { - ASSERT_FALSE (node.active.insert (block).inserted); + node.active.insert (block); ASSERT_NO_ERROR (system.poll (5ms)); } ASSERT_NO_ERROR (system.poll_until_true (1s, [&node, &block, i] { @@ -1123,19 +1127,26 @@ TEST (active_transactions, insertion_prioritization) node.active.update_active_multiplier (lock); }; - ASSERT_TRUE (node.active.insert (blocks[2]).election->prioritized ()); + node.block_confirm (blocks[2]); + ASSERT_TRUE (node.active.election (blocks[2]->qualified_root ())->prioritized ()); update_active_multiplier (); - ASSERT_FALSE (node.active.insert (blocks[3]).election->prioritized ()); + node.block_confirm (blocks[3]); + ASSERT_FALSE (node.active.election (blocks[3]->qualified_root ())->prioritized ()); update_active_multiplier (); - ASSERT_TRUE (node.active.insert (blocks[1]).election->prioritized ()); + node.block_confirm (blocks[1]); + ASSERT_TRUE (node.active.election (blocks[1]->qualified_root ())->prioritized ()); update_active_multiplier (); - ASSERT_FALSE (node.active.insert (blocks[4]).election->prioritized ()); + node.block_confirm (blocks[4]); + ASSERT_FALSE (node.active.election (blocks[4]->qualified_root ())->prioritized ()); update_active_multiplier (); - ASSERT_TRUE (node.active.insert (blocks[0]).election->prioritized ()); + node.block_confirm (blocks[0]); + ASSERT_TRUE (node.active.election (blocks[0]->qualified_root ())->prioritized ()); update_active_multiplier (); - ASSERT_FALSE (node.active.insert (blocks[5]).election->prioritized ()); + node.block_confirm (blocks[5]); + ASSERT_FALSE (node.active.election (blocks[5]->qualified_root ())->prioritized ()); update_active_multiplier (); - ASSERT_FALSE (node.active.insert (blocks[6]).election->prioritized ()); + node.block_confirm (blocks[6]); + ASSERT_FALSE (node.active.election (blocks[6]->qualified_root ())->prioritized ()); ASSERT_EQ (4, node.stats.count (nano::stat::type::election, nano::stat::detail::election_non_priority)); ASSERT_EQ (3, node.stats.count (nano::stat::type::election, nano::stat::detail::election_priority)); @@ -1580,42 +1591,40 @@ TEST (active_transactions, activate_account_chain) ASSERT_EQ (nano::process_result::progress, node.process (*open).code); ASSERT_EQ (nano::process_result::progress, node.process (*receive).code); - auto result = node.active.activate (nano::dev_genesis_key.pub); - ASSERT_TRUE (result.inserted); + node.active.activate (nano::dev_genesis_key.pub); + auto election1 = node.active.election (send->qualified_root ()); ASSERT_EQ (1, node.active.size ()); - ASSERT_EQ (1, result.election->blocks ().count (send->hash ())); - auto result2 = node.active.activate (nano::dev_genesis_key.pub); - ASSERT_FALSE (result2.inserted); - ASSERT_EQ (result2.election, result.election); - result.election->force_confirm (); + ASSERT_EQ (1, election1->blocks ().count (send->hash ())); + node.active.activate (nano::dev_genesis_key.pub); + auto election2 = node.active.election (send->qualified_root ()); + ASSERT_EQ (election2, election1); + election1->force_confirm (); ASSERT_TIMELY (3s, node.block_confirmed (send->hash ())); // On cementing, the next election is started ASSERT_TIMELY (3s, node.active.active (send2->qualified_root ())); - auto result3 = node.active.activate (nano::dev_genesis_key.pub); - ASSERT_FALSE (result3.inserted); - ASSERT_NE (nullptr, result3.election); - ASSERT_EQ (1, result3.election->blocks ().count (send2->hash ())); - result3.election->force_confirm (); + node.active.activate (nano::dev_genesis_key.pub); + auto election3 = node.active.election (send2->qualified_root ()); + ASSERT_NE (nullptr, election3); + ASSERT_EQ (1, election3->blocks ().count (send2->hash ())); + election3->force_confirm (); ASSERT_TIMELY (3s, node.block_confirmed (send2->hash ())); // On cementing, the next election is started ASSERT_TIMELY (3s, node.active.active (open->qualified_root ())); ASSERT_TIMELY (3s, node.active.active (send3->qualified_root ())); - auto result4 = node.active.activate (nano::dev_genesis_key.pub); - ASSERT_FALSE (result4.inserted); - ASSERT_NE (nullptr, result4.election); - ASSERT_EQ (1, result4.election->blocks ().count (send3->hash ())); - auto result5 = node.active.activate (key.pub); - ASSERT_FALSE (result5.inserted); - ASSERT_NE (nullptr, result5.election); - ASSERT_EQ (1, result5.election->blocks ().count (open->hash ())); - result5.election->force_confirm (); + node.active.activate (nano::dev_genesis_key.pub); + auto election4 = node.active.election (send3->qualified_root ()); + ASSERT_NE (nullptr, election4); + ASSERT_EQ (1, election4->blocks ().count (send3->hash ())); + node.active.activate (key.pub); + auto election5 = node.active.election (open->qualified_root ()); + ASSERT_NE (nullptr, election5); + ASSERT_EQ (1, election5->blocks ().count (open->hash ())); + election5->force_confirm (); ASSERT_TIMELY (3s, node.block_confirmed (open->hash ())); // Until send3 is also confirmed, the receive block should not activate std::this_thread::sleep_for (200ms); - auto result6 = node.active.activate (key.pub); - ASSERT_FALSE (result6.inserted); - ASSERT_EQ (nullptr, result6.election); - result4.election->force_confirm (); + node.active.activate (key.pub); + election4->force_confirm (); ASSERT_TIMELY (3s, node.block_confirmed (send3->hash ())); ASSERT_TIMELY (3s, node.active.active (receive->qualified_root ())); } diff --git a/nano/core_test/bootstrap.cpp b/nano/core_test/bootstrap.cpp index b1c32f8f32..dd11dc54f6 100644 --- a/nano/core_test/bootstrap.cpp +++ b/nano/core_test/bootstrap.cpp @@ -1224,6 +1224,7 @@ TEST (bulk, offline_send) auto send1 (system.wallet (0)->send_action (nano::dev_genesis_key.pub, key2.pub, node1->config.receive_minimum.number ())); ASSERT_NE (nullptr, send1); ASSERT_NE (std::numeric_limits::max (), node1->balance (nano::dev_genesis_key.pub)); + node1->block_processor.flush (); // Wait to finish election background tasks ASSERT_TIMELY (10s, node1->active.empty ()); ASSERT_TRUE (node1->block_confirmed (send1->hash ())); diff --git a/nano/core_test/conflicts.cpp b/nano/core_test/conflicts.cpp index 6db6315434..0ab539493a 100644 --- a/nano/core_test/conflicts.cpp +++ b/nano/core_test/conflicts.cpp @@ -18,10 +18,11 @@ TEST (conflicts, start_stop) node1.work_generate_blocking (*send1); ASSERT_EQ (nano::process_result::progress, node1.process (*send1).code); ASSERT_EQ (0, node1.active.size ()); - auto election1 = node1.active.insert (send1); + node1.active.activate (nano::dev_genesis_key.pub); + auto election1 = node1.active.election (send1->qualified_root ()); ASSERT_EQ (1, node1.active.size ()); - ASSERT_NE (nullptr, election1.election); - ASSERT_EQ (1, election1.election->votes ().size ()); + ASSERT_NE (nullptr, election1); + ASSERT_EQ (1, election1->votes ().size ()); } TEST (conflicts, add_existing) @@ -33,17 +34,18 @@ TEST (conflicts, add_existing) auto send1 (std::make_shared (genesis.hash (), key1.pub, 0, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); node1.work_generate_blocking (*send1); ASSERT_EQ (nano::process_result::progress, node1.process (*send1).code); - node1.active.insert (send1); + node1.active.activate (nano::dev_genesis_key.pub); nano::keypair key2; auto send2 (std::make_shared (genesis.hash (), key2.pub, 0, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); send2->sideband_set ({}); - auto election1 = node1.active.insert (send2); + node1.active.activate (nano::dev_genesis_key.pub); + auto election1 = node1.active.election (send2->qualified_root ()); ASSERT_EQ (1, node1.active.size ()); auto vote1 (std::make_shared (key2.pub, key2.prv, 0, send2)); node1.active.vote (vote1); - ASSERT_NE (nullptr, election1.election); - ASSERT_EQ (2, election1.election->votes ().size ()); - auto votes (election1.election->votes ()); + ASSERT_NE (nullptr, election1); + ASSERT_EQ (2, election1->votes ().size ()); + auto votes (election1->votes ()); ASSERT_NE (votes.end (), votes.find (key2.pub)); } @@ -56,12 +58,13 @@ TEST (conflicts, add_two) auto send1 (std::make_shared (genesis.hash (), key1.pub, 0, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); node1.work_generate_blocking (*send1); ASSERT_EQ (nano::process_result::progress, node1.process (*send1).code); - node1.active.insert (send1); + node1.block_confirm (send1); + node1.active.election (send1->qualified_root ())->force_confirm (); nano::keypair key2; auto send2 (std::make_shared (send1->hash (), key2.pub, 0, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); node1.work_generate_blocking (*send2); ASSERT_EQ (nano::process_result::progress, node1.process (*send2).code); - node1.active.insert (send2); + node1.active.activate (nano::dev_genesis_key.pub); ASSERT_EQ (2, node1.active.size ()); } diff --git a/nano/core_test/election.cpp b/nano/core_test/election.cpp index 4d41f2d716..adab19f26e 100644 --- a/nano/core_test/election.cpp +++ b/nano/core_test/election.cpp @@ -12,7 +12,8 @@ TEST (election, construction) nano::genesis genesis; auto & node = *system.nodes[0]; genesis.open->sideband_set (nano::block_sideband (nano::genesis_account, 0, nano::genesis_amount, 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false, false, false, nano::epoch::epoch_0)); - auto election = node.active.insert (genesis.open).election; + node.block_confirm (genesis.open); + auto election = node.active.election (genesis.open->qualified_root ()); election->transition_active (); } @@ -47,17 +48,17 @@ TEST (election, quorum_minimum_flip_success) .build_shared (); node1.work_generate_blocking (*send2); node1.process_active (send1); + node1.block_processor.flush (); node1.process_active (send2); node1.block_processor.flush (); - auto election{ node1.active.insert (send1) }; - ASSERT_FALSE (election.inserted); - ASSERT_NE (nullptr, election.election); - ASSERT_EQ (2, election.election->blocks ().size ()); + auto election = node1.active.election (send1->qualified_root ()); + ASSERT_NE (nullptr, election); + ASSERT_EQ (2, election->blocks ().size ()); auto vote1 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, std::numeric_limits::max (), send2)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1)); node1.block_processor.flush (); ASSERT_NE (nullptr, node1.block (send2->hash ())); - ASSERT_TRUE (election.election->confirmed ()); + ASSERT_TRUE (election->confirmed ()); } TEST (election, quorum_minimum_flip_fail) @@ -91,17 +92,17 @@ TEST (election, quorum_minimum_flip_fail) .build_shared (); node1.work_generate_blocking (*send2); node1.process_active (send1); + node1.block_processor.flush (); node1.process_active (send2); node1.block_processor.flush (); - auto election{ node1.active.insert (send1) }; - ASSERT_FALSE (election.inserted); - ASSERT_NE (nullptr, election.election); - ASSERT_EQ (2, election.election->blocks ().size ()); + auto election = node1.active.election (send1->qualified_root ()); + ASSERT_NE (nullptr, election); + ASSERT_EQ (2, election->blocks ().size ()); auto vote1 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, std::numeric_limits::max (), send2)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1)); node1.block_processor.flush (); ASSERT_NE (nullptr, node1.block (send1->hash ())); - ASSERT_FALSE (election.election->confirmed ()); + ASSERT_FALSE (election->confirmed ()); } TEST (election, quorum_minimum_confirm_success) @@ -125,15 +126,15 @@ TEST (election, quorum_minimum_confirm_success) node1.work_generate_blocking (*send1); node1.process_active (send1); node1.block_processor.flush (); - auto election{ node1.active.insert (send1) }; - ASSERT_FALSE (election.inserted); - ASSERT_NE (nullptr, election.election); - ASSERT_EQ (1, election.election->blocks ().size ()); + node1.active.activate (nano::dev_genesis_key.pub); + auto election = node1.active.election (send1->qualified_root ()); + ASSERT_NE (nullptr, election); + ASSERT_EQ (1, election->blocks ().size ()); auto vote1 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, std::numeric_limits::max (), send1)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1)); node1.block_processor.flush (); ASSERT_NE (nullptr, node1.block (send1->hash ())); - ASSERT_TRUE (election.election->confirmed ()); + ASSERT_TRUE (election->confirmed ()); } TEST (election, quorum_minimum_confirm_fail) @@ -157,15 +158,15 @@ TEST (election, quorum_minimum_confirm_fail) node1.work_generate_blocking (*send1); node1.process_active (send1); node1.block_processor.flush (); - auto election{ node1.active.insert (send1) }; - ASSERT_FALSE (election.inserted); - ASSERT_NE (nullptr, election.election); - ASSERT_EQ (1, election.election->blocks ().size ()); + node1.active.activate (nano::dev_genesis_key.pub); + auto election = node1.active.election (send1->qualified_root ()); + ASSERT_NE (nullptr, election); + ASSERT_EQ (1, election->blocks ().size ()); auto vote1 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, std::numeric_limits::max (), send1)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1)); node1.block_processor.flush (); ASSERT_NE (nullptr, node1.block (send1->hash ())); - ASSERT_FALSE (election.election->confirmed ()); + ASSERT_FALSE (election->confirmed ()); } namespace nano @@ -227,17 +228,17 @@ TEST (election, quorum_minimum_update_weight_before_quorum_checks) node2.block_processor.flush (); ASSERT_EQ (node2.ledger.cache.block_count, 4); - auto election{ node1.active.insert (send1) }; - ASSERT_FALSE (election.inserted); - ASSERT_NE (nullptr, election.election); - ASSERT_EQ (1, election.election->blocks ().size ()); + node1.active.activate (nano::dev_genesis_key.pub); + auto election = node1.active.election (send1->qualified_root ()); + ASSERT_NE (nullptr, election); + ASSERT_EQ (1, election->blocks ().size ()); auto vote1 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, std::numeric_limits::max (), send1)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1)); auto vote2 (std::make_shared (key1.pub, key1.prv, std::numeric_limits::max (), send1)); auto channel = node1.network.find_channel (node2.network.endpoint ()); ASSERT_NE (channel, nullptr); ASSERT_TIMELY (10s, !node1.rep_crawler.response (channel, vote2)); - ASSERT_FALSE (election.election->confirmed ()); + ASSERT_FALSE (election->confirmed ()); { nano::lock_guard 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. @@ -246,6 +247,6 @@ TEST (election, quorum_minimum_update_weight_before_quorum_checks) ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote2)); node1.block_processor.flush (); ASSERT_NE (nullptr, node1.block (send1->hash ())); - ASSERT_TRUE (election.election->confirmed ()); + ASSERT_TRUE (election->confirmed ()); } } diff --git a/nano/core_test/ledger.cpp b/nano/core_test/ledger.cpp index 383248800b..b83c427e2c 100644 --- a/nano/core_test/ledger.cpp +++ b/nano/core_test/ledger.cpp @@ -767,8 +767,9 @@ TEST (votes, check_signature) auto transaction (node1.store.tx_begin_write ()); ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code); } - auto election1 = node1.active.insert (send1); - ASSERT_EQ (1, election1.election->votes ().size ()); + node1.active.activate (nano::dev_genesis_key.pub); + auto election1 = node1.active.election (send1->qualified_root ()); + ASSERT_EQ (1, election1->votes ().size ()); auto vote1 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 1, send1)); vote1->signature.bytes[0] ^= 1; ASSERT_EQ (nano::vote_code::invalid, node1.vote_processor.vote_blocking (vote1, std::make_shared (node1))); @@ -787,19 +788,20 @@ TEST (votes, add_one) node1.work_generate_blocking (*send1); auto transaction (node1.store.tx_begin_write ()); ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code); - auto election1 = node1.active.insert (send1); - ASSERT_EQ (1, election1.election->votes ().size ()); + node1.block_confirm (send1); + auto election1 = node1.active.election (send1->qualified_root ()); + ASSERT_EQ (1, election1->votes ().size ()); auto vote1 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 1, send1)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1)); auto vote2 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 2, send1)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote2)); - ASSERT_EQ (2, election1.election->votes ().size ()); - auto votes1 (election1.election->votes ()); + ASSERT_EQ (2, election1->votes ().size ()); + auto votes1 (election1->votes ()); auto existing1 (votes1.find (nano::dev_genesis_key.pub)); ASSERT_NE (votes1.end (), existing1); ASSERT_EQ (send1->hash (), existing1->second.hash); nano::lock_guard guard (node1.active.mutex); - auto winner (*election1.election->tally ().begin ()); + auto winner (*election1->tally ().begin ()); ASSERT_EQ (*send1, *winner.second); ASSERT_EQ (nano::genesis_amount - 100, winner.first); } @@ -814,20 +816,21 @@ TEST (votes, add_two) node1.work_generate_blocking (*send1); auto transaction (node1.store.tx_begin_write ()); ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code); - auto election1 = node1.active.insert (send1); + node1.block_confirm (send1); + auto election1 = node1.active.election (send1->qualified_root ()); nano::keypair key2; auto send2 (std::make_shared (genesis.hash (), key2.pub, 0, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); auto vote2 (std::make_shared (key2.pub, key2.prv, 1, send2)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote2)); auto vote1 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 1, send1)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1)); - ASSERT_EQ (3, election1.election->votes ().size ()); - auto votes1 (election1.election->votes ()); + ASSERT_EQ (3, election1->votes ().size ()); + auto votes1 (election1->votes ()); ASSERT_NE (votes1.end (), votes1.find (nano::dev_genesis_key.pub)); ASSERT_EQ (send1->hash (), votes1[nano::dev_genesis_key.pub].hash); ASSERT_NE (votes1.end (), votes1.find (key2.pub)); ASSERT_EQ (send2->hash (), votes1[key2.pub].hash); - ASSERT_EQ (*send1, *election1.election->winner ()); + ASSERT_EQ (*send1, *election1->winner ()); } namespace nano @@ -853,12 +856,13 @@ TEST (votes, add_existing) .build (); node1.work_generate_blocking (*send1); ASSERT_EQ (nano::process_result::progress, node1.ledger.process (node1.store.tx_begin_write (), *send1).code); - auto election1 = node1.active.insert (send1); + node1.active.activate (nano::dev_genesis_key.pub); + auto election1 = node1.active.election (send1->qualified_root ()); auto vote1 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 1, send1)); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote1)); // Block is already processed from vote ASSERT_TRUE (node1.active.publish (send1)); - ASSERT_EQ (1, election1.election->last_votes[nano::dev_genesis_key.pub].timestamp); + ASSERT_EQ (1, election1->last_votes[nano::dev_genesis_key.pub].timestamp); nano::keypair key2; std::shared_ptr send2 = builder.state () .account (nano::dev_genesis_key.pub) @@ -872,23 +876,23 @@ TEST (votes, add_existing) node1.work_generate_blocking (*send2); auto vote2 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 2, send2)); // Pretend we've waited the timeout - nano::unique_lock lock (election1.election->mutex); - election1.election->last_votes[nano::dev_genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20); + nano::unique_lock lock (election1->mutex); + election1->last_votes[nano::dev_genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20); lock.unlock (); ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote2)); ASSERT_FALSE (node1.active.publish (send2)); - ASSERT_EQ (2, election1.election->last_votes[nano::dev_genesis_key.pub].timestamp); + ASSERT_EQ (2, election1->last_votes[nano::dev_genesis_key.pub].timestamp); // Also resend the old vote, and see if we respect the timestamp lock.lock (); - election1.election->last_votes[nano::dev_genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20); + election1->last_votes[nano::dev_genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20); lock.unlock (); ASSERT_EQ (nano::vote_code::replay, node1.active.vote (vote1)); - ASSERT_EQ (2, election1.election->votes ()[nano::dev_genesis_key.pub].timestamp); - auto votes (election1.election->votes ()); + ASSERT_EQ (2, election1->votes ()[nano::dev_genesis_key.pub].timestamp); + auto votes (election1->votes ()); ASSERT_EQ (2, votes.size ()); ASSERT_NE (votes.end (), votes.find (nano::dev_genesis_key.pub)); ASSERT_EQ (send2->hash (), votes[nano::dev_genesis_key.pub].hash); - ASSERT_EQ (*send2, *election1.election->tally ().begin ()->second); + ASSERT_EQ (*send2, *election1->tally ().begin ()->second); } // Lower timestamps are ignored @@ -902,7 +906,8 @@ TEST (votes, add_old) node1.work_generate_blocking (*send1); auto transaction (node1.store.tx_begin_write ()); ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code); - auto election1 = node1.active.insert (send1); + node1.block_confirm (send1); + auto election1 = node1.active.election (send1->qualified_root ()); auto vote1 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 2, send1)); auto channel (std::make_shared (node1)); node1.vote_processor.vote_blocking (vote1, channel); @@ -911,15 +916,15 @@ TEST (votes, add_old) node1.work_generate_blocking (*send2); auto vote2 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 1, send2)); { - nano::lock_guard lock (election1.election->mutex); - election1.election->last_votes[nano::dev_genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20); + nano::lock_guard lock (election1->mutex); + election1->last_votes[nano::dev_genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20); } node1.vote_processor.vote_blocking (vote2, channel); - ASSERT_EQ (2, election1.election->votes ().size ()); - auto votes (election1.election->votes ()); + ASSERT_EQ (2, election1->votes ().size ()); + auto votes (election1->votes ()); ASSERT_NE (votes.end (), votes.find (nano::dev_genesis_key.pub)); ASSERT_EQ (send1->hash (), votes[nano::dev_genesis_key.pub].hash); - ASSERT_EQ (*send1, *election1.election->winner ()); + ASSERT_EQ (*send1, *election1->winner ()); } } @@ -975,7 +980,8 @@ TEST (votes, add_cooldown) node1.work_generate_blocking (*send1); auto transaction (node1.store.tx_begin_write ()); ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send1).code); - auto election1 = node1.active.insert (send1); + node1.block_confirm (send1); + auto election1 = node1.active.election (send1->qualified_root ()); auto vote1 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 1, send1)); auto channel (std::make_shared (node1)); node1.vote_processor.vote_blocking (vote1, channel); @@ -984,11 +990,11 @@ TEST (votes, add_cooldown) node1.work_generate_blocking (*send2); auto vote2 (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 2, send2)); node1.vote_processor.vote_blocking (vote2, channel); - ASSERT_EQ (2, election1.election->votes ().size ()); - auto votes (election1.election->votes ()); + ASSERT_EQ (2, election1->votes ().size ()); + auto votes (election1->votes ()); ASSERT_NE (votes.end (), votes.find (nano::dev_genesis_key.pub)); ASSERT_EQ (send1->hash (), votes[nano::dev_genesis_key.pub].hash); - ASSERT_EQ (*send1, *election1.election->winner ()); + ASSERT_EQ (*send1, *election1->winner ()); } // Query for block successor diff --git a/nano/core_test/network.cpp b/nano/core_test/network.cpp index b665d68192..bd89774103 100644 --- a/nano/core_test/network.cpp +++ b/nano/core_test/network.cpp @@ -332,7 +332,7 @@ TEST (receivable_processor, confirm_insufficient_pos) auto block1 (std::make_shared (genesis.hash (), 0, 0, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); node1.work_generate_blocking (*block1); ASSERT_EQ (nano::process_result::progress, node1.process (*block1).code); - node1.active.insert (block1); + node1.active.activate (nano::dev_genesis_key.pub); nano::keypair key1; auto vote (std::make_shared (key1.pub, key1.prv, 0, block1)); nano::confirm_ack con1 (vote); @@ -347,7 +347,7 @@ TEST (receivable_processor, confirm_sufficient_pos) auto block1 (std::make_shared (genesis.hash (), 0, 0, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); node1.work_generate_blocking (*block1); ASSERT_EQ (nano::process_result::progress, node1.process (*block1).code); - node1.active.insert (block1); + node1.active.activate (nano::dev_genesis_key.pub); auto vote (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 0, block1)); nano::confirm_ack con1 (vote); node1.network.process_message (con1, node1.network.udp_channels.create (node1.network.endpoint ())); diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index 06a9cae56b..2c6384291c 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -1866,11 +1866,13 @@ TEST (node, rep_self_vote) .work (*system.work.generate (fund_big.hash ())) .build_shared (); ASSERT_EQ (nano::process_result::progress, node0->process (*block0).code); - auto & active (node0->active); - auto election1 = active.insert (block0); + auto & active = node0->active; + active.activate (nano::dev_genesis_key.pub); + auto election1 = active.election (block0->qualified_root ()); + ASSERT_NE (nullptr, election1); // Wait until representatives are activated & make vote - ASSERT_TIMELY (1s, election1.election->votes ().size () == 3); - auto rep_votes (election1.election->votes ()); + ASSERT_TIMELY (1s, election1->votes ().size () == 3); + auto rep_votes (election1->votes ()); ASSERT_NE (rep_votes.end (), rep_votes.find (nano::dev_genesis_key.pub)); ASSERT_NE (rep_votes.end (), rep_votes.find (rep_big.pub)); } @@ -1953,7 +1955,6 @@ TEST (node, bootstrap_fork_open) auto node0 = system.add_node (node_config); node_config.peering_port = nano::get_available_port (); auto node1 = system.add_node (node_config); - system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv); nano::keypair key0; nano::block_builder builder; auto send0 = *builder.send () @@ -1984,6 +1985,7 @@ TEST (node, bootstrap_fork_open) for (auto node : system.nodes) { node->block_confirm (node->block (node->latest (nano::dev_genesis_key.pub))); + ASSERT_TIMELY (1s, node->active.election (send0.qualified_root ())); auto election = node->active.election (send0.qualified_root ()); ASSERT_NE (nullptr, election); election->force_confirm (); @@ -1993,10 +1995,11 @@ TEST (node, bootstrap_fork_open) // They disagree about open0/open1 ASSERT_EQ (nano::process_result::progress, node0->process (open0).code); ASSERT_EQ (nano::process_result::progress, node1->process (open1).code); + system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv); ASSERT_FALSE (node1->ledger.block_exists (open0.hash ())); ASSERT_FALSE (node1->bootstrap_initiator.in_progress ()); node1->bootstrap_initiator.bootstrap (node0->network.endpoint (), false); - ASSERT_TRUE (node1->active.empty ()); + ASSERT_TIMELY (1s, node1->active.empty ()); ASSERT_TIMELY (10s, !node1->ledger.block_exists (open1.hash ()) && node1->ledger.block_exists (open0.hash ())); } @@ -2551,6 +2554,7 @@ TEST (node, block_confirm) nano::genesis genesis; nano::keypair key; nano::state_block_builder builder; + system.wallet (1)->insert_adhoc (nano::dev_genesis_key.prv); auto send1 = builder.make_block () .account (nano::dev_genesis_key.pub) .previous (genesis.hash ()) @@ -2573,21 +2577,7 @@ TEST (node, block_confirm) node2.block_confirm (send1_copy); auto election = node2.active.election (send1_copy->qualified_root ()); ASSERT_NE (nullptr, election); - election->force_confirm (); - ASSERT_TIMELY (3s, node2.block_confirmed (send1_copy->hash ()) && node2.active.empty ()); - system.wallet (1)->insert_adhoc (nano::dev_genesis_key.prv); - auto send2 (std::make_shared (nano::dev_genesis_key.pub, send1->hash (), nano::dev_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio * 2, key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node1.work_generate_blocking (send1->hash ()))); - { - auto transaction (node1.store.tx_begin_write ()); - ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, *send2).code); - } - { - auto transaction (node2.store.tx_begin_write ()); - ASSERT_EQ (nano::process_result::progress, node2.ledger.process (transaction, *send2).code); - } - ASSERT_TRUE (node1.active.list_recently_cemented ().empty ()); - node1.block_confirm (send2); - ASSERT_TIMELY (10s, node1.active.list_recently_cemented ().size () == 2); + ASSERT_TIMELY (10s, node1.active.list_recently_cemented ().size () == 1); } } @@ -2982,10 +2972,10 @@ TEST (node, vote_by_hash_bundle) blocks.push_back (block); ASSERT_EQ (nano::process_result::progress, node.ledger.process (node.store.tx_begin_write (), *blocks.back ()).code); } - auto election_insertion_result = node.active.insert (blocks.back ()); - ASSERT_TRUE (election_insertion_result.inserted); - ASSERT_NE (nullptr, election_insertion_result.election); - election_insertion_result.election->force_confirm (); + node.block_confirm (blocks.back ()); + auto election = node.active.election (blocks.back ()->qualified_root ()); + ASSERT_NE (nullptr, election); + election->force_confirm (); system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv); nano::keypair key1; system.wallet (0)->insert_adhoc (key1.prv); @@ -4032,6 +4022,7 @@ TEST (node, rollback_vote_self) ASSERT_TIMELY (5s, node.ledger.cache.cemented_count == 3); ASSERT_EQ (weight, node.weight (key.pub)); node.process_active (send2); + node.block_processor.flush (); node.process_active (fork); node.block_processor.flush (); election = node.active.election (send2->qualified_root ()); @@ -4756,18 +4747,14 @@ TEST (node, pruning_depth) node1.process_active (send2); node1.block_processor.flush (); // Confirm last block to prune previous - { - auto election = node1.active.election (send1->qualified_root ()); - ASSERT_NE (nullptr, election); - election->force_confirm (); - } + auto election1 = node1.active.election (send1->qualified_root ()); + ASSERT_NE (nullptr, election1); + election1->force_confirm (); ASSERT_TIMELY (2s, node1.block_confirmed (send1->hash ()) && node1.active.active (send2->qualified_root ())); ASSERT_EQ (0, node1.ledger.cache.pruned_count); - { - auto election = node1.active.election (send2->qualified_root ()); - ASSERT_NE (nullptr, election); - election->force_confirm (); - } + auto election2 = node1.active.election (send2->qualified_root ()); + ASSERT_NE (nullptr, election2); + election2->force_confirm (); ASSERT_TIMELY (2s, node1.active.empty () && node1.block_confirmed (send2->hash ())); // Pruning with default depth (unlimited) node1.ledger_pruning (1, true, false); diff --git a/nano/core_test/vote_processor.cpp b/nano/core_test/vote_processor.cpp index 03745804c6..8ac81502ac 100644 --- a/nano/core_test/vote_processor.cpp +++ b/nano/core_test/vote_processor.cpp @@ -29,7 +29,8 @@ TEST (vote_processor, codes) // First vote from an account for an ongoing election genesis.open->sideband_set (nano::block_sideband (nano::genesis_account, 0, nano::genesis_amount, 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false, false, false, nano::epoch::epoch_0)); - ASSERT_TRUE (node.active.insert (genesis.open).inserted); + node.block_confirm (genesis.open); + ASSERT_NE (nullptr, node.active.election (genesis.open->qualified_root ())); ASSERT_EQ (nano::vote_code::vote, node.vote_processor.vote_blocking (vote, channel)); // Processing the same vote is a replay @@ -78,15 +79,16 @@ TEST (vote_processor, invalid_signature) auto channel (std::make_shared (node)); genesis.open->sideband_set (nano::block_sideband (nano::genesis_account, 0, nano::genesis_amount, 1, nano::seconds_since_epoch (), nano::epoch::epoch_0, false, false, false, nano::epoch::epoch_0)); - auto election (node.active.insert (genesis.open)); - ASSERT_TRUE (election.election && election.inserted); - ASSERT_EQ (1, election.election->votes ().size ()); + node.block_confirm (genesis.open); + auto election = node.active.election (genesis.open->qualified_root ()); + ASSERT_TRUE (election); + ASSERT_EQ (1, election->votes ().size ()); node.vote_processor.vote (vote_invalid, channel); node.vote_processor.flush (); - ASSERT_EQ (1, election.election->votes ().size ()); + ASSERT_EQ (1, election->votes ().size ()); node.vote_processor.vote (vote, channel); node.vote_processor.flush (); - ASSERT_EQ (2, election.election->votes ().size ()); + ASSERT_EQ (2, election->votes ().size ()); } TEST (vote_processor, no_capacity) diff --git a/nano/core_test/websocket.cpp b/nano/core_test/websocket.cpp index 8ad481008a..b7fec3e16d 100644 --- a/nano/core_test/websocket.cpp +++ b/nano/core_test/websocket.cpp @@ -206,6 +206,7 @@ TEST (websocket, stopped_election) auto channel1 (node1->network.udp_channels.create (node1->network.endpoint ())); node1->network.process_message (publish1, channel1); node1->block_processor.flush (); + ASSERT_TIMELY (1s, node1->active.election (send1->qualified_root ())); node1->active.erase (*send1); ASSERT_TIMELY (5s, future.wait_for (0s) == std::future_status::ready); diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index 7ee296cbf2..9b4ae0cb29 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -2127,12 +2127,12 @@ TEST (rpc, process_subtype_open) auto & node2 = *system.add_node (); nano::keypair key; auto latest (node1.latest (nano::dev_genesis_key.pub)); - nano::state_block send (nano::genesis_account, latest, nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node1.work_generate_blocking (latest)); - ASSERT_EQ (nano::process_result::progress, node1.process (send).code); - ASSERT_EQ (nano::process_result::progress, node2.process (send).code); + auto send = std::make_shared (nano::genesis_account, latest, nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node1.work_generate_blocking (latest)); + ASSERT_EQ (nano::process_result::progress, node1.process (*send).code); + ASSERT_EQ (nano::process_result::progress, node2.process (*send).code); scoped_io_thread_name_change scoped_thread_name_io; - node1.active.insert (std::make_shared (send)); - nano::state_block open (key.pub, 0, key.pub, nano::Gxrb_ratio, send.hash (), key.prv, key.pub, *node1.work_generate_blocking (key.pub)); + node1.active.insert (send); + nano::state_block open (key.pub, 0, key.pub, nano::Gxrb_ratio, send->hash (), key.prv, key.pub, *node1.work_generate_blocking (key.pub)); nano::node_rpc_config node_rpc_config; nano::ipc::ipc_server ipc_server (node1, node_rpc_config); nano::rpc_config rpc_config (nano::get_available_port (), true); @@ -2170,12 +2170,12 @@ TEST (rpc, process_subtype_receive) auto & node1 = *add_ipc_enabled_node (system); auto & node2 = *system.add_node (); auto latest (node1.latest (nano::dev_genesis_key.pub)); - nano::state_block send (nano::genesis_account, latest, nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node1.work_generate_blocking (latest)); - ASSERT_EQ (nano::process_result::progress, node1.process (send).code); - ASSERT_EQ (nano::process_result::progress, node2.process (send).code); + auto send = std::make_shared (nano::genesis_account, latest, nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node1.work_generate_blocking (latest)); + ASSERT_EQ (nano::process_result::progress, node1.process (*send).code); + ASSERT_EQ (nano::process_result::progress, node2.process (*send).code); scoped_io_thread_name_change scoped_thread_name_io; - node1.active.insert (std::make_shared (send)); - nano::state_block receive (nano::dev_genesis_key.pub, send.hash (), nano::dev_genesis_key.pub, nano::genesis_amount, send.hash (), nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node1.work_generate_blocking (send.hash ())); + node1.active.insert (send); + nano::state_block receive (nano::dev_genesis_key.pub, send->hash (), nano::dev_genesis_key.pub, nano::genesis_amount, send->hash (), nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node1.work_generate_blocking (send->hash ())); nano::node_rpc_config node_rpc_config; nano::ipc::ipc_server ipc_server (node1, node_rpc_config); nano::rpc_config rpc_config (nano::get_available_port (), true); diff --git a/nano/slow_test/node.cpp b/nano/slow_test/node.cpp index 1e12b04f98..ee3e2676fb 100644 --- a/nano/slow_test/node.cpp +++ b/nano/slow_test/node.cpp @@ -535,10 +535,10 @@ TEST (confirmation_height, many_accounts_single_confirmation) { auto block = node->block (last_open_hash); ASSERT_NE (nullptr, block); - auto election_insertion_result (node->active.insert (block)); - ASSERT_TRUE (election_insertion_result.inserted); - ASSERT_NE (nullptr, election_insertion_result.election); - election_insertion_result.election->force_confirm (); + node->active.insert (block); + auto election = node->active.election (block->qualified_root ()); + ASSERT_NE (nullptr, election); + election->force_confirm (); } ASSERT_TIMELY (120s, node->ledger.block_confirmed (node->store.tx_begin_read (), last_open_hash)); @@ -603,10 +603,10 @@ TEST (confirmation_height, many_accounts_many_confirmations) // Confirm all of the accounts for (auto & open_block : open_blocks) { - auto election_insertion_result (node->active.insert (open_block)); - ASSERT_TRUE (election_insertion_result.inserted); - ASSERT_NE (nullptr, election_insertion_result.election); - election_insertion_result.election->force_confirm (); + node->active.insert (open_block); + auto election = node->active.election (open_block->qualified_root ()); + ASSERT_NE (nullptr, election); + election->force_confirm (); } auto const num_blocks_to_confirm = (num_accounts - 1) * 2; @@ -690,10 +690,10 @@ TEST (confirmation_height, long_chains) // Call block confirm on the existing receive block on the genesis account which will confirm everything underneath on both accounts { - auto election_insertion_result (node->active.insert (receive1)); - ASSERT_TRUE (election_insertion_result.inserted); - ASSERT_NE (nullptr, election_insertion_result.election); - election_insertion_result.election->force_confirm (); + node->active.insert (receive1); + auto election = node->active.election (receive1->qualified_root ()); + ASSERT_NE (nullptr, election); + election->force_confirm (); } ASSERT_TIMELY (30s, node->ledger.block_confirmed (node->store.tx_begin_read (), receive1->hash ())); @@ -1852,10 +1852,11 @@ TEST (node, wallet_create_block_confirm_conflicts) // Call block confirm on the top level send block which will confirm everything underneath on both accounts. { - auto election_insertion_result (node->active.insert (node->store.block_get (node->store.tx_begin_read (), latest))); - ASSERT_TRUE (election_insertion_result.inserted); - ASSERT_NE (nullptr, election_insertion_result.election); - election_insertion_result.election->force_confirm (); + auto block = node->store.block_get (node->store.tx_begin_read (), latest); + node->active.insert (block); + auto election = node->active.election (block->qualified_root ()); + ASSERT_NE (nullptr, election); + election->force_confirm (); } ASSERT_TIMELY (120s, node->ledger.block_confirmed (node->store.tx_begin_read (), latest) && node->confirmation_height_processor.current () == 0); From d852944450f373af4bbc297b0364519bac76e1d5 Mon Sep 17 00:00:00 2001 From: clemahieu Date: Tue, 20 Apr 2021 14:26:16 +0200 Subject: [PATCH 07/10] New clang format rules. --- nano/core_test/election_scheduler.cpp | 96 +++++++++++++-------------- nano/node/blockprocessor.cpp | 42 ++++++++---- nano/node/election_scheduler.cpp | 6 +- nano/node/wallet.cpp | 15 +++-- 4 files changed, 89 insertions(+), 70 deletions(-) diff --git a/nano/core_test/election_scheduler.cpp b/nano/core_test/election_scheduler.cpp index 08dc077c6a..4108bcaa9e 100644 --- a/nano/core_test/election_scheduler.cpp +++ b/nano/core_test/election_scheduler.cpp @@ -18,14 +18,14 @@ TEST (election_scheduler, activate_one_timely) nano::system system{ 1 }; nano::state_block_builder builder; auto send1 = builder.make_block () - .account (nano::dev_genesis_key.pub) - .previous (nano::genesis_hash) - .representative (nano::dev_genesis_key.pub) - .balance (nano::genesis_amount - nano::Gxrb_ratio) - .link (nano::dev_genesis_key.pub) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (nano::genesis_hash)) - .build_shared (); + .account (nano::dev_genesis_key.pub) + .previous (nano::genesis_hash) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - nano::Gxrb_ratio) + .link (nano::dev_genesis_key.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (nano::genesis_hash)) + .build_shared (); system.nodes[0]->ledger.process (system.nodes[0]->store.tx_begin_write (), *send1); system.nodes[0]->scheduler.activate (nano::dev_genesis_key.pub, system.nodes[0]->store.tx_begin_read ()); ASSERT_TIMELY (1s, system.nodes[0]->active.election (send1->qualified_root ())); @@ -36,14 +36,14 @@ TEST (election_scheduler, activate_one_flush) nano::system system{ 1 }; nano::state_block_builder builder; auto send1 = builder.make_block () - .account (nano::dev_genesis_key.pub) - .previous (nano::genesis_hash) - .representative (nano::dev_genesis_key.pub) - .balance (nano::genesis_amount - nano::Gxrb_ratio) - .link (nano::dev_genesis_key.pub) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (nano::genesis_hash)) - .build_shared (); + .account (nano::dev_genesis_key.pub) + .previous (nano::genesis_hash) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - nano::Gxrb_ratio) + .link (nano::dev_genesis_key.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (nano::genesis_hash)) + .build_shared (); system.nodes[0]->ledger.process (system.nodes[0]->store.tx_begin_write (), *send1); system.nodes[0]->scheduler.activate (nano::dev_genesis_key.pub, system.nodes[0]->store.tx_begin_read ()); system.nodes[0]->scheduler.flush (); @@ -62,23 +62,23 @@ TEST (election_scheduler, no_vacancy) // Activating accounts depends on confirmed dependencies. First, prepare 2 accounts auto send = builder.make_block () - .account (nano::dev_genesis_key.pub) - .previous (nano::genesis_hash) - .representative (nano::dev_genesis_key.pub) - .link (key.pub) - .balance (nano::genesis_amount - nano::Gxrb_ratio) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (nano::genesis_hash)) - .build_shared (); + .account (nano::dev_genesis_key.pub) + .previous (nano::genesis_hash) + .representative (nano::dev_genesis_key.pub) + .link (key.pub) + .balance (nano::genesis_amount - nano::Gxrb_ratio) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (nano::genesis_hash)) + .build_shared (); auto receive = builder.make_block () - .account (key.pub) - .previous (0) - .representative (key.pub) - .link (send->hash ()) - .balance (nano::Gxrb_ratio) - .sign (key.prv, key.pub) - .work (*system.work.generate (key.pub)) - .build_shared (); + .account (key.pub) + .previous (0) + .representative (key.pub) + .link (send->hash ()) + .balance (nano::Gxrb_ratio) + .sign (key.prv, key.pub) + .work (*system.work.generate (key.pub)) + .build_shared (); ASSERT_EQ (nano::process_result::progress, node.process (*send).code); ASSERT_EQ (nano::process_result::progress, node.process (*receive).code); node.block_confirm (send); @@ -90,23 +90,23 @@ TEST (election_scheduler, no_vacancy) // Second, process two eligble transactions auto block0 = builder.make_block () - .account (nano::dev_genesis_key.pub) - .previous (send->hash ()) - .representative (nano::dev_genesis_key.pub) - .link (nano::dev_genesis_key.pub) - .balance (nano::genesis_amount - 2 * nano::Gxrb_ratio) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (send->hash ())) - .build_shared (); + .account (nano::dev_genesis_key.pub) + .previous (send->hash ()) + .representative (nano::dev_genesis_key.pub) + .link (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - 2 * nano::Gxrb_ratio) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (send->hash ())) + .build_shared (); auto block1 = builder.make_block () - .account (key.pub) - .previous (receive->hash ()) - .representative (key.pub) - .link (key.pub) - .balance (0) - .sign (key.prv, key.pub) - .work (*system.work.generate (receive->hash ())) - .build_shared (); + .account (key.pub) + .previous (receive->hash ()) + .representative (key.pub) + .link (key.pub) + .balance (0) + .sign (key.prv, key.pub) + .work (*system.work.generate (receive->hash ())) + .build_shared (); ASSERT_EQ (nano::process_result::progress, node.process (*block0).code); ASSERT_EQ (nano::process_result::progress, node.process (*block1).code); node.scheduler.activate (nano::dev_genesis_key.pub, node.store.tx_begin_read ()); diff --git a/nano/node/blockprocessor.cpp b/nano/node/blockprocessor.cpp index 2134b4ad7a..f127fae6b1 100644 --- a/nano/node/blockprocessor.cpp +++ b/nano/node/blockprocessor.cpp @@ -376,7 +376,8 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction result = node.ledger.process (transaction_a, *block, info_a.verified); switch (result.code) { - case nano::process_result::progress: { + case nano::process_result::progress: + { release_assert (info_a.account.is_zero () || info_a.account == node.store.block_account_calculated (*block)); if (node.config.logging.ledger_logging ()) { @@ -400,7 +401,8 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction } break; } - case nano::process_result::gap_previous: { + case nano::process_result::gap_previous: + { if (node.config.logging.ledger_logging ()) { node.logger.try_log (boost::str (boost::format ("Gap previous for: %1%") % hash.to_string ())); @@ -419,7 +421,8 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction node.stats.inc (nano::stat::type::ledger, nano::stat::detail::gap_previous); break; } - case nano::process_result::gap_source: { + case nano::process_result::gap_source: + { if (node.config.logging.ledger_logging ()) { node.logger.try_log (boost::str (boost::format ("Gap source for: %1%") % hash.to_string ())); @@ -438,7 +441,8 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction node.stats.inc (nano::stat::type::ledger, nano::stat::detail::gap_source); break; } - case nano::process_result::gap_epoch_open_pending: { + case nano::process_result::gap_epoch_open_pending: + { if (node.config.logging.ledger_logging ()) { node.logger.try_log (boost::str (boost::format ("Gap pending entries for epoch open: %1%") % hash.to_string ())); @@ -455,7 +459,8 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction node.stats.inc (nano::stat::type::ledger, nano::stat::detail::gap_source); break; } - case nano::process_result::old: { + case nano::process_result::old: + { if (node.config.logging.ledger_duplicate_logging ()) { node.logger.try_log (boost::str (boost::format ("Old for: %1%") % hash.to_string ())); @@ -464,7 +469,8 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction node.stats.inc (nano::stat::type::ledger, nano::stat::detail::old); break; } - case nano::process_result::bad_signature: { + case nano::process_result::bad_signature: + { if (node.config.logging.ledger_logging ()) { node.logger.try_log (boost::str (boost::format ("Bad signature for: %1%") % hash.to_string ())); @@ -472,21 +478,24 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction events_a.events.emplace_back ([this, hash, info_a] (nano::transaction const & /* unused */) { requeue_invalid (hash, info_a); }); break; } - case nano::process_result::negative_spend: { + case nano::process_result::negative_spend: + { if (node.config.logging.ledger_logging ()) { node.logger.try_log (boost::str (boost::format ("Negative spend for: %1%") % hash.to_string ())); } break; } - case nano::process_result::unreceivable: { + case nano::process_result::unreceivable: + { if (node.config.logging.ledger_logging ()) { node.logger.try_log (boost::str (boost::format ("Unreceivable for: %1%") % hash.to_string ())); } break; } - case nano::process_result::fork: { + case nano::process_result::fork: + { node.stats.inc (nano::stat::type::ledger, nano::stat::detail::fork); events_a.events.emplace_back ([this, block] (nano::transaction const &) { this->node.active.publish (block); }); if (node.config.logging.ledger_logging ()) @@ -495,32 +504,37 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction } break; } - case nano::process_result::opened_burn_account: { + case nano::process_result::opened_burn_account: + { node.logger.always_log (boost::str (boost::format ("*** Rejecting open block for burn account ***: %1%") % hash.to_string ())); break; } - case nano::process_result::balance_mismatch: { + case nano::process_result::balance_mismatch: + { if (node.config.logging.ledger_logging ()) { node.logger.try_log (boost::str (boost::format ("Balance mismatch for: %1%") % hash.to_string ())); } break; } - case nano::process_result::representative_mismatch: { + case nano::process_result::representative_mismatch: + { if (node.config.logging.ledger_logging ()) { node.logger.try_log (boost::str (boost::format ("Representative mismatch for: %1%") % hash.to_string ())); } break; } - case nano::process_result::block_position: { + case nano::process_result::block_position: + { if (node.config.logging.ledger_logging ()) { node.logger.try_log (boost::str (boost::format ("Block %1% cannot follow predecessor %2%") % hash.to_string () % block->previous ().to_string ())); } break; } - case nano::process_result::insufficient_work: { + case nano::process_result::insufficient_work: + { if (node.config.logging.ledger_logging ()) { node.logger.try_log (boost::str (boost::format ("Insufficient work for %1% : %2% (difficulty %3%)") % hash.to_string () % nano::to_string_hex (block->block_work ()) % nano::to_string_hex (block->difficulty ()))); diff --git a/nano/node/election_scheduler.cpp b/nano/node/election_scheduler.cpp index da3b13a4c2..39d892e3ee 100644 --- a/nano/node/election_scheduler.cpp +++ b/nano/node/election_scheduler.cpp @@ -2,9 +2,9 @@ #include nano::election_scheduler::election_scheduler (nano::node & node) : -node{ node }, -stopped{ false }, -thread{ [this] () { run (); } } + node{ node }, + stopped{ false }, + thread{ [this] () { run (); } } { } diff --git a/nano/node/wallet.cpp b/nano/node/wallet.cpp index d13cb0454d..2a750a7e2f 100644 --- a/nano/node/wallet.cpp +++ b/nano/node/wallet.cpp @@ -114,13 +114,15 @@ void nano::wallet_store::deterministic_clear (nano::transaction const & transact { switch (key_type (nano::wallet_value (i->second))) { - case nano::key_type::deterministic: { + case nano::key_type::deterministic: + { auto const & key (i->first); erase (transaction_a, key); i = begin (transaction_a, key); break; } - default: { + default: + { ++i; break; } @@ -484,21 +486,24 @@ bool nano::wallet_store::fetch (nano::transaction const & transaction_a, nano::a { switch (key_type (value)) { - case nano::key_type::deterministic: { + case nano::key_type::deterministic: + { nano::raw_key seed_l; seed (seed_l, transaction_a); uint32_t index (static_cast (value.key.number () & static_cast (-1))); prv = deterministic_key (transaction_a, index); break; } - case nano::key_type::adhoc: { + case nano::key_type::adhoc: + { // Ad-hoc keys nano::raw_key password_l; wallet_key (password_l, transaction_a); prv.decrypt (value.key, password_l, pub.owords[0].number ()); break; } - default: { + default: + { result = true; break; } From f8f88c47fe20cfd41496ebeb76e55db64cddac55 Mon Sep 17 00:00:00 2001 From: clemahieu Date: Thu, 22 Apr 2021 01:48:37 +0200 Subject: [PATCH 08/10] Revert commit bringing the diff back toward 'develop' --- nano/node/wallet.cpp | 13 ++++++++++++- nano/secure/ledger.cpp | 20 +++++++++++--------- nano/secure/ledger.hpp | 1 + 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/nano/node/wallet.cpp b/nano/node/wallet.cpp index 2a750a7e2f..cededd746b 100644 --- a/nano/node/wallet.cpp +++ b/nano/node/wallet.cpp @@ -1188,7 +1188,18 @@ bool nano::wallet::search_pending (nano::transaction const & wallet_transaction_ if (wallets.node.config.receive_minimum.number () <= amount) { wallets.node.logger.try_log (boost::str (boost::format ("Found a pending block %1% for account %2%") % hash.to_string () % pending.source.to_account ())); - if (wallets.node.ledger.block_confirmed (block_transaction, hash)) + bool confirmed (wallets.node.ledger.block_confirmed (block_transaction, hash)); + if (confirmed) + { + auto block (wallets.node.store.block_get (block_transaction, hash)); + release_assert (block->type () == nano::block_type::state || block->type () == nano::block_type::send); + } + else if (wallets.node.ledger.pruning) + { + // All pruned blocks should be confirmed + confirmed = wallets.node.store.pruned_exists (block_transaction, hash); + } + if (confirmed) { auto representative = store.representative (wallet_transaction_a); // Receive confirmed block diff --git a/nano/secure/ledger.cpp b/nano/secure/ledger.cpp index bb3513c95d..e5b9ad87cf 100644 --- a/nano/secure/ledger.cpp +++ b/nano/secure/ledger.cpp @@ -894,6 +894,11 @@ bool nano::ledger::block_or_pruned_exists (nano::block_hash const & hash_a) cons return block_or_pruned_exists (store.tx_begin_read (), hash_a); } +bool nano::ledger::block_confirmed_or_pruned_exists (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const +{ + return block_confirmed (transaction_a, hash_a) || (pruning && store.pruned_exists (transaction_a, hash_a)); +} + std::string nano::ledger::block_text (char const * hash_a) { return block_text (nano::block_hash (hash_a)); @@ -1317,16 +1322,13 @@ std::shared_ptr nano::ledger::forked_block (nano::transaction const bool nano::ledger::block_confirmed (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const { - auto confirmed = store.pruned_exists (transaction_a, hash_a); - if (!confirmed) + auto confirmed (false); + auto block = store.block_get (transaction_a, hash_a); + if (block) { - auto block = store.block_get (transaction_a, hash_a); - if (block) - { - nano::confirmation_height_info confirmation_height_info; - store.confirmation_height_get (transaction_a, block->account ().is_zero () ? block->sideband ().account : block->account (), confirmation_height_info); - confirmed = (confirmation_height_info.height >= block->sideband ().height); - } + nano::confirmation_height_info confirmation_height_info; + store.confirmation_height_get (transaction_a, block->account ().is_zero () ? block->sideband ().account : block->account (), confirmation_height_info); + confirmed = (confirmation_height_info.height >= block->sideband ().height); } return confirmed; } diff --git a/nano/secure/ledger.hpp b/nano/secure/ledger.hpp index c36ff5b131..f04cc580ca 100644 --- a/nano/secure/ledger.hpp +++ b/nano/secure/ledger.hpp @@ -48,6 +48,7 @@ class ledger final bool block_exists (nano::block_hash const &) const; bool block_or_pruned_exists (nano::transaction const &, nano::block_hash const &) const; bool block_or_pruned_exists (nano::block_hash const &) const; + bool block_confirmed_or_pruned_exists (nano::transaction const &, nano::block_hash const &) const; std::string block_text (char const *); std::string block_text (nano::block_hash const &); bool is_send (nano::transaction const &, nano::state_block const &) const; From 65acbefce9d30fe4b22ffd28045cb03894443049 Mon Sep 17 00:00:00 2001 From: clemahieu Date: Thu, 22 Apr 2021 02:03:19 +0200 Subject: [PATCH 09/10] Cleaning up tests. Adding thread role name to election scheduler --- nano/core_test/election_scheduler.cpp | 8 +------- nano/lib/threading.cpp | 2 ++ nano/lib/threading.hpp | 3 ++- nano/node/election_scheduler.cpp | 1 + 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/nano/core_test/election_scheduler.cpp b/nano/core_test/election_scheduler.cpp index 4108bcaa9e..31d1d21d95 100644 --- a/nano/core_test/election_scheduler.cpp +++ b/nano/core_test/election_scheduler.cpp @@ -56,7 +56,6 @@ TEST (election_scheduler, no_vacancy) nano::node_config config{ nano::get_available_port (), system.logging }; config.active_elections_size = 1; auto & node = *system.add_node (config); - ; nano::state_block_builder builder; nano::keypair key; @@ -81,12 +80,7 @@ TEST (election_scheduler, no_vacancy) .build_shared (); ASSERT_EQ (nano::process_result::progress, node.process (*send).code); ASSERT_EQ (nano::process_result::progress, node.process (*receive).code); - node.block_confirm (send); - auto election1 = node.active.election (send->qualified_root ()); - election1->force_confirm (); - node.block_confirm (receive); - auto election2 = node.active.election (receive->qualified_root ()); - election2->force_confirm (); + nano::blocks_confirm (node, { send, receive }, true); // Second, process two eligble transactions auto block0 = builder.make_block () diff --git a/nano/lib/threading.cpp b/nano/lib/threading.cpp index 05cdb87514..e1f474162e 100644 --- a/nano/lib/threading.cpp +++ b/nano/lib/threading.cpp @@ -87,6 +87,8 @@ std::string nano::thread_role::get_string (nano::thread_role::name role) case nano::thread_role::name::db_parallel_traversal: thread_role_name_string = "DB par traversl"; break; + case nano::thread_role::name::election_scheduler: + thread_role_name_string = "Election Sched"; } /* diff --git a/nano/lib/threading.hpp b/nano/lib/threading.hpp index 3a6478f87b..3d9c5ddb33 100644 --- a/nano/lib/threading.hpp +++ b/nano/lib/threading.hpp @@ -38,7 +38,8 @@ namespace thread_role request_aggregator, state_block_signature_verification, epoch_upgrader, - db_parallel_traversal + db_parallel_traversal, + election_scheduler }; /* * Get/Set the identifier for the current thread diff --git a/nano/node/election_scheduler.cpp b/nano/node/election_scheduler.cpp index 39d892e3ee..1a438f89f6 100644 --- a/nano/node/election_scheduler.cpp +++ b/nano/node/election_scheduler.cpp @@ -86,6 +86,7 @@ size_t nano::election_scheduler::priority_queue_size () const void nano::election_scheduler::run () { + nano::thread_role::set (nano::thread_role::name::election_scheduler); nano::unique_lock lock{ mutex }; while (!stopped) { From 06159ed9670ae59b76c2ec3c83cc1b6720179847 Mon Sep 17 00:00:00 2001 From: clemahieu Date: Thu, 22 Apr 2021 11:44:04 +0200 Subject: [PATCH 10/10] Fixing race condition by not adding things to the manual queue from the prioritized queue. --- nano/node/election_scheduler.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/nano/node/election_scheduler.cpp b/nano/node/election_scheduler.cpp index 1a438f89f6..039ea9257a 100644 --- a/nano/node/election_scheduler.cpp +++ b/nano/node/election_scheduler.cpp @@ -102,10 +102,9 @@ void nano::election_scheduler::run () if (!priority.empty ()) { auto block = priority.top (); - lock.unlock (); - manual (block); - lock.lock (); - auto election = node.active.election (block->qualified_root ()); + std::shared_ptr election; + nano::unique_lock lock2 (node.active.mutex); + election = node.active.insert_impl (lock2, block).election; if (election != nullptr) { election->transition_active (); @@ -116,10 +115,8 @@ void nano::election_scheduler::run () if (!manual_queue.empty ()) { auto const [block, previous_balance, election_behavior, confirmation_action] = manual_queue.front (); - lock.unlock (); nano::unique_lock lock2 (node.active.mutex); node.active.insert_impl (lock2, block, previous_balance, election_behavior, confirmation_action); - lock.lock (); manual_queue.pop_front (); ++manual_queued; }