diff --git a/src/chasers/chaser_confirm.cpp b/src/chasers/chaser_confirm.cpp index 3ef2d797..e75f49e1 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; @@ -132,13 +133,17 @@ 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; + // Stop while suspended as iteration is O(N^2) if blocks not organized. + if (suspended()) + return; + // 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. @@ -221,6 +226,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 +244,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 bc0b05f8..bac455d9 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 fb47bdd4..6eaba1ef 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 0b46dc3d..9a6c0828 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 e114c8d8..3e4a86f5 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 3c9b59a1..4f3be1db 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); }