From 2477558958d014084afbaa903691cffdba57cc15 Mon Sep 17 00:00:00 2001 From: SergiySW Date: Sat, 11 Aug 2018 04:51:58 +0300 Subject: [PATCH] Do not mix confirmed & aborted elections (#1048) * 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 --- rai/core_test/node.cpp | 14 ++++++++------ rai/node/node.cpp | 13 +++++++------ rai/node/node.hpp | 3 ++- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/rai/core_test/node.cpp b/rai/core_test/node.cpp index e7a6f6eff5..6902fb3b06 100644 --- a/rai/core_test/node.cpp +++ b/rai/core_test/node.cpp @@ -144,10 +144,12 @@ TEST (node, send_out_of_order) rai::genesis genesis; rai::send_block send1 (genesis.hash (), key2.pub, std::numeric_limits::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::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::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 (new rai::send_block (send3))); system.nodes[0]->process_active (std::unique_ptr (new rai::send_block (send2))); system.nodes[0]->process_active (std::unique_ptr (new rai::send_block (send1))); system.deadline_set (10s); - while (std::any_of (system.nodes.begin (), system.nodes.end (), [&](std::shared_ptr 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 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 ()); } @@ -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; @@ -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); @@ -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 (genesis.hash (), key1.pub, rai::genesis_amount - 100, rai::test_genesis_key.prv, rai::test_genesis_key.pub, system.work.generate (genesis.hash ()))); @@ -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 ()); @@ -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 (genesis.hash (), key1.pub, rai::genesis_amount - 100, rai::test_genesis_key.prv, rai::test_genesis_key.pub, system.work.generate (genesis.hash ()))); @@ -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 (); @@ -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 (genesis.hash (), key1.pub, 0, rai::test_genesis_key.prv, rai::test_genesis_key.pub, system.work.generate (genesis.hash ()))); @@ -861,6 +862,7 @@ TEST (node, fork_open) auto open2 (std::make_shared (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 (); } @@ -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; @@ -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 (); diff --git a/rai/node/node.cpp b/rai/node/node.cpp index d219d2de2e..8dd56ee067 100644 --- a/rai/node/node.cpp +++ b/rai/node/node.cpp @@ -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) { } @@ -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 (); } @@ -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) @@ -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) { @@ -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> (node.peers.representatives (std::numeric_limits::max ()))); diff --git a/rai/node/node.hpp b/rai/node/node.hpp index 1d897bef80..b9edc52d88 100644 --- a/rai/node/node.hpp +++ b/rai/node/node.hpp @@ -63,7 +63,7 @@ class election : public std::enable_shared_from_this // 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 @@ -74,6 +74,7 @@ class election : public std::enable_shared_from_this std::unordered_map last_votes; rai::election_status status; std::atomic confirmed; + bool aborted; }; class conflict_info {