Skip to content

Commit

Permalink
Republish only winners for forked elections (#3027)
Browse files Browse the repository at this point in the history
  • Loading branch information
SergiySW authored Jan 5, 2021
1 parent 7af41fb commit 38cbfa4
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 6 deletions.
65 changes: 65 additions & 0 deletions nano/core_test/active_transactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,71 @@ TEST (active_transactions, dropped_cleanup)
ASSERT_EQ (0, node.active.blocks.count (block->hash ()));
}

TEST (active_transactions, republish_winner)
{
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));
node_config.peering_port = nano::get_available_port ();
auto & node2 (*system.add_node (node_config));

nano::genesis genesis;
nano::keypair key;
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 - nano::Gxrb_ratio)
.link (key.pub)
.sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub)
.work (*system.work.generate (genesis.hash ()))
.build_shared ();

node1.process_active (send1);
node1.block_processor.flush ();
ASSERT_TIMELY (3s, node2.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::in) == 1);

// Several forks
for (auto i (0); i < 5; i++)
{
auto fork = builder.make_block ()
.account (nano::dev_genesis_key.pub)
.previous (genesis.hash ())
.representative (nano::dev_genesis_key.pub)
.balance (nano::genesis_amount - 1 - i)
.link (key.pub)
.sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub)
.work (*system.work.generate (genesis.hash ()))
.build_shared ();
node1.process_active (fork);
}
node1.block_processor.flush ();
ASSERT_TIMELY (3s, !node1.active.empty ());
ASSERT_EQ (1, node2.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::in));

// Process new fork with vote to change winner
auto fork = builder.make_block ()
.account (nano::dev_genesis_key.pub)
.previous (genesis.hash ())
.representative (nano::dev_genesis_key.pub)
.balance (nano::genesis_amount - 2 * nano::Gxrb_ratio)
.link (key.pub)
.sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub)
.work (*system.work.generate (genesis.hash ()))
.build_shared ();

node1.process_active (fork);
node1.block_processor.flush ();
auto vote (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 0, std::vector<nano::block_hash>{ fork->hash () }));
node1.vote_processor.vote (vote, std::make_shared<nano::transport::channel_loopback> (node1));
node1.vote_processor.flush ();
node1.block_processor.flush ();

ASSERT_TIMELY (3s, node2.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::in) == 2);
}

TEST (active_transactions, fork_filter_cleanup)
{
nano::system system;
Expand Down
1 change: 0 additions & 1 deletion nano/node/active_transactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1269,7 +1269,6 @@ bool nano::active_transactions::publish (std::shared_ptr<nano::block> block_a)
auto const cache = find_inactive_votes_cache_impl (block_a->hash ());
lock.unlock ();
election->insert_inactive_votes_cache (cache);
node.network.flood_block (block_a, nano::buffer_drop_policy::no_limiter_drop);
node.stats.inc (nano::stat::type::election, nano::stat::detail::election_block_conflict);
}
}
Expand Down
6 changes: 3 additions & 3 deletions nano/node/blockprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ void nano::block_processor::process_batch (nano::unique_lock<std::mutex> & lock_
}
}
number_of_blocks_processed++;
process_one (transaction, post_events, info);
process_one (transaction, post_events, info, false, force);
}
lock_a.lock ();
}
Expand Down Expand Up @@ -363,7 +363,7 @@ void nano::block_processor::process_live (nano::transaction const & transaction_
}
}

nano::process_return nano::block_processor::process_one (nano::write_transaction const & transaction_a, block_post_events & events_a, nano::unchecked_info info_a, const bool watch_work_a, nano::block_origin const origin_a)
nano::process_return nano::block_processor::process_one (nano::write_transaction const & transaction_a, block_post_events & events_a, nano::unchecked_info info_a, const bool watch_work_a, const bool forced_a, nano::block_origin const origin_a)
{
nano::process_return result;
auto block (info_a.block);
Expand All @@ -380,7 +380,7 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction
block->serialize_json (block_string, node.config.logging.single_line_record ());
node.logger.try_log (boost::str (boost::format ("Processing block %1%: %2%") % hash.to_string () % block_string));
}
if (info_a.modified > nano::seconds_since_epoch () - 300 && node.block_arrival.recent (hash))
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); });
}
Expand Down
2 changes: 1 addition & 1 deletion nano/node/blockprocessor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class block_processor final
bool have_blocks_ready ();
bool have_blocks ();
void process_blocks ();
nano::process_return process_one (nano::write_transaction const &, block_post_events &, nano::unchecked_info, const bool = false, nano::block_origin const = nano::block_origin::remote);
nano::process_return process_one (nano::write_transaction const &, block_post_events &, nano::unchecked_info, const bool = false, const bool = false, nano::block_origin const = nano::block_origin::remote);
nano::process_return process_one (nano::write_transaction const &, block_post_events &, std::shared_ptr<nano::block> const &, const bool = false);
std::atomic<bool> flushing{ false };
// Delay required for average network propagartion before requesting confirmation
Expand Down
2 changes: 1 addition & 1 deletion nano/node/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ nano::process_return nano::node::process_local (std::shared_ptr<nano::block> con
// Process block
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 }, { tables::confirmation_height }));
return block_processor.process_one (transaction, post_events, info, work_watcher_a, nano::block_origin::local);
return block_processor.process_one (transaction, post_events, info, work_watcher_a, false, nano::block_origin::local);
}

void nano::node::start ()
Expand Down

0 comments on commit 38cbfa4

Please sign in to comment.