Skip to content

refactor: remove Bitcoin's specific workarounds around BIP30/BIP34#7335

Draft
knst wants to merge 4 commits into
dashpay:developfrom
knst:bip-30-cleanup
Draft

refactor: remove Bitcoin's specific workarounds around BIP30/BIP34#7335
knst wants to merge 4 commits into
dashpay:developfrom
knst:bip-30-cleanup

Conversation

@knst
Copy link
Copy Markdown
Collaborator

@knst knst commented May 25, 2026

Issue being fixed or feature implemented

Bitcoin Core has workarounds for BIP30/BIP34 historical blocks; this workaround is irrelevant for Dash Core.

What was done?

Removed Bitcoin Core exceptions from validation for Dash Core.
Removed bip30 counter from RPC output gettxoutsetinfo which is always 0 for dash core.

Though, we can't fully remove checks from validation.cpp same as it is done in PIVX (PIVX-Project#1775) because we had 951 blocks at mainnet and 76 blocks on testnet before BIP34 has been activated and this check is still used for validation of old blocks.

How Has This Been Tested?

Run scan-pre-bip34-coinbases.py to find a blocks that violates bip34 safety measures before bip34 is activated for both main and testnet.

$ ./scan-pre-bip34-coinbases.py --network=test --datadir=/DASH/.dashcore
Scanning test heights 1..75 (BIP34Height=76)  @ http://127.0.0.1:19998/

Scanned 75 blocks (heights 1..75, BIP34Height=76).
  0 candidate future-collision targets (indicated height > BIP34Height).
  1 scriptSigs not minimally encoding any integer.
    These are safe ONLY IF the decoder above is exhaustive -- please eyeball:
      h=    16  scriptSig=0110062f503253482f042c51615308f800000402000000102f7374726174756d2d7365727665722f

RESULT: No pre-BIP34 coinbase has a leading minimal CScriptNum > BIP34Height.
        Assuming the decoder is correct (verify against the unparseable list),
        BIP30 enforcement is unreachable on this chain.

$ ./scan-pre-bip34-coinbases.py --network=main --datadir=/DASH/.dashcore
Scanning main heights 1..950 (BIP34Height=951)  @ http://127.0.0.1:9998/

Scanned 950 blocks (heights 1..950, BIP34Height=951).
  0 candidate future-collision targets (indicated height > BIP34Height).
  0 scriptSigs not minimally encoding any integer.
    These are safe ONLY IF the decoder above is exhaustive -- please eyeball:

RESULT: No pre-BIP34 coinbase has a leading minimal CScriptNum > BIP34Height.
        Assuming the decoder is correct (verify against the unparseable list),
        BIP30 enforcement is unreachable on this chain.

Extra double check is call of gettxoutsetinfo none to be sure that bip30 is 0 for main and testnets:

$ gettxoutsetinfo none
{
  "height": 2476080,
  "bestblock": "0000000000000010ee3a3763bed9f1b5ec25e08d0594749a968636b714d0924b",
  "txouts": 4514705,
  "bogosize": 339509165,
  "total_amount": 12710996.18871387,
  "total_unspendable_amount": -740940.11336565,
  "block_info": {
    "prevout_spent": 6.93831412,
    "coinbase": 1.27251741,
    "new_outputs_ex_coinbase": 6.93814597,
    "unspendable": 0.49787579,
    "unspendables": {
      "genesis_block": 0.00000000,
      "bip30": 0.00000000,
      "scripts": 0.49787579,
      "unclaimed_rewards": 0.00000000
    }
  }
}

Breaking Changes

Removed rpc field bip30 from RPC gettxoutsetinfo

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

@knst knst added this to the 24 milestone May 25, 2026
@knst knst requested review from PastaPastaPasta and UdjinM6 May 25, 2026 06:51
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 25, 2026

✅ No Merge Conflicts Detected

This PR currently has no conflicts with other open PRs.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1bac78340c

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/validation.cpp Outdated

