Skip to content

Commit

Permalink
Do not mix confirmed & aborted elections (#1048)
Browse files Browse the repository at this point in the history
* Do not mix confirmed & aborted elections

* Add delay before aborting election

In case of uncommited write transaction in block_processor

* Fix node.fork_open_flip test

* Fixing possible tests issues

node.fork_multi_flip, node.fork_open, node.fork_flip, node.fork_keep
  • Loading branch information
SergiySW authored and argakiig committed Aug 11, 2018
1 parent ef8185a commit 2477558
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 13 deletions.
14 changes: 8 additions & 6 deletions rai/core_test/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,12 @@ TEST (node, send_out_of_order)
rai::genesis genesis;
rai::send_block send1 (genesis.hash (), key2.pub, std::numeric_limits<rai::uint128_t>::max () - system.nodes[0]->config.receive_minimum.number (), rai::test_genesis_key.prv, rai::test_genesis_key.pub, system.work.generate (genesis.hash ()));
rai::send_block send2 (send1.hash (), key2.pub, std::numeric_limits<rai::uint128_t>::max () - system.nodes[0]->config.receive_minimum.number () * 2, rai::test_genesis_key.prv, rai::test_genesis_key.pub, system.work.generate (send1.hash ()));
rai::send_block send3 (send2.hash (), key2.pub, std::numeric_limits<rai::uint128_t>::max () - system.nodes[0]->config.receive_minimum.number () * 3, rai::test_genesis_key.prv, rai::test_genesis_key.pub, system.work.generate (send2.hash ()));
system.nodes[0]->process_active (std::unique_ptr<rai::block> (new rai::send_block (send3)));
system.nodes[0]->process_active (std::unique_ptr<rai::block> (new rai::send_block (send2)));
system.nodes[0]->process_active (std::unique_ptr<rai::block> (new rai::send_block (send1)));
system.deadline_set (10s);
while (std::any_of (system.nodes.begin (), system.nodes.end (), [&](std::shared_ptr<rai::node> const & node_a) { return node_a->balance (rai::test_genesis_key.pub) != rai::genesis_amount - system.nodes[0]->config.receive_minimum.number () * 2; }))
while (std::any_of (system.nodes.begin (), system.nodes.end (), [&](std::shared_ptr<rai::node> const & node_a) { return node_a->balance (rai::test_genesis_key.pub) != rai::genesis_amount - system.nodes[0]->config.receive_minimum.number () * 3; }))
{
ASSERT_NO_ERROR (system.poll ());
}
Expand Down Expand Up @@ -649,7 +651,6 @@ TEST (node, fork_keep)
auto & node1 (*system.nodes[0]);
auto & node2 (*system.nodes[1]);
ASSERT_EQ (1, node1.peers.size ());
system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv);
rai::keypair key1;
rai::keypair key2;
rai::genesis genesis;
Expand All @@ -662,6 +663,7 @@ TEST (node, fork_keep)
node2.block_processor.flush ();
ASSERT_EQ (1, node1.active.roots.size ());
ASSERT_EQ (1, node2.active.roots.size ());
system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv);
node1.process_active (send2);
node1.block_processor.flush ();
node2.process_active (send2);
Expand Down Expand Up @@ -699,7 +701,6 @@ TEST (node, fork_flip)
auto & node1 (*system.nodes[0]);
auto & node2 (*system.nodes[1]);
ASSERT_EQ (1, node1.peers.size ());
system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv);
rai::keypair key1;
rai::genesis genesis;
auto send1 (std::make_shared<rai::send_block> (genesis.hash (), key1.pub, rai::genesis_amount - 100, rai::test_genesis_key.prv, rai::test_genesis_key.pub, system.work.generate (genesis.hash ())));
Expand All @@ -713,6 +714,7 @@ TEST (node, fork_flip)
node2.block_processor.flush ();
ASSERT_EQ (1, node1.active.roots.size ());
ASSERT_EQ (1, node2.active.roots.size ());
system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv);
node1.process_message (publish2, node1.network.endpoint ());
node1.block_processor.flush ();
node2.process_message (publish1, node2.network.endpoint ());
Expand Down Expand Up @@ -750,7 +752,6 @@ TEST (node, fork_multi_flip)
auto & node1 (*system.nodes[0]);
auto & node2 (*system.nodes[1]);
ASSERT_EQ (1, node1.peers.size ());
system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv);
rai::keypair key1;
rai::genesis genesis;
auto send1 (std::make_shared<rai::send_block> (genesis.hash (), key1.pub, rai::genesis_amount - 100, rai::test_genesis_key.prv, rai::test_genesis_key.pub, system.work.generate (genesis.hash ())));
Expand All @@ -767,6 +768,7 @@ TEST (node, fork_multi_flip)
node2.block_processor.flush ();
ASSERT_EQ (1, node1.active.roots.size ());
ASSERT_EQ (2, node2.active.roots.size ());
system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv);
node1.process_message (publish2, node1.network.endpoint ());
node1.process_message (publish3, node1.network.endpoint ());
node1.block_processor.flush ();
Expand Down Expand Up @@ -847,7 +849,6 @@ TEST (node, fork_open)
{
rai::system system (24000, 1);
auto & node1 (*system.nodes[0]);
system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv);
rai::keypair key1;
rai::genesis genesis;
auto send1 (std::make_shared<rai::send_block> (genesis.hash (), key1.pub, 0, rai::test_genesis_key.prv, rai::test_genesis_key.pub, system.work.generate (genesis.hash ())));
Expand All @@ -861,6 +862,7 @@ TEST (node, fork_open)
auto open2 (std::make_shared<rai::open_block> (publish1.block->hash (), 2, key1.pub, key1.prv, key1.pub, system.work.generate (key1.pub)));
rai::publish publish3 (open2);
ASSERT_EQ (2, node1.active.roots.size ());
system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv);
node1.process_message (publish3, node1.network.endpoint ());
node1.block_processor.flush ();
}
Expand All @@ -871,7 +873,6 @@ TEST (node, fork_open_flip)
auto & node1 (*system.nodes[0]);
auto & node2 (*system.nodes[1]);
ASSERT_EQ (1, node1.peers.size ());
system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv);
rai::keypair key1;
rai::genesis genesis;
rai::keypair rep1;
Expand All @@ -892,6 +893,7 @@ TEST (node, fork_open_flip)
node2.block_processor.flush ();
ASSERT_EQ (2, node1.active.roots.size ());
ASSERT_EQ (2, node2.active.roots.size ());
system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv);
// Notify both nodes that a fork exists
node1.process_active (open2);
node1.block_processor.flush ();
Expand Down
13 changes: 7 additions & 6 deletions rai/node/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3484,7 +3484,8 @@ confirmation_action (confirmation_action_a),
votes (block_a),
node (node_a),
status ({ block_a, 0 }),
confirmed (false)
confirmed (false),
aborted (false)
{
}

