Skip to content

Conversation

@PastaPastaPasta
Copy link
Member

Please remove the italicized help prompts before submitting or merging

Provide a general summary of your changes in the Title above

Pull requests without a rationale and clear improvement may be closed
immediately.

Please provide clear motivation for your patch and explain how it improves
Dash Core user experience or Dash Core developer experience
significantly:

  • Any test improvements or new tests that improve coverage are always welcome.
  • All other changes should have accompanying unit tests (see src/test/) or
    functional tests (see test/). Contributors should note which tests cover
    modified code. If no tests exist for a region of modified code, new tests
    should accompany the change.
  • Bug fixes are most welcome when they come with steps to reproduce or an
    explanation of the potential issue as well as reasoning for the way the bug
    was fixed.
  • Features are welcome, but might be rejected due to design or scope issues.
    If a feature is based on a lot of dependencies, contributors should first
    consider building the system outside of Dash Core, if possible.

Issue being fixed or feature implemented

  • Why is this change required? What problem does it solve?
  • If it fixes an open issue, please link to the issue here.

What was done?

Describe your changes in detail

How Has This Been Tested?

Please describe in detail how you tested your changes.

Include details of your testing environment, and the tests you ran
to see how your change affects other areas of the code, etc.

Breaking Changes

Please describe any breaking changes your code introduces

Checklist:

Go over all the following points, and put an x in all the boxes that apply.

  • 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)

@coderabbitai
Copy link

coderabbitai bot commented Nov 18, 2025

Walkthrough

This pull request introduces context-free basic validation functions for various special transaction types in the codebase. Specific basic validators are added for asset unlock transactions, coinbase transactions, ProTx variants (ProReg, ProUpServ, ProUpReg, ProUpRev), MNHF transactions, and LLMQ commitments. Each validates transaction type, payload presence, and version ranges. A dispatcher function CheckSpecialTxBasic routes transactions to their corresponding basic check. The CheckBlock function is updated to call this early validation on all transactions before proceeding with further block processing.

Sequence Diagram

sequenceDiagram
    participant CheckBlock
    participant CheckSpecialTxBasic
    participant SpecificBasicCheck as CheckXxxBasic()
    participant TxValidationState

    CheckBlock->>CheckBlock: for each tx in block.vtx
    CheckBlock->>CheckSpecialTxBasic: CheckSpecialTxBasic(tx, state)
    
    CheckSpecialTxBasic->>CheckSpecialTxBasic: check tx has extra_payload
    alt has extra payload
        CheckSpecialTxBasic->>TxValidationState: Invalid (TX_CONSENSUS)
        CheckSpecialTxBasic-->>CheckBlock: false
    else no extra payload
        CheckSpecialTxBasic->>CheckSpecialTxBasic: dispatch by tx.nType
        CheckSpecialTxBasic->>SpecificBasicCheck: CheckCbTxBasic/CheckProRegTxBasic/etc.
        SpecificBasicCheck->>SpecificBasicCheck: validate tx type
        SpecificBasicCheck->>SpecificBasicCheck: validate payload presence
        SpecificBasicCheck->>SpecificBasicCheck: validate version
        alt all valid
            SpecificBasicCheck-->>CheckSpecialTxBasic: true
            CheckSpecialTxBasic-->>CheckBlock: true
        else validation failed
            SpecificBasicCheck->>TxValidationState: set error state
            SpecificBasicCheck-->>CheckSpecialTxBasic: false
            CheckSpecialTxBasic-->>CheckBlock: false
        end
    end
    
    alt CheckSpecialTxBasic failed
        CheckBlock->>CheckBlock: assert TX_CONSENSUS
        CheckBlock->>CheckBlock: return BLOCK_CONSENSUS invalid
    else CheckSpecialTxBasic passed
        CheckBlock->>CheckBlock: continue block processing
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Multiple homogeneous additions across similar files: Eight files receive new basic validation function declarations/implementations following a consistent pattern (type check, payload validation, version validation).
  • Dispatcher logic in CheckSpecialTxBasic: Requires verification that all special transaction types are properly routed and error codes are correct.
  • Integration point in CheckBlock: Verify the placement and error handling when basic validation fails; ensure TX_CONSENSUS assertion is appropriate.
  • Specific areas requiring attention:
    • Version range validation logic in each basic check (ensure all use correct CURRENT_VERSION constants)
    • Dispatcher in CheckSpecialTxBasic ensures complete coverage of all special transaction types without gaps
    • Error code consistency (each basic check should return appropriate TX_CONSENSUS error strings)
    • CheckBlock integration verifies early validation doesn't break existing flow or cause unexpected blocks to be rejected

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description consists entirely of template placeholder text with empty sections and no actual implementation details, rationale, testing, or breaking changes documented. Fill in the PR description with concrete information about why the changes are needed, what was implemented, how it was tested, and any breaking changes, removing all template prompts.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title is vague and generic, using 'properly' without specifying what distinction or changes are being addressed. Revise the title to be more specific about the actual change, such as 'Add context-free basic validation functions for special transactions' or describe the specific CheckBlock/ConnectBlock distinction being implemented.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/evo/mnhftx.cpp (1)

114-131: CheckMNHFTxBasic is well‑scoped; consider reusing it in CheckMNHFTx

The new basic validator correctly enforces MNHF type, payload presence, and version range in a context‑free way with consensus errors (bad-mnhf-type, bad-mnhf-payload, bad-mnhf-version), which fits the new CheckSpecialTxBasic flow.

You now have the same three checks duplicated at the top of CheckMNHFTx; as a future cleanup, you could delegate to CheckMNHFTxBasic (or factor the common bits) to avoid drift if these rules ever evolve.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 97bd9fa and e7e9bef.

📒 Files selected for processing (13)
  • src/evo/assetlocktx.cpp (1 hunks)
  • src/evo/assetlocktx.h (1 hunks)
  • src/evo/cbtx.cpp (1 hunks)
  • src/evo/cbtx.h (1 hunks)
  • src/evo/deterministicmns.cpp (4 hunks)
  • src/evo/deterministicmns.h (1 hunks)
  • src/evo/mnhftx.cpp (1 hunks)
  • src/evo/mnhftx.h (1 hunks)
  • src/evo/specialtx.cpp (1 hunks)
  • src/evo/specialtx.h (1 hunks)
  • src/llmq/commitment.cpp (1 hunks)
  • src/llmq/commitment.h (1 hunks)
  • src/validation.cpp (1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: kwvg
Repo: dashpay/dash PR: 6543
File: src/wallet/receive.cpp:240-251
Timestamp: 2025-02-06T14:34:30.466Z
Learning: Pull request #6543 is focused on move-only changes and refactoring, specifically backporting from Bitcoin. Behavior changes should be proposed in separate PRs.
Learnt from: knst
Repo: dashpay/dash PR: 6692
File: src/llmq/blockprocessor.cpp:217-224
Timestamp: 2025-08-19T14:57:31.801Z
Learning: In PR #6692, knst acknowledged a null pointer dereference issue in ProcessBlock() method where LookupBlockIndex may return nullptr but is passed to gsl::not_null, and created follow-up PR #6789 to address it, consistent with avoiding scope creep in performance-focused PRs.
Learnt from: UdjinM6
Repo: dashpay/dash PR: 6933
File: src/llmq/utils.cpp:284-298
Timestamp: 2025-11-04T18:24:27.241Z
Learning: In consensus-critical code (such as quorum formation, block validation, or deployment activation logic), do not suggest changes to the logic itself even if the implementation appears theoretically incorrect or off-by-one. Consensus rules, once deployed on the Dash network, must be preserved exactly to avoid network forks. Refactoring PRs should maintain perfect behavioral equivalence. Only suggest logic changes if explicitly accompanied by a DIP (Dash Improvement Proposal) or if the maintainer indicates the consensus rule needs to be changed with appropriate activation logic.
Learnt from: knst
Repo: dashpay/dash PR: 6883
File: src/rpc/rawtransaction.cpp:1088-1125
Timestamp: 2025-10-13T12:37:12.357Z
Learning: In backport pull requests (especially from Bitcoin Core), treat "moved" or refactored code as out-of-scope for content-level review. Focus validation on verifying that code is moved correctly: no fields added, no fields removed, no fields reordered, and no unexpected changes beyond whitespace adjustments. Pre-existing issues in the upstream code should be preserved to maintain fidelity to the original implementation.
Learnt from: kwvg
Repo: dashpay/dash PR: 6718
File: test/functional/test_framework/test_framework.py:2102-2102
Timestamp: 2025-06-09T16:43:20.996Z
Learning: In the test framework consolidation PR (#6718), user kwvg prefers to limit functional changes to those directly related to MasternodeInfo, avoiding scope creep even for minor improvements like error handling consistency.
Learnt from: kwvg
Repo: dashpay/dash PR: 6729
File: src/evo/deterministicmns.cpp:1313-1316
Timestamp: 2025-07-09T15:02:26.899Z
Learning: In Dash's masternode transaction validation, `IsVersionChangeValid()` is only called by transaction types that update existing masternode entries (like `ProUpServTx`, `ProUpRegTx`, `ProUpRevTx`), not by `ProRegTx` which creates new entries. This means validation logic in `IsVersionChangeValid()` only applies to the subset of transaction types that actually call it, not all masternode transaction types.
Learnt from: kwvg
Repo: dashpay/dash PR: 6665
File: src/evo/providertx.h:82-82
Timestamp: 2025-06-06T11:53:09.094Z
Learning: In ProTx serialization code (SERIALIZE_METHODS), version checks should use hardcoded maximum flags (/*is_basic_scheme_active=*/true, /*is_extended_addr=*/true) rather than deployment-based flags. This is because serialization code should be able to deserialize any structurally valid ProTx up to the maximum version the code knows how to handle, regardless of current consensus validity. Validation code, not serialization code, is responsible for checking whether a ProTx version is consensus-valid based on deployment status.
📚 Learning: 2025-06-06T11:53:09.094Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6665
File: src/evo/providertx.h:82-82
Timestamp: 2025-06-06T11:53:09.094Z
Learning: In ProTx serialization code (SERIALIZE_METHODS), version checks should use hardcoded maximum flags (/*is_basic_scheme_active=*/true, /*is_extended_addr=*/true) rather than deployment-based flags. This is because serialization code should be able to deserialize any structurally valid ProTx up to the maximum version the code knows how to handle, regardless of current consensus validity. Validation code, not serialization code, is responsible for checking whether a ProTx version is consensus-valid based on deployment status.

Applied to files:

  • src/evo/cbtx.cpp
  • src/evo/cbtx.h
  • src/evo/deterministicmns.h
  • src/validation.cpp
  • src/evo/deterministicmns.cpp
  • src/evo/mnhftx.cpp
  • src/evo/specialtx.cpp
📚 Learning: 2025-07-09T15:02:26.899Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6729
File: src/evo/deterministicmns.cpp:1313-1316
Timestamp: 2025-07-09T15:02:26.899Z
Learning: In Dash's masternode transaction validation, `IsVersionChangeValid()` is only called by transaction types that update existing masternode entries (like `ProUpServTx`, `ProUpRegTx`, `ProUpRevTx`), not by `ProRegTx` which creates new entries. This means validation logic in `IsVersionChangeValid()` only applies to the subset of transaction types that actually call it, not all masternode transaction types.

Applied to files:

  • src/evo/deterministicmns.h
  • src/validation.cpp
  • src/evo/deterministicmns.cpp
  • src/evo/mnhftx.cpp
  • src/evo/specialtx.cpp
📚 Learning: 2025-11-13T20:02:55.480Z
Learnt from: UdjinM6
Repo: dashpay/dash PR: 6969
File: src/evo/deterministicmns.h:441-479
Timestamp: 2025-11-13T20:02:55.480Z
Learning: In `src/evo/deterministicmns.h`, the `internalId` field in `CDeterministicMN` and the `mnInternalIdMap` in `CDeterministicMNList` are non-deterministic and used only for internal bookkeeping and efficient lookups. Different nodes can assign different internalIds to the same masternode depending on their sync history. Methods like `IsEqual()` intentionally ignore internalId mappings and only compare consensus-critical deterministic fields (proTxHash, collateral, state, etc.).

Applied to files:

  • src/evo/deterministicmns.cpp
📚 Learning: 2025-01-07T18:50:44.838Z
Learnt from: knst
Repo: dashpay/dash PR: 6511
File: src/evo/deterministicmns.cpp:1369-1373
Timestamp: 2025-01-07T18:50:44.838Z
Learning: The functions `MigrateDBIfNeeded` and `MigrateDBIfNeeded2` in `src/evo/deterministicmns.cpp` are temporary and will be removed in a future version. Refactoring suggestions for these functions should be avoided.

Applied to files:

  • src/evo/deterministicmns.cpp
📚 Learning: 2025-10-02T18:29:54.756Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6840
File: src/net_processing.cpp:2882-2886
Timestamp: 2025-10-02T18:29:54.756Z
Learning: Across net_processing.cpp, once LLMQContext (m_llmq_ctx) is asserted non-null, its subcomponents (e.g., isman, qdkgsman, quorum_block_processor) are treated as initialized and used without extra null checks.

Applied to files:

  • src/llmq/commitment.cpp
🧬 Code graph analysis (12)
src/evo/cbtx.cpp (1)
src/validation.h (1)
  • state (169-194)
src/evo/specialtx.h (2)
src/evo/specialtx.cpp (2)
  • CheckSpecialTxBasic (17-47)
  • CheckSpecialTxBasic (17-17)
src/validation.h (1)
  • state (169-194)
src/evo/mnhftx.h (1)
src/evo/mnhftx.cpp (2)
  • CheckMNHFTxBasic (114-131)
  • CheckMNHFTxBasic (114-114)
src/evo/assetlocktx.cpp (1)
src/validation.h (1)
  • state (169-194)
src/evo/assetlocktx.h (1)
src/evo/assetlocktx.cpp (2)
  • CheckAssetUnlockTxBasic (114-140)
  • CheckAssetUnlockTxBasic (114-114)
src/evo/cbtx.h (1)
src/evo/cbtx.cpp (2)
  • CheckCbTxBasic (22-44)
  • CheckCbTxBasic (22-22)
src/llmq/commitment.h (1)
src/llmq/commitment.cpp (2)
  • CheckLLMQCommitmentBasic (216-244)
  • CheckLLMQCommitmentBasic (216-216)
src/evo/deterministicmns.h (1)
src/evo/deterministicmns.cpp (14)
  • CheckProRegTxBasic (1093-1106)
  • CheckProRegTxBasic (1093-1093)
  • CheckProRegTx (1108-1239)
  • CheckProRegTx (1108-1108)
  • CheckProUpServTxBasic (1241-1254)
  • CheckProUpServTxBasic (1241-1241)
  • CheckProUpServTx (1256-1330)
  • CheckProUpServTx (1256-1256)
  • CheckProUpRegTxBasic (1332-1345)
  • CheckProUpRegTxBasic (1332-1332)
  • CheckProUpRegTx (1347-1415)
  • CheckProUpRegTx (1347-1347)
  • CheckProUpRevTxBasic (1417-1430)
  • CheckProUpRevTxBasic (1417-1417)
src/validation.cpp (1)
src/evo/specialtx.cpp (2)
  • CheckSpecialTxBasic (17-47)
  • CheckSpecialTxBasic (17-17)
src/evo/deterministicmns.cpp (1)
src/validation.h (1)
  • state (169-194)
src/evo/specialtx.cpp (5)
src/evo/deterministicmns.cpp (8)
  • CheckProRegTxBasic (1093-1106)
  • CheckProRegTxBasic (1093-1093)
  • CheckProUpServTxBasic (1241-1254)
  • CheckProUpServTxBasic (1241-1241)
  • CheckProUpRegTxBasic (1332-1345)
  • CheckProUpRegTxBasic (1332-1332)
  • CheckProUpRevTxBasic (1417-1430)
  • CheckProUpRevTxBasic (1417-1417)
src/evo/cbtx.cpp (2)
  • CheckCbTxBasic (22-44)
  • CheckCbTxBasic (22-22)
src/llmq/commitment.cpp (2)
  • CheckLLMQCommitmentBasic (216-244)
  • CheckLLMQCommitmentBasic (216-216)
src/evo/mnhftx.cpp (2)
  • CheckMNHFTxBasic (114-131)
  • CheckMNHFTxBasic (114-114)
src/evo/assetlocktx.cpp (4)
  • CheckAssetLockTx (44-95)
  • CheckAssetLockTx (44-44)
  • CheckAssetUnlockTxBasic (114-140)
  • CheckAssetUnlockTxBasic (114-114)
src/llmq/commitment.cpp (1)
src/validation.h (1)
  • state (169-194)
🔇 Additional comments (15)
src/evo/assetlocktx.h (1)

158-158: LGTM!

The function declaration is correctly placed and consistent with the existing validation functions. The implementation in assetlocktx.cpp performs appropriate context-free validation.

src/llmq/commitment.h (1)

167-167: LGTM!

The function declaration is correctly placed and follows the established pattern for basic validation functions. The implementation performs appropriate context-free checks.

src/evo/deterministicmns.h (1)

770-777: LGTM!

All four Basic validation function declarations are correctly added and follow a consistent pattern. Each is appropriately placed before its corresponding full validation function. The implementations perform context-free validation checking transaction type and payload presence.

src/llmq/commitment.cpp (1)

216-244: LGTM!

The implementation of CheckLLMQCommitmentBasic correctly performs context-free validation:

  • Transaction type verification
  • Payload presence check
  • LLMQ type validation
  • Version range enforcement
  • Size validation for non-null commitments

All checks are appropriately context-free and error messages are consistent with the codebase.

src/evo/mnhftx.h (1)

172-172: LGTM!

The function declaration is correctly placed and consistent with other Basic validation functions in the PR. The implementation performs appropriate context-free validation.

src/evo/cbtx.cpp (1)

22-44: LGTM!

The implementation of CheckCbTxBasic correctly performs context-free validation:

  • Coinbase transaction verification
  • Transaction type check
  • Payload presence validation
  • Version range enforcement

All checks are appropriately context-free and consistent with other Basic validation functions in this PR.

src/evo/specialtx.cpp (1)

8-47: Centralized basic special-tx precheck looks consistent and context-free

CheckSpecialTxBasic cleanly gates on HasExtraPayloadField() and then dispatches by tx.nType to the appropriate *Basic function (or CheckAssetLockTx), with a conservative default of rejecting unknown types via "bad-tx-type". The implementation stays context-free and mirrors the per-type basic validators added elsewhere, which fits the intended CheckBlock-vs-ConnectBlock split.

src/evo/cbtx.h (1)

71-71: Basic CBTx validator declaration matches usage

The CheckCbTxBasic declaration is correctly typed, aligned with the implementation in cbtx.cpp, and placed coherently next to CheckCbTx, keeping the public validation API consistent.

src/evo/assetlocktx.cpp (1)

114-140: Asset unlock basic validator mirrors full checks; confirm result-category choice

CheckAssetUnlockTxBasic intentionally mirrors the structural checks in CheckAssetUnlockTx (type, no inputs, max outputs, payload presence, version range) while staying context-free, which fits the new “Basic” validation layer. The main behavioral difference is the use of TxValidationResult::TX_CONSENSUS here vs TX_BAD_SPECIAL in the full check for the same error strings—if that distinction is meaningful for how callers classify failures, it’d be good to double‑check that this is the intended split.

src/evo/deterministicmns.cpp (4)

1093-1106: CheckProRegTxBasic provides minimal, context-free ProReg validation

This basic ProReg validator keeps to type + payload presence checks with consensus error codes and no chainstate dependencies, matching the pattern used by other ProTx validation helpers and making it safe to call from CheckBlock.


1241-1254: CheckProUpServTxBasic aligns with the ProTx basic-validation pattern

The service-update basic check mirrors CheckProRegTxBasic: it enforces the expected special-tx type and payload presence only, deferring all stateful and version-change logic to the full CheckProUpServTx path. This is appropriate for a context-free precheck.


1332-1345: CheckProUpRegTxBasic cleanly splits structural from stateful checks

For ProUpReg, the basic validator correctly limits itself to tx.nType and payload existence checks and reuses the standard "bad-protx-type" / "bad-protx-payload" errors, keeping behavior consistent with the other ProTx flows while enabling early rejection in CheckBlock.


1417-1430: CheckProUpRevTxBasic completes the ProTx basic-validator set

The revocation basic check follows the same minimal, context-free pattern as the other ProTx basic validators, giving CheckBlock a uniform way to reject malformed ProUpRev transactions before touching masternode state.

src/validation.cpp (1)

4029-4039: Good separation of context‑free special‑tx checks into CheckBlock

Running CheckSpecialTxBasic over block.vtx here cleanly extends the existing context‑free CheckBlock semantics and correctly maps any basic special‑tx failure to a BLOCK_CONSENSUS invalid, with an assertion guarding that only TX_CONSENSUS results are produced.

Please double‑check that all Check*TxBasic callees reachable from CheckSpecialTxBasic remain strictly context‑free (no chain/mempool access) and only ever mark TxValidationResult::TX_CONSENSUS, so the new assertion and error mapping stay valid over time.

src/evo/specialtx.h (1)

17-20: Header API for CheckSpecialTxBasic looks consistent

Forward‑declaring TxValidationState and exposing CheckSpecialTxBasic(const CTransaction&, TxValidationState&) here cleanly matches the implementation and keeps dependencies minimal.

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.

1 participant