if (fEnforceBIP30) {
//Only continue to enforce if we're below BIP34 activation height
if (fEnforceBIP30 || pindex->nHeight <= m_params.GetConsensus().BIP34Height) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Gate BIP30 checks to pre-BIP34 heights

fEnforceBIP30 is hardcoded to true and then combined with || in the guard, so the BIP30 duplicate-output scan now runs for every block rather than only around pre-BIP34 history as the comment describes. This reintroduces unnecessary HaveCoin lookups during normal sync/validation and can noticeably degrade IBD performance on production nodes.

Useful? React with 👍 / 👎.

@knst knst added the RPC Some notable changes to RPC params/behaviour/descriptions label May 25, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

Review Change Stack

Walkthrough

This PR removes BIP30 duplicate-transaction-ID consensus logic from the Dash codebase. The changes eliminate the BIP34Hash consensus parameter, delete helper functions that detected BIP30 repeat blocks and unspendable coinbases, simplify block validation logic in DisconnectBlock and ConnectBlock to remove BIP30-specific exception handling, and update RPC endpoints and coin stats index to track only Genesis block unspendables rather than BIP30 unspendables. All network chain parameters (mainnet, testnet, regtest) are updated accordingly.

sequenceDiagram
  participant Block as Block
  participant Connect as CChainState::ConnectBlock
  participant CoinsDB as UTXO_DB
  participant CoinStats as CoinStatsIndex::WriteBlock
  participant RPC as gettxoutsetinfo/getblockstats

  Block->>Connect: apply block (validation & overwrite checks)
  Connect->>CoinsDB: update UTXO set (apply txins/txouts)
  Connect->>CoinStats: notify/WriteBlock (index updates per-vout only)
  CoinStats->>CoinsDB: read coin changes (compute unspendables)
  RPC->>CoinStats: query block_info.unspendables (returns genesis_block only)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested reviewers

  • UdjinM6
  • PastaPastaPasta
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% 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 summarizes the main change: removal of Bitcoin's BIP30/BIP34-specific workarounds that are irrelevant to Dash Core, which is the primary focus across all modified files.
Description check ✅ Passed The description is directly related to the changeset, explaining the issue being fixed (irrelevant Bitcoin workarounds), what was done (removing BIP30/BIP34 exceptions), testing methodology, and noting breaking changes.
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.

Copy link
Copy Markdown

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

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

2373-2382: ⚡ Quick win

Remove the dead fEnforceBIP30 branch.

Line 2375 hardcodes fEnforceBIP30 to true, so Line 2382 is unconditional and the BIP34-height clause never affects behavior. The surrounding comments now describe logic the code no longer has, which is easy to misread in a consensus path.

Proposed cleanup
-    // This prevents exploiting the issue against nodes during their
-    // initial block download.
-    bool fEnforceBIP30 = true;
-
-    // Once BIP34 activated it was not possible to create new duplicate coinbases and thus other than starting
-    // with the 2 existing duplicate coinbase pairs, not possible to create overwriting txs.
-    // If we're on the known chain at height greater than where BIP34 activated, we can save the db accesses needed for the BIP30 check.
-    assert(pindex->pprev);
-    //Only continue to enforce if we're below BIP34 activation height
-    if (fEnforceBIP30 || pindex->nHeight <= m_params.GetConsensus().BIP34Height) {
+    // Dash enforces the duplicate-txid overwrite check unconditionally.
+    assert(pindex->pprev);
+    {
         for (const auto& tx : block.vtx) {
             for (size_t o = 0; o < tx->vout.size(); o++) {
                 if (view.HaveCoin(COutPoint(tx->GetHash(), o))) {
🤖 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 2373 - 2382, Remove the dead fEnforceBIP30
branch: delete the hardcoded declaration of fEnforceBIP30 and replace the
combined condition if (fEnforceBIP30 || pindex->nHeight <=
m_params.GetConsensus().BIP34Height) with a single check that uses only the
BIP34 height clause (e.g. if (pindex->nHeight <=
m_params.GetConsensus().BIP34Height) { ... }). Also tidy up the surrounding
comments that reference the removed flag so the code and comments reflect the
actual consensus check; keep existing references to pindex and
m_params.GetConsensus().BIP34Height.
🤖 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/validation.cpp`:
- Around line 2373-2382: Remove the dead fEnforceBIP30 branch: delete the
hardcoded declaration of fEnforceBIP30 and replace the combined condition if
(fEnforceBIP30 || pindex->nHeight <= m_params.GetConsensus().BIP34Height) with a
single check that uses only the BIP34 height clause (e.g. if (pindex->nHeight <=
m_params.GetConsensus().BIP34Height) { ... }). Also tidy up the surrounding
comments that reference the removed flag so the code and comments reflect the
actual consensus check; keep existing references to pindex and
m_params.GetConsensus().BIP34Height.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 4c9dee68-e33a-4409-9710-6e55d6188f2e

📥 Commits

Reviewing files that changed from the base of the PR and between beca567 and 1bac783.

📒 Files selected for processing (9)
  • src/chain.h
  • src/chainparams.cpp
  • src/consensus/params.h
  • src/index/coinstatsindex.cpp
  • src/index/coinstatsindex.h
  • src/kernel/coinstats.h
  • src/rpc/blockchain.cpp
  • src/validation.cpp
  • src/validation.h
💤 Files with no reviewable changes (2)
  • src/validation.h
  • src/index/coinstatsindex.cpp

Copy link
Copy Markdown

@thepastaclaw thepastaclaw left a comment

Choose a reason for hiding this comment

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

Code Review

The branch is not merge-ready at 1bac78340ccba0da66c8c41b0cf14a1ef7e961b1. The gettxoutsetinfo() RPC no longer returns unspendables.bip30, but the functional test suite still asserts exact dictionaries containing that key, and the earlier BIP30 refactor in this branch also removed the post-BIP34 fast path so ConnectBlock() now does duplicate-coin checks on every block indefinitely.

🔴 1 blocking | 🟡 1 suggestion(s)

2 additional finding(s)

blocking: `feature_coinstatsindex` still expects the removed `unspendables.bip30` field

test/functional/feature_coinstatsindex.py (line 131)

This test compares block_info with exact dictionaries that still include 'bip30': 0, but gettxoutsetinfo() no longer emits that key in src/rpc/blockchain.cpp. The first failure is in the genesis-block assertion here, and the same stale expectation is repeated for the block-102, block-108, and block-109 checks later in the file. As written, the functional suite will fail as soon as it exercises the indexed verbose path.

suggestion: The BIP30 duplicate-output scan now stays enabled for every block

src/validation.cpp (line 2375)

fEnforceBIP30 is hard-coded to true, so if (fEnforceBIP30 || pindex->nHeight <= m_params.GetConsensus().BIP34Height) is always true and the view.HaveCoin() scan runs for every output in every block. The surrounding comment still says the check can be skipped once validation is past BIP34 activation, and the parent version of this code used a known-chain guard to do exactly that. The new branch state therefore removes an existing hot-path optimization and adds permanent extra UTXO lookups during IBD and steady-state block validation.

🤖 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.

- [BLOCKING] In `test/functional/feature_coinstatsindex.py`:131-141: `feature_coinstatsindex` still expects the removed `unspendables.bip30` field
  This test compares `block_info` with exact dictionaries that still include `'bip30': 0`, but `gettxoutsetinfo()` no longer emits that key in `src/rpc/blockchain.cpp`. The first failure is in the genesis-block assertion here, and the same stale expectation is repeated for the block-102, block-108, and block-109 checks later in the file. As written, the functional suite will fail as soon as it exercises the indexed verbose path.
- [SUGGESTION] In `src/validation.cpp`:2375-2382: The BIP30 duplicate-output scan now stays enabled for every block
  `fEnforceBIP30` is hard-coded to `true`, so `if (fEnforceBIP30 || pindex->nHeight <= m_params.GetConsensus().BIP34Height)` is always true and the `view.HaveCoin()` scan runs for every output in every block. The surrounding comment still says the check can be skipped once validation is past BIP34 activation, and the parent version of this code used a known-chain guard to do exactly that. The new branch state therefore removes an existing hot-path optimization and adds permanent extra UTXO lookups during IBD and steady-state block validation.

Inline posting hit GitHub HTTP 422, so I posted the same verified findings as a top-level review body.

@knst knst force-pushed the bip-30-cleanup branch from 1bac783 to 1ba97e5 Compare May 25, 2026 08:20
@knst knst force-pushed the bip-30-cleanup branch from 1ba97e5 to cb6b058 Compare May 25, 2026 08:21
@knst
Copy link
Copy Markdown
Collaborator Author

knst commented May 25, 2026

@knst knst force-pushed the bip-30-cleanup branch from 1ba97e5 to cb6b058 now

Force-pushed twice to fix feature_coinstatsindex.py test and replace || to && in validation.cpp [which is matched with a statement in comment "only continue to enforce if we're below BIP34 activation height"

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cb6b058891

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/validation.cpp

if (fEnforceBIP30) {
//Only continue to enforce if we're below BIP34 activation height
if (fEnforceBIP30 && pindex->nHeight <= m_params.GetConsensus().BIP34Height) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep BIP30 checks active on non-buried histories

The new height gate in ConnectBlock disables BIP30 for every block above BIP34Height, which changes consensus behavior on regtest/dev/custom-activation chains and on any non-buried alternative history: duplicate coinbase txids after activation are no longer rejected with bad-txns-BIP30 and can overwrite live UTXOs. This contradicts the intended regtest behavior (see test/functional/feature_block.py, where duplicate coinbases are expected to be rejected even with -testactivationheight=bip34@2) and re-opens CVE-2012-1909-style acceptance in those environments.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

@knst knst May 25, 2026

Choose a reason for hiding this comment

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

duplicate coinbase txids after activation are no longer rejected with bad-txns-BIP30 and can overwrite live UTXOs.

there's no any in Dash Core, see testing section in PR description

Copy link
Copy Markdown

@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: 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`:
- Around line 2373-2382: The BIP30 enforcement in validation.cpp currently gates
on pindex->nHeight <= m_params.GetConsensus().BIP34Height which conflicts with
regtest's expectation (CRegTestParams sets consensus.BIP34Height=1 but tests
expect BIP30 always enforced); either make the BIP30 check unconditional when
m_params.NetworkIDString() == "regtest" (i.e., bypass the BIP34Height comparison
for regtest) or update the test/comment to reflect the height-window
behavior—locate the check around pindex->nHeight,
m_params.GetConsensus().BIP34Height in function(s) performing the BIP30 check
and implement the chosen behavior so regtest always enforces BIP30 or tests/docs
match the conditional enforcement.
🪄 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: 97d489ff-bbe5-4222-9771-918d368d9288

📥 Commits

Reviewing files that changed from the base of the PR and between 1bac783 and cb6b058.

📒 Files selected for processing (10)
  • src/chain.h
  • src/chainparams.cpp
  • src/consensus/params.h
  • src/index/coinstatsindex.cpp
  • src/index/coinstatsindex.h
  • src/kernel/coinstats.h
  • src/rpc/blockchain.cpp
  • src/validation.cpp
  • src/validation.h
  • test/functional/feature_coinstatsindex.py
💤 Files with no reviewable changes (3)
  • src/validation.h
  • src/index/coinstatsindex.cpp
  • test/functional/feature_coinstatsindex.py
✅ Files skipped from review due to trivial changes (3)
  • src/index/coinstatsindex.h
  • src/chain.h
  • src/kernel/coinstats.h

Comment thread src/validation.cpp
Comment on lines +2373 to +2382
// This prevents exploiting the issue against nodes during their
// initial block download.
bool fEnforceBIP30 = !IsBIP30Repeat(*pindex);
bool fEnforceBIP30 = true;

// Once BIP34 activated it was not possible to create new duplicate coinbases and thus other than starting
// with the 2 existing duplicate coinbase pairs, not possible to create overwriting txs. But by the
// time BIP34 activated, in each of the existing pairs the duplicate coinbase had overwritten the first
// before the first had been spent. Since those coinbases are sufficiently buried it's no longer possible to create further
// duplicate transactions descending from the known pairs either.
// with the 2 existing duplicate coinbase pairs, not possible to create overwriting txs.
// If we're on the known chain at height greater than where BIP34 activated, we can save the db accesses needed for the BIP30 check.
assert(pindex->pprev);
CBlockIndex* pindexBIP34height = pindex->pprev->GetAncestor(m_params.GetConsensus().BIP34Height);
//Only continue to enforce if we're below BIP34 activation height or the block hash at that height doesn't correspond.
fEnforceBIP30 = fEnforceBIP30 && (!pindexBIP34height || !(pindexBIP34height->GetBlockHash() == m_params.GetConsensus().BIP34Hash));

if (fEnforceBIP30) {
//Only continue to enforce if we're below BIP34 activation height
if (fEnforceBIP30 && pindex->nHeight <= m_params.GetConsensus().BIP34Height) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Regtest BIP34Height / chainparams ==="
rg -n -C3 'CRegTestParams|BIP34Height|regtest' src/chainparams.cpp

echo
echo "=== BIP30 functional-test expectation ==="
rg -n -C3 'BIP30 is always checked on regtest|bad-txns-BIP30' test/functional/feature_block.py

Repository: dashpay/dash

Length of output: 10822


Regtest BIP30 enforcement still matches the functional-test expectation

src/validation.cpp gates the duplicate-coinbase (BIP30) check on pindex->nHeight <= m_params.GetConsensus().BIP34Height, but regtest’s CRegTestParams sets consensus.BIP34Height to 1 by default and allows overriding via -testactivationheight=bip34@<height>, which means the functional test’s expectation is only valid for the configured BIP34 activation height window.

Update: test/functional/feature_block.py explicitly expects bad-txns-BIP30 on regtest and documents “BIP30 is always checked on regtest, regardless of the BIP34 activation height”, so this comment should be reconciled with the actual consensus gating on BIP34Height (either by making the code truly unconditional for regtest or by adjusting the test/comment to reflect the height window).

🤖 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 2373 - 2382, The BIP30 enforcement in
validation.cpp currently gates on pindex->nHeight <=
m_params.GetConsensus().BIP34Height which conflicts with regtest's expectation
(CRegTestParams sets consensus.BIP34Height=1 but tests expect BIP30 always
enforced); either make the BIP30 check unconditional when
m_params.NetworkIDString() == "regtest" (i.e., bypass the BIP34Height comparison
for regtest) or update the test/comment to reflect the height-window
behavior—locate the check around pindex->nHeight,
m_params.GetConsensus().BIP34Height in function(s) performing the BIP30 check
and implement the chosen behavior so regtest always enforces BIP30 or tests/docs
match the conditional enforcement.

Copy link
Copy Markdown

@thepastaclaw thepastaclaw left a comment

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 1ba97e51c95448039dbf6ec173b4004e961cd5fd: the latest delta fixes the prior blocking feature_coinstatsindex failure by removing all stale unspendables.bip30 expectations from the exact dictionaries. The remaining carried-forward issue is the validation hot-path regression: the BIP30 duplicate-output scan is still enabled for every block, so this run has one non-blocking suggestion and no new findings from the latest delta.

Reviewed commit: 1ba97e5

🟡 1 suggestion(s)

Prior findings reconciliation

  • FIXED: feature_coinstatsindex no longer expects the removed unspendables.bip30 field.
  • STILL VALID: The BIP30 duplicate-output scan now stays enabled for every block.

Verified findings

🟡 suggestion: The BIP30 duplicate-output scan now stays enabled for every block

src/validation.cpp lines 2375-2382

This is a carried-forward prior finding that is still valid at 1ba97e51. fEnforceBIP30 is hard-coded to true, and the following condition is if (fEnforceBIP30 || pindex->nHeight <= m_params.GetConsensus().BIP34Height), so the view.HaveCoin() duplicate-output scan runs for every output in every connected block indefinitely. The surrounding comment still says the check can be skipped once validation is past BIP34 activation, and the parent code used that guard to avoid these UTXO lookups on the known chain. Since this PR's premise is that the Bitcoin-specific historical BIP30 exceptions are irrelevant for Dash, keeping permanent duplicate-output scans does not add the intended exception handling; it only adds extra work on the IBD and steady-state validation hot path.

source: codex

Copy link
Copy Markdown

@thepastaclaw thepastaclaw left a comment

Choose a reason for hiding this comment

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

Code Review

The latest delta fixes the carried-forward prior-1 issue in src/validation.cpp: the BIP30 duplicate-output scan is no longer executed for every block after BIP34 activation. After re-reading the current validation path and the existing functional coverage, I did not confirm any remaining correctness, Dash-specific integration, or test-coverage issue in this checkout. The only agent finding in this round is a false positive because test/functional/feature_block.py already provides automated BIP30 rejection coverage, so the PR is clean at SHA cb6b05889154f78445fe12745dce833c2f86ae9f.

@knst knst marked this pull request as draft May 25, 2026 11:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

RPC Some notable changes to RPC params/behaviour/descriptions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants