Skip to content

fix: restore BLS scheme after failed block validation#7345

Open
thepastaclaw wants to merge 4 commits into
dashpay:developfrom
thepastaclaw:fix/bls-scheme-restore
Open

fix: restore BLS scheme after failed block validation#7345
thepastaclaw wants to merge 4 commits into
dashpay:developfrom
thepastaclaw:fix/bls-scheme-restore

Conversation

@thepastaclaw

Copy link
Copy Markdown

Restore BLS scheme after failed block validation

Issue being fixed or feature implemented

V19-boundary block validation can temporarily switch the process-wide BLS
scheme from legacy to basic while validating a candidate block. If validation
fails after that switch, early returns from ConnectBlock or
TestBlockValidity could leave bls::bls_legacy_scheme in the wrong state
even though the active chain tip did not advance.

What was done?

  • Added an RAII guard for bls::bls_legacy_scheme snapshots in validation code.
  • Restored the previous BLS scheme on all ConnectBlock failure paths.
  • Preserved successful real post-activation behavior by dismissing the guard
    only after a full successful real block connection.
  • Replaced the old success-only restore in TestBlockValidity so dry-run and
    proposal validation restores on both success and failure.
  • Added a regression test that validates and processes a malformed V19-boundary
    candidate block which flips the scheme and then fails later with
    bad-txns-inputs-missingorspent.

How Has This Been Tested?

Tested on macOS 15.6 arm64 in a local Dash Core worktree.

  • git diff --check
  • make -C src -j8 test/test_dash
  • Focused Boost regression:
    evo_dip3_activation_tests/v19_boundary_validation_failure_restores_bls_scheme
  • Full nearby Boost suite: evo_dip3_activation_tests
  • Pre-PR code review gate: ship

Breaking Changes

None.

Checklist

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation
  • I have assigned this pull request to a milestone (for repository
    code-owners and collaborators only)

@thepastaclaw

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown

✅ No Merge Conflicts Detected

This PR currently has no conflicts with other open PRs.

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 996887b5-9841-4ee1-b0ba-4cce055de7a8

📥 Commits

Reviewing files that changed from the base of the PR and between 894ec38 and 43094d6.

📒 Files selected for processing (1)
  • src/validation.cpp

Walkthrough

src/validation.cpp gains a ScopedBLSLegacyScheme RAII class (anonymous namespace) that snapshots bls::bls_legacy_scheme on construction and restores it on destruction unless Commit() was called. CChainState::ConnectBlock() instantiates this guard at entry and calls Commit() on the success path, so scheme changes persist only when a block fully connects. CChainState::ConnectTip() also instantiates the guard and commits it before advancing the chain tip, restoring the scheme if a later step fails. TestBlockValidity() drops its manual save/restore in favor of the RAII guard. CVerifyDB::VerifyDB() adds an entry-scope guard and updates its reconnect-loop comment to explain that successful ConnectBlock() iterations leave the scheme globally set until VerifyDB() exits. A new BLS regression test (v19_boundary_validation_failure_restores_bls_scheme) builds a V19-boundary chain state, submits an invalid block, and asserts the global scheme is restored after both the validation failure and a subsequent connect attempt.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 35.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: restoring BLS scheme state after failed block validation, which directly addresses the core issue described in the PR objectives.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, covering the issue, implementation details, testing approach, and breaking changes assessment.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/validation.cpp`:
- Line 2599: The call to bls_scheme_guard.Dismiss() inside ConnectBlock causes
the switched BLS scheme to persist across non-tip replays (e.g.
CVerifyDB::VerifyDB calling ConnectBlock on a temporary cache), so move the
persistence decision out of ConnectBlock and into the real chain advance site
(CChainState::ConnectTip) or gate it behind an explicit opt-in flag;
specifically, remove or stop calling ScopedBLSLegacyScheme::Dismiss() from
within ConnectBlock and instead create and dismiss ScopedBLSLegacyScheme in
ConnectTip (around the actual Flush/Commit, m_chain.SetTip and UpdateTip
sequence) so that bls::bls_legacy_scheme only flips when the tip truly advances,
or add an explicit parameter on ConnectBlock (e.g., persist_scheme=false) and
have ConnectTip call ConnectBlock with persist_scheme=true and perform the
Dismiss() there.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 044045a9-71a1-40ba-978c-ff4e44e465b0

📥 Commits

Reviewing files that changed from the base of the PR and between 317917a and ca30a72.

📒 Files selected for processing (2)
  • src/test/evo_deterministicmns_tests.cpp
  • src/validation.cpp

Comment thread src/validation.cpp Outdated
@thepastaclaw thepastaclaw force-pushed the fix/bls-scheme-restore branch 2 times, most recently from aacbd36 to 67427a9 Compare June 9, 2026 00:42
@thepastaclaw

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/test/validation_block_tests.cpp`:
- Around line 384-410: The test mutates the global bls::bls_legacy_scheme flag
without restoring it; capture the current value of bls::bls_legacy_scheme before
calling bls::bls_legacy_scheme.store(true) and restore it at the end of the test
(or use an RAII/scope-guard) so the global state is reset regardless of test
assertions or failures; reference the mutation point
(bls::bls_legacy_scheme.store(true)) and ensure restoration runs after the
TestBlockValidity/ProcessNewBlock checks (or in a teardown/scope guard) to avoid
cross-test leakage.

In `@src/validation.cpp`:
- Around line 3088-3090: The tip is published with the old BLS scheme because
SetBLSLegacyScheme(effective_bls_legacy_scheme, __func__) is called after
UpdateTip; move the SetBLSLegacyScheme call to immediately after
m_chain.SetTip(*pindexNew) and before UpdateTip(pindexNew) so the process-wide
BLS scheme is updated prior to notifying waiters (locate the sequence
m_chain.SetTip(*pindexNew); UpdateTip(pindexNew); SetBLSLegacyScheme(...) and
reorder to m_chain.SetTip(*pindexNew); SetBLSLegacyScheme(...);
UpdateTip(pindexNew)).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 82e1b1aa-3913-48be-b707-4994ca6f17aa

📥 Commits

Reviewing files that changed from the base of the PR and between ca30a72 and 67427a9.

📒 Files selected for processing (3)
  • src/test/validation_block_tests.cpp
  • src/validation.cpp
  • src/validation.h

Comment thread src/test/validation_block_tests.cpp Outdated
Comment thread src/validation.cpp Outdated
@thepastaclaw

Copy link
Copy Markdown
Author

Addressed latest CodeRabbit findings in a34f16a: restored the test-local BLS scheme after the regression check and moved SetBLSLegacyScheme before UpdateTip so tip notifications observe the effective scheme. Validation: make -C src -j8 test/test_dash-validation_block_tests.o test/test_dash and src/test/test_dash --run_test=bls_validation_tests/v19_boundary_validation_failure_restores_bls_scheme --catch_system_errors=no.

@thepastaclaw thepastaclaw force-pushed the fix/bls-scheme-restore branch from 67427a9 to a34f16a Compare June 9, 2026 00:53
@thepastaclaw

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@thepastaclaw thepastaclaw force-pushed the fix/bls-scheme-restore branch from a34f16a to 82e5634 Compare June 9, 2026 01:27
@thepastaclaw

Copy link
Copy Markdown
Author

Follow-up pushed in 82e5634: moved the BLS regression check into the existing Evo activation suite so CI no longer tries to run a disabled filtered test in nowallet/tsan builds. Validation: make -C src -j8 test/evo_deterministicmns_tests.cpp.test test/validation_block_tests.cpp.test.

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

@thepastaclaw I'll trigger a review of the latest changes including the follow-up commit 82e5634.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/test/evo_deterministicmns_tests.cpp (1)

1001-1027: ⚡ Quick win

Use scoped restoration for bls::bls_legacy_scheme to avoid cross-test state leaks.

The end-of-test restore is skipped if a fatal abort/exception happens after Line 1008, which can leave the global scheme mutated for subsequent tests.

Suggested hardening
-    const bool previous_bls_scheme{bls::bls_legacy_scheme.load()};
+    const bool previous_bls_scheme{bls::bls_legacy_scheme.load()};
+    struct ScopedRestoreBlsScheme {
+        explicit ScopedRestoreBlsScheme(bool saved) : saved_scheme(saved) {}
+        ~ScopedRestoreBlsScheme() { bls::bls_legacy_scheme.store(saved_scheme); }
+        bool saved_scheme;
+    } bls_scheme_restore_guard{previous_bls_scheme};
@@
-    bls::bls_legacy_scheme.store(previous_bls_scheme);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/evo_deterministicmns_tests.cpp` around lines 1001 - 1027, Replace
the manual save/restore of bls::bls_legacy_scheme with a scoped RAII guard so
the original value is always restored even if the test aborts or throws;
specifically, instead of storing previous_bls_scheme and calling
bls::bls_legacy_scheme.store(previous_bls_scheme) at the end, create a small
scoped restorer object (or use an existing SCOPE_EXIT/ScopedRestore helper) that
captures bls::bls_legacy_scheme and its current value on construction and calls
store(original) in its destructor, and then call
bls::bls_legacy_scheme.store(true) to set the test value — this ensures
bls::bls_legacy_scheme is restored no matter how the test exits.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/test/evo_deterministicmns_tests.cpp`:
- Around line 1001-1027: Replace the manual save/restore of
bls::bls_legacy_scheme with a scoped RAII guard so the original value is always
restored even if the test aborts or throws; specifically, instead of storing
previous_bls_scheme and calling
bls::bls_legacy_scheme.store(previous_bls_scheme) at the end, create a small
scoped restorer object (or use an existing SCOPE_EXIT/ScopedRestore helper) that
captures bls::bls_legacy_scheme and its current value on construction and calls
store(original) in its destructor, and then call
bls::bls_legacy_scheme.store(true) to set the test value — this ensures
bls::bls_legacy_scheme is restored no matter how the test exits.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 2605dc77-85b5-4bbd-87f1-352ee65d2ff2

