feat(dataset): admit four P2SH redeem-script failures with complete bodies - #13
Merged
Merged
Conversation
…odies p2sh_redeem_script_failure covers a spend of a pay-to-script-hash output that passes the pre-BIP16 template check but fails once the redeem script runs. CI finds the input spending the named failing_prevout, fetches and authenticates the previous transaction, and evaluates the input with and without SCRIPT_VERIFY_P2SH. Blocks 173928, 173957, 173998 and 174605 from April 2012 carry the same 123-byte spend; their bodies are reconstructions whose merkle roots reproduce.
deadmanoz
force-pushed
the
p2sh-bodies
branch
from
September 21, 2026 07:48
b22ed5f to
46bebe6
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Four blocks from April 2012, at heights 173928, 173957, 173998 and 174605, include the same 123-byte transaction, which spends a pay-to-script-hash output of a transaction confirmed at 170054. Its scriptSig pushes only the redeem script, a 1-of-1
OP_CHECKMULTISIG. The pre-BIP16 template check hashes that push, compares it with the output and passes; executing the redeem script finds no signature on the stack and fails. Nodes applying the 1 April 2012 rules rejected these blocks while older nodes accepted them, which is why the same spend kept being mined for months. Core today applies P2SH from genesis with one exception and reportsblock-script-verify-flag-failed (Operation not valid with the current stack size).The new rule
p2sh_redeem_script_failurenames the spent output infailing_prevout(schema section). CI requires a complete body with header time at or after BIP16 activation, finds the one input spending that outpoint, fetches and authenticates the previous transaction through the sigops cache, and evaluates the input twice with python-bitcoinlib:VerifySignaturebinds it to the previous output and runs it with no flags, thenVerifyScriptruns it withSCRIPT_VERIFY_P2SH; it must pass the first and fail the second. An input that fails without P2SH is an error rather than evidence. This evaluates one input with a library interpreter, not Core's, and says nothing about the block's other inputs.The four bodies are reconstructions: the coinbase from Namecoin's AuxPoW record, the other transactions from their later confirmations on the accepted chain, and the invalid spend itself; each reproduces its header's merkle root. 173928 and 173957 carry OzCoin's
ozco.intag and 173998 NMCbit'snmcbit.com, both listed in mining-pools, so those records attribute by tag; 174605's coinbase carries no tag. Each record has two observations: the Namecoin witness that merge-mining-research holds at a pinned commit, and the blockchain.info block page the Wayback Machine captured in April 2012 (for example 174605). The 2 April 2012 bitcoin-dev log records the first rejections and the 4 April log preserves the transaction. Eighty-five further blocks carry the same spend with authenticated inclusion proofs but no complete body; a proof-based path for them follows separately and reuses the script check added here.Testing
python ci/sanity-check.py --fetch-prevoutspasses with 58 blocks, 58 contexts, 207 observations and 16 block files, and the offline run passes against the same cache. All 42 tests pass. The unit test evaluates the real spend against its real funding output and checks that an input failing even without P2SH raises; the dataset test admits 173928 from the cache and rejects an unspent outpoint, a pre-activation time and a missing cache. Eachprev_hashwas checked against mempool.space's block at height minus one.