Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Election encapsulation #3185

Merged
merged 1 commit into from
Apr 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 0 additions & 36 deletions nano/core_test/bootstrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -927,42 +927,6 @@ TEST (bootstrap_processor, multiple_attempts)
node2->stop ();
}

TEST (bootstrap_processor, bootstrap_fork)
{
nano::system system;
nano::node_config config (nano::get_available_port (), system.logging);
config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
nano::node_flags node_flags;
node_flags.disable_bootstrap_bulk_push_client = true;
node_flags.disable_lazy_bootstrap = true;
node_flags.disable_legacy_bootstrap = true;
auto node0 (system.add_node (config, node_flags));
nano::keypair key;
auto send (std::make_shared<nano::state_block> (nano::dev_genesis_key.pub, node0->latest (nano::dev_genesis_key.pub), nano::dev_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (node0->latest (nano::dev_genesis_key.pub))));
ASSERT_EQ (nano::process_result::progress, node0->process (*send).code);
// Confirm send block to vote later
nano::blocks_confirm (*node0, { send }, true); // Confirm blocks
ASSERT_TIMELY (5s, node0->block_confirmed (send->hash ()) && node0->active.empty ());
node0->active.erase (*send);
auto open_work (*system.work.generate (key.pub));
auto open (std::make_shared<nano::state_block> (key.pub, 0, key.pub, nano::Gxrb_ratio, send->hash (), key.prv, key.pub, open_work));
ASSERT_EQ (nano::process_result::progress, node0->process (*open).code);
system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv);

// Create forked node
config.peering_port = nano::get_available_port ();
node_flags.disable_legacy_bootstrap = false;
auto node1 (system.add_node (config, node_flags));
ASSERT_EQ (nano::process_result::progress, node1->process (*send).code);
auto open_fork (std::make_shared<nano::state_block> (key.pub, 0, nano::dev_genesis_key.pub, nano::Gxrb_ratio, send->hash (), key.prv, key.pub, open_work));
ASSERT_EQ (nano::process_result::progress, node1->process (*open_fork).code);
// Resolve fork
node1->bootstrap_initiator.bootstrap (node0->network.endpoint (), false);
ASSERT_TIMELY (10s, node1->ledger.block_exists (open->hash ()));
ASSERT_FALSE (node1->ledger.block_exists (open_fork->hash ()));
node1->stop ();
}

TEST (frontier_req_response, DISABLED_destruction)
{
{
Expand Down
42 changes: 14 additions & 28 deletions nano/core_test/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1119,12 +1119,13 @@ TEST (node, fork_publish_inactive)
.sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub)
.work (send1->block_work ())
.build_shared ();
auto & node (*system.nodes[0]);
ASSERT_EQ (nano::process_result::progress, node.process (*send1).code);
auto & node = *system.nodes[0];
node.process_active (send1);
ASSERT_TIMELY (3s, nullptr != node.block (send1->hash ()));
ASSERT_EQ (nano::process_result::fork, node.process_local (send2).code);
auto election (node.active.election (send1->qualified_root ()));
auto election = node.active.election (send1->qualified_root ());
ASSERT_NE (election, nullptr);
auto blocks (election->blocks ());
auto blocks = election->blocks ();
ASSERT_NE (blocks.end (), blocks.find (send1->hash ()));
ASSERT_NE (blocks.end (), blocks.find (send2->hash ()));
ASSERT_EQ (election->winner ()->hash (), send1->hash ());
Expand Down Expand Up @@ -1320,17 +1321,16 @@ TEST (node, fork_bootstrap_flip)
{
nano::system system0;
nano::system system1;
nano::node_config config0 (nano::get_available_port (), system0.logging);
nano::node_config config0{ nano::get_available_port (), system0.logging };
config0.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
nano::node_flags node_flags;
node_flags.disable_bootstrap_bulk_push_client = true;
node_flags.disable_lazy_bootstrap = true;
auto & node1 (*system0.add_node (config0, node_flags));
auto & node1 = *system0.add_node (config0, node_flags);
nano::node_config config1 (nano::get_available_port (), system1.logging);
config1.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto & node2 (*system1.add_node (config1, node_flags));
auto & node2 = *system1.add_node (config1, node_flags);
system0.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv);
nano::block_hash latest (node1.latest (nano::dev_genesis_key.pub));
nano::block_hash latest = node1.latest (nano::dev_genesis_key.pub);
nano::keypair key1;
nano::send_block_builder builder;
auto send1 = builder.make_block ()
Expand All @@ -1349,23 +1349,17 @@ TEST (node, fork_bootstrap_flip)
.work (*system0.work.generate (latest))
.build_shared ();
// Insert but don't rebroadcast, simulating settled blocks
node1.block_processor.add (send1, nano::seconds_since_epoch ());
node1.block_processor.flush ();
node2.block_processor.add (send2, nano::seconds_since_epoch ());
node2.block_processor.flush ();
{
auto transaction (node2.store.tx_begin_read ());
ASSERT_TRUE (node2.store.block_exists (transaction, send2->hash ()));
}
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (node1.store.tx_begin_write (), *send1).code);
ASSERT_EQ (nano::process_result::progress, node2.ledger.process (node2.store.tx_begin_write (), *send2).code);
ASSERT_TRUE (node2.store.block_exists (node2.store.tx_begin_read (), send2->hash ()));
node2.bootstrap_initiator.bootstrap (node1.network.endpoint ()); // Additionally add new peer to confirm & replace bootstrap block
auto again (true);
system1.deadline_set (50s);
while (again)
{
ASSERT_NO_ERROR (system0.poll ());
ASSERT_NO_ERROR (system1.poll ());
auto transaction (node2.store.tx_begin_read ());
again = !node2.store.block_exists (transaction, send1->hash ());
again = !node2.store.block_exists (node2.store.tx_begin_read (), send1->hash ());
}
}

Expand Down Expand Up @@ -1956,7 +1950,6 @@ TEST (node, bootstrap_fork_open)
{
nano::system system;
nano::node_config node_config (nano::get_available_port (), system.logging);
node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled;
auto node0 = system.add_node (node_config);
node_config.peering_port = nano::get_available_port ();
auto node1 = system.add_node (node_config);
Expand Down Expand Up @@ -4489,7 +4482,7 @@ TEST (node, deferred_dependent_elections)
.build_shared ();
auto fork = builder.make_block ()
.from (*receive)
.representative (nano::dev_genesis_key.pub)
.representative (nano::dev_genesis_key.pub) // was key.pub
.sign (key.prv, key.pub)
.build_shared ();
node.process_local (send1);
Expand Down Expand Up @@ -4581,13 +4574,6 @@ TEST (node, deferred_dependent_elections)
ASSERT_TIMELY (2s, node.active.active (receive->qualified_root ()));
node.active.erase (*receive);
ASSERT_FALSE (node.active.active (receive->qualified_root ()));
node.process_local (fork, false);
node.block_processor.flush ();
ASSERT_TRUE (node.active.active (receive->qualified_root ()));

/// If dropped, the election can be restarted once higher work is provided
node.active.erase (*fork);
ASSERT_FALSE (node.active.active (fork->qualified_root ()));
node.work_generate_blocking (*receive, receive->difficulty () + 1);
node.process_local (receive, false);
node.block_processor.flush ();
Expand Down
2 changes: 1 addition & 1 deletion nano/node/blockprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -468,8 +468,8 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction
}
case nano::process_result::fork:
{
events_a.events.emplace_back ([this, block = info_a.block, modified = info_a.modified](nano::transaction const & post_event_transaction_a) { this->node.process_fork (post_event_transaction_a, block, modified); });
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 ())
{
node.logger.try_log (boost::str (boost::format ("Fork for: %1% root: %2%") % hash.to_string () % block->root ().to_string ()));
Expand Down
42 changes: 0 additions & 42 deletions nano/node/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -532,48 +532,6 @@ bool nano::node::copy_with_compaction (boost::filesystem::path const & destinati
return store.copy_db (destination);
}

void nano::node::process_fork (nano::transaction const & transaction_a, std::shared_ptr<nano::block> const & block_a, uint64_t const modified_a)
{
auto root (block_a->root ());
if (!store.block_exists (transaction_a, block_a->hash ()) && store.root_exists (transaction_a, block_a->root ()))
{
std::shared_ptr<nano::block> ledger_block (ledger.forked_block (transaction_a, *block_a));
if (ledger_block && !block_confirmed_or_being_confirmed (transaction_a, ledger_block->hash ()) && (ledger.dependents_confirmed (transaction_a, *ledger_block) || modified_a < nano::seconds_since_epoch () - 300 || !block_arrival.recent (block_a->hash ())))
{
std::weak_ptr<nano::node> this_w (shared_from_this ());
auto election = active.insert (ledger_block, boost::none, nano::election_behavior::normal, [this_w, root, root_block_type = block_a->type ()](std::shared_ptr<nano::block> const &) {
if (auto this_l = this_w.lock ())
{
auto attempt (this_l->bootstrap_initiator.current_attempt ());
if (attempt && attempt->mode == nano::bootstrap_mode::legacy)
{
auto transaction (this_l->store.tx_begin_read ());
nano::account account{ 0 };
if (root_block_type == nano::block_type::receive || root_block_type == nano::block_type::send || root_block_type == nano::block_type::change || root_block_type == nano::block_type::open)
{
account = this_l->ledger.store.frontier_get (transaction, root.as_block_hash ());
}
if (!account.is_zero ())
{
this_l->bootstrap_initiator.connections->requeue_pull (nano::pull_info (account, root.as_block_hash (), root.as_block_hash (), attempt->incremental_id));
}
else if (this_l->ledger.store.account_exists (transaction, root.as_account ()))
{
this_l->bootstrap_initiator.connections->requeue_pull (nano::pull_info (root, nano::block_hash (0), nano::block_hash (0), attempt->incremental_id));
}
}
}
});
if (election.inserted)
{
logger.always_log (boost::str (boost::format ("Resolving fork between our block: %1% and block %2% both with root %3%") % ledger_block->hash ().to_string () % block_a->hash ().to_string () % block_a->root ().to_string ()));
election.election->transition_active ();
}
}
active.publish (block_a);
}
}

std::unique_ptr<nano::container_info_component> nano::collect_container_info (node & node, std::string const & name)
{
auto composite = std::make_unique<container_info_composite> (name);
Expand Down
1 change: 0 additions & 1 deletion nano/node/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ class node final : public std::enable_shared_from_this<nano::node>
void block_confirm (std::shared_ptr<nano::block> const &);
bool block_confirmed (nano::block_hash const &);
bool block_confirmed_or_being_confirmed (nano::transaction const &, nano::block_hash const &);
void process_fork (nano::transaction const &, std::shared_ptr<nano::block> const &, uint64_t);
void do_rpc_callback (boost::asio::ip::tcp::resolver::iterator i_a, std::string const &, uint16_t, std::shared_ptr<std::string> const &, std::shared_ptr<std::string> const &, std::shared_ptr<boost::asio::ip::tcp::resolver> const &);
void ongoing_online_weight_calculation ();
void ongoing_online_weight_calculation_queue ();
Expand Down