Unresolved forks during initial bootstrap (#2833)
* Unresolved forks during initial bootstrap * Additional check for unchecked info arrival/modification time Co-authored-by: Sergey Kroshnin <sergiysw@gmail.com>
This commit is contained in:
parent
3af6dd6f26
commit
d120985c3b
4 changed files with 45 additions and 4 deletions
|
@ -866,6 +866,47 @@ 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::test_genesis_key.pub, node0->latest (nano::test_genesis_key.pub), nano::test_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (node0->latest (nano::test_genesis_key.pub))));
|
||||
ASSERT_EQ (nano::process_result::progress, node0->process (*send).code);
|
||||
// Confirm send block to vote later
|
||||
node0->block_confirm (send);
|
||||
{
|
||||
auto election = node0->active.election (send->qualified_root ());
|
||||
ASSERT_NE (nullptr, election);
|
||||
nano::lock_guard<std::mutex> guard (node0->active.mutex);
|
||||
election->confirm_once ();
|
||||
}
|
||||
ASSERT_TIMELY (2s, node0->block_confirmed (send->hash ()));
|
||||
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::test_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::test_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 ());
|
||||
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)
|
||||
{
|
||||
{
|
||||
|
|
|
@ -432,7 +432,7 @@ nano::process_return nano::block_processor::process_one (nano::write_transaction
|
|||
}
|
||||
case nano::process_result::fork:
|
||||
{
|
||||
node.process_fork (transaction_a, info_a.block);
|
||||
node.process_fork (transaction_a, info_a.block, info_a.modified);
|
||||
node.stats.inc (nano::stat::type::ledger, nano::stat::detail::fork);
|
||||
if (node.config.logging.ledger_logging ())
|
||||
{
|
||||
|
|
|
@ -518,13 +518,13 @@ 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> block_a)
|
||||
void nano::node::process_fork (nano::transaction const & transaction_a, std::shared_ptr<nano::block> block_a, uint64_t modified_a)
|
||||
{
|
||||
auto root (block_a->root ());
|
||||
if (!store.block_exists (transaction_a, block_a->type (), 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.can_vote (transaction_a, *ledger_block))
|
||||
if (ledger_block && !block_confirmed_or_being_confirmed (transaction_a, ledger_block->hash ()) && (ledger.can_vote (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, [this_w, root](std::shared_ptr<nano::block>) {
|
||||
|
|
|
@ -139,7 +139,7 @@ public:
|
|||
void block_confirm (std::shared_ptr<nano::block>);
|
||||
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>);
|
||||
void process_fork (nano::transaction const &, std::shared_ptr<nano::block>, uint64_t);
|
||||
void do_rpc_callback (boost::asio::ip::tcp::resolver::iterator i_a, std::string const &, uint16_t, std::shared_ptr<std::string>, std::shared_ptr<std::string>, std::shared_ptr<boost::asio::ip::tcp::resolver>);
|
||||
nano::uint128_t delta () const;
|
||||
void ongoing_online_weight_calculation ();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue