From 8814a22093f86578fb37aa5bf6c3f14ef0e4ce6e Mon Sep 17 00:00:00 2001 From: evoskuil Date: Wed, 17 Dec 2025 16:49:22 -0500 Subject: [PATCH 1/3] Comments on chaser operation while suspended. --- src/chasers/chaser_confirm.cpp | 3 +++ src/chasers/chaser_snapshot.cpp | 1 + src/chasers/chaser_template.cpp | 1 + src/chasers/chaser_transaction.cpp | 1 + src/chasers/chaser_validate.cpp | 2 ++ src/full_node.cpp | 1 + 6 files changed, 9 insertions(+) diff --git a/src/chasers/chaser_confirm.cpp b/src/chasers/chaser_confirm.cpp index 3ef2d797c..b31cbd670 100644 --- a/src/chasers/chaser_confirm.cpp +++ b/src/chasers/chaser_confirm.cpp @@ -65,6 +65,7 @@ bool chaser_confirm::handle_event(const code&, chase event_, return false; // Stop generating query during suspension. + // Incoming events may already be flushed to the strand at this point. if (suspended()) return true; @@ -221,6 +222,7 @@ void chaser_confirm::organize(header_states& fork, const header_links& popped, auto& query = archive(); auto height = add1(fork_point); + // Continue when suspended as write error terminates synchronous loop. for (const auto& state: fork) { switch (state.ec.value()) @@ -238,6 +240,7 @@ void chaser_confirm::organize(header_states& fork, const header_links& popped, } case database::error::block_valid: { + // False always sets a store fault (including for disk full). if (!confirm_block(state.link, height, popped, fork_point)) return; diff --git a/src/chasers/chaser_snapshot.cpp b/src/chasers/chaser_snapshot.cpp index bc0b05f86..bac455d9b 100644 --- a/src/chasers/chaser_snapshot.cpp +++ b/src/chasers/chaser_snapshot.cpp @@ -79,6 +79,7 @@ bool chaser_snapshot::handle_event(const code&, chase event_, return false; // Stop generating query during suspension. + // Incoming events may already be flushed to the strand at this point. if (suspended()) return true; diff --git a/src/chasers/chaser_template.cpp b/src/chasers/chaser_template.cpp index fb47bdd4b..6eaba1ef4 100644 --- a/src/chasers/chaser_template.cpp +++ b/src/chasers/chaser_template.cpp @@ -57,6 +57,7 @@ bool chaser_template::handle_event(const code&, chase event_, return false; // Stop generating query during suspension. + // Incoming events may already be flushed to the strand at this point. if (suspended()) return true; diff --git a/src/chasers/chaser_transaction.cpp b/src/chasers/chaser_transaction.cpp index 0b46dc3d4..9a6c0828c 100644 --- a/src/chasers/chaser_transaction.cpp +++ b/src/chasers/chaser_transaction.cpp @@ -58,6 +58,7 @@ bool chaser_transaction::handle_event(const code&, chase event_, // TODO: allow required messages. ////// Stop generating query during suspension. + ////// Incoming events may already be flushed to the strand at this point. ////if (suspended()) //// return true; diff --git a/src/chasers/chaser_validate.cpp b/src/chasers/chaser_validate.cpp index e114c8d87..3e4a86f5c 100644 --- a/src/chasers/chaser_validate.cpp +++ b/src/chasers/chaser_validate.cpp @@ -67,6 +67,7 @@ bool chaser_validate::handle_event(const code&, chase event_, return false; // Stop generating query during suspension. + // Incoming events may already be flushed to the strand at this point. if (suspended()) return true; @@ -161,6 +162,7 @@ void chaser_validate::do_bumped(height_t height) NOEXCEPT const auto& query = archive(); // Bypass until next event if validation backlog is full. + // Stop when suspended as write error des not terminate asynchronous loop. while ((backlog_ < maximum_backlog_) && !closed() && !suspended()) { const auto link = query.to_candidate(height); diff --git a/src/full_node.cpp b/src/full_node.cpp index 3c9b59a1a..4f3be1db1 100644 --- a/src/full_node.cpp +++ b/src/full_node.cpp @@ -379,6 +379,7 @@ void full_node::fault(const code& ec) NOEXCEPT LOGF("Node fault, " << ec.message()); } + // If a call does not get all of the channels, subsequent failures do so. suspend(ec); } From 4b87f366a68c566ea73ebb0c7f6570b49b33be9a Mon Sep 17 00:00:00 2001 From: evoskuil Date: Wed, 17 Dec 2025 16:49:48 -0500 Subject: [PATCH 2/3] Suspend outer confirm loop while network is suspended. --- src/chasers/chaser_confirm.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/chasers/chaser_confirm.cpp b/src/chasers/chaser_confirm.cpp index b31cbd670..9b3b67c02 100644 --- a/src/chasers/chaser_confirm.cpp +++ b/src/chasers/chaser_confirm.cpp @@ -138,6 +138,10 @@ void chaser_confirm::do_bumped(height_t) NOEXCEPT if (closed()) return; + // Stop while suspended as iteration is O(N^2) if blocks not organized. + if (suspended()) + return; + // Guarded by candidate interlock. size_t fork_point{}; auto fork = query.get_validated_fork(fork_point, checkpoint(), filter_); From d656cf79bfd027cff156cfb86343a9752e0e6944 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Wed, 17 Dec 2025 16:50:04 -0500 Subject: [PATCH 3/3] Defer query init until use. --- src/chasers/chaser_confirm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chasers/chaser_confirm.cpp b/src/chasers/chaser_confirm.cpp index 9b3b67c02..e75f49e15 100644 --- a/src/chasers/chaser_confirm.cpp +++ b/src/chasers/chaser_confirm.cpp @@ -133,7 +133,6 @@ void chaser_confirm::do_bump(height_t) NOEXCEPT void chaser_confirm::do_bumped(height_t) NOEXCEPT { BC_ASSERT(stranded()); - const auto& query = archive(); if (closed()) return; @@ -144,6 +143,7 @@ void chaser_confirm::do_bumped(height_t) NOEXCEPT // Guarded by candidate interlock. size_t fork_point{}; + const auto& query = archive(); auto fork = query.get_validated_fork(fork_point, checkpoint(), filter_); // Fork may be empty if candidates were reorganized.