Admit 1Hash block 474294 under a new missing-parent-transaction rule - #5
Conversation
ad2790c to
c7d24f5
Compare
|
Drafting because I need to update the observation source in merge-mining-research so that the JSON entry has the correct "final" link (it needs to be demoted in that dataset to an error block) |
c7d24f5 to
8e70c0b
Compare
1Hash block 00000000000000000182acdf5657c93a0769dc6f9004047496b2e15efc6a4232 spends an output whose parent transaction confirmed only in the same-height competitor. That is bad-txns-inputs-missingorspent at connect time, not an in-block ordering error. The replacement record and binary are in bitcoin-data/invalid-blocks#5. Point the README at the companion repository rather than the pre-474294 tree snapshot.
1Hash block 00000000000000000182acdf5657c93a0769dc6f9004047496b2e15efc6a4232 spends an output whose parent transaction confirmed only in the same-height competitor. That is bad-txns-inputs-missingorspent at connect time, not an in-block ordering error. The replacement record and binary are in bitcoin-data/invalid-blocks#5. Point the README at the companion repository rather than the pre-474294 tree snapshot.
1Hash block 00000000000000000182acdf5657c93a0769dc6f9004047496b2e15efc6a4232 spends an output whose parent transaction confirmed only in the same-height competitor. That is bad-txns-inputs-missingorspent at connect time, not an in-block ordering error. The replacement record and binary are in bitcoin-data/invalid-blocks#5. Point the README at the companion repository rather than the pre-474294 tree snapshot.
…ce lookups Split the download into a bounded HTTP read and a retry loop that takes the URL path, and move the cache into one helper that decodes a cached file or downloads, decodes and then stores the reply, so other evidence lookups can share the pacing, provider fallback, size limit and atomic write. Expose the per-transaction loader that the pool runs.
The in-block forward-spend checker cannot see a parent transaction that
confirmed only in a competing same-height block. Add a
missing_unconfirmed_parent rule whose record names the failing outpoint
in missing_prevout, and the 1Hash body so ConnectBlock's
missing-or-spent failure is re-derivable.
CI requires the body to spend that outpoint from outside the block,
requires a public API's block hash at the previous height to equal
prev_hash, fetches the parent transaction and checks its txid and the
output index, and requires the API to report that transaction confirmed
in another block at this height or later. The canonical previous block
is what makes the inference hold. Cache files are {txid}.bin, the raw
{txid}.status.json reply and height-{n}.hash.
8e70c0b to
2ed2222
Compare
I will need to fix this afterwards, I have got myself into a bit a of circular dependency bind with this repo and merge-mining-research. Specifically, I will be using the evidence of this repo to change the classification of blocks (stales), to invalid, where relevant. |
1Hash block 00000000000000000182acdf5657c93a0769dc6f9004047496b2e15efc6a4232 spends an output whose parent transaction confirmed only in the same-height competitor. That is bad-txns-inputs-missingorspent at connect time, not an in-block ordering error. The replacement record and binary are in bitcoin-data/invalid-blocks#5. Point the README at the companion repository rather than the pre-474294 tree snapshot.
|
Feel free to merge once you think its good. I'm still not sure about adding a bunch of CI code for showing each invalid-block was/is actually invalid, but also don't have strong opinion on it here. Might be fine to just do it during addition/review once. It might be nice to also have a website for linking to invalid-blocks and SEO going forward. Maybe we could add the markdown descriptions there too.. #6 |
This is a fair criticism: I'll change the CI so it is only running for new inclusions. |
|
I mean, if we have the CI, we might as well run it each time. I just meant: Once we merged a block as invalid here, it won't turn valid at a point in the future. So we probably only need to show (or convince) that a block is invalid when opening a PR. We might not need CI at all for blocks that have been added. |
Summary
Adds a
missing_unconfirmed_parentevidence rule and the first block it admits: height 474294,00000000000000000182acdf5657c93a0769dc6f9004047496b2e15efc6a4232, mined by 1Hash in July 2017.Transaction 110 of the block spends
b11a78c6c61af1cb37586f639050d74b95c2b0fd525623b6cb6a4bb4fba46a0e:1. That parent transaction is not in the block and did not exist at the tip of 474293, soConnectBlockfails withbad-txns-inputs-missingorspent. Both transactions confirmed in the same-height competitor000000000000000000db2504327e272fe7658fac0dd0741f46b212256e500886.The existing
bad-txns-inputs-missingorspentchecker (477115, 809478) only recognises a parent that appears later in the same block. 474294 has none, and a prevout absent from the body is what every valid block looks like, so absence alone cannot be the evidence. The record therefore names the failing outpoint in a newmissing_prevoutcontext field, and CI checks that one outpoint rather than searching the block's 2,141 outside parents for one that happens to fit.CI admits the record only if the body spends the recorded outpoint from a transaction that is not in the block; a public Esplora API reports
prev_hashas the block at height 474293, so the candidate extends the canonical chain; the parent transaction is fetched, verified by txid and contains the spent output; and the API currently reports that transaction confirmed in another block at this height or later. That is, the parent was not in the chain below the candidate, so its output did not exist when the block was mined. An unconfirmed or unknown parent is not evidence, and a parent confirmed below this height is a normal spend.CI does not rebuild the UTXO set at 474293 or replay
ConnectBlock. It trusts the configured providers for the confirmation and the canonical hash (mempool.space and blockstream.info agree on the parent's confirmation), and the cached replies are snapshots from their first fetch.parent_kindremains a descriptive field on every record; the schema now says so.Changes
ci/prevouts.py: one fetch helper that returns bytes and one cached-lookup helper that decodes a file or downloads, decodes and then stores the reply. The same two functions now serve previous transactions ({txid}.bin), the/tx/{txid}/statusreply ({txid}.status.json) and the/block-height/{n}reply (height-{n}.hash). That refactor is the first commit and changes nothing for the sigops path.ci/block_evidence.pyandci/sanity-check.py:omitted_prevouts, theconfirmed_at_or_afterinference, theRULESentry requiringmissing_prevout, and themissing_parentevidence mode.data/invalid-blocks.jsonlandblocks/474294-….bin, byte-identical to the copy in bitcoin-data/stale-blocks at2633e0e. Observations: the merge-mining-research Namecoin witness at child height 349887 and the chainquery.com orphan listing in NStifter/mergedmonitor. merge-mining-research still classifies the block as a stale; that reclassification is a separate change, after which the observation link will be repinned.docs/schema.mdanddocs/notes.md: themissing_prevoutfield, the evidence contract row, a section on why a later confirmation elsewhere proves the failure, and a plainer explanation of whyConnectBlocknever runs when one of these blocks is replayed today.Testing
python ci/sanity-check.py --fetch-prevoutsadmits 47 blocks with 6 block files and prints the fetched evidence for 474294: parent confirmed at 474294 in…500886, canonical block at 474293 equal to the record'sprev_hash. The offline run passes with the three cached files present and fails naming the missing entry when the cache is incomplete.python -m unittest discover -s ci -p 'test_*.py'runs 32 tests. CI on this head: run 34950924462.Related
bitcoin-data/stale-blocks#139 removes the invalid block from stale-blocks once this is published.
Original discussion: https://bitcointalk.org/index.php?topic=2041607.0.