diff --git a/rai/node/node.cpp b/rai/node/node.cpp index 963e8838..f3a0886d 100644 --- a/rai/node/node.cpp +++ b/rai/node/node.cpp @@ -1298,11 +1298,22 @@ bool rai::block_processor::have_blocks () return !blocks.empty () || !forced.empty () || !state_blocks.empty (); } -void rai::block_processor::verify_state_blocks (std::unique_lock & lock_a) +void rai::block_processor::verify_state_blocks (std::unique_lock & lock_a, size_t max_count) { - lock_a.lock (); + assert (!mutex.try_lock ()); std::deque, std::chrono::steady_clock::time_point>> items; - items.swap (state_blocks); + if (max_count == std::numeric_limits::max () || max_count >= state_blocks.size ()) + { + items.swap (state_blocks); + } + else + { + auto keep_size (state_blocks.size () - max_count); + items.resize (keep_size); + std::swap_ranges (state_blocks.end () - keep_size, state_blocks.end (), items.begin ()); + state_blocks.resize (max_count); + items.swap (state_blocks); + } lock_a.unlock (); auto size (items.size ()); std::vector hashes; @@ -1340,14 +1351,20 @@ void rai::block_processor::verify_state_blocks (std::unique_lock & l } items.pop_front (); } - lock_a.unlock (); } void rai::block_processor::process_receive_many (std::unique_lock & lock_a) { - verify_state_blocks (lock_a); - auto transaction (node.store.tx_begin_write ()); + lock_a.lock (); auto start_time (std::chrono::steady_clock::now ()); + // Limit state blocks verification time + while (!state_blocks.empty () && std::chrono::steady_clock::now () - start_time < std::chrono::seconds (2)) + { + verify_state_blocks (lock_a, 2048); + } + lock_a.unlock (); + auto transaction (node.store.tx_begin_write ()); + start_time = std::chrono::steady_clock::now (); lock_a.lock (); // Processing blocks while ((!blocks.empty () || !forced.empty ()) && std::chrono::steady_clock::now () - start_time < node.config.block_processor_batch_max_time) @@ -1388,6 +1405,12 @@ void rai::block_processor::process_receive_many (std::unique_lock & auto process_result (process_receive_one (transaction, block.first, block.second, validated_state_block)); (void)process_result; lock_a.lock (); + /* Verify more state blocks if blocks deque is empty + Because verification is long process, avoid large deque verification inside of write transaction */ + if (blocks.empty () && !state_blocks.empty ()) + { + verify_state_blocks (lock_a, 256); + } } lock_a.unlock (); } diff --git a/rai/node/node.hpp b/rai/node/node.hpp index b2c519d8..f92b5411 100644 --- a/rai/node/node.hpp +++ b/rai/node/node.hpp @@ -429,7 +429,7 @@ public: private: void queue_unchecked (rai::transaction const &, rai::block_hash const &); - void verify_state_blocks (std::unique_lock &); + void verify_state_blocks (std::unique_lock &, size_t = std::numeric_limits::max ()); void process_receive_many (std::unique_lock &); bool stopped; bool active;