diff --git a/src/chasers/chaser_validate.cpp b/src/chasers/chaser_validate.cpp index 05a0a0c2..df812cbe 100644 --- a/src/chasers/chaser_validate.cpp +++ b/src/chasers/chaser_validate.cpp @@ -35,6 +35,15 @@ using namespace system::neutrino; using namespace database; using namespace std::placeholders; +// In this build we are evaluating an unconfigurable backlog of blocks based +// on their cumulative tx count. Value loosely approximates 100 full blocks. +// Since validation is being deferred until download is current, there is no +// material issue with starving the CPU. The backlog here is filled when the +// validator is starved, but that should consume the CPU. Splitting download, +// populate, and validate mitigates thrashing that is otherwise likely on low +// resource machines. This can be made more dynamic to optimize big machines. +constexpr auto validation_window = 5'000_size * 100_size; + // TODO: update specialized fault codes, reintegrate neutrino. // Shared pointer is required to keep the race object alive in bind closure. @@ -47,7 +56,7 @@ chaser_validate::chaser_validate(full_node& node) NOEXCEPT initial_subsidy_(node.config().bitcoin.initial_subsidy()), subsidy_interval_(node.config().bitcoin.subsidy_interval_blocks), threadpool_(std::max(node.config().node.threads, 1_u32), - network::thread_priority::low) + network::thread_priority::high) { } @@ -151,8 +160,6 @@ void chaser_validate::do_checked(height_t height) NOEXCEPT do_bump(height); } -constexpr auto validation_window = 1'000_size; - void chaser_validate::do_bump(height_t) NOEXCEPT { BC_ASSERT(stranded()); @@ -166,13 +173,14 @@ void chaser_validate::do_bump(height_t) NOEXCEPT const auto link = query.to_candidate(height); const auto ec = query.get_block_state(link); - // TODO: make this more flexible/configurable. + // TODO: make currency requirement more flexible/configurable. + // TODO: machines with high/fast RAM/SSD can handle much more. // Wait until the gap is filled at a current height. - if (ec == database::error::unassociated)//// || !is_current(link)) + if (ec == database::error::unassociated || !is_current(link)) return; // complete_block always follows and decrements. - ++validation_backlog_; + validation_backlog_ += query.get_tx_count(link); // Causes a reorganization (should have been encountered by headers). if (ec == database::error::block_unconfirmable) @@ -251,7 +259,9 @@ void chaser_validate::complete_block(const code& ec, const header_link& link, size_t height) NOEXCEPT { BC_ASSERT(stranded()); - --validation_backlog_; + + // Probably cheaper to requery this than to pass it. + validation_backlog_ -= archive().get_tx_count(link); if (ec) { @@ -271,8 +281,8 @@ void chaser_validate::complete_block(const code& ec, const header_link& link, if (is_current(link)) notify(ec, chase::valid, possible_wide_cast(height)); - // Prevent stall when window was full. - if (validation_backlog_ == sub1(validation_window)) + // Prevent stall. + if (is_zero(validation_backlog_)) do_bump(height_t{}); }