Fix active transactions difficulty update for state blocks (#2279)
* Fix active transactions difficulty update for state blocks due to verify_state_blocks () old blocks filter * Remove unused read transaction * Formatting
This commit is contained in:
parent
05e685a595
commit
a4c70b773d
3 changed files with 56 additions and 14 deletions
|
@ -512,3 +512,54 @@ TEST (active_transactions, inactive_votes_cache_multiple_votes)
|
|||
}
|
||||
ASSERT_EQ (2, system.nodes[0]->stats.count (nano::stat::type::election, nano::stat::detail::vote_cached));
|
||||
}
|
||||
|
||||
TEST (active_transactions, update_difficulty)
|
||||
{
|
||||
nano::system system (24000, 2);
|
||||
auto & node1 = *system.nodes[0];
|
||||
auto & node2 = *system.nodes[1];
|
||||
nano::genesis genesis;
|
||||
nano::keypair key1;
|
||||
// Generate blocks & start elections
|
||||
auto send1 (std::make_shared<nano::send_block> (genesis.hash (), key1.pub, nano::genesis_amount - 100, nano::test_genesis_key.prv, nano::test_genesis_key.pub, system.work.generate (genesis.hash ())));
|
||||
uint64_t difficulty1 (0);
|
||||
nano::work_validate (*send1, &difficulty1);
|
||||
auto send2 (std::make_shared<nano::state_block> (nano::test_genesis_key.pub, send1->hash (), nano::test_genesis_key.pub, nano::genesis_amount - 200, key1.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, system.work.generate (send1->hash ())));
|
||||
uint64_t difficulty2 (0);
|
||||
nano::work_validate (*send2, &difficulty2);
|
||||
node1.process_active (send1);
|
||||
node1.process_active (send2);
|
||||
node1.block_processor.flush ();
|
||||
system.deadline_set (10s);
|
||||
while (node1.active.size () != 2 || node2.active.size () != 2)
|
||||
{
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
// Update work with higher difficulty
|
||||
node1.work_generate_blocking (*send1, difficulty1 + 1);
|
||||
node1.work_generate_blocking (*send2, difficulty2 + 1);
|
||||
node1.process_active (send1);
|
||||
node1.process_active (send2);
|
||||
node1.block_processor.flush ();
|
||||
system.deadline_set (10s);
|
||||
bool done (false);
|
||||
while (!done)
|
||||
{
|
||||
{
|
||||
// node1
|
||||
nano::lock_guard<std::mutex> guard1 (node1.active.mutex);
|
||||
auto const existing1 (node1.active.roots.find (send1->qualified_root ()));
|
||||
ASSERT_NE (existing1, node1.active.roots.end ());
|
||||
auto const existing2 (node1.active.roots.find (send2->qualified_root ()));
|
||||
ASSERT_NE (existing2, node1.active.roots.end ());
|
||||
// node2
|
||||
nano::lock_guard<std::mutex> guard2 (node2.active.mutex);
|
||||
auto const existing3 (node2.active.roots.find (send1->qualified_root ()));
|
||||
ASSERT_NE (existing3, node2.active.roots.end ());
|
||||
auto const existing4 (node2.active.roots.find (send2->qualified_root ()));
|
||||
ASSERT_NE (existing4, node2.active.roots.end ());
|
||||
done = (existing1->difficulty > difficulty1) && (existing2->difficulty > difficulty2) && (existing3->difficulty > difficulty1) && (existing4->difficulty > difficulty2);
|
||||
}
|
||||
ASSERT_NO_ERROR (system.poll ());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,20 +147,12 @@ bool nano::block_processor::have_blocks ()
|
|||
return !blocks.empty () || !forced.empty () || !state_blocks.empty ();
|
||||
}
|
||||
|
||||
void nano::block_processor::verify_state_blocks (nano::transaction const & transaction_a, nano::unique_lock<std::mutex> & lock_a, size_t max_count)
|
||||
void nano::block_processor::verify_state_blocks (nano::unique_lock<std::mutex> & lock_a, size_t max_count)
|
||||
{
|
||||
assert (!mutex.try_lock ());
|
||||
nano::timer<std::chrono::milliseconds> timer_l (nano::timer_state::started);
|
||||
std::deque<nano::unchecked_info> items;
|
||||
for (auto i (0); i < max_count && !state_blocks.empty (); i++)
|
||||
{
|
||||
auto & item (state_blocks.front ());
|
||||
if (!node.ledger.store.block_exists (transaction_a, item.block->type (), item.block->hash ()))
|
||||
{
|
||||
items.push_back (std::move (item));
|
||||
}
|
||||
state_blocks.pop_front ();
|
||||
}
|
||||
items.swap (state_blocks);
|
||||
lock_a.unlock ();
|
||||
if (!items.empty ())
|
||||
{
|
||||
|
@ -253,10 +245,9 @@ void nano::block_processor::process_batch (nano::unique_lock<std::mutex> & lock_
|
|||
if (!state_blocks.empty ())
|
||||
{
|
||||
size_t max_verification_batch (node.flags.block_processor_verification_size != 0 ? node.flags.block_processor_verification_size : 2048 * (node.config.signature_checker_threads + 1));
|
||||
auto transaction (node.store.tx_begin_read ());
|
||||
while (!state_blocks.empty () && timer_l.before_deadline (std::chrono::seconds (2)))
|
||||
{
|
||||
verify_state_blocks (transaction, lock_a, max_verification_batch);
|
||||
verify_state_blocks (lock_a, max_verification_batch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -354,7 +345,7 @@ void nano::block_processor::process_batch (nano::unique_lock<std::mutex> & lock_
|
|||
Because verification is long process, avoid large deque verification inside of write transaction */
|
||||
if (blocks.empty () && !state_blocks.empty ())
|
||||
{
|
||||
verify_state_blocks (transaction, lock_a, 256 * (node.config.signature_checker_threads + 1));
|
||||
verify_state_blocks (lock_a, 256 * (node.config.signature_checker_threads + 1));
|
||||
}
|
||||
}
|
||||
awaiting_write = false;
|
||||
|
|
|
@ -56,7 +56,7 @@ public:
|
|||
|
||||
private:
|
||||
void queue_unchecked (nano::write_transaction const &, nano::block_hash const &);
|
||||
void verify_state_blocks (nano::transaction const & transaction_a, nano::unique_lock<std::mutex> &, size_t = std::numeric_limits<size_t>::max ());
|
||||
void verify_state_blocks (nano::unique_lock<std::mutex> &, size_t = std::numeric_limits<size_t>::max ());
|
||||
void process_batch (nano::unique_lock<std::mutex> &);
|
||||
void process_live (nano::block_hash const &, std::shared_ptr<nano::block>, const bool = false);
|
||||
bool stopped;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue