Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions include/bitcoin/node/chase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ enum class chase
/// Issued by 'full_node' and handled by 'check', 'validate', 'confirm'.
resume,

/// Node is recovering from disk full condition.
/// Issued by 'storage' and handled by 'validate'.
unfull,

/// Channel starved for work (object_t).
/// Issued by 'block_in_31800' and handled by 'session_outbound'.
starved,
Expand Down
1 change: 1 addition & 0 deletions include/bitcoin/node/chasers/chaser_validate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ class BCN_API chaser_validate
std::atomic<size_t> validate_backlog_{};
std::atomic<size_t> batch_backlog_{};
std::atomic_bool maximum_posted_{};
std::atomic_bool recovering_{};

network::asio::strand validation_strand_;
const uint32_t subsidy_interval_;
Expand Down
3 changes: 3 additions & 0 deletions src/chasers/chaser_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ void chaser_storage::do_reload() NOEXCEPT
}
else
{
// Recovery from disk full message sent in addition to chase::resume.
notify(error::success, chase::unfull, {});

resume();
const auto span = duration_cast<seconds>(logger::now() - start);
LOGN("Reload from disk full complete in " << span.count() << " secs.");
Expand Down
27 changes: 16 additions & 11 deletions src/chasers/chaser_validate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ bool chaser_validate::handle_chase(const code&, chase event_,
if (closed())
return false;

// Latch recovering from disk full, before suspension is lifted.
// Because in-flight blocks are lost, reset position when backlog clears.
if (event_ == chase::unfull)
{
recovering_.store(true);
return true;
}

// Stop generating query during suspension.
// Incoming events may already be flushed to the strand at this point.
if (suspended())
Expand Down Expand Up @@ -138,6 +146,12 @@ void chaser_validate::do_bump(height_t) NOEXCEPT
{
BC_ASSERT(stranded());

if (recovering_.load() && is_zero(validate_backlog_.load()))
{
recovering_.store(false);
set_position(archive().get_fork());
}

const auto height = add1(position());
if (archive().is_validateable(height))
do_bumped(height);
Expand Down Expand Up @@ -257,19 +271,10 @@ void chaser_validate::complete_block(const code& ec, const header_link& link,
// Batch jobs (all posting from unstranded).
// ------------------------------------------------------------------------

// Avoid posting new work when closing.
if (closed() || !batch_enabled_)
// Faulted implies disk full prevented threshold batch writes.
if (closed() || !batch_enabled_ || faulted)
return;

// TODO: ensure doesn't lead to tight revalidation loop under disk full.
// Retry faulted threshold, re-enters backlog (presumes disk full).
if (faulted)
{
++validate_backlog_;
POST(post_block, link, bypass);
return;
}

// Queue block and process batch if ready.
if (batched)
{
Expand Down
Loading