diff --git a/console/executor_test_reader.cpp b/console/executor_test_reader.cpp index 7db66ce4..f67b5d0e 100644 --- a/console/executor_test_reader.cpp +++ b/console/executor_test_reader.cpp @@ -40,6 +40,7 @@ using namespace system; using namespace std::chrono; using namespace std::placeholders; +// arbitrary testing (const). void executor::read_test(bool dump) const { using namespace database; @@ -273,7 +274,14 @@ void executor::read_test(bool dump) const #if defined(UNDEFINED) -// arbitrary testing (const). +void executor::read_test(bool) const +{ + database::header_link link{ 350'017_u32 }; + const auto ec = query_.block_confirmable(link); + logger(format("block_confirmable [%1%] at height [%2%].") % ec.message() % + query_.get_height(link)); +} + void executor::read_test(bool dump) const { logger("Wire size computation."); diff --git a/include/bitcoin/node/chasers/chaser_confirm.hpp b/include/bitcoin/node/chasers/chaser_confirm.hpp index d4512436..ebd504f4 100644 --- a/include/bitcoin/node/chasers/chaser_confirm.hpp +++ b/include/bitcoin/node/chasers/chaser_confirm.hpp @@ -70,9 +70,6 @@ class BCN_API chaser_confirm database::header_link link{}; }; - void reset_position(size_t confirmed_height) NOEXCEPT; - bool update_neutrino(const database::header_link& link) NOEXCEPT; - bool set_organized(const database::header_link& link, height_t height) NOEXCEPT; bool reset_organized(const database::header_link& link, @@ -89,8 +86,6 @@ class BCN_API chaser_confirm // These are protected by strand. bool mature_{}; - bool filters_{}; - neutrino_header neutrino_{}; network::threadpool threadpool_; // These are thread safe. diff --git a/include/bitcoin/node/chasers/chaser_validate.hpp b/include/bitcoin/node/chasers/chaser_validate.hpp index 93b59290..6a684d21 100644 --- a/include/bitcoin/node/chasers/chaser_validate.hpp +++ b/include/bitcoin/node/chasers/chaser_validate.hpp @@ -59,6 +59,8 @@ class BCN_API chaser_validate const system::chain::context& ctx) NOEXCEPT; virtual code populate(bool bypass, const system::chain::block& block, const system::chain::context& ctx) NOEXCEPT; + virtual void tracked_complete_block(const code& ec, + const database::header_link& link, size_t height) NOEXCEPT; virtual void complete_block(const code& ec, const database::header_link& link, size_t height) NOEXCEPT; diff --git a/src/chasers/chaser_confirm.cpp b/src/chasers/chaser_confirm.cpp index e29241ea..83a88995 100644 --- a/src/chasers/chaser_confirm.cpp +++ b/src/chasers/chaser_confirm.cpp @@ -50,8 +50,7 @@ chaser_confirm::chaser_confirm(full_node& node) NOEXCEPT code chaser_confirm::start() NOEXCEPT { const auto& query = archive(); - filters_ = query.neutrino_enabled(); - reset_position(query.get_fork()); + set_position(query.get_fork()); SUBSCRIBE_EVENTS(handle_event, _1, _2, _3); return error::success; } @@ -163,7 +162,7 @@ void chaser_confirm::do_regressed(height_t branch_point) NOEXCEPT } } - reset_position(branch_point); + set_position(branch_point); } // Candidate block validated at given height, if next then confirm/advance. @@ -189,108 +188,93 @@ void chaser_confirm::do_bump(height_t) NOEXCEPT const auto link = query.to_candidate(height); auto ec = query.get_block_state(link); - // Don't report bypassed block is confirmable until associated. if (ec == database::error::unassociated) + { + // Wait until the gap is filled. return; - - if (is_under_checkpoint(height) || query.is_milestone(link)) + } + else if (is_under_checkpoint(height) || query.is_milestone(link)) { - notify(error::success, chase::confirmable, height); - fire(events::confirm_bypassed, height); - LOGV("Block confirmation bypassed: " << height); - ////return; + // Fall through (report confirmed). + } + else if (ec == database::error::unvalidated) + { + // Wait until this block is validated. + return; } else if (ec == database::error::block_valid) { - if (!query.set_strong(link)) - { - fault(error::confirm2); - return; - } - - ////////////////////////////////////////// // Confirmation query. - // This will pull from new prevouts table. - ////////////////////////////////////////// if ((ec = query.block_confirmable(link))) { if (ec == database::error::integrity) { - fault(error::confirm3); + fault(error::confirm2); return; } if (!query.set_block_unconfirmable(link)) { - fault(error::confirm4); - return; - } - - if (!query.set_unstrong(link)) - { - fault(error::confirm5); + fault(error::confirm3); return; } - // Blocks between link and fork point will be set_unstrong - // by header reorganization, picked up by do_regressed. notify(ec, chase::unconfirmable, link); fire(events::block_unconfirmable, height); - LOGR("Unconfirmable block [" << height << "] " - << ec.message()); + LOGR("Unconfirmable block [" << height << "] " << ec.message()); return; } if (!query.set_block_confirmable(link)) { - fault(error::confirm6); + fault(error::confirm4); return; } - if (!set_organized(link, height)) + if (!query.set_strong(link)) { - fault(error::confirm7); + fault(error::confirm5); return; } - - notify(error::success, chase::confirmable, height); - fire(events::block_confirmed, height); - LOGV("Block confirmed: " << height); - ////return; } else if (ec == database::error::block_confirmable) { if (!query.set_strong(link)) { - fault(error::confirm8); + fault(error::confirm6); return; } - - notify(error::success, chase::confirmable, height); - fire(events::confirm_bypassed, height); - LOGV("Block previously confirmable: " << height); - ////return; } else { // With or without an error code, shouldn't be here. + // database::error::unassociated [wait state ] + // database::error::unvalidated [wait state ] // database::error::block_valid [canonical state ] // database::error::block_confirmable [resurrected state] // database::error::block_unconfirmable [shouldn't be here] // database::error::unknown_state [shouldn't be here] - // database::error::unassociated [shouldn't be here] - // database::error::unvalidated [shouldn't be here] - fault(error::confirm9); + fault(error::confirm7); + return; + } + + if (!query.set_filter_head(link)) + { + fault(error::confirm8); return; } - if (!update_neutrino(link)) + if (!set_organized(link, height)) { - fault(error::confirm10); + fault(error::confirm9); return; } set_position(height); + + notify(error::success, chase::confirmable, height); + fire(events::block_confirmed, height); + ////LOGV("Block confirmed: " << height); } } @@ -624,42 +608,6 @@ bool chaser_confirm::get_is_strong(bool& strong, const uint256_t& fork_work, return true; } -// neutrino -// ---------------------------------------------------------------------------- - -bool chaser_confirm::update_neutrino(const header_link& link) NOEXCEPT -{ - // neutrino_.link is only used for this assertion, should compile away. - BC_ASSERT(archive().get_height(link) == - add1(archive().get_height(neutrino_.link))); - - if (!filters_) - return true; - - data_chunk filter{}; - auto& query = archive(); - if (!query.get_filter_body(filter, link)) - return false; - - neutrino_.link = link; - neutrino_.head = neutrino::compute_filter_header(neutrino_.head, filter); - return query.set_filter_head(link, neutrino_.head); -} - -// Expects confirmed height. -// Use for startup and regression, to read current filter header from store. -void chaser_confirm::reset_position(size_t confirmed_height) NOEXCEPT -{ - set_position(confirmed_height); - - if (filters_) - { - const auto& query = archive(); - neutrino_.link = query.to_confirmed(confirmed_height); - query.get_filter_head(neutrino_.head, neutrino_.link); - } -} - // Strand. // ---------------------------------------------------------------------------- diff --git a/src/chasers/chaser_validate.cpp b/src/chasers/chaser_validate.cpp index a2efab26..0443cc6a 100644 --- a/src/chasers/chaser_validate.cpp +++ b/src/chasers/chaser_validate.cpp @@ -173,21 +173,17 @@ void chaser_validate::do_bump(height_t) NOEXCEPT const auto link = query.to_candidate(height); const auto ec = query.get_block_state(link); - // Wait until the gap is filled at a current height (or next top). if (ec == database::error::unassociated) + { + // Wait until the gap is filled. return; - - // The size of the job is not relevant to the backlog cost. - ++backlog_; - - if (ec == database::error::block_unconfirmable) + } + else if (ec == database::error::block_unconfirmable) { complete_block(ec, link, height); return; } - set_position(height); - const auto bypass = (ec == database::error::block_valid) || (ec == database::error::block_confirmable) || @@ -196,10 +192,14 @@ void chaser_validate::do_bump(height_t) NOEXCEPT if (bypass && !filter_) { complete_block(error::success, link, height); - continue; + } + else + { + ++backlog_; + PARALLEL(validate_block, link, bypass); } - PARALLEL(validate_block, link, bypass); + set_position(height); } } @@ -237,13 +237,9 @@ void chaser_validate::validate_block(const header_link& link, { ec = error::validate5; } - else - { - fire(events::block_validated, ctx.height); - } // Return to strand to handle result. - POST(complete_block, ec, link, ctx.height); + POST(tracked_complete_block, ec, link, ctx.height); } code chaser_validate::populate(bool bypass, const system::chain::block& block, @@ -285,22 +281,29 @@ code chaser_validate::validate(bool bypass, const system::chain::block& block, if ((ec = block.connect(ctx))) return ec; - if (!query.set_block_valid(link, block.fees())) + if (!query.set_prevouts(link, block)) return error::validate6; - if (!query.set_prevouts(link, block)) + if (!query.set_block_valid(link, block.fees())) return error::validate7; return ec; } -void chaser_validate::complete_block(const code& ec, const header_link& link, - size_t height) NOEXCEPT +// The size of the job is not relevant to the backlog cost. +void chaser_validate::tracked_complete_block(const code& ec, + const header_link& link, size_t height) NOEXCEPT { BC_ASSERT(stranded()); - // The size of the job is not relevant to the backlog cost. --backlog_; + complete_block(ec, link, height); +} + +void chaser_validate::complete_block(const code& ec, const header_link& link, + size_t height) NOEXCEPT +{ + BC_ASSERT(stranded()); if (ec) { @@ -317,13 +320,15 @@ void chaser_validate::complete_block(const code& ec, const header_link& link, return; } - LOGR("Unconfirmable block [" << height << "] " << ec.message()); - fire(events::block_unconfirmable, height); notify(ec, chase::unvalid, link); + fire(events::block_unconfirmable, height); + LOGR("Unconfirmable block [" << height << "] " << ec.message()); return; } notify(ec, chase::valid, possible_wide_cast(height)); + fire(events::block_validated, height); + ////LOGV("Block validated: " << height); // Prevent stall by posting internal event, avoid hitting external handlers. if (is_zero(backlog_))