From 961b12eb178073b009bc6904e0a89c6621caf813 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sun, 5 Jan 2025 16:35:47 -0500 Subject: [PATCH 1/6] Refactor validator, use new db set_filter_body(block) method. --- .../bitcoin/node/chasers/chaser_validate.hpp | 6 -- src/chasers/chaser_validate.cpp | 88 +++++++------------ 2 files changed, 32 insertions(+), 62 deletions(-) diff --git a/include/bitcoin/node/chasers/chaser_validate.hpp b/include/bitcoin/node/chasers/chaser_validate.hpp index dd5a98fc..25573395 100644 --- a/include/bitcoin/node/chasers/chaser_validate.hpp +++ b/include/bitcoin/node/chasers/chaser_validate.hpp @@ -66,12 +66,6 @@ class BCN_API chaser_validate return backlog_ < maximum_backlog_; } - bool set_neutrino(const database::header_link& link, - const system::chain::block& block) NOEXCEPT; - - bool set_prevouts(size_t height, - const system::chain::block& block) NOEXCEPT; - // These are thread safe. const bool concurrent_; const size_t maximum_backlog_; diff --git a/src/chasers/chaser_validate.cpp b/src/chasers/chaser_validate.cpp index 87eb1e37..67c58ce3 100644 --- a/src/chasers/chaser_validate.cpp +++ b/src/chasers/chaser_validate.cpp @@ -206,52 +206,51 @@ void chaser_validate::validate_block(const header_link& link) NOEXCEPT if (closed()) return; + code ec{}; + chain::context ctx{}; auto& query = archive(); const auto block = query.get_block(link); + if (!block) { - POST(complete_block, error::validate1, link, zero); - return; + ec = error::validate1; } - - chain::context ctx{}; - if (!query.get_context(ctx, link)) + else if (!query.get_context(ctx, link)) { - POST(complete_block, error::validate2, link, zero); - return; + ec = error::validate2; } - - if (!block->populate()) + else if (!block->populate()) { - // input.metadata.locked set invalid for relative locktime (bip68). - // Otherwise internal spends do not require confirmability checks. - POST(complete_block, error::validate3, link, ctx.height); - return; + ec = system::error::relative_time_locked; } else if (!query.populate(*block)) { - // Prepopulated prevouts are bypassed here, including metadata. - // .input.metadata.parent (tx link) and .coinbase (bool) are set here. - POST(complete_block, error::validate4, link, ctx.height); - return; + ec = system::error::missing_previous_output; } - - code ec{}; - if (((ec = block->accept(ctx, subsidy_interval_, initial_subsidy_))) || - ((ec = block->connect(ctx)))) + else if ((ec = block->accept(ctx, subsidy_interval_, initial_subsidy_))) { if (!query.set_block_unconfirmable(link)) - ec = error::validate5; + ec = error::validate3; + } + else if ((ec = block->connect(ctx))) + { + if (!query.set_block_unconfirmable(link)) + ec = error::validate4; } else if (!query.set_block_valid(link, block->fees())) + { + ec = error::validate5; + } + else if (false) ////!archive().set_prevouts(ctx.height, *block) { ec = error::validate6; } + else if (filters_ && query.set_filter_body(link, *block)) + { + ec = error::validate7; + } else { - set_neutrino(link, *block); - set_prevouts(ctx.height, *block); - fire(events::block_validated, ctx.height); } @@ -268,7 +267,14 @@ void chaser_validate::complete_block(const code& ec, const header_link& link, if (ec) { - if (ec == error::validate7) + // Differentiated fault codes for troubleshooting. + if (ec == error::validate1 || + ec == error::validate2 || + ec == error::validate3 || + ec == error::validate4 || + ec == error::validate5 || + ec == error::validate6 || + ec == error::validate7) { fault(ec); return; @@ -287,36 +293,6 @@ void chaser_validate::complete_block(const code& ec, const header_link& link, handle_event(ec, chase::bump, height_t{}); } -// setters -// ---------------------------------------------------------------------------- -// unstranded (concurrent by block) - -bool chaser_validate::set_neutrino(const header_link& link, - const chain::block& block) NOEXCEPT -{ - if (!filters_) - return true; - - // Avoid computing the filter if already stored. - auto& query = archive(); - if (!query.to_filter(link).is_terminal()) - return true; - - // Only fails if prevouts are not fully populated. - data_chunk filter{}; - if (!neutrino::compute_filter(filter, block)) - return false; - - return query.set_filter_body(link, filter); -} - -bool chaser_validate::set_prevouts(size_t, const chain::block&) NOEXCEPT -{ - // TODO: need to be able to differentiate internal vs. store. - // This tells us what to cache, skip internal and set store populated. - return {}; -} - // Strand. // ---------------------------------------------------------------------------- From 54feb3ed9903bb6a2f876468ed75eb3fc0e8a994 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sun, 5 Jan 2025 16:56:13 -0500 Subject: [PATCH 2/6] Comment. --- src/chasers/chaser_confirm.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/chasers/chaser_confirm.cpp b/src/chasers/chaser_confirm.cpp index 8c4559b2..b68f6058 100644 --- a/src/chasers/chaser_confirm.cpp +++ b/src/chasers/chaser_confirm.cpp @@ -613,7 +613,6 @@ bool chaser_confirm::get_is_strong(bool& strong, const uint256_t& fork_work, // neutrino // ---------------------------------------------------------------------------- -// This can only fail if prevouts are not fully populated. bool chaser_confirm::update_neutrino(const header_link& link) NOEXCEPT { // neutrino_.link is only used for this assertion, should compile away. From 136baf1cd2b0a848d15540246f75150f915328b0 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sun, 5 Jan 2025 16:56:50 -0500 Subject: [PATCH 3/6] Remove now-redundant filters guard in validation chaser. --- include/bitcoin/node/chasers/chaser_validate.hpp | 1 - src/chasers/chaser_validate.cpp | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/include/bitcoin/node/chasers/chaser_validate.hpp b/include/bitcoin/node/chasers/chaser_validate.hpp index 25573395..d7be6e6e 100644 --- a/include/bitcoin/node/chasers/chaser_validate.hpp +++ b/include/bitcoin/node/chasers/chaser_validate.hpp @@ -76,7 +76,6 @@ class BCN_API chaser_validate // These are protected by strand. network::threadpool threadpool_; size_t backlog_{}; - bool filters_{}; bool mature_{}; }; diff --git a/src/chasers/chaser_validate.cpp b/src/chasers/chaser_validate.cpp index 67c58ce3..12e5ce79 100644 --- a/src/chasers/chaser_validate.cpp +++ b/src/chasers/chaser_validate.cpp @@ -55,7 +55,6 @@ chaser_validate::chaser_validate(full_node& node) NOEXCEPT code chaser_validate::start() NOEXCEPT { const auto& query = archive(); - filters_ = query.neutrino_enabled(); set_position(query.get_fork()); SUBSCRIBE_EVENTS(handle_event, _1, _2, _3); return error::success; @@ -200,7 +199,7 @@ void chaser_validate::do_bump(height_t) NOEXCEPT } } -// unstranded (concurrent by block) +// Unstranded (concurrent by block). void chaser_validate::validate_block(const header_link& link) NOEXCEPT { if (closed()) @@ -241,11 +240,11 @@ void chaser_validate::validate_block(const header_link& link) NOEXCEPT { ec = error::validate5; } - else if (false) ////!archive().set_prevouts(ctx.height, *block) + else if (!query.set_prevouts(ctx.height, *block)) { ec = error::validate6; } - else if (filters_ && query.set_filter_body(link, *block)) + else if (query.set_filter_body(link, *block)) { ec = error::validate7; } @@ -254,6 +253,7 @@ void chaser_validate::validate_block(const header_link& link) NOEXCEPT fire(events::block_validated, ctx.height); } + // Return to strand to handle result. POST(complete_block, ec, link, ctx.height); } From 0558cdf7fcc36d078628f663b38f3b7551d5ea23 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sun, 5 Jan 2025 17:04:22 -0500 Subject: [PATCH 4/6] Disable unused var. --- console/executor_test_reader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/console/executor_test_reader.cpp b/console/executor_test_reader.cpp index f94780df..7db66ce4 100644 --- a/console/executor_test_reader.cpp +++ b/console/executor_test_reader.cpp @@ -105,7 +105,7 @@ void executor::read_test(bool dump) const if (cancel_) return; - size_t found{}; + ////size_t found{}; auto address_it = store_.address.it(key); if (address_it.self().is_terminal()) { @@ -179,7 +179,7 @@ void executor::read_test(bool dump) const sp_tx_fk = spend.parent_fk; } - ++found; + ////++found; outs.push_back(out { key, From 7baf31b3f3858045ac4fa46a43e8cbfbffe96b7d Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sun, 5 Jan 2025 17:04:55 -0500 Subject: [PATCH 5/6] Fix validate/confirm threadpool/strand initialization order. --- .../bitcoin/node/chasers/chaser_confirm.hpp | 14 +++++++------- .../bitcoin/node/chasers/chaser_validate.hpp | 18 +++++++++--------- src/chasers/chaser_confirm.cpp | 4 ++-- src/chasers/chaser_validate.cpp | 10 +++++----- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/include/bitcoin/node/chasers/chaser_confirm.hpp b/include/bitcoin/node/chasers/chaser_confirm.hpp index a5f18a4b..d4512436 100644 --- a/include/bitcoin/node/chasers/chaser_confirm.hpp +++ b/include/bitcoin/node/chasers/chaser_confirm.hpp @@ -87,15 +87,15 @@ class BCN_API chaser_confirm bool get_is_strong(bool& strong, const uint256_t& fork_work, size_t fork_point) const NOEXCEPT; - // These are thread safe. - const bool concurrent_; - network::asio::strand independent_strand_; - // These are protected by strand. - network::threadpool threadpool_; - neutrino_header neutrino_{}; - bool filters_{}; bool mature_{}; + bool filters_{}; + neutrino_header neutrino_{}; + network::threadpool threadpool_; + + // These are thread safe. + network::asio::strand independent_strand_; + const bool concurrent_; }; } // namespace node diff --git a/include/bitcoin/node/chasers/chaser_validate.hpp b/include/bitcoin/node/chasers/chaser_validate.hpp index d7be6e6e..88cabfdf 100644 --- a/include/bitcoin/node/chasers/chaser_validate.hpp +++ b/include/bitcoin/node/chasers/chaser_validate.hpp @@ -66,17 +66,17 @@ class BCN_API chaser_validate return backlog_ < maximum_backlog_; } - // These are thread safe. - const bool concurrent_; - const size_t maximum_backlog_; - const uint64_t initial_subsidy_; - const uint32_t subsidy_interval_; - network::asio::strand independent_strand_; - // These are protected by strand. - network::threadpool threadpool_; - size_t backlog_{}; bool mature_{}; + size_t backlog_{}; + network::threadpool threadpool_; + + // These are thread safe. + network::asio::strand independent_strand_; + const uint32_t subsidy_interval_; + const uint64_t initial_subsidy_; + const size_t maximum_backlog_; + const bool concurrent_; }; } // namespace node diff --git a/src/chasers/chaser_confirm.cpp b/src/chasers/chaser_confirm.cpp index b68f6058..c49e7810 100644 --- a/src/chasers/chaser_confirm.cpp +++ b/src/chasers/chaser_confirm.cpp @@ -41,9 +41,9 @@ BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT) // Higher priority than validator ensures locality to validator reads. chaser_confirm::chaser_confirm(full_node& node) NOEXCEPT : chaser(node), - concurrent_(node.config().node.concurrent_confirmation), threadpool_(one, node.config().node.priority_()), - independent_strand_(threadpool_.service().get_executor()) + independent_strand_(threadpool_.service().get_executor()), + concurrent_(node.config().node.concurrent_confirmation) { } diff --git a/src/chasers/chaser_validate.cpp b/src/chasers/chaser_validate.cpp index 12e5ce79..78c1fb9a 100644 --- a/src/chasers/chaser_validate.cpp +++ b/src/chasers/chaser_validate.cpp @@ -43,12 +43,12 @@ BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT) // Higher priority than downloader (net) ensures locality to downloader writes. chaser_validate::chaser_validate(full_node& node) NOEXCEPT : chaser(node), - concurrent_(node.config().node.concurrent_validation), - maximum_backlog_(node.config().node.maximum_concurrency_()), - initial_subsidy_(node.config().bitcoin.initial_subsidy()), - subsidy_interval_(node.config().bitcoin.subsidy_interval_blocks), threadpool_(node.config().node.threads_(), node.config().node.priority_()), - independent_strand_(threadpool_.service().get_executor()) + independent_strand_(threadpool_.service().get_executor()), + subsidy_interval_(node.config().bitcoin.subsidy_interval_blocks), + initial_subsidy_(node.config().bitcoin.initial_subsidy()), + maximum_backlog_(node.config().node.maximum_concurrency_()), + concurrent_(node.config().node.concurrent_validation) { } From 557ee4561150652744bbfa1f89e8c388b04ac648 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sun, 5 Jan 2025 17:25:36 -0500 Subject: [PATCH 6/6] Add set_organized to confirmation. --- src/chasers/chaser_confirm.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/chasers/chaser_confirm.cpp b/src/chasers/chaser_confirm.cpp index c49e7810..20e9da34 100644 --- a/src/chasers/chaser_confirm.cpp +++ b/src/chasers/chaser_confirm.cpp @@ -207,8 +207,10 @@ void chaser_confirm::do_bump(height_t) NOEXCEPT fault(error::confirm2); return; } - + + ///////////////////////////////////////// // Confirmation query. + ///////////////////////////////////////// if ((ec = query.block_confirmable(link))) { if (ec == database::error::integrity) @@ -243,6 +245,12 @@ void chaser_confirm::do_bump(height_t) NOEXCEPT fault(error::confirm6); return; } + + if (!set_organized(link, height)) + { + fault(error::confirm7); + return; + } notify(error::success, chase::confirmable, height); fire(events::block_confirmed, height); @@ -253,7 +261,7 @@ void chaser_confirm::do_bump(height_t) NOEXCEPT { if (!query.set_strong(link)) { - fault(error::confirm7); + fault(error::confirm8); return; } @@ -271,7 +279,7 @@ void chaser_confirm::do_bump(height_t) NOEXCEPT // database::error::unknown_state [shouldn't be here] // database::error::unassociated [shouldn't be here] // database::error::unvalidated [shouldn't be here] - fault(error::confirm8); + fault(error::confirm9); return; } @@ -286,7 +294,7 @@ void chaser_confirm::do_bump(height_t) NOEXCEPT // first) here. Candidate chain reorganizations will result in reported heights // moving in any direction. Each is treated as independent and only one // representing a stronger chain is considered. - +//// ////// Compute relative work, set fork and fork_point, and invoke reorganize. ////void chaser_confirm::do_validated(height_t height) NOEXCEPT ////{