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

Epoch open blocks should have corresponding pending entries #2673

Merged
merged 5 commits into from
Apr 2, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 3 additions & 1 deletion nano/core_test/conflicts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,12 +275,14 @@ TEST (conflicts, adjusted_difficulty)
ASSERT_GT (adjusted_difficulties.find (open2->hash ())->second, adjusted_difficulties.find (change1->hash ())->second);
// Independent elections can have higher difficulty than adjusted tree
nano::keypair key4;
auto send5 (std::make_shared<nano::state_block> (key3.pub, change1->hash (), nano::test_genesis_key.pub, 0, key4.pub, key3.prv, key3.pub, *system.work.generate (change1->hash ()))); // Pending for open epoch block
node1.process_active (send5);
auto open_epoch2 (std::make_shared<nano::state_block> (key4.pub, 0, 0, 0, node1.ledger.epoch_link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (key4.pub, adjusted_difficulties.find (send1->hash ())->second)));
ASSERT_GT (open_epoch2->difficulty (), adjusted_difficulties.find (send1->hash ())->second);
node1.process_active (open_epoch2);
node1.block_processor.flush ();
system.deadline_set (3s);
while (node1.active.size () != 11)
while (node1.active.size () != 12)
{
ASSERT_NO_ERROR (system.poll ());
}
Expand Down
13 changes: 13 additions & 0 deletions nano/core_test/ledger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2568,16 +2568,29 @@ TEST (ledger, successor_epoch)
nano::state_block open (key1.pub, 0, key1.pub, 1, send1.hash (), key1.prv, key1.pub, *pool.generate (key1.pub));
nano::state_block change (key1.pub, open.hash (), key1.pub, 1, 0, key1.prv, key1.pub, *pool.generate (open.hash ()));
auto open_hash = open.hash ();
nano::send_block send2 (send1.hash (), reinterpret_cast<nano::account const &> (open_hash), nano::genesis_amount - 2, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (send1.hash ()));
nano::state_block epoch_open (reinterpret_cast<nano::account const &> (open_hash), 0, 0, 0, node1.ledger.epoch_link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (open.hash ()));
auto transaction (node1.store.tx_begin_write ());
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, send1).code);
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, open).code);
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, change).code);
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, send2).code);
ASSERT_EQ (nano::process_result::progress, node1.ledger.process (transaction, epoch_open).code);
ASSERT_EQ (change, *node1.ledger.successor (transaction, change.qualified_root ()));
ASSERT_EQ (epoch_open, *node1.ledger.successor (transaction, epoch_open.qualified_root ()));
}

TEST (ledger, epoch_open_pending)
{
nano::system system (1);
auto & node1 (*system.nodes[0]);
nano::work_pool pool (std::numeric_limits<unsigned>::max ());
nano::keypair key1;
nano::state_block epoch_open (key1.pub, 0, 0, 0, node1.ledger.epoch_link (nano::epoch::epoch_1), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *pool.generate (key1.pub));
auto transaction (node1.store.tx_begin_write ());
ASSERT_EQ (nano::process_result::block_position, node1.ledger.process (transaction, epoch_open).code);
}

TEST (ledger, block_hash_account_conflict)
{
nano::block_builder builder;
Expand Down
13 changes: 8 additions & 5 deletions nano/core_test/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2992,22 +2992,25 @@ TEST (node, epoch_conflict_confirm)
auto send (std::make_shared<nano::state_block> (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - 1, key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (genesis.hash ())));
auto open (std::make_shared<nano::state_block> (key.pub, 0, key.pub, 1, send->hash (), key.prv, key.pub, *system.work.generate (key.pub)));
auto change (std::make_shared<nano::state_block> (key.pub, open->hash (), key.pub, 1, 0, key.prv, key.pub, *system.work.generate (open->hash ())));
auto epoch (std::make_shared<nano::state_block> (change->root (), 0, 0, 0, node0->ledger.epoch_link (nano::epoch::epoch_1), epoch_signer.prv, epoch_signer.pub, *system.work.generate (open->hash ())));
auto send2 (std::make_shared<nano::state_block> (nano::test_genesis_key.pub, send->hash (), nano::test_genesis_key.pub, nano::genesis_amount - 2, open->hash (), nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (send->hash ())));
auto epoch_open (std::make_shared<nano::state_block> (change->root (), 0, 0, 0, node0->ledger.epoch_link (nano::epoch::epoch_1), epoch_signer.prv, epoch_signer.pub, *system.work.generate (open->hash ())));
{
auto transaction (node0->store.tx_begin_write ());
ASSERT_EQ (nano::process_result::progress, node0->block_processor.process_one (transaction, send).code);
ASSERT_EQ (nano::process_result::progress, node0->block_processor.process_one (transaction, send2).code);
ASSERT_EQ (nano::process_result::progress, node0->block_processor.process_one (transaction, open).code);
}
{
auto transaction (node1->store.tx_begin_write ());
ASSERT_EQ (nano::process_result::progress, node1->block_processor.process_one (transaction, send).code);
ASSERT_EQ (nano::process_result::progress, node1->block_processor.process_one (transaction, send2).code);
ASSERT_EQ (nano::process_result::progress, node1->block_processor.process_one (transaction, open).code);
}
node0->process_active (change);
node0->process_active (epoch);
node0->process_active (epoch_open);
node0->block_processor.flush ();
system.deadline_set (5s);
while (!node0->block (change->hash ()) || !node0->block (epoch->hash ()) || !node1->block (change->hash ()) || !node1->block (epoch->hash ()))
while (!node0->block (change->hash ()) || !node0->block (epoch_open->hash ()) || !node1->block (change->hash ()) || !node1->block (epoch_open->hash ()))
{
ASSERT_NO_ERROR (system.poll ());
}
Expand All @@ -3019,7 +3022,7 @@ TEST (node, epoch_conflict_confirm)
{
nano::lock_guard<std::mutex> lock (node0->active.mutex);
ASSERT_TRUE (node0->active.blocks.find (change->hash ()) != node0->active.blocks.end ());
ASSERT_TRUE (node0->active.blocks.find (epoch->hash ()) != node0->active.blocks.end ());
ASSERT_TRUE (node0->active.blocks.find (epoch_open->hash ()) != node0->active.blocks.end ());
}
system.wallet (1)->insert_adhoc (nano::test_genesis_key.prv);
system.deadline_set (5s);
Expand All @@ -3030,7 +3033,7 @@ TEST (node, epoch_conflict_confirm)
{
auto transaction (node0->store.tx_begin_read ());
ASSERT_TRUE (node0->ledger.store.block_exists (transaction, change->hash ()));
ASSERT_TRUE (node0->ledger.store.block_exists (transaction, epoch->hash ()));
ASSERT_TRUE (node0->ledger.store.block_exists (transaction, epoch_open->hash ()));
}
}

Expand Down
12 changes: 12 additions & 0 deletions nano/secure/ledger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,18 @@ void ledger_processor::epoch_block_impl (nano::state_block & block_a)
else
{
result.code = block_a.hashables.representative.is_zero () ? nano::process_result::progress : nano::process_result::representative_mismatch;
// Non-exisitng account should have pending entries
if (result.code == nano::process_result::progress)
{
bool pending_exists (false);
nano::account end (block_a.hashables.account.number () + 1);
for (auto i (ledger.store.pending_begin (transaction, nano::pending_key (block_a.hashables.account, 0))), n (ledger.store.pending_begin (transaction, nano::pending_key (end, 0))); i != n && i != ledger.store.pending_end (); ++i)
{
pending_exists = true;
break;
}
guilhermelawless marked this conversation as resolved.
Show resolved Hide resolved
result.code = pending_exists ? nano::process_result::progress : nano::process_result::block_position;
}
}
if (result.code == nano::process_result::progress)
{
Expand Down