Skip to content

Speed up DIP3 and Spark reindex validation safely#1866

Open
navidR wants to merge 19 commits into
firoorg:masterfrom
navidR:dev/navidr/reindex-speedup
Open

Speed up DIP3 and Spark reindex validation safely#1866
navidR wants to merge 19 commits into
firoorg:masterfrom
navidR:dev/navidr/reindex-speedup

Conversation

@navidR

@navidR navidR commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Overall this PR should result in -reindex process 2x-3x faster.

  1. This PR speeds up early -reindex around the DIP3 deterministic masternode activation window by avoiding redundant cbTx masternode-list merkle-root work. During block connection, Firo already builds the deterministic masternode list and diff for the block; the patch reuses that freshly computed list for cbTx MN merkle validation, and skips rebuilding the simplified MN-list merkle root when a diff only changes fields that are not serialized into CSimplifiedMNListEntry. Consensus-relevant MN changes still force recomputation.

  2. For Spark-heavy reindex, this PR defers Spark spend proof verification during raw block import and batch-verifies proofs before validation state is persisted, while preserving fail-closed behavior. It also avoids rebuilding unnecessary full cover sets for Grootle batch checks, keeps proof-cache entries tied to exact proof inputs, verifies deferred batches before flush/shutdown/reindex completion, and gates high-volume Spark validation trace logs behind -debug=validation to reduce log I/O during reindex.

First part of this PR already evaluated/approved by @levonpetrosyan93 at #1864

navidR added 15 commits June 15, 2026 16:29
Keep non-wallet VerifyDB paths from honoring fVerifySparkSpendProof=false for Spark spend proofs, while preserving wallet DB load behavior by marking that call as wallet validation. Extend the Spark tampered-proof regression test to cover both paths.
Do not mark non-stateful CheckBlock results as fully cached for blocks containing Spark spends. This keeps default proof verification and VerifyDB behavior intact while preventing soft-passed Spark proof-input cases from poisoning block.fChecked.\n\nAdd Spark regressions for VerifyDB cache bypass, wallet-load cheap validation with proof skipping, and BatchProofContainer collection around tampered spends.
@navidR

navidR commented Jun 17, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

This PR refactors Spark spend proof verification to support deferred, batched, and context-scoped validation via a new CSparkValidationContext and SparkSpendProofVerificationResult enum. It reworks BatchProofContainer cover-set construction and exception safety, fixes the Grootle batch verifier MSM data layout, adds a CDeterministicMNManager::ScopedCacheRestorer RAII guard with granular CbTx merkle root caching, wires all changes through ConnectBlock/VerifyDB/init.cpp, and extends unit and integration tests for all affected paths.

Changes

Spark Proof Pipeline and DIP3 Cache Fixes

Layer / File(s) Summary
Grootle batch verifier MSM layout and MultiExponent error handling
src/libspark/grootle.cpp, src/libspark/spend_transaction.cpp, src/secp256k1/src/cpp/MultiExponent.cpp, src/libspark/test/grootle_test.cpp
Grootle::verify now emits S and V as separate MSM terms instead of a precomputed combined array, adds per-proof set-size bounds checks, and precomputes I_last. SpendTransaction::verify adds cover-set size bounds validation. MultiExponent::get_multiple throws std::runtime_error on scratch allocation or computation failure. Tests added for boundary sizes and mutations.
Spark validation context types and SparkName notify gating
src/spark/state.h, src/sparkname.h, src/sparkname.cpp
Declares CSparkValidationContext, SparkSpendProofVerificationResult, and extends CSparkState constructor/Reset with fShutdownWalletOnReset. CSparkNameManager::AddBlock/RemoveBlock gain fNotify parameter to suppress UI notifications during non-interactive verification.
Spark proof-input-hash caching and CheckSparkSpendTransaction rework
src/spark/state.cpp
Introduces ProofCheckState with proofInputHash, SparkBlockIndexDataBackup, GetSparkSpendProofInputHash, and validation-scoped helpers. CheckSparkSpendTransaction gains fVerifySparkSpendProof, SparkSpendProofVerificationResult*, and CSparkValidationContext*; routes results to Verified/Batched/Deferred via a new setProofResult helper and invalidates stale cache entries by hash.
ConnectBlockSpark with validation-scoped state
src/spark/state.cpp
ConnectBlockSpark gains fVerifyDB and sparkValidationContext; all spend/LTag/mint/name updates route through GetValidationSparkState/GetValidationSparkNameManager instead of global singletons; adds metadata mismatch detection via SparkBlockIndexDataBackup.
BatchProofContainer clear, verify exception safety, and batch_spark cover-set rework
src/batchproof_container.h, src/batchproof_container.cpp
Adds clear() to reset collection state; verify() calls clear() inside a catch before rethrowing. batch_spark() replaces the one-pass cover-set approach with a two-phase computation: derives per-cover-set maxHeight with ancestry validation, then populates cover_sets via GetCoinSetForSpend.
DeterministicMN ScopedCacheRestorer, HasCbTxMerkleRootChanges, and CbTx merkle root caching
src/evo/deterministicmns.h, src/evo/deterministicmns.cpp, src/evo/cbtx.h, src/evo/cbtx.cpp, src/evo/specialtx.cpp, src/dsnotificationinterface.cpp
CDeterministicMNList gains HasSameMNMap; CDeterministicMNListDiff gains HasCbTxMerkleRootChanges. CDeterministicMNManager adds ScopedCacheRestorer RAII and scopedCacheRestorerDepth; ProcessBlock gains newListRet/cbTxMerkleRootMNListChangedRet out-parameters. CalcCbTxMerkleRootMNList gains a CDeterministicMNList overload with multi-artifact caching. dsnotificationinterface moves UpdatedBlockTip before the pindexFork early-return.
Validation pipeline wiring
src/validation.h, src/validation.cpp, src/wallet/walletdb.cpp
Adds VerifyPendingSparkBatch, CanDeferSparkSpendProofVerificationOnImport; extends CheckTransaction/ConnectBlock/CheckBlock/AcceptBlock with Spark proof parameters; ConnectBlock adds SparkBatchCleanup RAII and finalizes batched proofs before persistent state; VerifyDB adds ScopedCacheRestorer scope and builds a Spark validation context for level-4 reconnect. walletdb.cpp callsite updated.
init.cpp Spark batch integration and reindex flag error handling
src/init.cpp
Shutdown calls VerifyPendingSparkBatch under cs_main; ThreadImport verifies pending Spark batch before clearing the reindex flag; AppInitMain error-checks WriteReindexing(true) and updates genesis wait logic.
Unit and integration tests
src/libspark/test/groot le_test.cpp, src/test/evo_deterministicmns_tests.cpp, src/test/evo_simplifiedmns_tests.cpp, src/test/spark_tests.cpp, src/test/sparkname_tests.cpp, qa/rpc-tests/dip3-deterministicmns.py
Adds boundary_sizes_and_mutations for Grootle; DIP3 tests for MN list correctness after invalidation, cache boundaries, VerifyDB reconnect, and concurrent readers; deterministicmn_diff_cbtx_merkle_relevance; import_spark_proof_deferral_policy, extended checktransaction, verifydb_level4_connected_spark_spend_preserves_spark_state, verifydb_level4_spark_name_transfer_uses_readonly_mode; assert_mnlist_now for immediate post-invalidation checks.

Sequence Diagram(s)

sequenceDiagram
  participant AcceptBlock
  participant CheckBlock
  participant CheckTransaction
  participant ConnectBlock
  participant SparkBatchCleanup
  participant BatchProofContainer
  participant ConnectBlockSpark
  participant VerifyDB

  AcceptBlock->>AcceptBlock: CanDeferSparkSpendProofVerificationOnImport(...)
  AcceptBlock->>CheckBlock: CheckBlock(..., fDeferSparkSpendProofVerification)
  CheckBlock->>CheckTransaction: per-tx, fVerifySparkSpendProof, sparkSpendProofResult
  CheckTransaction-->>CheckBlock: SparkSpendProofVerificationResult (Verified/Deferred/Batched)
  CheckBlock-->>AcceptBlock: fChecked only if all proofs complete

  AcceptBlock->>ConnectBlock: ConnectBlock(..., fVerifyDB, sparkValidationContext)
  ConnectBlock->>SparkBatchCleanup: construct (RAII cleanup guard)
  ConnectBlock->>CheckTransaction: fVerifySparkSpendProof=true, sparkValidationContext
  CheckTransaction->>BatchProofContainer: collect batched proof
  ConnectBlock->>BatchProofContainer: finalize() + verify()
  alt batch verify fails
    BatchProofContainer-->>ConnectBlock: exception
    ConnectBlock->>ConnectBlock: DoS bad-txns-sparkproof
  else batch verify ok
    ConnectBlock->>SparkBatchCleanup: dismiss()
    ConnectBlock->>ConnectBlockSpark: sparkValidationContext
    ConnectBlockSpark->>ConnectBlockSpark: route state through CSparkValidationContext
  end

  VerifyDB->>VerifyDB: ScopedCacheRestorer (scopes MN cache mutations)
  VerifyDB->>VerifyDB: build Spark validation context
  VerifyDB->>ConnectBlock: level-4 reconnect with sparkValidationContext
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • firoorg/firo#1818: Directly modifies DIP3Test in qa/rpc-tests/dip3-deterministicmns.py to add timeout-based polling assertions, which is the counterpart to this PR's assert_mnlist_now immediate-check helper.
  • firoorg/firo#1805: Modifies BatchProofContainer in src/batchproof_container.cpp to strip Lelantus batching, directly preceding this PR's rework of clear(), verify() exception handling, and batch_spark() cover-set construction.
  • firoorg/firo#1787: Modifies CheckSparkSpendTransaction and spend-proof caching logic in src/spark/state.cpp, overlapping directly with this PR's proof-input-hash caching and SparkSpendProofVerificationResult flow.

Suggested reviewers

  • psolstice
  • levonpetrosyan93
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.31% 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 accurately summarizes the PR's main objectives: speeding up DIP3 and Spark reindex validation. It is concise, specific, and clearly conveys the primary change.
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.
Description check ✅ Passed PR description clearly explains optimization goals, implementation approach, and measured performance improvements across different block ranges.

✏️ 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.

@navidR

navidR commented Jun 17, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor
✅ 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 added size:XL This PR changes 500-999 lines, ignoring generated files Spark labels Jun 17, 2026

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 4

Caution

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

⚠️ Outside diff range comments (1)
src/libspark/test/grootle_test.cpp (1)

65-71: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix undefined writes in legacy root construction paths.

Line 69 and Line 143 call reserve() and then write via root.data() without sizing the vector first. That is undefined behavior and can make tests flaky.

🛠️ Proposed fix
-        Scalar temp;
-        temp.randomize();
-        std::vector<unsigned char> root;
-        root.reserve(SCALAR_ENCODING);
-        temp.serialize(root.data());
-        roots.emplace_back(root);
+        roots.emplace_back(random_root());

Apply the same replacement in both loops.

Also applies to: 138-144

🤖 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/libspark/test/grootle_test.cpp` around lines 65 - 71, The code in the
legacy root construction paths calls reserve() on the root vector and then
writes to root.data() without properly sizing the vector, which causes undefined
behavior. Replace the reserve() call with resize() passing SCALAR_ENCODING as
the argument to properly set the vector size before writing data via
root.data(). This fix needs to be applied in both locations mentioned: the first
occurrence around lines 65-71 where temp.serialize(root.data()) is called, and
the second occurrence around lines 138-144 where the same pattern occurs.
🧹 Nitpick comments (2)
src/spark/state.cpp (1)

1000-1009: 💤 Low value

Cache eviction clears entire cache on limit.

The current strategy clears the entire proof cache when it reaches 10,000 entries. During sustained reindex of Spark-heavy blocks, this could cause temporary performance degradation from repeated cache thrashing.

Consider an LRU eviction policy or removing the oldest entries instead of clearing the entire cache, though this is acceptable for the current optimization goals.

🤖 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/spark/state.cpp` around lines 1000 - 1009, In the cache management block
where gCheckedSparkSpendTransactions reaches MAX_CACHED_SPARK_SPEND_PROOFS,
replace the current clear() operation with an LRU (Least Recently Used) eviction
strategy that removes only the oldest entry instead of clearing the entire
cache. This prevents the cache thrashing issue during sustained reindex
operations by maintaining a partial cache rather than losing all entries at
once. Implement this by removing just one or a few of the least recently used
entries from gCheckedSparkSpendTransactions instead of calling clear() on the
entire collection.
src/validation.cpp (1)

2711-2725: ⚡ Quick win

Apply Linux brace style to changed definitions.

struct SparkBatchCleanup and CheckBlock place the opening brace on the declaration line. As per coding guidelines, C++ code should use Linux brace style: new line for classes and function definitions.

♻️ Proposed style fix
-    struct SparkBatchCleanup {
+    struct SparkBatchCleanup
+    {
-bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW, bool fCheckMerkleRoot, int nHeight, bool isVerifyDB, bool fDeferSparkSpendProofVerification) {
+bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW, bool fCheckMerkleRoot, int nHeight, bool isVerifyDB, bool fDeferSparkSpendProofVerification)
+{

Also applies to: 4201-4201

🤖 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 2711 - 2725, The struct SparkBatchCleanup
definition does not follow Linux brace style where the opening brace should be
placed on a new line instead of at the end of the struct declaration line. Move
the opening brace of struct SparkBatchCleanup to a new line so the struct name
and opening brace are on separate lines. Apply the same formatting fix to the
CheckBlock struct definition mentioned at line 4201 to maintain consistent code
style throughout the file.

Source: Coding guidelines

🤖 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/init.cpp`:
- Around line 767-788: The early return statements in the reindex cleanup block
do not signal the genesis wait condition variable before exiting, which can
cause deadlock if the genesis wait path is waiting on condvar_GenesisWait.
Before each of the four early return statements (after ActivateBestChain fails,
after ShutdownRequested check, after VerifyPendingSparkBatch fails, and after
WriteReindexing fails), ensure the genesis wait condition variable is signaled
to wake up any threads waiting on it. This prevents the initialization from
blocking indefinitely when the reindex cleanup path exits early.

In `@src/test/spark_tests.cpp`:
- Around line 834-837: The MobileArgGuard struct's destructor is hard-coding the
`-mobile` argument to "0" instead of restoring its original state, which causes
test pollution. Modify the MobileArgGuard struct to capture the original value
of `-mobile` in the constructor (before setting it to "1"), then restore that
original value in the destructor instead of forcing it to "0". This ensures the
global argument state is properly restored to its pre-test condition rather than
leaving it in a fixed state that affects subsequent tests.

In `@src/validation.cpp`:
- Around line 2846-2851: After the successful verify() call in the
batchProofContainer verification block, call batchProofContainer->clear() before
dismissing the sparkBatchCleanup guard. This ensures that the temporary proof
state variables (fCollectProofs, tempSparkTransactions, and sparkTransactions)
are properly reset after verification completes, preventing state contamination
for subsequent validations or flush batches.

In `@src/validation.h`:
- Around line 55-58: The namespace spark block in validation.h (lines 55-58) is
missing a forward declaration for CSparkValidationContext, which is used as a
pointer type at lines 427 and 559. Add a forward declaration for class
CSparkValidationContext in the existing namespace spark block alongside the
other forward declarations (CSparkTxInfo and SparkSpendProofVerificationResult)
to resolve the compile failures in translation units that include validation.h
without transitively including spark/state.h.

---

Outside diff comments:
In `@src/libspark/test/grootle_test.cpp`:
- Around line 65-71: The code in the legacy root construction paths calls
reserve() on the root vector and then writes to root.data() without properly
sizing the vector, which causes undefined behavior. Replace the reserve() call
with resize() passing SCALAR_ENCODING as the argument to properly set the vector
size before writing data via root.data(). This fix needs to be applied in both
locations mentioned: the first occurrence around lines 65-71 where
temp.serialize(root.data()) is called, and the second occurrence around lines
138-144 where the same pattern occurs.

---

Nitpick comments:
In `@src/spark/state.cpp`:
- Around line 1000-1009: In the cache management block where
gCheckedSparkSpendTransactions reaches MAX_CACHED_SPARK_SPEND_PROOFS, replace
the current clear() operation with an LRU (Least Recently Used) eviction
strategy that removes only the oldest entry instead of clearing the entire
cache. This prevents the cache thrashing issue during sustained reindex
operations by maintaining a partial cache rather than losing all entries at
once. Implement this by removing just one or a few of the least recently used
entries from gCheckedSparkSpendTransactions instead of calling clear() on the
entire collection.

In `@src/validation.cpp`:
- Around line 2711-2725: The struct SparkBatchCleanup definition does not follow
Linux brace style where the opening brace should be placed on a new line instead
of at the end of the struct declaration line. Move the opening brace of struct
SparkBatchCleanup to a new line so the struct name and opening brace are on
separate lines. Apply the same formatting fix to the CheckBlock struct
definition mentioned at line 4201 to maintain consistent code style throughout
the file.
🪄 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: a5d1673d-a5aa-4e67-b568-323429fcd23f

📥 Commits

Reviewing files that changed from the base of the PR and between 7fabe1e and 43ada17.

📒 Files selected for processing (25)
  • qa/rpc-tests/dip3-deterministicmns.py
  • src/batchproof_container.cpp
  • src/batchproof_container.h
  • src/dsnotificationinterface.cpp
  • src/evo/cbtx.cpp
  • src/evo/cbtx.h
  • src/evo/deterministicmns.cpp
  • src/evo/deterministicmns.h
  • src/evo/specialtx.cpp
  • src/init.cpp
  • src/libspark/grootle.cpp
  • src/libspark/spend_transaction.cpp
  • src/libspark/test/grootle_test.cpp
  • src/secp256k1/src/cpp/MultiExponent.cpp
  • src/spark/state.cpp
  • src/spark/state.h
  • src/sparkname.cpp
  • src/sparkname.h
  • src/test/evo_deterministicmns_tests.cpp
  • src/test/evo_simplifiedmns_tests.cpp
  • src/test/spark_tests.cpp
  • src/test/sparkname_tests.cpp
  • src/validation.cpp
  • src/validation.h
  • src/wallet/walletdb.cpp

Comment thread src/init.cpp
Comment thread src/test/spark_tests.cpp
Comment on lines +834 to +837
struct MobileArgGuard {
MobileArgGuard() { ForceSetArg("-mobile", "1"); }
~MobileArgGuard() { ForceSetArg("-mobile", "0"); }
} mobileArgGuard;

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Restore -mobile to its original state instead of forcing "0" on teardown.

Line 836 hard-codes -mobile to "0" in the destructor. That leaks global arg state into later tests (especially when prior state was unset or nonzero), which can cause order-dependent behavior.

🤖 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/spark_tests.cpp` around lines 834 - 837, The MobileArgGuard struct's
destructor is hard-coding the `-mobile` argument to "0" instead of restoring its
original state, which causes test pollution. Modify the MobileArgGuard struct to
capture the original value of `-mobile` in the constructor (before setting it to
"1"), then restore that original value in the destructor instead of forcing it
to "0". This ensures the global argument state is properly restored to its
pre-test condition rather than leaving it in a fixed state that affects
subsequent tests.

Comment thread src/validation.cpp
Comment on lines +2846 to +2851
if (batchProofContainer->fCollectProofs) {
try {
batchProofContainer->finalize();
batchProofContainer->verify();
sparkBatchCleanup.dismiss();
}

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Reset the Spark batch container on the successful path.

The success path verifies the singleton batch and then dismisses the RAII cleanup, so this scope never calls clear(). That leaves fCollectProofs/temporary proof state dependent on verify() internals and can contaminate the next validation or flush batch. Clear after successful verification, or leave the cleanup guard armed. Based on provided PR context, BatchProofContainer::clear() resets tempSparkTransactions, sparkTransactions, and fCollectProofs.

🐛 Proposed fix
         try {
             batchProofContainer->finalize();
             batchProofContainer->verify();
+            batchProofContainer->clear();
             sparkBatchCleanup.dismiss();
         }
🤖 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 2846 - 2851, After the successful verify()
call in the batchProofContainer verification block, call
batchProofContainer->clear() before dismissing the sparkBatchCleanup guard. This
ensures that the temporary proof state variables (fCollectProofs,
tempSparkTransactions, and sparkTransactions) are properly reset after
verification completes, preventing state contamination for subsequent
validations or flush batches.

Comment thread src/validation.h
Comment on lines +55 to +58
namespace spark {
class CSparkTxInfo;
enum class SparkSpendProofVerificationResult;
} // namespace spark

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.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Inspect spark forward declarations in validation.h"
rg -n -C2 'namespace spark|CSparkTxInfo|CSparkValidationContext|SparkSpendProofVerificationResult' src/validation.h

echo
echo "Locate concrete CSparkValidationContext declaration"
rg -n -C2 'class CSparkValidationContext|struct CSparkValidationContext' src/spark/state.h

Repository: firoorg/firo

Length of output: 1481


Forward-declare spark::CSparkValidationContext in validation.h.

Lines 427 and 559 use spark::CSparkValidationContext*, but this type is not forward-declared in the namespace spark block (lines 55-58). This causes compile failures in translation units that include validation.h without a transitive include of spark/state.h.

💡 Proposed fix
 namespace spark {
 class CSparkTxInfo;
+struct CSparkValidationContext;
 enum class SparkSpendProofVerificationResult;
 } // namespace spark
🤖 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.h` around lines 55 - 58, The namespace spark block in
validation.h (lines 55-58) is missing a forward declaration for
CSparkValidationContext, which is used as a pointer type at lines 427 and 559.
Add a forward declaration for class CSparkValidationContext in the existing
namespace spark block alongside the other forward declarations (CSparkTxInfo and
SparkSpendProofVerificationResult) to resolve the compile failures in
translation units that include validation.h without transitively including
spark/state.h.

@navidR navidR marked this pull request as ready for review June 17, 2026 16:07

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
src/init.cpp (1)

833-839: 💤 Low value

Post-failure execution continues without early return.

After ActivateBestChain fails, the code calls NotifyGenesisWaitFailure() and StartShutdown() but does not return, so subsequent initialization code (masternode init, mempool loading, etc. on lines 850-866) still executes. While ShutdownRequested() is set, this differs from the explicit early returns in the reindex block above.

Consider adding an early return after StartShutdown() for consistency, or verify that the subsequent operations are safe to execute in this failure state.

♻️ Optional: Add early return for consistency
 if (!ActivateBestChain(state, chainparams)) {
     LogPrintf("Failed to connect best block");
     NotifyGenesisWaitFailure();
     StartShutdown();
+    return;
 }
🤖 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/init.cpp` around lines 833 - 839, The ActivateBestChain failure block in
the initialization sequence calls NotifyGenesisWaitFailure() and StartShutdown()
but does not return early, allowing subsequent initialization code (masternode
init, mempool loading, etc.) to continue executing. This is inconsistent with
error handling patterns in the reindex block above. Add an early return
statement immediately after the StartShutdown() call within the
!ActivateBestChain conditional block to prevent further initialization code from
executing when this critical failure occurs.
🤖 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/init.cpp`:
- Around line 833-839: The ActivateBestChain failure block in the initialization
sequence calls NotifyGenesisWaitFailure() and StartShutdown() but does not
return early, allowing subsequent initialization code (masternode init, mempool
loading, etc.) to continue executing. This is inconsistent with error handling
patterns in the reindex block above. Add an early return statement immediately
after the StartShutdown() call within the !ActivateBestChain conditional block
to prevent further initialization code from executing when this critical failure
occurs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: a5709e3e-2dbb-48b3-b7c4-2918a622798e

📥 Commits

Reviewing files that changed from the base of the PR and between 43ada17 and 152bb44.

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

@codeant-ai

codeant-ai Bot commented Jun 18, 2026

Copy link
Copy Markdown

User rahimi.nv@gmail.com does not have a PR Review subscription.

Go to Team management and add this email to the PR Review subscription.

@justanwar

Copy link
Copy Markdown
Member

Reindex on master 2fade3d: 27 hours 17 minutes
Reindex on this branch 84982a0: 9 hours 20 minutes

Comment thread src/libspark/grootle.cpp
bind_weight.randomize();
}

// Bind the commitment lists

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.

Please make a benchmark comparison with the changes in this .cpp versus without those changes. The changes actually look reasonable and simplify the code, but our Multiexponent algorithm complexity is not linear, so we need to understand the impact of this. In case it's not much or even makes the performance worse, please revert the changes, as this is a very critical part.

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.

Sure. Thanks for your comment. I am running the benchmarks. Will put the results here once finished. It will take few hours though.

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

Labels

size:XL This PR changes 500-999 lines, ignoring generated files Spark

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants