From 2ea3b28352754023c0b911a7e0a384bb5fa183c6 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Tue, 16 Dec 2025 02:46:05 -0500 Subject: [PATCH] Add defer_validation/confirmation. --- .../bitcoin/node/chasers/chaser_confirm.hpp | 3 ++- .../bitcoin/node/chasers/chaser_validate.hpp | 1 + include/bitcoin/node/settings.hpp | 2 ++ src/chasers/chaser_confirm.cpp | 9 +++++++-- src/chasers/chaser_validate.cpp | 18 +++++++++++++----- src/parser.cpp | 10 ++++++++++ src/settings.cpp | 2 ++ test/settings.cpp | 2 ++ 8 files changed, 39 insertions(+), 8 deletions(-) diff --git a/include/bitcoin/node/chasers/chaser_confirm.hpp b/include/bitcoin/node/chasers/chaser_confirm.hpp index e2a25a567..904228df6 100644 --- a/include/bitcoin/node/chasers/chaser_confirm.hpp +++ b/include/bitcoin/node/chasers/chaser_confirm.hpp @@ -69,8 +69,9 @@ class BCN_API chaser_confirm size_t top) NOEXCEPT; void announce(const header_link& link, height_t height) NOEXCEPT; - // This is thread safe. + // These are thread safe. const bool filter_; + const bool defer_; }; } // namespace node diff --git a/include/bitcoin/node/chasers/chaser_validate.hpp b/include/bitcoin/node/chasers/chaser_validate.hpp index 999283bce..1b4840239 100644 --- a/include/bitcoin/node/chasers/chaser_validate.hpp +++ b/include/bitcoin/node/chasers/chaser_validate.hpp @@ -89,6 +89,7 @@ class BCN_API chaser_validate const size_t maximum_backlog_; const bool node_witness_; const bool filter_; + const bool defer_; }; } // namespace node diff --git a/include/bitcoin/node/settings.hpp b/include/bitcoin/node/settings.hpp index 61a1f115c..33d104386 100644 --- a/include/bitcoin/node/settings.hpp +++ b/include/bitcoin/node/settings.hpp @@ -74,6 +74,8 @@ class BCN_API settings bool headers_first; bool thread_priority; bool memory_priority; + bool defer_validation; + bool defer_confirmation; float allowed_deviation; uint16_t announcement_cache; uint16_t allocation_multiple; diff --git a/src/chasers/chaser_confirm.cpp b/src/chasers/chaser_confirm.cpp index d08460765..3ef2d797c 100644 --- a/src/chasers/chaser_confirm.cpp +++ b/src/chasers/chaser_confirm.cpp @@ -35,7 +35,8 @@ BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT) chaser_confirm::chaser_confirm(full_node& node) NOEXCEPT : chaser(node), - filter_(node.archive().filter_enabled()) + filter_(node.archive().filter_enabled()), + defer_(node.config().node.defer_confirmation) { } @@ -49,7 +50,11 @@ code chaser_confirm::start() NOEXCEPT LOGN("Node is current at startup block [" << position() << "]."); } - SUBSCRIBE_EVENTS(handle_event, _1, _2, _3); + if (!defer_) + { + SUBSCRIBE_EVENTS(handle_event, _1, _2, _3); + } + return error::success; } diff --git a/src/chasers/chaser_validate.cpp b/src/chasers/chaser_validate.cpp index 574acb281..530641330 100644 --- a/src/chasers/chaser_validate.cpp +++ b/src/chasers/chaser_validate.cpp @@ -44,7 +44,8 @@ chaser_validate::chaser_validate(full_node& node) NOEXCEPT initial_subsidy_(node.config().bitcoin.initial_subsidy()), maximum_backlog_(node.config().node.maximum_concurrency_()), node_witness_(node.config().network.witness_node()), - filter_(node.archive().filter_enabled()) + filter_(node.archive().filter_enabled()), + defer_(node.config().node.defer_validation) { } @@ -170,12 +171,13 @@ void chaser_validate::do_bumped(height_t height) NOEXCEPT if (ec == database::error::unassociated) return; - const auto bypass = is_under_checkpoint(height) || + const auto bypass = defer_ || is_under_checkpoint(height) || query.is_milestone(link); if (bypass) { - if (filter_) + // Filters will be set on subsequent unsupressed run. + if (filter_ && !defer_) { post_block(link, bypass); } @@ -350,9 +352,15 @@ void chaser_validate::complete_block(const code& ec, const header_link& link, } // VALID BLOCK + // Under deferral there is no state change, but downloads will stall unless + // he window is closed out, so notify the check chaser of the increment. notify(ec, chase::valid, possible_wide_cast(height)); - fire(events::block_validated, height); - LOGV("Block validated: " << height << (bypass ? " (bypass)" : "")); + + if (!defer_) + { + fire(events::block_validated, height); + LOGV("Block validated: " << height << (bypass ? " (bypass)" : "")); + } } // Overrides due to independent priority thread pool diff --git a/src/parser.cpp b/src/parser.cpp index ccd20fdd5..5eac0ec2e 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1029,6 +1029,16 @@ options_metadata parser::load_settings() THROWS value(&configured.node.delay_inbound), "Delay accepting inbound connections until node is current, defaults to 'true'." ) + ( + "node.defer_validation", + value(&configured.node.defer_validation), + "Defer validation, defaults to 'false'." + ) + ( + "node.defer_confirmation", + value(&configured.node.defer_confirmation), + "Defer confirmation, defaults to 'false'." + ) ////( //// "node.headers_first", //// value(&configured.node.headers_first), diff --git a/src/settings.cpp b/src/settings.cpp index 0d8f03c17..10d0ceb26 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -85,6 +85,8 @@ settings::settings() NOEXCEPT headers_first{ true }, memory_priority{ true }, thread_priority{ true }, + defer_validation{ false }, + defer_confirmation{ false }, allowed_deviation{ 1.5 }, announcement_cache{ 42 }, allocation_multiple{ 20 }, diff --git a/test/settings.cpp b/test/settings.cpp index 459f1455f..8bb4e1a75 100644 --- a/test/settings.cpp +++ b/test/settings.cpp @@ -58,6 +58,8 @@ BOOST_AUTO_TEST_CASE(settings__node__default_context__expected) BOOST_REQUIRE_EQUAL(node.thread_priority, true); BOOST_REQUIRE_EQUAL(node.delay_inbound, true); BOOST_REQUIRE_EQUAL(node.headers_first, true); + BOOST_REQUIRE_EQUAL(node.defer_validation, false); + BOOST_REQUIRE_EQUAL(node.defer_confirmation, false); BOOST_REQUIRE_EQUAL(node.allowed_deviation, 1.5); BOOST_REQUIRE_EQUAL(node.announcement_cache, 42_u16); BOOST_REQUIRE_EQUAL(node.allocation_multiple, 20_u16);