From 46804899252ffa653e4a8bb8ae19c9916527aace Mon Sep 17 00:00:00 2001 From: clemahieu Date: Wed, 30 Mar 2016 19:44:47 -0500 Subject: [PATCH] Fixed rare deadlock condition :( --- rai/node/node.cpp | 26 +++++++++++++------------- rai/node/node.hpp | 4 ++-- rai/secure.cpp | 5 ++--- rai/secure.hpp | 2 +- 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/rai/node/node.cpp b/rai/node/node.cpp index bc131890..04973e4a 100644 --- a/rai/node/node.cpp +++ b/rai/node/node.cpp @@ -926,7 +926,7 @@ application_path (application_path_a) }); observers.add_vote ([this] (rai::vote const & vote_a) { - rai::transaction transaction (store.environment, nullptr, false); + rai::transaction transaction (store.environment, nullptr, true); this->gap_cache.vote (transaction, vote_a); }); if (config.logging.log_to_cerr ()) @@ -1031,7 +1031,7 @@ void rai::gap_cache::vote (MDB_txn * transaction_a, rai::vote const & vote_a) auto existing (blocks.get <2> ().find (hash)); if (existing != blocks.get <2> ().end ()) { - auto changed (existing->votes->vote (node.store, vote_a)); + auto changed (existing->votes->vote (transaction_a, node.store, vote_a)); if (changed) { auto winner (node.ledger.winner (transaction_a, *existing->votes)); @@ -2198,26 +2198,25 @@ void rai::election::confirm_once () } } -bool rai::election::recalculate_winner () +bool rai::election::recalculate_winner (MDB_txn * transaction_a) { auto result (false); - rai::transaction transaction (node.store.environment, nullptr, true); - auto tally_l (node.ledger.tally (transaction, votes)); + auto tally_l (node.ledger.tally (transaction_a, votes)); assert (tally_l.size () > 0); - auto quorum_threshold_l (quorum_threshold (transaction, node.ledger)); + auto quorum_threshold_l (quorum_threshold (transaction_a, node.ledger)); auto winner (std::move (tally_l.begin ())); if (!(*winner->second == *last_winner) && (winner->first > quorum_threshold_l)) { // Replace our block with the winner and roll back any dependent blocks - node.ledger.rollback (transaction, last_winner->hash ()); - node.ledger.process (transaction, *winner->second); + node.ledger.rollback (transaction_a, last_winner->hash ()); + node.ledger.process (transaction_a, *winner->second); last_winner = std::move (winner->second); } // Check if we can do a fast confirm for the usual case of good actors if (tally_l.size () == 1) { // No forks detected - if (tally_l.begin ()->first > quorum_threshold (transaction, node.ledger)) + if (tally_l.begin ()->first > quorum_threshold (transaction_a, node.ledger)) { // We have vote quarum result = true; @@ -2226,9 +2225,9 @@ bool rai::election::recalculate_winner () return result; } -void rai::election::confirm_if_quarum () +void rai::election::confirm_if_quarum (MDB_txn * transaction_a) { - auto quarum (recalculate_winner ()); + auto quarum (recalculate_winner (transaction_a)); if (quarum) { confirm_once (); @@ -2242,10 +2241,11 @@ void rai::election::confirm_cutoff () void rai::election::vote (rai::vote const & vote_a) { - auto tally_changed (votes.vote (node.store, vote_a)); + rai::transaction transaction (node.store.environment, nullptr, true); + auto tally_changed (votes.vote (transaction, node.store, vote_a)); if (tally_changed) { - confirm_if_quarum (); + confirm_if_quarum (transaction); } } diff --git a/rai/node/node.hpp b/rai/node/node.hpp index 1e33a61a..30d41b8d 100644 --- a/rai/node/node.hpp +++ b/rai/node/node.hpp @@ -42,13 +42,13 @@ public: election (rai::node &, rai::block const &, std::function const &); void vote (rai::vote const &); // Set last_winner based on our current state of the ledger - bool recalculate_winner (); + bool recalculate_winner (MDB_txn *); // Tell the network our view of the winner void broadcast_winner (); // Change our winner to agree with the network void recompute_winner (); // Confirmation method 1, uncontested quarum - void confirm_if_quarum (); + void confirm_if_quarum (MDB_txn *); // Confirmation method 2, settling time void confirm_cutoff (); rai::uint128_t quorum_threshold (MDB_txn *, rai::ledger &); diff --git a/rai/secure.cpp b/rai/secure.cpp index c7c4bf4a..8ff5feb0 100644 --- a/rai/secure.cpp +++ b/rai/secure.cpp @@ -123,15 +123,14 @@ bool rai::unique_ptr_block_hash::operator () (std::unique_ptr const return *lhs == *rhs; } -bool rai::votes::vote (rai::block_store & store_a, rai::vote const & vote_a) +bool rai::votes::vote (MDB_txn * transaction_a, rai::block_store & store_a, rai::vote const & vote_a) { auto result (false); // Reject unsigned votes if (!rai::validate_message (vote_a.account, vote_a.hash (), vote_a.signature)) { - rai::transaction transaction (store_a.environment, nullptr, true); // Make sure this sequence number is > any we've seen from this account before - if (store_a.sequence_atomic_observe (transaction, vote_a.account, vote_a.sequence) == vote_a.sequence) + if (store_a.sequence_atomic_observe (transaction_a, vote_a.account, vote_a.sequence) == vote_a.sequence) { // Check if we're adding a new vote entry or modifying an existing one. auto existing (rep_votes.find (vote_a.account)); diff --git a/rai/secure.hpp b/rai/secure.hpp index 13d54a4a..981d5637 100644 --- a/rai/secure.hpp +++ b/rai/secure.hpp @@ -436,7 +436,7 @@ class votes { public: votes (rai::block const &); - bool vote (rai::block_store &, rai::vote const &); + bool vote (MDB_txn *, rai::block_store &, rai::vote const &); // Root block of fork rai::block_hash id; // All votes received by account