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

Flip pre confirm #909

Merged
merged 4 commits into from
Jun 7, 2018
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
60 changes: 60 additions & 0 deletions rai/core_test/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1058,6 +1058,66 @@ TEST (node, fork_no_vote_quorum)
ASSERT_TRUE (node3.latest (rai::test_genesis_key.pub) == send1.hash ());
}

TEST (node, fork_pre_confirm)
{
rai::system system (24000, 3);
auto & node0 (*system.nodes[0]);
auto & node1 (*system.nodes[1]);
auto & node2 (*system.nodes[2]);
rai::genesis genesis;
node0.ledger.state_block_parse_canary = genesis.hash ();
node1.ledger.state_block_parse_canary = genesis.hash ();
node2.ledger.state_block_parse_canary = genesis.hash ();
system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv);
rai::keypair key1;
system.wallet (1)->insert_adhoc (key1.prv);
{
rai::transaction transaction (system.wallet (1)->store.environment, nullptr, true);
system.wallet (1)->store.representative_set (transaction, key1.pub);
}
rai::keypair key2;
system.wallet (2)->insert_adhoc (key2.prv);
{
rai::transaction transaction (system.wallet (2)->store.environment, nullptr, true);
system.wallet (2)->store.representative_set (transaction, key2.pub);
}
auto iterations (0);
auto block0 (system.wallet (0)->send_action (rai::test_genesis_key.pub, key1.pub, rai::genesis_amount / 3));
ASSERT_NE (nullptr, block0);
while (node0.balance (key1.pub) == 0)
{
system.poll ();
++iterations;
ASSERT_LT (iterations, 400);
}
auto block1 (system.wallet (0)->send_action (rai::test_genesis_key.pub, key2.pub, rai::genesis_amount / 3));
ASSERT_NE (nullptr, block1);
while (node0.balance (key2.pub) == 0)
{
system.poll ();
++iterations;
ASSERT_LT (iterations, 400);
}
rai::keypair key3;
rai::keypair key4;
auto block2 (std::make_shared<rai::state_block> (rai::test_genesis_key.pub, node0.latest (rai::test_genesis_key.pub), key3.pub, node0.balance (rai::test_genesis_key.pub), 0, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0));
auto block3 (std::make_shared<rai::state_block> (rai::test_genesis_key.pub, node0.latest (rai::test_genesis_key.pub), key4.pub, node0.balance (rai::test_genesis_key.pub), 0, rai::test_genesis_key.prv, rai::test_genesis_key.pub, 0));
node0.work_generate_blocking (*block2);
node0.work_generate_blocking (*block3);
node0.process_active (block2);
node1.process_active (block2);
node2.process_active (block3);
auto done (false);
while (!done)
{
done |= node0.latest (rai::test_genesis_key.pub) == block2->hash () && node1.latest (rai::test_genesis_key.pub) == block2->hash () && node2.latest (rai::test_genesis_key.pub) == block2->hash ();
done |= node0.latest (rai::test_genesis_key.pub) == block3->hash () && node1.latest (rai::test_genesis_key.pub) == block3->hash () && node2.latest (rai::test_genesis_key.pub) == block3->hash ();
system.poll ();
++iterations;
ASSERT_LT (iterations, 600);
}
}

TEST (node, broadcast_elected)
{
rai::system system (24000, 3);
Expand Down
82 changes: 35 additions & 47 deletions rai/node/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3115,51 +3115,13 @@ void rai::election::confirm_once (MDB_txn * transaction_a)
{
if (!confirmed.exchange (true))
{
auto tally_l (node.ledger.tally (transaction_a, votes));
assert (tally_l.size () > 0);
auto have_quorum_l = have_quorum (tally_l);
auto winner (tally_l.begin ());
auto block_l (winner->second);
if (node.config.logging.vote_logging () || !votes.uncontested ())
{
BOOST_LOG (node.log) << boost::str (boost::format ("Vote tally for root %1%") % status.winner->root ().to_string ());
for (auto i (tally_l.begin ()), n (tally_l.end ()); i != n; ++i)
{
BOOST_LOG (node.log) << boost::str (boost::format ("Block %1% weight %2%") % i->second->hash ().to_string () % i->first.convert_to<std::string> ());
}
for (auto i (votes.rep_votes.begin ()), n (votes.rep_votes.end ()); i != n; ++i)
{
BOOST_LOG (node.log) << boost::str (boost::format ("%1% %2%") % i->first.to_account () % i->second->hash ().to_string ());
}
}
if (!(*block_l == *status.winner))
{
if (have_quorum_l)
{
auto node_l (node.shared ());
node_l->block_processor.force (block_l);
status.winner = block_l;
}
else
{
BOOST_LOG (node.log) << boost::str (boost::format ("Retaining block %1%") % status.winner->hash ().to_string ());
}
}
status.tally = winner->first;
if (have_quorum_l)
{
auto winner_l (status.winner);
auto node_l (node.shared ());
auto confirmation_action_l (confirmation_action);
node.background ([node_l, winner_l, confirmation_action_l]() {
node_l->process_confirmed (winner_l);
confirmation_action_l (winner_l);
});
}
else
{
BOOST_LOG (node.log) << boost::str (boost::format ("Insufficient quorum for block %1% %2%") % status.winner->hash ().to_string () % status.tally.number ().convert_to<std::string> ());
}
auto winner_l (status.winner);
auto node_l (node.shared ());
auto confirmation_action_l (confirmation_action);
node.background ([node_l, winner_l, confirmation_action_l]() {
node_l->process_confirmed (winner_l);
confirmation_action_l (winner_l);
});
}
}

Expand All @@ -3177,9 +3139,35 @@ bool rai::election::have_quorum (rai::tally_t const & tally_a)
void rai::election::confirm_if_quorum (MDB_txn * transaction_a)
{
auto tally_l (node.ledger.tally (transaction_a, votes));
auto quorum (have_quorum (tally_l));
if (quorum)
assert (tally_l.size () > 0);
auto winner (tally_l.begin ());
auto block_l (winner->second);
status.tally = winner->first;
rai::uint128_t sum (0);
for (auto & i : tally_l)
{
sum += i.first;
}
if (sum >= node.config.online_weight_minimum.number () && !(*block_l == *status.winner))
{
auto node_l (node.shared ());
node_l->block_processor.force (block_l);
status.winner = block_l;
}
if (have_quorum (tally_l))
{
if (node.config.logging.vote_logging () || !votes.uncontested ())
{
BOOST_LOG (node.log) << boost::str (boost::format ("Vote tally for root %1%") % status.winner->root ().to_string ());
for (auto i (tally_l.begin ()), n (tally_l.end ()); i != n; ++i)
{
BOOST_LOG (node.log) << boost::str (boost::format ("Block %1% weight %2%") % i->second->hash ().to_string () % i->first.convert_to<std::string> ());
}
for (auto i (votes.rep_votes.begin ()), n (votes.rep_votes.end ()); i != n; ++i)
{
BOOST_LOG (node.log) << boost::str (boost::format ("%1% %2%") % i->first.to_account () % i->second->hash ().to_string ());
}
}
confirm_once (transaction_a);
}
}
Expand Down