Skip to content

fix: improve miner thread robustness - #7510

Open
brice-stacks wants to merge 6 commits into
stacks-network:mainfrom
brice-stacks:feat/miner-retries
Open

fix: improve miner thread robustness#7510
brice-stacks wants to merge 6 commits into
stacks-network:mainfrom
brice-stacks:feat/miner-retries

Conversation

@brice-stacks

@brice-stacks brice-stacks commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Fixed the miner thread exiting (and stalling the chain for the remainder of the tenure) on transient error. The miner now retries when it hits DB contention, a parent block that has not been processed yet, a new parent block discovered mid-mining, or a mempool cache reset failure, instead of giving up on the tenure.

These changes are difficult to test and not worth the effort in my opinion.
Never mind -- this does need testing. I'm working on it.

Checklist

  • Test coverage for new or modified code paths
  • For new Clarity features or consensus changes, add property tests (see
    docs/property-testing.md)
  • Changelog fragment(s) or "no changelog" label added (see
    changelog.d/README.md). If this PR breaks
    anything for node operators or users, or requires them to manually do
    anything (such as adjust a setting), use the breaking category.
  • Required documentation changes (e.g.,
    rpc/openapi.yaml for RPC endpoints,
    event-dispatcher.md for new events)
  • New clarity functions have corresponding PR in clarity-benchmarking repo

Fixed the miner thread exiting (and stalling the chain for the remainder
of the tenure) on transient error. The miner now retries when it hits DB
contention, a parent block that has not been processed yet, a new parent
block discovered mid-mining, or a mempool cache reset failure, instead
of giving up on the tenure.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Improves miner resilience by retrying recoverable failures instead of ending the tenure’s mining thread.

Changes:

  • Adds abort-aware retry handling for parent changes, DB errors, and timestamp validation.
  • Retries failed mempool cache resets.
  • Preserves underlying DB errors for retry classification.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
stacks-node/src/nakamoto_node/miner.rs Adds miner retry and abort behavior.
changelog.d/miner-thread-retry-transient-errors.fixed Documents the robustness fix.
Suppressed comments (1)

stacks-node/src/nakamoto_node/miner.rs:826

  • This arm classifies all DBError values as transient, but the wrapped error type also includes permanent conditions such as Corruption, ReadOnly, OldSchema, TooOldForEpoch, and BlockHeightOutOfRange (stackslib/src/util_lib/db.rs:54-91). Such faults will now loop and log until the tenure changes. Narrow this arm to explicitly retryable contention errors (and any intentionally retryable not-found cases), allowing all other errors to reach the fatal path.
            Err(
                ref e @ (NakamotoNodeError::MiningFailure(ChainstateError::DBError(_))
                | NakamotoNodeError::DBError(_)),

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread stacks-node/src/nakamoto_node/miner.rs
Comment thread stacks-node/src/nakamoto_node/miner.rs Outdated
Comment on lines +673 to +677
if let Err(e) = reset_result {
// A mempool DB error here is likely transient (e.g. lock
// contention); sleep and retry rather than exiting the miner
// thread.
warn!("Miner: failed to reset mempool caches, will try again: {e:?}");

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it hurts anything if the miner keeps retrying with no possibility of recovery, and that case might be more obvious in the logs. I'll take a closer look.

@cylewitruk-stacks cylewitruk-stacks Aug 12, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only thing that I'd be careful of is the potential for this warn! to spam the logs 5x/second if it is e.g. some db/storage (or other persistent) issue 🙈 But the expect() above would maybe crash the thread then..

EDIT: But I guess we do that in a bunch of other places here already, so likely moot. I don't think it hurts anything, either -- the node will crash for other reasons if out of space or there's a corrupt db somewhere, etc.

@coveralls

coveralls commented Aug 12, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 32298405099

Coverage decreased (-0.01%) to 86.59%

Details

  • Coverage decreased (-0.01%) from the base build.
  • Patch coverage: 10 uncovered changes across 1 file (95 of 105 lines covered, 90.48%).
  • 135 coverage regressions across 33 files.

Uncovered Changes

File Changed Covered %
stacks-node/src/nakamoto_node/miner.rs 101 91 90.1%
Total (2 files) 105 95 90.48%

Coverage Regressions

135 previously-covered lines in 33 files lost coverage.

Top 10 Files by Coverage Loss Lines Losing Coverage Coverage
stackslib/src/net/p2p.rs 25 73.93%
stacks-node/src/nakamoto_node/miner.rs 13 86.78%
stackslib/src/net/inv/epoch2x.rs 10 80.01%
stacks-node/src/nakamoto_node/relayer.rs 9 86.26%
stackslib/src/burnchains/burnchain.rs 8 71.39%
stackslib/src/net/stackerdb/sync.rs 6 76.37%
stacks-node/src/neon_node.rs 6 83.33%
stacks-signer/src/v0/signer_state.rs 6 92.95%
stackslib/src/chainstate/stacks/index/marf.rs 5 84.07%
stackslib/src/net/mod.rs 4 78.01%

Coverage Stats

Coverage Status
Relevant Lines: 233083
Covered Lines: 201827
Line Coverage: 86.59%
Coverage Strength: 19408614.31 hits per line

💛 - Coveralls

Comment thread stacks-node/src/nakamoto_node/miner.rs Outdated
Replace a boolean flag that was set manually with an optional block id
to ensure that we reset the caches when appropriate.

@cylewitruk-stacks cylewitruk-stacks left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At a first glance this lgtm 👍 Not approving just yet only because I want to circle back with more focus and follow the error paths more closely.

Comment thread stacks-node/src/nakamoto_node/miner.rs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Comment thread stacks-node/src/nakamoto_node/miner.rs
Comment thread stacks-node/src/nakamoto_node/miner.rs
Comment thread stacks-node/src/nakamoto_node/miner.rs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

stacks-node/src/tests/nakamoto_integrations.rs:19784

  • These errors are all injected at the start of mine_block(), before parent loading, cache reset, block building, and the post-broadcast processing wait. The test therefore covers only the top-level match arms; it cannot catch regressions in the newly added DB retry inside wait_for_last_block_mined_and_processed() or retry behavior after an actual cache-reset failure. Add operation-specific fault points so those production paths fail once and then recover within the same tenure.
    TEST_MINE_TRANSIENT_ERRORS.set(vec![
        TestTransientError::ParentNotFound,
        TestTransientError::NewParentDiscovered,
        TestTransientError::DBError,
    ]);

Comment thread stacks-node/src/nakamoto_node/miner.rs

@francesco-stacks francesco-stacks left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants