From ee85e1cc8e39369d6d957fcb7a9c30ce6e54332a Mon Sep 17 00:00:00 2001 From: Guilherme Lawless Date: Tue, 25 Aug 2020 11:27:02 +0100 Subject: [PATCH] Remove election fallback behaviors and adjusted multiplier calculations (#2891) * Remove election fallback behaviors and adjusted multiplier calculations Removes backtracking and dependency activation. The move to sequential elections also allows removing the adjusted multiplier from chains. Frontier successor insertion (https://github.com/nanocurrency/nano-node/pull/2885) is the new fallback behavior which does not escalate. * Fix node.block_confirm which relied on activating dependencies --- nano/core_test/active_transactions.cpp | 364 ------------------------- nano/core_test/conflicts.cpp | 103 ------- nano/core_test/election.cpp | 158 ----------- nano/core_test/ledger.cpp | 51 ---- nano/core_test/node.cpp | 17 +- nano/node/active_transactions.cpp | 194 +------------ nano/node/active_transactions.hpp | 11 +- nano/node/election.cpp | 73 ----- nano/node/election.hpp | 9 - nano/secure/ledger.cpp | 13 - nano/secure/ledger.hpp | 1 - 11 files changed, 16 insertions(+), 978 deletions(-) diff --git a/nano/core_test/active_transactions.cpp b/nano/core_test/active_transactions.cpp index 2153a5c3..38d0373c 100644 --- a/nano/core_test/active_transactions.cpp +++ b/nano/core_test/active_transactions.cpp @@ -99,166 +99,6 @@ TEST (active_transactions, confirm_frontier) } } -TEST (active_transactions, adjusted_multiplier_priority) -{ - nano::system system; - nano::node_config node_config (nano::get_available_port (), system.logging); - node_config.enable_voting = false; - node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; - auto & node1 = *system.add_node (node_config); - nano::keypair key1, key2, key3; - - 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 - 10 * nano::xrb_ratio) - .link (key1.pub) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (nano::genesis_hash)) - .build_shared (); - auto send2 = builder.make_block () - .account (nano::dev_genesis_key.pub) - .previous (send1->hash ()) - .representative (nano::dev_genesis_key.pub) - .balance (nano::genesis_amount - 20 * nano::xrb_ratio) - .link (key2.pub) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (send1->hash ())) - .build_shared (); - auto open1 = builder.make_block () - .account (key1.pub) - .previous (0) - .representative (key1.pub) - .balance (10 * nano::xrb_ratio) - .link (send1->hash ()) - .sign (key1.prv, key1.pub) - .work (*system.work.generate (key1.pub)) - .build_shared (); - auto open2 = builder.make_block () - .account (key2.pub) - .previous (0) - .representative (key2.pub) - .balance (10 * nano::xrb_ratio) - .link (send2->hash ()) - .sign (key2.prv, key2.pub) - .work (*system.work.generate (key2.pub)) - .build_shared (); - node1.process_active (send1); // genesis - node1.process_active (send2); // genesis - node1.process_active (open1); // key1 - node1.process_active (open2); // key2 - nano::blocks_confirm (node1, { send1, send2, open1, open2 }); - ASSERT_TIMELY (10s, node1.active.size () == 4); - - // Check adjusted difficulty - { - nano::lock_guard active_guard (node1.active.mutex); - node1.active.update_adjusted_multiplier (); - ASSERT_EQ (node1.active.roots.get<1> ().begin ()->election->status.winner->hash (), send1->hash ()); - ASSERT_LT (node1.active.roots.find (send2->qualified_root ())->adjusted_multiplier, node1.active.roots.find (send1->qualified_root ())->adjusted_multiplier); - ASSERT_LT (node1.active.roots.find (open1->qualified_root ())->adjusted_multiplier, node1.active.roots.find (send1->qualified_root ())->adjusted_multiplier); - ASSERT_LT (node1.active.roots.find (open2->qualified_root ())->adjusted_multiplier, node1.active.roots.find (send2->qualified_root ())->adjusted_multiplier); - } - - // Confirm elections - system.deadline_set (10s); - while (!node1.active.empty ()) - { - nano::lock_guard active_guard (node1.active.mutex); - if (!node1.active.roots.empty ()) - { - node1.active.roots.begin ()->election->confirm_once (); - } - } - ASSERT_TIMELY (10s, node1.ledger.cache.cemented_count == 5 && node1.active.empty ()); - - //genesis and key1,key2 are opened - //start chain of 2 on each - auto send3 = builder.make_block () - .account (nano::dev_genesis_key.pub) - .previous (send2->hash ()) - .representative (nano::dev_genesis_key.pub) - .balance (9 * nano::xrb_ratio) - .link (key3.pub) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (send2->hash (), nano::difficulty::from_multiplier (150, node1.network_params.network.publish_thresholds.base))) - .build_shared (); - auto send4 = builder.make_block () - .account (nano::dev_genesis_key.pub) - .previous (send3->hash ()) - .representative (nano::dev_genesis_key.pub) - .balance (8 * nano::xrb_ratio) - .link (key3.pub) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (send3->hash (), nano::difficulty::from_multiplier (150, node1.network_params.network.publish_thresholds.base))) - .build_shared (); - auto send5 = builder.make_block () - .account (key1.pub) - .previous (open1->hash ()) - .representative (key1.pub) - .balance (9 * nano::xrb_ratio) - .link (key3.pub) - .sign (key1.prv, key1.pub) - .work (system.work_generate_limited (open1->hash (), nano::difficulty::from_multiplier (10, node1.network_params.network.publish_thresholds.base), nano::difficulty::from_multiplier (50, node1.network_params.network.publish_thresholds.base))) - .build_shared (); - auto send6 = builder.make_block () - .account (key1.pub) - .previous (send5->hash ()) - .representative (key1.pub) - .balance (8 * nano::xrb_ratio) - .link (key3.pub) - .sign (key1.prv, key1.pub) - .work (system.work_generate_limited (send5->hash (), nano::difficulty::from_multiplier (10, node1.network_params.network.publish_thresholds.base), nano::difficulty::from_multiplier (50, node1.network_params.network.publish_thresholds.base))) - .build_shared (); - auto send7 = builder.make_block () - .account (key2.pub) - .previous (open2->hash ()) - .representative (key2.pub) - .balance (9 * nano::xrb_ratio) - .link (key3.pub) - .sign (key2.prv, key2.pub) - .work (system.work_generate_limited (open2->hash (), nano::difficulty::from_multiplier (50, node1.network_params.network.publish_thresholds.base), nano::difficulty::from_multiplier (150, node1.network_params.network.publish_thresholds.base))) - .build_shared (); - auto send8 = builder.make_block () - .account (key2.pub) - .previous (send7->hash ()) - .representative (key2.pub) - .balance (8 * nano::xrb_ratio) - .link (key3.pub) - .sign (key2.prv, key2.pub) - .work (system.work_generate_limited (send7->hash (), nano::difficulty::from_multiplier (50, node1.network_params.network.publish_thresholds.base), nano::difficulty::from_multiplier (150, node1.network_params.network.publish_thresholds.base))) - .build_shared (); - - node1.process_active (send3); // genesis - node1.process_active (send5); // key1 - node1.process_active (send7); // key2 - node1.process_active (send4); // genesis - node1.process_active (send6); // key1 - node1.process_active (send8); // key2 - nano::blocks_confirm (node1, { send3, send4, send5, send6, send7, send8 }); - - ASSERT_TIMELY (10s, node1.active.size () == 6); - - // Check adjusted difficulty - nano::lock_guard lock (node1.active.mutex); - node1.active.update_adjusted_multiplier (); - double last_adjusted (0.0); - for (auto i (node1.active.roots.get<1> ().begin ()), n (node1.active.roots.get<1> ().end ()); i != n; ++i) - { - //first root has nothing to compare - if (last_adjusted != 0.0) - { - ASSERT_LE (i->adjusted_multiplier, last_adjusted); - } - last_adjusted = i->adjusted_multiplier; - } - ASSERT_LT (node1.active.roots.find (send4->qualified_root ())->adjusted_multiplier, node1.active.roots.find (send3->qualified_root ())->adjusted_multiplier); - ASSERT_LT (node1.active.roots.find (send6->qualified_root ())->adjusted_multiplier, node1.active.roots.find (send5->qualified_root ())->adjusted_multiplier); - ASSERT_LT (node1.active.roots.find (send8->qualified_root ())->adjusted_multiplier, node1.active.roots.find (send7->qualified_root ())->adjusted_multiplier); -} - TEST (active_transactions, keep_local) { nano::system system; @@ -328,129 +168,6 @@ TEST (active_transactions, keep_local) ASSERT_EQ (1, node.stats.count (nano::stat::type::election, nano::stat::detail::election_drop)); } -TEST (active_transactions, prioritize_chains) -{ - nano::system system; - nano::node_config node_config (nano::get_available_port (), system.logging); - node_config.enable_voting = false; - node_config.active_elections_size = 4; //bound to 4, wont drop wallet created transactions, but good to test dropping remote - // Disable frontier confirmation to allow the test to finish before - node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; - auto & node1 = *system.add_node (node_config); - nano::genesis genesis; - nano::keypair key1, key2, key3; - - nano::state_block_builder builder; - auto send1 = builder.make_block () - .account (nano::dev_genesis_key.pub) - .previous (genesis.hash ()) - .representative (nano::dev_genesis_key.pub) - .balance (nano::genesis_amount - 10 * nano::xrb_ratio) - .link (key1.pub) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (genesis.hash ())) - .build_shared (); - auto open1 = builder.make_block () - .account (key1.pub) - .previous (0) - .representative (key1.pub) - .balance (10 * nano::xrb_ratio) - .link (send1->hash ()) - .sign (key1.prv, key1.pub) - .work (*system.work.generate (key1.pub)) - .build_shared (); - auto send2 = builder.make_block () - .account (key1.pub) - .previous (open1->hash ()) - .representative (key1.pub) - .balance (9 * nano::xrb_ratio) - .link (key2.pub) - .sign (key1.prv, key1.pub) - .work (*system.work.generate (open1->hash ())) - .build_shared (); - auto send3 = builder.make_block () - .from (*send2) - .previous (send2->hash ()) - .balance (8 * nano::xrb_ratio) - .sign (key1.prv, key1.pub) - .work (*system.work.generate (send2->hash ())) - .build_shared (); - auto send4 = builder.make_block () - .from (*send3) - .previous (send3->hash ()) - .balance (7 * nano::xrb_ratio) - .sign (key1.prv, key1.pub) - .work (*system.work.generate (send3->hash ())) - .build_shared (); - auto send5 = builder.make_block () - .from (*send1) - .previous (send1->hash ()) - .balance (nano::genesis_amount - 20 * nano::xrb_ratio) - .link (key2.pub) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (send1->hash ())) - .build_shared (); - auto send6 = builder.make_block () - .from (*send5) - .previous (send5->hash ()) - .balance (nano::genesis_amount - 30 * nano::xrb_ratio) - .link (key3.pub) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (send5->hash ())) - .build_shared (); - auto open2 = builder.make_block () - .account (key2.pub) - .previous (0) - .representative (key2.pub) - .balance (10 * nano::xrb_ratio) - .link (send5->hash ()) - .sign (key2.prv, key2.pub) - .work (*system.work.generate (key2.pub)) - .build_shared (); - - auto multiplier1 (nano::normalized_multiplier (nano::difficulty::to_multiplier (open2->difficulty (), nano::work_threshold (open2->work_version (), nano::block_details (nano::epoch::epoch_0, false, true, false))), node1.network_params.network.publish_thresholds.epoch_1)); - auto multiplier2 (nano::normalized_multiplier (nano::difficulty::to_multiplier (send6->difficulty (), nano::work_threshold (open2->work_version (), nano::block_details (nano::epoch::epoch_0, true, false, false))), node1.network_params.network.publish_thresholds.epoch_1)); - - node1.process_active (send1); - node1.process_active (open1); - node1.process_active (send5); - nano::blocks_confirm (node1, { send1, open1, send5 }); - ASSERT_TIMELY (10s, node1.active.size () == 3); - while (!node1.active.empty ()) - { - nano::lock_guard active_guard (node1.active.mutex); - if (!node1.active.roots.empty ()) - { - node1.active.roots.begin ()->election->confirm_once (); - } - } - node1.process_active (send2); - node1.process_active (send3); - node1.process_active (send4); - node1.process_active (send6); - nano::blocks_confirm (node1, { send2, send3, send4, send6 }); - ASSERT_TIMELY (10s, node1.active.size () == 4); - std::this_thread::sleep_for (1s); - node1.process_active (open2); - ASSERT_TIMELY (10s, node1.active.size () == 4); - size_t seen (0); - { - nano::lock_guard active_guard (node1.active.mutex); - node1.active.update_adjusted_multiplier (); - auto it (node1.active.roots.get<1> ().begin ()); - while (!node1.active.roots.empty () && it != node1.active.roots.get<1> ().end ()) - { - if (it->multiplier == multiplier1 || it->multiplier == multiplier2) - { - seen++; - } - it++; - } - } - ASSERT_LT (seen, 2); - ASSERT_EQ (node1.active.size (), 4); -} - TEST (active_transactions, inactive_votes_cache) { nano::system system (1); @@ -977,89 +694,8 @@ TEST (active_transactions, vote_replays) } } -TEST (active_transactions, activate_dependencies) -{ - // Ensure that we attempt to backtrack if an election isn't getting confirmed and there are more uncemented blocks to start elections for - nano::system system; - nano::node_config config (nano::get_available_port (), system.logging); - config.enable_voting = true; - nano::node_flags flags; - flags.disable_bootstrap_listener = true; - config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; - auto node1 (system.add_node (config, flags)); - config.peering_port = nano::get_available_port (); - auto node2 (system.add_node (config, flags)); - system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv); - nano::genesis genesis; - nano::block_builder builder; - auto block0 = builder.state () - .account (nano::dev_genesis_key.pub) - .previous (genesis.hash ()) - .representative (nano::dev_genesis_key.pub) - .balance (nano::genesis_amount - nano::Gxrb_ratio) - .link (0) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (node1->work_generate_blocking (genesis.hash ()).value ()) - .build_shared (); - // Establish a representative - node2->process_active (block0); - node2->block_processor.flush (); - ASSERT_TIMELY (10s, node1->block (block0->hash ())); - auto block1 = builder.state () - .account (nano::dev_genesis_key.pub) - .previous (block0->hash ()) - .representative (nano::dev_genesis_key.pub) - .balance (nano::genesis_amount - nano::Gxrb_ratio) - .link (0) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (node1->work_generate_blocking (block0->hash ()).value ()) - .build (); - // Wait for confirmation of the previous block, which tries to activate the successor - // We want to test that behavior through activating dependencies instead - ASSERT_TIMELY (3s, node2->block_confirmed (block0->hash ())); - { - auto transaction = node2->store.tx_begin_write (); - ASSERT_EQ (nano::process_result::progress, node2->ledger.process (transaction, *block1).code); - } - std::shared_ptr block2 = builder.state () - .account (nano::dev_genesis_key.pub) - .previous (block1->hash ()) - .representative (nano::dev_genesis_key.pub) - .balance (nano::genesis_amount - 2 * nano::Gxrb_ratio) - .link (0) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (node1->work_generate_blocking (block1->hash ()).value ()) - .build (); - node2->process_active (block2); - node2->block_processor.flush (); - node2->block_confirm (block2); - ASSERT_TIMELY (10s, node1->block (block2->hash ())); - ASSERT_NE (nullptr, node1->block (block2->hash ())); - ASSERT_TIMELY (10s, node1->active.empty () && node2->active.empty ()); - ASSERT_TRUE (node1->block_confirmed_or_being_confirmed (node1->store.tx_begin_read (), block2->hash ())); - ASSERT_TRUE (node2->block_confirmed_or_being_confirmed (node2->store.tx_begin_read (), block2->hash ())); -} - namespace nano { -TEST (active_transactions, activate_dependencies_invalid) -{ - nano::system system; - nano::node_flags flags; - flags.disable_request_loop = true; - auto & node (*system.add_node (flags)); - node.active.pending_dependencies.emplace_back (nano::genesis ().open->hash (), 10); - node.active.pending_dependencies.emplace_back (1, 1); - node.active.pending_dependencies.emplace_back (0, -1); - node.active.pending_dependencies.emplace_back (-1, 0); - { - nano::unique_lock lock (node.active.mutex); - node.active.activate_dependencies (lock); - } - ASSERT_TRUE (node.active.empty ()); - ASSERT_EQ (0, node.active.pending_dependencies.size ()); -} - // Tests that blocks are correctly cleared from the duplicate filter for unconfirmed elections TEST (active_transactions, dropped_cleanup) { diff --git a/nano/core_test/conflicts.cpp b/nano/core_test/conflicts.cpp index 786c55d2..e3385791 100644 --- a/nano/core_test/conflicts.cpp +++ b/nano/core_test/conflicts.cpp @@ -189,106 +189,3 @@ TEST (conflicts, reprioritize) ASSERT_EQ (multiplier2, existing2->multiplier); } } - -TEST (conflicts, dependency) -{ - nano::system system; - nano::node_config node_config (nano::get_available_port (), system.logging); - node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; - auto node1 = system.add_node (node_config); - nano::genesis genesis; - nano::keypair key1; - auto send1 (std::make_shared (genesis.hash (), key1.pub, nano::genesis_amount - nano::xrb_ratio, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); - node1->work_generate_blocking (*send1); - auto state_open1 (std::make_shared (key1.pub, 0, nano::dev_genesis_key.pub, nano::xrb_ratio, send1->hash (), key1.prv, key1.pub, 0)); - node1->work_generate_blocking (*state_open1); - ASSERT_EQ (nano::process_result::progress, node1->process (*send1).code); - ASSERT_EQ (nano::process_result::progress, node1->process (*state_open1).code); - ASSERT_EQ (0, node1->active.size ()); - auto election1 = node1->active.insert (send1); - node1->active.insert (state_open1); - ASSERT_EQ (2, node1->active.size ()); - // Check dependency for send block - { - nano::lock_guard guard (node1->active.mutex); - ASSERT_NE (nullptr, election1.election); - ASSERT_EQ (1, election1.election->dependent_blocks.size ()); - ASSERT_NE (election1.election->dependent_blocks.end (), election1.election->dependent_blocks.find (state_open1->hash ())); - } -} - -TEST (conflicts, adjusted_multiplier) -{ - nano::system system; - nano::node_flags flags; - flags.disable_request_loop = true; - auto & node1 (*system.add_node (flags)); - nano::genesis genesis; - nano::keypair key1; - nano::keypair key2; - nano::keypair key3; - ASSERT_EQ (0, node1.active.size ()); - auto send1 (std::make_shared (genesis.hash (), key1.pub, nano::genesis_amount - 2 * nano::xrb_ratio, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (genesis.hash ()))); - node1.process_active (send1); - auto send2 (std::make_shared (send1->hash (), nano::dev_genesis_key.pub, nano::genesis_amount - 3 * nano::xrb_ratio, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (send1->hash ()))); - node1.process_active (send2); - auto receive1 (std::make_shared (send2->hash (), send2->hash (), nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (send2->hash ()))); - node1.process_active (receive1); - auto open1 (std::make_shared (send1->hash (), key1.pub, key1.pub, key1.prv, key1.pub, *system.work.generate (key1.pub))); - node1.process_active (open1); - auto send3 (std::make_shared (key1.pub, open1->hash (), key1.pub, nano::xrb_ratio, key2.pub, key1.prv, key1.pub, *system.work.generate (open1->hash ()))); - node1.process_active (send3); - auto send4 (std::make_shared (key1.pub, send3->hash (), key1.pub, 0, key3.pub, key1.prv, key1.pub, *system.work.generate (send3->hash ()))); - node1.process_active (send4); - ASSERT_EQ (node1.ledger.epoch_signer (node1.ledger.epoch_link (nano::epoch::epoch_1)), nano::dev_genesis_key.pub); - auto open_epoch1 (std::make_shared (key2.pub, 0, 0, 0, node1.ledger.epoch_link (nano::epoch::epoch_1), nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (key2.pub))); - node1.process_active (open_epoch1); - auto receive2 (std::make_shared (key2.pub, open_epoch1->hash (), 0, nano::xrb_ratio, send3->hash (), key2.prv, key2.pub, *system.work.generate (open_epoch1->hash ()))); - node1.process_active (receive2); - auto open2 (std::make_shared (key3.pub, 0, key3.pub, nano::xrb_ratio, send4->hash (), key3.prv, key3.pub, *system.work.generate (key3.pub))); - node1.process_active (open2); - auto change1 (std::make_shared (key3.pub, open2->hash (), nano::dev_genesis_key.pub, nano::xrb_ratio, 0, key3.prv, key3.pub, *system.work.generate (open2->hash ()))); - node1.process_active (change1); - nano::keypair key4; - auto send5 (std::make_shared (key3.pub, change1->hash (), nano::dev_genesis_key.pub, 0, key4.pub, key3.prv, key3.pub, *system.work.generate (change1->hash ()))); // Pending for open epoch block - node1.process_active (send5); - nano::blocks_confirm (node1, { send1, send2, receive1, open1, send3, send4, open_epoch1, receive2, open2, change1, send5 }); - ASSERT_TIMELY (3s, node1.active.size () == 11); - std::unordered_map adjusted_multipliers; - { - nano::lock_guard guard (node1.active.mutex); - node1.active.update_adjusted_multiplier (); - ASSERT_EQ (node1.active.roots.get<1> ().begin ()->election->status.winner->hash (), send1->hash ()); - for (auto i (node1.active.roots.get<1> ().begin ()), n (node1.active.roots.get<1> ().end ()); i != n; ++i) - { - adjusted_multipliers.insert (std::make_pair (i->election->status.winner->hash (), i->adjusted_multiplier)); - } - } - // genesis - ASSERT_GT (adjusted_multipliers.find (send1->hash ())->second, adjusted_multipliers.find (send2->hash ())->second); - ASSERT_GT (adjusted_multipliers.find (send2->hash ())->second, adjusted_multipliers.find (receive1->hash ())->second); - // key1 - ASSERT_GT (adjusted_multipliers.find (send1->hash ())->second, adjusted_multipliers.find (open1->hash ())->second); - ASSERT_GT (adjusted_multipliers.find (open1->hash ())->second, adjusted_multipliers.find (send3->hash ())->second); - ASSERT_GT (adjusted_multipliers.find (send3->hash ())->second, adjusted_multipliers.find (send4->hash ())->second); - //key2 - ASSERT_GT (adjusted_multipliers.find (send3->hash ())->second, adjusted_multipliers.find (receive2->hash ())->second); - ASSERT_GT (adjusted_multipliers.find (open_epoch1->hash ())->second, adjusted_multipliers.find (receive2->hash ())->second); - // key3 - ASSERT_GT (adjusted_multipliers.find (send4->hash ())->second, adjusted_multipliers.find (open2->hash ())->second); - ASSERT_GT (adjusted_multipliers.find (open2->hash ())->second, adjusted_multipliers.find (change1->hash ())->second); - ASSERT_GT (adjusted_multipliers.find (change1->hash ())->second, adjusted_multipliers.find (send5->hash ())->second); - // Independent elections can have higher difficulty than adjusted tree - auto open_epoch2 (std::make_shared (key4.pub, 0, 0, 0, node1.ledger.epoch_link (nano::epoch::epoch_1), nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (key4.pub, nano::difficulty::from_multiplier ((adjusted_multipliers.find (send1->hash ())->second), node1.network_params.network.publish_thresholds.base)))); - ASSERT_GT (open_epoch2->difficulty (), nano::difficulty::from_multiplier ((adjusted_multipliers.find (send1->hash ())->second), node1.network_params.network.publish_thresholds.base)); - node1.process_active (open_epoch2); - node1.block_processor.flush (); - node1.block_confirm (open_epoch2); - ASSERT_TIMELY (3s, node1.active.size () == 12); - { - nano::lock_guard guard (node1.active.mutex); - node1.active.update_adjusted_multiplier (); - ASSERT_EQ (node1.active.roots.size (), 12); - ASSERT_EQ (node1.active.roots.get<1> ().begin ()->election->status.winner->hash (), open_epoch2->hash ()); - } -} diff --git a/nano/core_test/election.cpp b/nano/core_test/election.cpp index 3879e510..d64ba3b0 100644 --- a/nano/core_test/election.cpp +++ b/nano/core_test/election.cpp @@ -13,161 +13,3 @@ TEST (election, construction) auto election = node.active.insert (genesis.open).election; election->transition_active (); } - -namespace nano -{ -TEST (election, bisect_dependencies) -{ - nano::system system; - nano::node_flags flags; - flags.disable_request_loop = true; - auto & node = *system.add_node (flags); - nano::genesis genesis; - nano::confirmation_height_info conf_info; - ASSERT_FALSE (node.store.confirmation_height_get (node.store.tx_begin_read (), nano::dev_genesis_key.pub, conf_info)); - ASSERT_EQ (1, conf_info.height); - std::vector> blocks; - blocks.push_back (nullptr); // idx == height - blocks.push_back (genesis.open); - nano::block_builder builder; - auto amount = nano::genesis_amount; - for (int i = 0; i < 299; ++i) - { - auto latest = blocks.back (); - blocks.push_back (builder.state () - .previous (latest->hash ()) - .account (nano::dev_genesis_key.pub) - .representative (nano::dev_genesis_key.pub) - .balance (--amount) - .link (nano::dev_genesis_key.pub) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (latest->hash ())) - .build ()); - ASSERT_EQ (nano::process_result::progress, node.process (*blocks.back ()).code); - } - ASSERT_EQ (301, blocks.size ()); - ASSERT_TRUE (node.active.empty ()); - { - auto election = node.active.insert (blocks.back ()).election; - ASSERT_NE (nullptr, election); - ASSERT_EQ (300, election->blocks.begin ()->second->sideband ().height); - nano::unique_lock lock (node.active.mutex); - election->activate_dependencies (); - node.active.activate_dependencies (lock); - } - // The first dependency activation also starts an election for the first unconfirmed block - ASSERT_EQ (3, node.active.size ()); - { - auto election = node.active.election (blocks[2]->qualified_root ()); - ASSERT_NE (nullptr, election); - ASSERT_EQ (2, election->blocks.begin ()->second->sideband ().height); - } - - auto check_height_and_activate_next = [&node, &blocks](uint64_t height_a) { - auto election = node.active.election (blocks[height_a]->qualified_root ()); - ASSERT_NE (nullptr, election); - ASSERT_EQ (height_a, election->blocks.begin ()->second->sideband ().height); - nano::unique_lock lock (node.active.mutex); - election->activate_dependencies (); - node.active.activate_dependencies (lock); - }; - check_height_and_activate_next (300 - 128); // ensure limited by 128 jumps - ASSERT_EQ (4, node.active.size ()); - check_height_and_activate_next (87); - ASSERT_EQ (5, node.active.size ()); - check_height_and_activate_next (44); - ASSERT_EQ (6, node.active.size ()); - check_height_and_activate_next (23); - ASSERT_EQ (7, node.active.size ()); - check_height_and_activate_next (12); - ASSERT_EQ (8, node.active.size ()); - check_height_and_activate_next (7); - ASSERT_EQ (9, node.active.size ()); - check_height_and_activate_next (4); - ASSERT_EQ (10, node.active.size ()); - check_height_and_activate_next (3); - ASSERT_EQ (10, node.active.size ()); // height 2 already inserted initially, no more blocks to activate - check_height_and_activate_next (2); - ASSERT_EQ (10, node.active.size ()); // conf height is 1, no more blocks to activate - ASSERT_EQ (node.active.blocks.size (), node.active.roots.size ()); -} - -// Tests successful dependency activation of the open block of an account, and its corresponding source -TEST (election, dependencies_open_link) -{ - nano::system system; - nano::node_flags flags; - flags.disable_request_loop = true; - auto & node = *system.add_node (flags); - - nano::state_block_builder builder; - nano::keypair key; - - // Send to key - auto gen_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 - 1) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*system.work.generate (nano::genesis_hash)) - .build (); - // Receive from genesis - auto key_open = builder.make_block () - .account (key.pub) - .previous (0) - .representative (key.pub) - .link (gen_send->hash ()) - .balance (1) - .sign (key.prv, key.pub) - .work (*system.work.generate (key.pub)) - .build (); - - // Send to self - std::shared_ptr key_send = builder.make_block () - .account (key.pub) - .previous (key_open->hash ()) - .representative (key.pub) - .link (key.pub) - .balance (0) - .sign (key.prv, key.pub) - .work (*system.work.generate (key_open->hash ())) - .build (); - - node.process (*gen_send); - node.process (*key_open); - node.process (*key_send); - - // Insert frontier - node.block_confirm (key_send); - ASSERT_EQ (1, node.active.size ()); - { - auto election = node.active.election (key_send->qualified_root ()); - ASSERT_NE (nullptr, election); - nano::unique_lock lock (node.active.mutex); - election->activate_dependencies (); - node.active.activate_dependencies (lock); - } - // Must have activated the open block - ASSERT_EQ (2, node.active.size ()); - { - auto election = node.active.election (key_open->qualified_root ()); - ASSERT_NE (nullptr, election); - nano::unique_lock lock (node.active.mutex); - election->activate_dependencies (); - node.active.activate_dependencies (lock); - } - // Must have activated the open's source block - ASSERT_EQ (3, node.active.size ()); - { - auto election = node.active.election (gen_send->qualified_root ()); - ASSERT_NE (nullptr, election); - nano::unique_lock lock (node.active.mutex); - election->activate_dependencies (); - node.active.activate_dependencies (lock); - } - // Nothing else to activate - ASSERT_EQ (3, node.active.size ()); -} -} diff --git a/nano/core_test/ledger.cpp b/nano/core_test/ledger.cpp index 49d2032c..8ec22b1f 100644 --- a/nano/core_test/ledger.cpp +++ b/nano/core_test/ledger.cpp @@ -3244,54 +3244,3 @@ TEST (ledger, can_vote) ledger.store.confirmation_height_put (transaction, nano::genesis_account, height); ASSERT_TRUE (ledger.can_vote (transaction, *receive2)); } - -TEST (ledger, backtrack) -{ - nano::genesis genesis; - nano::stat stats; - nano::logger_mt logger; - auto store = nano::make_store (logger, nano::unique_path ()); - ASSERT_TRUE (!store->init_error ()); - bool cb_hit = false; - nano::ledger ledger (*store, stats, nano::generate_cache (), [&cb_hit]() { - cb_hit = true; - }); - { - auto transaction (store->tx_begin_write ()); - store->initialize (transaction, genesis, ledger.cache); - } - nano::work_pool pool (std::numeric_limits::max ()); - std::vector> blocks; - blocks.push_back (nullptr); // idx == height - blocks.push_back (genesis.open); - auto amount = nano::genesis_amount; - for (auto i = 0; i < 300; ++i) - { - nano::block_builder builder; - std::error_code ec; - auto latest = blocks.back (); - blocks.push_back (builder.state () - .previous (latest->hash ()) - .account (nano::dev_genesis_key.pub) - .representative (nano::dev_genesis_key.pub) - .balance (--amount) - .link (nano::dev_genesis_key.pub) - .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) - .work (*pool.generate (latest->hash ())) - .build (ec)); - ASSERT_FALSE (ec); - ASSERT_EQ (nano::process_result::progress, ledger.process (store->tx_begin_write (), *blocks.back ()).code); - } - ASSERT_EQ (302, blocks.size ()); - ASSERT_EQ (301, blocks[301]->sideband ().height); - auto transaction (store->tx_begin_read ()); - auto block_100 = ledger.backtrack (transaction, blocks[300], 200); - ASSERT_NE (nullptr, block_100); - ASSERT_EQ (*block_100, *blocks[100]); - ASSERT_NE (nullptr, ledger.backtrack (transaction, blocks[10], 10)); - ASSERT_NE (ledger.backtrack (transaction, blocks[10], 1), ledger.backtrack (transaction, blocks[11], 2)); - ASSERT_EQ (ledger.backtrack (transaction, blocks[1], 0), ledger.backtrack (transaction, blocks[1], 1)); - ASSERT_NE (ledger.backtrack (transaction, blocks[2], 0), ledger.backtrack (transaction, blocks[2], 1)); - ASSERT_EQ (nullptr, ledger.backtrack (transaction, nullptr, 0)); - ASSERT_EQ (nullptr, ledger.backtrack (transaction, nullptr, 10)); -} diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index 6b1ee3ac..2936782d 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -2513,7 +2513,6 @@ TEST (node, block_confirm) auto & node2 (*system.nodes[1]); nano::genesis genesis; nano::keypair key; - system.wallet (1)->insert_adhoc (nano::dev_genesis_key.prv); nano::state_block_builder builder; auto send1 = builder.make_block () .account (nano::dev_genesis_key.pub) @@ -2533,6 +2532,16 @@ TEST (node, block_confirm) ASSERT_TIMELY (5s, node1.ledger.block_exists (send1->hash ()) && node2.ledger.block_exists (send1_copy->hash ())); ASSERT_TRUE (node1.ledger.block_exists (send1->hash ())); ASSERT_TRUE (node2.ledger.block_exists (send1_copy->hash ())); + // Confirm send1 on node2 so it can vote for send2 + node2.block_confirm (send1_copy); + { + auto election = node2.active.election (send1_copy->qualified_root ()); + ASSERT_NE (nullptr, election); + nano::lock_guard guard (node2.active.mutex); + election->confirm_once (); + } + 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 ()); @@ -2542,9 +2551,9 @@ TEST (node, block_confirm) auto transaction (node2.store.tx_begin_write ()); ASSERT_EQ (nano::process_result::progress, node2.ledger.process (transaction, *send2).code); } - node1.block_confirm (send2); ASSERT_TRUE (node1.active.list_recently_cemented ().empty ()); - ASSERT_TIMELY (10s, !node1.active.list_recently_cemented ().empty ()); + node1.block_confirm (send2); + ASSERT_TIMELY (10s, node1.active.list_recently_cemented ().size () == 2); } } @@ -4197,7 +4206,7 @@ TEST (node, dependency_graph) } // Confirm a complex dependency graph starting from a frontier -TEST (node, dependency_graph_frontier) +TEST (node, DISABLED_dependency_graph_frontier) { nano::system system; nano::node_config config (nano::get_available_port (), system.logging); diff --git a/nano/node/active_transactions.cpp b/nano/node/active_transactions.cpp index 6771a65f..19bd7f62 100644 --- a/nano/node/active_transactions.cpp +++ b/nano/node/active_transactions.cpp @@ -273,7 +273,6 @@ void nano::active_transactions::request_confirm (nano::unique_lock & solicitor.flush (); generator_session.flush (); lock_a.lock (); - activate_dependencies (lock_a); // This is updated after the loop to ensure slow machines don't do the full check often if (check_all_elections_l) @@ -312,100 +311,6 @@ void nano::active_transactions::frontiers_confirmation (nano::unique_lock & lock_a) -{ - debug_assert (lock_a.owns_lock ()); - decltype (pending_dependencies) pending_l; - pending_l.swap (pending_dependencies); - lock_a.unlock (); - - auto first_unconfirmed = [this](nano::transaction const & transaction_a, nano::account const & account_a, nano::block_hash const & confirmed_frontier_a) { - if (!confirmed_frontier_a.is_zero ()) - { - return this->node.store.block_successor (transaction_a, confirmed_frontier_a); - } - else - { - nano::account_info account_info_l; - auto error = node.store.account_get (transaction_a, account_a, account_info_l); - (void)error; - debug_assert (!error); - return account_info_l.open_block; - } - }; - - // Store blocks to activate when the lock is re-acquired, adding the hash of the original election as a dependency - std::vector, nano::block_hash>> activate_l; - { - auto transaction = node.store.tx_begin_read (); - for (auto const & entry_l : pending_l) - { - auto const & hash_l (entry_l.first); - auto const block_l (node.store.block_get (transaction, hash_l)); - if (block_l) - { - auto const height_l (entry_l.second); - auto const previous_hash_l (block_l->previous ()); - if (!previous_hash_l.is_zero ()) - { - /* Insert first unconfirmed block (pessimistic) and bisect the chain (likelihood) */ - auto const account (node.store.block_account_calculated (*block_l)); - nano::confirmation_height_info conf_info_l; - if (!node.store.confirmation_height_get (transaction, account, conf_info_l)) - { - if (height_l > conf_info_l.height + 1) - { - auto const successor_hash_l = first_unconfirmed (transaction, account, conf_info_l.frontier); - if (!confirmation_height_processor.is_processing_block (successor_hash_l)) - { - auto const successor_l = node.store.block_get (transaction, successor_hash_l); - debug_assert (successor_l != nullptr); - if (successor_l != nullptr) - { - activate_l.emplace_back (successor_l, hash_l); - } - } - } - if (height_l > conf_info_l.height + 2) - { - auto const jumps_l = std::min (128, (height_l - conf_info_l.height) / 2); - auto const backtracked_l (node.ledger.backtrack (transaction, block_l, jumps_l)); - if (backtracked_l != nullptr) - { - activate_l.emplace_back (backtracked_l, hash_l); - } - } - } - } - /* If previous block not existing/not commited yet, block_source can cause segfault for state blocks - So source check can be done only if previous != nullptr or previous is 0 (open account) */ - if (previous_hash_l.is_zero () || node.ledger.block_exists (previous_hash_l)) - { - auto source_hash_l (node.ledger.block_source (transaction, *block_l)); - if (!source_hash_l.is_zero () && source_hash_l != previous_hash_l && blocks.find (source_hash_l) == blocks.end ()) - { - auto source_l (node.store.block_get (transaction, source_hash_l)); - if (source_l != nullptr && !node.block_confirmed_or_being_confirmed (transaction, source_hash_l)) - { - activate_l.emplace_back (source_l, hash_l); - } - } - } - } - } - } - lock_a.lock (); - for (auto const & entry_l : activate_l) - { - auto election = insert_impl (entry_l.first); - if (election.inserted) - { - election.election->transition_active (); - election.election->dependent_blocks.insert (entry_l.second); - } - } -} - void nano::active_transactions::request_loop () { nano::unique_lock lock (mutex); @@ -424,7 +329,6 @@ void nano::active_transactions::request_loop () // Account for the time spent in request_confirm by defining the wakeup point beforehand const auto wakeup_l (std::chrono::steady_clock::now () + std::chrono::milliseconds (node.network_params.network.request_interval_ms)); - update_adjusted_multiplier (); // frontiers_confirmation should be above update_active_multiplier to ensure new sorted roots are updated frontiers_confirmation (lock); update_active_multiplier (lock); @@ -642,9 +546,8 @@ nano::election_insertion_result nano::active_transactions::insert_impl (std::sha double multiplier (normalized_multiplier (*block_a)); bool prioritized = roots.size () < prioritized_cutoff || multiplier > last_prioritized_multiplier.value_or (0); result.election = nano::make_shared (node, block_a, confirmation_action_a, prioritized); - roots.get ().emplace (nano::active_transactions::conflict_info{ root, multiplier, multiplier, result.election, epoch, previous_balance }); + roots.get ().emplace (nano::active_transactions::conflict_info{ root, multiplier, result.election, epoch, previous_balance }); blocks.emplace (hash, result.election); - add_adjust_difficulty (hash); result.election->insert_inactive_votes_cache (hash); node.stats.inc (nano::stat::type::election, prioritized ? nano::stat::detail::election_priority : nano::stat::detail::election_non_priority); } @@ -835,7 +738,6 @@ bool nano::active_transactions::update_difficulty_impl (nano::active_transaction roots.get ().modify (root_it_a, [multiplier](nano::active_transactions::conflict_info & info_a) { info_a.multiplier = multiplier; }); - add_adjust_difficulty (block_a.hash ()); node.stats.inc (nano::stat::type::election, nano::stat::detail::election_difficulty_update); } return error; @@ -922,97 +824,6 @@ double nano::active_transactions::normalized_multiplier (nano::block const & blo return multiplier; } -void nano::active_transactions::add_adjust_difficulty (nano::block_hash const & hash_a) -{ - debug_assert (!mutex.try_lock ()); - adjust_difficulty_list.push_back (hash_a); -} - -void nano::active_transactions::update_adjusted_multiplier () -{ - debug_assert (!mutex.try_lock ()); - std::unordered_set processed_blocks; - while (!adjust_difficulty_list.empty ()) - { - auto const & adjust_difficulty_item (adjust_difficulty_list.front ()); - std::deque> remaining_blocks; - remaining_blocks.emplace_back (adjust_difficulty_item, 0); - adjust_difficulty_list.pop_front (); - std::vector> elections_list; - double sum (0.); - int64_t highest_level (0); - int64_t lowest_level (0); - while (!remaining_blocks.empty ()) - { - auto const & item (remaining_blocks.front ()); - auto hash (item.first); - auto level (item.second); - if (processed_blocks.find (hash) == processed_blocks.end ()) - { - auto existing (blocks.find (hash)); - if (existing != blocks.end () && !existing->second->confirmed () && existing->second->status.winner->hash () == hash) - { - auto previous (existing->second->status.winner->previous ()); - if (!previous.is_zero ()) - { - remaining_blocks.emplace_back (previous, level + 1); - } - auto source (existing->second->status.winner->source ()); - if (!source.is_zero () && source != previous) - { - remaining_blocks.emplace_back (source, level + 1); - } - auto link (existing->second->status.winner->link ()); - if (!link.is_zero () && !node.ledger.is_epoch_link (link) && link != previous) - { - remaining_blocks.emplace_back (link, level + 1); - } - for (auto & dependent_block : existing->second->dependent_blocks) - { - remaining_blocks.emplace_back (dependent_block, level - 1); - } - processed_blocks.insert (hash); - nano::qualified_root root (previous, existing->second->status.winner->root ()); - auto existing_root (roots.get ().find (root)); - if (existing_root != roots.get ().end ()) - { - sum += existing_root->multiplier; - elections_list.emplace_back (root, level); - if (level > highest_level) - { - highest_level = level; - } - else if (level < lowest_level) - { - lowest_level = level; - } - } - } - } - remaining_blocks.pop_front (); - } - if (!elections_list.empty ()) - { - double avg_multiplier = sum / elections_list.size (); - double min_unit = 32.0 * avg_multiplier * std::numeric_limits::epsilon (); - debug_assert (min_unit > 0); - - // Set adjusted multiplier - for (auto & item : elections_list) - { - auto existing_root (roots.get ().find (item.first)); - double multiplier_a = avg_multiplier + (double)item.second * min_unit; - if (existing_root->adjusted_multiplier != multiplier_a) - { - roots.get ().modify (existing_root, [multiplier_a](nano::active_transactions::conflict_info & info_a) { - info_a.adjusted_multiplier = multiplier_a; - }); - } - } - } - } -} - void nano::active_transactions::update_active_multiplier (nano::unique_lock & lock_a) { debug_assert (!mutex.try_lock ()); @@ -1028,7 +839,7 @@ void nano::active_transactions::update_active_multiplier (nano::unique_lockelection->confirmed ()) { - prioritized.push_back (it->adjusted_multiplier); + prioritized.push_back (it->multiplier); } } if (prioritized.size () > 10 || (node.network_params.network.is_dev_network () && !prioritized.empty ())) @@ -1125,7 +936,6 @@ void nano::active_transactions::erase (nano::block const & block_a) if (root_it != roots.get ().end ()) { root_it->election->cleanup (); - root_it->election->adjust_dependent_difficulty (); roots.get ().erase (root_it); lock.unlock (); node.logger.try_log (boost::str (boost::format ("Election erased for block block %1% root %2%") % block_a.hash ().to_string () % block_a.root ().to_string ())); diff --git a/nano/node/active_transactions.hpp b/nano/node/active_transactions.hpp index 2d377c9d..fc51916a 100644 --- a/nano/node/active_transactions.hpp +++ b/nano/node/active_transactions.hpp @@ -117,7 +117,6 @@ class active_transactions final public: nano::qualified_root root; double multiplier; - double adjusted_multiplier; std::shared_ptr election; nano::epoch epoch; nano::uint128_t previous_balance; @@ -142,7 +141,7 @@ public: mi::hashed_unique, mi::member>, mi::ordered_non_unique, - mi::member, + mi::member, std::greater>>>; // clang-format on ordered_roots roots; @@ -169,8 +168,6 @@ public: // Returns false if the election was restarted bool restart (std::shared_ptr const &, nano::write_transaction const &); double normalized_multiplier (nano::block const &, boost::optional const & = boost::none) const; - void add_adjust_difficulty (nano::block_hash const &); - void update_adjusted_multiplier (); void update_active_multiplier (nano::unique_lock &); uint64_t active_difficulty (); uint64_t limited_active_difficulty (nano::block const &); @@ -229,8 +226,6 @@ private: void frontiers_confirmation (nano::unique_lock &); nano::account next_frontier_account{ 0 }; std::chrono::steady_clock::time_point next_frontier_check{ std::chrono::steady_clock::now () }; - void activate_dependencies (nano::unique_lock &); - std::vector> pending_dependencies; nano::condition_variable condition; bool started{ false }; std::atomic stopped{ false }; @@ -273,7 +268,6 @@ private: void prioritize_account_for_confirmation (prioritize_num_uncemented &, size_t &, nano::account const &, nano::account_info const &, uint64_t); static size_t constexpr max_priority_cementable_frontiers{ 100000 }; static size_t constexpr confirmed_frontiers_max_pending_size{ 10000 }; - std::deque adjust_difficulty_list; // clang-format off using ordered_cache = boost::multi_index_container collect_container_info (active_transactions &, const std::string &); - friend class active_transactions_activate_dependencies_invalid_Test; friend class active_transactions_dropped_cleanup_dev; friend class active_transactions_vote_replays_Test; friend class confirmation_height_prioritize_frontiers_Test; friend class confirmation_height_prioritize_frontiers_overwrite_Test; friend class active_transactions_confirmation_consistency_Test; friend class node_deferred_dependent_elections_Test; - friend class election_bisect_dependencies_Test; - friend class election_dependencies_open_link_Test; }; std::unique_ptr collect_container_info (active_transactions & active_transactions, const std::string & name); diff --git a/nano/node/election.cpp b/nano/node/election.cpp index ef175307..10425115 100644 --- a/nano/node/election.cpp +++ b/nano/node/election.cpp @@ -9,7 +9,6 @@ using namespace std::chrono; int constexpr nano::election::passive_duration_factor; int constexpr nano::election::active_request_count_min; -int constexpr nano::election::active_broadcasting_duration_factor; int constexpr nano::election::confirmed_duration_factor; std::chrono::milliseconds nano::election::base_latency () const @@ -33,7 +32,6 @@ root (block_a->root ()) { last_votes.emplace (node.network_params.random.not_an_account, nano::vote_info{ std::chrono::steady_clock::now (), 0, block_a->hash () }); blocks.emplace (block_a->hash (), block_a); - update_dependent (); } void nano::election::confirm_once (nano::election_status_type type_a) @@ -58,7 +56,6 @@ void nano::election::confirm_once (nano::election_status_type type_a) node.background ([node_l, status_l, confirmation_action_l]() { confirmation_action_l (status_l.winner); }); - adjust_dependent_difficulty (); } } @@ -92,18 +89,6 @@ bool nano::election::valid_change (nano::election::state_t expected_a, nano::ele } break; case nano::election::state_t::broadcasting: - switch (desired_a) - { - case nano::election::state_t::backtracking: - case nano::election::state_t::confirmed: - case nano::election::state_t::expired_unconfirmed: - result = true; - break; - default: - break; - } - break; - case nano::election::state_t::backtracking: switch (desired_a) { case nano::election::state_t::confirmed: @@ -178,12 +163,6 @@ bool nano::election::confirmed () const return state_m == nano::election::state_t::confirmed || state_m == nano::election::state_t::expired_confirmed; } -void nano::election::activate_dependencies () -{ - debug_assert (!node.active.mutex.try_lock ()); - node.active.pending_dependencies.emplace_back (status.winner->hash (), height); -} - void nano::election::broadcast_block (nano::confirmation_solicitor & solicitor_a) { if (base_latency () * 15 < std::chrono::steady_clock::now () - last_block) @@ -216,15 +195,6 @@ bool nano::election::transition_time (nano::confirmation_solicitor & solicitor_a } break; case nano::election::state_t::broadcasting: - broadcast_block (solicitor_a); - send_confirm_req (solicitor_a); - if (base_latency () * active_broadcasting_duration_factor < std::chrono::steady_clock::now () - state_start) - { - state_change (nano::election::state_t::broadcasting, nano::election::state_t::backtracking); - activate_dependencies (); - } - break; - case nano::election::state_t::backtracking: broadcast_block (solicitor_a); send_confirm_req (solicitor_a); break; @@ -303,8 +273,6 @@ void nano::election::confirm_if_quorum () status.winner = block_l; remove_votes (status_winner_hash_l); node.block_processor.force (block_l); - update_dependent (); - node.active.add_adjust_difficulty (winner_hash_l); } if (have_quorum (tally_l, sum)) { @@ -433,47 +401,6 @@ size_t nano::election::last_votes_size () return last_votes.size (); } -void nano::election::update_dependent () -{ - debug_assert (!node.active.mutex.try_lock ()); - std::vector blocks_search; - auto hash (status.winner->hash ()); - auto previous (status.winner->previous ()); - if (!previous.is_zero ()) - { - blocks_search.push_back (previous); - } - auto source (status.winner->source ()); - if (!source.is_zero () && source != previous) - { - blocks_search.push_back (source); - } - auto link (status.winner->link ()); - if (!link.is_zero () && !node.ledger.is_epoch_link (link) && link != previous) - { - blocks_search.push_back (link); - } - for (auto & block_search : blocks_search) - { - auto existing (node.active.blocks.find (block_search)); - if (existing != node.active.blocks.end () && !existing->second->confirmed ()) - { - if (existing->second->dependent_blocks.find (hash) == existing->second->dependent_blocks.end ()) - { - existing->second->dependent_blocks.insert (hash); - } - } - } -} - -void nano::election::adjust_dependent_difficulty () -{ - for (auto & dependent_block : dependent_blocks) - { - node.active.add_adjust_difficulty (dependent_block); - } -} - void nano::election::cleanup () { bool unconfirmed (!confirmed ()); diff --git a/nano/node/election.hpp b/nano/node/election.hpp index 76824c86..1882bef1 100644 --- a/nano/node/election.hpp +++ b/nano/node/election.hpp @@ -42,14 +42,12 @@ private: // State management passive, // only listening for incoming votes active, // actively request confirmations broadcasting, // request confirmations and broadcast the winner - backtracking, // start an election for unconfirmed dependent blocks confirmed, // confirmed but still listening for votes expired_confirmed, expired_unconfirmed }; static int constexpr passive_duration_factor = 5; static int constexpr active_request_count_min = 2; - static int constexpr active_broadcasting_duration_factor = 30; static int constexpr confirmed_duration_factor = 5; std::atomic state_m = { state_t::passive }; @@ -63,7 +61,6 @@ private: // State management bool state_change (nano::election::state_t, nano::election::state_t); void broadcast_block (nano::confirmation_solicitor &); void send_confirm_req (nano::confirmation_solicitor &); - void activate_dependencies (); // Calculate votes for local representatives void generate_votes (); void remove_votes (nano::block_hash const &); @@ -81,8 +78,6 @@ public: void log_votes (nano::tally_t const &) const; bool publish (std::shared_ptr block_a); size_t last_votes_size (); - void update_dependent (); - void adjust_dependent_difficulty (); size_t insert_inactive_votes_cache (nano::block_hash const &); bool prioritized () const; void prioritize_election (nano::vote_generator_session &); @@ -105,14 +100,10 @@ public: nano::election_status status; unsigned confirmation_request_count{ 0 }; std::unordered_map last_tally; - std::unordered_set dependent_blocks; std::chrono::seconds late_blocks_delay{ 5 }; uint64_t const height; nano::root const root; friend class active_transactions; - - friend class election_bisect_dependencies_Test; - friend class election_dependencies_open_link_Test; }; } diff --git a/nano/secure/ledger.cpp b/nano/secure/ledger.cpp index e2c020ca..b06a53e8 100644 --- a/nano/secure/ledger.cpp +++ b/nano/secure/ledger.cpp @@ -1197,19 +1197,6 @@ std::shared_ptr nano::ledger::forked_block (nano::transaction const return result; } -std::shared_ptr nano::ledger::backtrack (nano::transaction const & transaction_a, std::shared_ptr const & start_a, uint64_t jumps_a) -{ - auto block = start_a; - while (jumps_a > 0 && block != nullptr && !block->previous ().is_zero ()) - { - block = store.block_get (transaction_a, block->previous ()); - debug_assert (block != nullptr); - --jumps_a; - } - debug_assert (block == nullptr || block->previous ().is_zero () || jumps_a == 0); - return block; -} - bool nano::ledger::block_confirmed (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const { auto confirmed (false); diff --git a/nano/secure/ledger.hpp b/nano/secure/ledger.hpp index cd7deeb9..619b161f 100644 --- a/nano/secure/ledger.hpp +++ b/nano/secure/ledger.hpp @@ -25,7 +25,6 @@ public: nano::uint128_t weight (nano::account const &); std::shared_ptr successor (nano::transaction const &, nano::qualified_root const &); std::shared_ptr forked_block (nano::transaction const &, nano::block const &); - std::shared_ptr backtrack (nano::transaction const &, std::shared_ptr const &, uint64_t); bool block_confirmed (nano::transaction const & transaction_a, nano::block_hash const & hash_a) const; bool block_not_confirmed_or_not_exists (nano::block const & block_a) const; nano::block_hash latest (nano::transaction const &, nano::account const &);