-
Notifications
You must be signed in to change notification settings - Fork 1.2k
refactor: remove Bitcoin's specific workarounds around BIP30/BIP34 #7335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
bd685b7
88aecec
cddae75
cb6b058
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2038,21 +2038,11 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI | |
| return DISCONNECT_FAILED; | ||
| } | ||
|
|
||
| // Ignore blocks that contain transactions which are 'overwritten' by later transactions, | ||
| // unless those are already completely spent. | ||
| // See https://github.com/bitcoin/bitcoin/issues/22596 for additional information. | ||
| // Note: the blocks specified here are different than the ones used in ConnectBlock because DisconnectBlock | ||
| // unwinds the blocks in reverse. As a result, the inconsistency is not discovered until the earlier | ||
| // blocks with the duplicate coinbase transactions are disconnected. | ||
| bool fEnforceBIP30 = !((pindex->nHeight==91722 && pindex->GetBlockHash() == uint256S("0x00000000000271a2dc26e7667f8419f2e15416dc6955e5a6c6cdf3f2574dd08e")) || | ||
| (pindex->nHeight==91812 && pindex->GetBlockHash() == uint256S("0x00000000000af0aed4792b1acee3d966af36cf5def14935db8de83d6f9306f2f"))); | ||
|
|
||
| // undo transactions in reverse order | ||
| for (int i = block.vtx.size() - 1; i >= 0; i--) { | ||
| const CTransaction &tx = *(block.vtx[i]); | ||
| uint256 hash = tx.GetHash(); | ||
| bool is_coinbase = tx.IsCoinBase(); | ||
| bool is_bip30_exception = (is_coinbase && !fEnforceBIP30); | ||
|
|
||
| if (fAddressIndex) { | ||
| for (unsigned int k = tx.vout.size(); k-- > 0;) { | ||
|
|
@@ -2081,9 +2071,7 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI | |
| Coin coin; | ||
| bool is_spent = view.SpendCoin(out, &coin); | ||
| if (!is_spent || tx.vout[o] != coin.out || pindex->nHeight != coin.nHeight || is_coinbase != coin.fCoinBase) { | ||
| if (!is_bip30_exception) { | ||
| fClean = false; // transaction output mismatch | ||
| } | ||
| fClean = false; // transaction output mismatch | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -2382,24 +2370,16 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, | |
| // can be duplicated to remove the ability to spend the first instance -- even after | ||
| // being sent to another address. | ||
| // See BIP30, CVE-2012-1909, and http://r6.ca/blog/20120206T005236Z.html for more information. | ||
| // This rule was originally applied to all blocks with a timestamp after March 15, 2012, 0:00 UTC. | ||
| // Now that the whole chain is irreversibly beyond that time it is applied to all blocks except the | ||
| // two in the chain that violate it. This prevents exploiting the issue against nodes during their | ||
| // 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) { | ||
|
Comment on lines
+2373
to
+2382
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 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.pyRepository: dashpay/dash Length of output: 10822 Regtest BIP30 enforcement still matches the functional-test expectation
Update: 🤖 Prompt for AI Agents |
||
| for (const auto& tx : block.vtx) { | ||
| for (size_t o = 0; o < tx->vout.size(); o++) { | ||
| if (view.HaveCoin(COutPoint(tx->GetHash(), o))) { | ||
|
|
@@ -6157,15 +6137,3 @@ ChainstateManager::~ChainstateManager() | |
| i.clear(); | ||
| } | ||
| } | ||
|
|
||
| bool IsBIP30Repeat(const CBlockIndex& block_index) | ||
| { | ||
| return (block_index.nHeight==91842 && block_index.GetBlockHash() == uint256S("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) || | ||
| (block_index.nHeight==91880 && block_index.GetBlockHash() == uint256S("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")); | ||
| } | ||
|
|
||
| bool IsBIP30Unspendable(const CBlockIndex& block_index) | ||
| { | ||
| return (block_index.nHeight==91722 && block_index.GetBlockHash() == uint256S("0x00000000000271a2dc26e7667f8419f2e15416dc6955e5a6c6cdf3f2574dd08e")) || | ||
| (block_index.nHeight==91812 && block_index.GetBlockHash() == uint256S("0x00000000000af0aed4792b1acee3d966af36cf5def14935db8de83d6f9306f2f")); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new height gate in
ConnectBlockdisables BIP30 for every block aboveBIP34Height, 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 withbad-txns-BIP30and can overwrite live UTXOs. This contradicts the intended regtest behavior (seetest/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 👍 / 👎.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there's no any in Dash Core, see testing section in PR description