List of rolled back blocks in block_processor (#1581)

* List of rolled back blocks in block_processor

With limit 1024

* Update node.cpp

* Make rolled_back_max static const
This commit is contained in:
Sergey Kroshnin 2019-01-14 16:06:05 +03:00 committed by Zach Hyatt
commit 5245414dee
2 changed files with 30 additions and 2 deletions

View file

@ -1232,8 +1232,9 @@ void nano::block_processor::add (std::shared_ptr<nano::block> block_a, std::chro
if (!nano::work_validate (block_a->root (), block_a->block_work ()))
{
{
auto hash (block_a->hash ());
std::lock_guard<std::mutex> lock (mutex);
if (blocks_hashes.find (block_a->hash ()) == blocks_hashes.end ())
if (blocks_hashes.find (hash) == blocks_hashes.end () && rolled_back.get<1> ().find (hash) == rolled_back.get<1> ().end ())
{
if (block_a->type () == nano::block_type::state && !node.ledger.is_epoch_link (block_a->link ()))
{
@ -1243,7 +1244,7 @@ void nano::block_processor::add (std::shared_ptr<nano::block> block_a, std::chro
{
blocks.push_back (std::make_pair (block_a, origination));
}
blocks_hashes.insert (block_a->hash ());
blocks_hashes.insert (hash);
}
condition.notify_all ();
}
@ -1431,6 +1432,20 @@ void nano::block_processor::process_batch (std::unique_lock<std::mutex> & lock_a
// Replace our block with the winner and roll back any dependent blocks
BOOST_LOG (node.log) << boost::str (boost::format ("Rolling back %1% and replacing with %2%") % successor->hash ().to_string () % hash.to_string ());
node.ledger.rollback (transaction, successor->hash ());
lock_a.lock ();
// Prevent rolled back blocks second insertion
auto inserted (rolled_back.insert (nano::rolled_hash{ std::chrono::steady_clock::now (), successor->hash () }));
if (inserted.second)
{
// Possible election winner change
rolled_back.get<1> ().erase (hash);
// Prevent overflow
if (rolled_back.size () > rolled_back_max)
{
rolled_back.erase (rolled_back.begin ());
}
}
lock_a.unlock ();
}
}
/* Forced state blocks are not validated in verify_state_blocks () function

View file

@ -410,6 +410,12 @@ private:
std::condition_variable condition;
std::thread thread;
};
class rolled_hash
{
public:
std::chrono::steady_clock::time_point time;
nano::block_hash hash;
};
// Processing blocks is a potentially long IO operation
// This class isolates block insertion from other operations like servicing network operations
class block_processor
@ -438,6 +444,13 @@ private:
std::deque<std::pair<std::shared_ptr<nano::block>, std::chrono::steady_clock::time_point>> blocks;
std::unordered_set<nano::block_hash> blocks_hashes;
std::deque<std::shared_ptr<nano::block>> forced;
boost::multi_index_container<
nano::rolled_hash,
boost::multi_index::indexed_by<
boost::multi_index::ordered_non_unique<boost::multi_index::member<nano::rolled_hash, std::chrono::steady_clock::time_point, &nano::rolled_hash::time>>,
boost::multi_index::hashed_unique<boost::multi_index::member<nano::rolled_hash, nano::block_hash, &nano::rolled_hash::hash>>>>
rolled_back;
static size_t const rolled_back_max = 1024;
std::condition_variable condition;
nano::node & node;
nano::vote_generator generator;