📥 Commits

Reviewing files that changed from the base of the PR and between a34f16a and 82e5634.

📒 Files selected for processing (4)
  • src/test/evo_deterministicmns_tests.cpp
  • src/test/validation_block_tests.cpp
  • src/validation.cpp
  • src/validation.h
✅ Files skipped from review due to trivial changes (1)
  • src/test/validation_block_tests.cpp
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/validation.h

@thepastaclaw thepastaclaw force-pushed the fix/bls-scheme-restore branch from 82e5634 to 17e316a Compare June 9, 2026 01:37
@thepastaclaw

Copy link
Copy Markdown
Author

Addressed the latest CodeRabbit nitpick in 17e316a: the BLS regression now uses a scoped restorer so bls::bls_legacy_scheme is restored even if the test exits early.

Validation: make -C src -j8 test/test_dash && src/test/test_dash --run_test=evo_dip3_activation_tests/v19_boundary_validation_failure_restores_bls_scheme --catch_system_errors=no.

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

@thepastaclaw: Thanks for the follow-up! Using a scoped RAII restorer in the regression test is the right approach — it guarantees bls::bls_legacy_scheme is restored on all exit paths (assertions, exceptions, early returns), consistent with the ScopedBLSLegacyScheme pattern introduced in the production code. I'll trigger a review of the latest changes.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@thepastaclaw

thepastaclaw commented Jun 9, 2026

Copy link
Copy Markdown
Author

✅ Review complete (commit 43094d6)

@thepastaclaw

Copy link
Copy Markdown
Author

CI note: the only red item is predict_conflicts; the full build/test matrix is green. The predictor flags overlaps in src/validation.cpp, src/validation.h, and nearby Evo tests against other open PRs, which are the files this fix necessarily touches. I don’t see a clean way to reduce the footprint further without losing the BLS-scheme restoration coverage, so this is blocked on PR ordering/merge sequencing rather than a test failure.

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Code Review

PR cleanly fixes the BLS scheme restoration on failed block validation via RAII guards in TestBlockValidity, ConnectBlock, and VerifyDB, while preserving the post-activation state in ConnectTip and VerifyDB's level-4 reconnect via a captured effective scheme. Verification confirms the design is sound; only two minor observations remain: a defensible but subtle change in when listeners observe the new scheme, and an unrelated whitespace insertion in a test file. No blockers; comment-only review.

🟡 1 suggestion(s) | 💬 1 nitpick(s)

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `src/validation.cpp`:
- [SUGGESTION] src/validation.cpp:3059-3089: BlockChecked / flush window now runs with pre-switch BLS scheme on V19-boundary connects
  On a successful V19-boundary ConnectBlock, the inner `ScopedBLSLegacyScheme` guard unconditionally restores the entry scheme before ConnectBlock returns, and the new scheme is re-applied only at line 3089 (after `m_chain.SetTip`). As a result, `GetMainSignals().BlockChecked(...)` (line 3060), `dbTx->Commit()`, `FlushStateToDisk`, `m_mempool->removeForBlock` / `removeExpiredAssetUnlock`, and `m_chain.SetTip` all execute with the OLD scheme on the boundary block — a transient inversion compared to the prior behavior. A scan of current BlockChecked listeners (net_processing, rpc/mining, test/util/mining, bitcoin-chainstate) and the intervening flush/mempool work shows none read `bls::bls_legacy_scheme` in that window, so this appears benign today. The final state set at line 3089 is correct. Worth calling out because future code reading `bls::bls_legacy_scheme` inside a BlockChecked listener or the flush window would observe a value inconsistent with the new tip; an alternative would be to apply the effective scheme before `BlockChecked` rather than after `SetTip`.

Comment thread src/validation.cpp Outdated
Comment thread src/test/validation_block_tests.cpp Outdated
@thepastaclaw thepastaclaw marked this pull request as ready for review June 15, 2026 12:21
@thepastaclaw

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@thepastaclaw

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@thepastaclaw thepastaclaw force-pushed the fix/bls-scheme-restore branch from 17e316a to e590e34 Compare June 17, 2026 01:29
@thepastaclaw

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@thepastaclaw

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Comment thread src/test/evo_deterministicmns_tests.cpp Outdated
FuncV19Activation(setup);
}

BOOST_AUTO_TEST_CASE(v19_boundary_validation_failure_restores_bls_scheme)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

that's improper location for bls tests

Use src/test/bls_tests.cpp

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in 35436f0529b425cdcfc3832f5d547f3d3d7dc93f — moved v19_boundary_validation_failure_restores_bls_scheme from src/test/evo_deterministicmns_tests.cpp into src/test/bls_tests.cpp, alongside the other BLS coverage.

Validation from the worktree:

  • git diff --check HEAD^ HEAD
  • bls_tests focused run: 17 cases passed
  • evo_dip3_activation_tests focused run: 13 cases passed

The v19_boundary_validation_failure_restores_bls_scheme regression
test exercises BLS-scheme bookkeeping after a failed block validation
at the V19 activation boundary, so it belongs alongside the other BLS
tests in src/test/bls_tests.cpp rather than the deterministicmns
suite.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@thepastaclaw

Copy link
Copy Markdown
Author

@coderabbitai review

@knst knst left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

NACK, adding one more un-typed bool to ConnectBlock is not error-prune, I will give other patch later today.

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@thepastaclaw

Copy link
Copy Markdown
Author

@coderabbitai review

@thepastaclaw

Copy link
Copy Markdown
Author

Ack — agreed on avoiding another untyped bool in ConnectBlock. I’ll hold off on more churn here and rework around your patch once you post it.

@knst

knst commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

@thepastaclaw please review this commit b0a03c6 and find down-sides compare to PR if any. Pull freely these changes to PR and adjust / improve if there's any inaccuraties or mistakes.

Adopts knst's review feedback: drop the second untyped bool parameter on
ConnectBlock and move the commit semantics inline. ScopedBLSLegacyScheme
is constructed at the top of ConnectBlock and Commit()ed right after
WriteBestBlock, so fJustCheck dry runs (which return earlier) restore the
scheme on scope exit and real connects keep it. TestBlockValidity no
longer needs its own manual save/restore, and ConnectTip drops the outer
guard now that ConnectBlock encapsulates the decision. VerifyDB keeps an
outer guard since the chain tip isn't advanced there.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@thepastaclaw

Copy link
Copy Markdown
Author

@knst thanks — I reviewed b0a03c633d424be1fcb98568219e0c3cff477d49 and ported the approach in 894ec38717e without pulling in the unrelated newer-develop merges from that base.

What changed:

  • removed the extra untyped ConnectBlock bool from the PR
  • moved the BLS scheme commit/restore decision inside ConnectBlock (Commit() after WriteBestBlock)
  • removed the now-unneeded outer ConnectTip guard and TestBlockValidity inner guard
  • kept the VerifyDB outer guard, since it reconnects blocks without advancing the active tip
  • kept the regression test in src/test/bls_tests.cpp, per your earlier location feedback; it still covers both TestBlockValidity and full ProcessNewBlock failure paths

Downsides / adjustments I found vs directly taking the commit:

  • the commit was based on a newer develop with unrelated merges, so I manually ported only the BLS change
  • I kept deleted copy/move on the scoped guard as a small safety improvement

Validation run locally:

  • git diff --check
  • make -C src test/test_dash
  • bls_tests/v19_boundary_validation_failure_restores_bls_scheme
  • full bls_tests (17 cases)
  • focused validation suites: evo_dip3_activation_tests,validation_tests,validation_block_tests,validation_chainstate_tests,validation_chainstatemanager_tests,validation_flush_tests (24 cases)

@thepastaclaw

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/validation.cpp (1)

3055-3073: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Guard the post-ConnectBlock() failure window in ConnectTip().

ConnectBlock() now commits the switched BLS scheme before returning, but ConnectTip() can still return at Line 3073 before m_chain.SetTip() runs. If FlushStateToDisk() fails there, the active tip did not advance while bls::bls_legacy_scheme remains switched. Add an outer guard in ConnectTip() and commit it only after the tip is advanced.

Proposed fix
     {
+        ScopedBLSLegacyScheme bls_scheme_guard;
         auto dbTx = m_evoDb.BeginTransaction();
 
         CCoinsViewCache view(&CoinsTip());
         bool rv = ConnectBlock(blockConnecting, state, pindexNew, view);
         GetMainSignals().BlockChecked(blockConnecting, state);
@@
     }
@@
     // Update m_chain & related variables.
     m_chain.SetTip(*pindexNew);
+    bls_scheme_guard.Commit();
     UpdateTip(pindexNew);

If the guard must span the whole function, declare it before the inner transaction block instead of inside that block.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/validation.cpp` around lines 3055 - 3073, The issue is that
ConnectBlock() commits a BLS scheme switch before ConnectTip() advances the
chain tip via m_chain.SetTip(), creating a window where FlushStateToDisk() can
fail and leave the chain tip unchanged while the BLS scheme remains switched. To
fix this, add an outer guard (transaction/RAII object) around the ConnectBlock()
call and subsequent operations in ConnectTip(), declaring it before the inner
transaction block rather than inside it, and ensure it is only committed after
m_chain.SetTip() has successfully advanced the tip so that the BLS scheme switch
and tip advancement remain atomic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/validation.cpp`:
- Around line 3055-3073: The issue is that ConnectBlock() commits a BLS scheme
switch before ConnectTip() advances the chain tip via m_chain.SetTip(), creating
a window where FlushStateToDisk() can fail and leave the chain tip unchanged
while the BLS scheme remains switched. To fix this, add an outer guard
(transaction/RAII object) around the ConnectBlock() call and subsequent
operations in ConnectTip(), declaring it before the inner transaction block
rather than inside it, and ensure it is only committed after m_chain.SetTip()
has successfully advanced the tip so that the BLS scheme switch and tip
advancement remain atomic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 5c03bd7a-ca88-4ee0-9550-3eb0e2610d29

📥 Commits

Reviewing files that changed from the base of the PR and between 35436f0 and 894ec38.

📒 Files selected for processing (1)
  • src/validation.cpp

@thepastaclaw

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

ConnectBlock commits the BLS-scheme switch when it succeeds, but
ConnectTip can still fail at FlushStateToDisk() before m_chain.SetTip()
runs. In that window the global bls::bls_legacy_scheme would stay
switched while the active tip stayed unchanged, leaving the node in an
inconsistent state.

Add an outer ScopedBLSLegacyScheme guard at the top of ConnectTip that
spans the inner ConnectBlock and the SetTip call, and Commit() it only
after m_chain.SetTip() returns. Any early return before that point now
restores the original scheme on scope exit.

ConnectBlock keeps its own self-contained guard so direct callers
(VerifyDB, TestBlockValidity) continue to work without a bool parameter.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@thepastaclaw

Copy link
Copy Markdown
Author

Addressed in 43094d685d60053086caabfb2b6ceac0cb4c77ea — the finding was valid.

ConnectTip now has an outer ScopedBLSLegacyScheme guard spanning successful ConnectBlock through m_chain.SetTip(). The guard is committed only immediately after m_chain.SetTip(*pindexNew), so any early return before the active tip advances restores the original BLS scheme. ConnectBlock still keeps its self-contained guard for direct callers, and no untyped bool parameter was reintroduced.

Validation run locally:

  • git diff --check
  • make -C src -j15 test/test_dash
  • ./src/test/test_dash --run_test=bls_tests/v19_boundary_validation_failure_restores_bls_scheme
  • focused sweep: bls_tests,validation_tests,validation_block_tests,validation_chainstatemanager_tests,validation_flush_tests,evo_deterministicmns_tests,blockfilter_index_tests (28 cases)

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

@thepastaclaw: The dual-guard design looks well-reasoned — having ConnectBlock carry its own self-contained guard (for direct callers like TestBlockValidity and VerifyDB) while ConnectTip wraps an outer guard committed only after m_chain.SetTip(*pindexNew) cleanly closes the window where the scheme could be left in a transitional state between a successful ConnectBlock and the tip actually advancing. I'll trigger a review of the latest commit.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Code Review

Incremental review of the BLS scheme RAII guard PR. Prior review at 894ec38 had no findings, so nothing carries forward. The new delta (43094d6) adds the ScopedBLSLegacyScheme guard inside ConnectTip and commits it after m_chain.SetTip(), closing the window between ConnectBlock success and tip advancement. Guard placement, fJustCheck semantics, commit ordering in both ConnectBlock and ConnectTip, and the V19-boundary regression test all check out. No in-scope defects found.

@thepastaclaw

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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.

3 participants