Expand All @@ -3499,14 +3500,14 @@ void rai::election::compute_rep_votes (MDB_txn * transaction_a)
}
}

void rai::election::broadcast_winner (MDB_txn * transaction_a)
void rai::election::broadcast_winner (MDB_txn * transaction_a, bool abort_allow)
{
if (node.ledger.could_fit (transaction_a, *status.winner))
{
compute_rep_votes (transaction_a);
node.network.republish_block (transaction_a, status.winner);
}
else
else if (abort_allow)
{
abort ();
}
Expand All @@ -3528,7 +3529,7 @@ void rai::election::confirm_once (MDB_txn * transaction_a)

void rai::election::abort ()
{
confirmed = true;
aborted = true;
}

bool rai::election::have_quorum (rai::tally_t const & tally_a)
Expand Down Expand Up @@ -3652,7 +3653,7 @@ void rai::active_transactions::announce_votes ()
for (auto i (roots.begin ()), n (roots.end ()); i != n; ++i)
{
auto election_l (i->election);
if (election_l->confirmed && i->announcements >= announcement_min - 1)
if ((election_l->confirmed || election_l->aborted) && i->announcements >= announcement_min - 1)
{
if (election_l->confirmed)
{
Expand All @@ -3677,7 +3678,7 @@ void rai::active_transactions::announce_votes ()
election_l->log_votes (tally_l);
}
}
election_l->broadcast_winner (transaction);
election_l->broadcast_winner (transaction, i->announcements > 3);
if (i->announcements % 4 == 1)
{
auto reps (std::make_shared<std::vector<rai::peer_information>> (node.peers.representatives (std::numeric_limits<size_t>::max ())));
Expand Down
3 changes: 2 additions & 1 deletion rai/node/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class election : public std::enable_shared_from_this<rai::election>
// Check if we have vote quorum
bool have_quorum (rai::tally_t const &);
// Tell the network our view of the winner
void broadcast_winner (MDB_txn *);
void broadcast_winner (MDB_txn *, bool = true);
// Change our winner to agree with the network
void compute_rep_votes (MDB_txn *);
// Confirm this block if quorum is met
Expand All @@ -74,6 +74,7 @@ class election : public std::enable_shared_from_this<rai::election>
std::unordered_map<rai::account, rai::vote_info> last_votes;
rai::election_status status;
std::atomic<bool> confirmed;
bool aborted;
};
class conflict_info
{
Expand Down

0 comments on commit 2477558

Please sign in to comment.