From 7c20bd25e56397ec3dd0e09f9c525addf13adf5a Mon Sep 17 00:00:00 2001 From: deadmanoz <62584182+deadmanoz@users.noreply.github.com> Date: Thu, 17 Sep 2026 15:13:30 +0800 Subject: [PATCH] feat(dataset): admit coinbase overpayments at 197438 and 584802 bad-cb-amount compares the coinbase output sum with the subsidy at the record height plus fees from authenticated previous transactions. The height is bound by the canonical block the API reports at the previous height, as for the missing-parent and parent-reuse rules, so no BIP34 prefix is needed and pre-BIP34 197438 qualifies. 584802 (AntPool, 2019) is coinbase-only and overpays by 76546691 sat; 197438 (Eligius, 2012) has one zero-fee transaction and overpays by 1000000 sat. --- README.md | 7 ++- ...ae2dca3ed9ce6af9e024412cb3ddfe8afd12a7.bin | Bin 0 -> 1890 bytes ...90c6a893e6e5cdef70c92beefb88f4c5fa5a69.bin | Bin 0 -> 334 bytes ci/block_evidence.py | 46 ++++++++++++++++- ci/sanity-check.py | 16 +++++- ci/test_block_evidence.py | 47 +++++++++++++++++- ci/test_sanity_check.py | 12 +++++ data/invalid-blocks.jsonl | 2 + docs/notes.md | 23 ++++++++- docs/schema.md | 17 ++++++- 10 files changed, 161 insertions(+), 9 deletions(-) create mode 100644 blocks/197438-0000000000000307872ec2eb0eae2dca3ed9ce6af9e024412cb3ddfe8afd12a7.bin create mode 100644 blocks/584802-0000000000000000000b47042b90c6a893e6e5cdef70c92beefb88f4c5fa5a69.bin diff --git a/README.md b/README.md index 264c8d8..95fe77c 100644 --- a/README.md +++ b/README.md @@ -55,9 +55,12 @@ It checks JSONL structure, types, ordering, uniqueness, header hash, PoW and dec It enforces the rule/reject-string mapping, required context and rule-specific predicates. Validation reports the first error in each record, with its file and line number, then continues to the next record. Available block files must parse completely and match their transaction merkle roots and applicable witness commitments. -CI checks output-value overflow, forward transaction spends, excessive sigop cost and transaction reuse from the canonical parent directly. +CI checks output-value overflow, forward transaction spends, excessive sigop cost, transaction reuse from the canonical parent and coinbase overpayment directly. -Sigops, missing-parent and parent-transaction reuse checks use a verified cache in `.cache/prevouts/`, restored between GitHub Actions runs. +For coinbase overpayment, CI compares the coinbase output sum with the subsidy at the record height plus fees calculated from authenticated previous output values. +Coinbase-only bodies have zero fees and need no previous transactions. + +Sigops, missing-parent, parent-transaction reuse and fee accounting checks use a verified cache in `.cache/prevouts/`, restored between GitHub Actions runs. Missing entries are fetched from public Esplora-compatible APIs when `--fetch-prevouts` is supplied. API failures, missing evidence and corrupt cache entries fail validation. After filling the cache, omit the flag for an offline run; `--prevouts-dir` selects another cache and `--api-url` selects an API base. diff --git a/blocks/197438-0000000000000307872ec2eb0eae2dca3ed9ce6af9e024412cb3ddfe8afd12a7.bin b/blocks/197438-0000000000000307872ec2eb0eae2dca3ed9ce6af9e024412cb3ddfe8afd12a7.bin new file mode 100644 index 0000000000000000000000000000000000000000..ad3d5024675b328b467754cef7885a5776ed715f GIT binary patch literal 1890 zcmaKtc{tQt7{`aP6e1xthB9GF6g8AYA%jF(6sC-QNwP0lW+L2^A?JJ)6*( zW}4cVUs&jNX&|~RZgr2l;@)cXx1(#`VKc&|s=7dB$0D)Gt)kcZSn6vZ8$W8$*Ks3@ zI<^3&tWR2imuK|@?(@HEWpx>&bIGOw*Nj zy`QGt+~kV3jCpn))8qj#zVWBP8d11Opi180_PC}Y)=rITyyz{iKLFs6syL!iAX*es zR=hOefIFbCX(zwqO|T*xz~X<=2oae!=Nj!a>96ILz6{zF`Z4*VeE`k^VT9-%Oy+AY zSb1=dd?e9o*xs}Gc=jZKw#4`RYd+>1jE#I@r;)Xs8J?kr((}wc6anBD)3btWL}iP{ zBeDU8v}CU7Qw`yjRAR`vQ7vI()#2G!g zRGFNeqDEoM3>nK(y;wqT6M!W)RfrEOrOnEDIES9_Nk(dSw5m?>EMo(J7wGi};duYb zu^-w_>V1JrSb?iJ?a;rqd;omBPYa1cBQ_-@qJ`YGV!OjC?y2yJ`+3X&s8?r*5YpE2 z6Mm*EA&tS;ppACo6Mr5~KY;6nvyg0gc1V>4^G}Rn&Q5BRg3MB0w-%HDIFDJ6XuOGL ztB+23*AXJMgbpc-!Q{Y%RUfQeGD0Z31a8t!XKw#I1Z6Cu)6$J|?uP;xVK#4RtVIgbJC+$M@d*(bAS z_faxd*OwnFcFM=&5lu~V$7;) ze8q=z<|^(AnZwSdm=p{Xha~{mQ<{QQU4J;Kf}N?snXSELAJ#HNBVQ}+1n}ZKFQU<= zArihXoV-6ir?1L4gQWP(2U7^3n(@$9_%ZX-KOgBs`u1&@o>2hRj_*Kf zsx6tNevoaUu*lSO%&;F1cu)A64`9^0NrVWJ@Ayc{YMnlCN&m=bq;A>m!$C9vB_C}2 zHP76+6^9O%PkLpi-Uzb!iC^&MwQ`nS0HV{o5vOv0i63lTjM;X5xA13-`BB{dw^%s< zTb%y%I&0(xR;n+#y;qJIs*05vva}X^1z=qE?^A;tWyD8AR`$Dt3yOrf%96RYb8nYK zF@VA?D~MCqV-!ip$0yycxyfr=f)=kmywSzgz{d379Q;z&a>&o+$ z_Kb@Fawp-}b&#+$M68?Oc;WZ|1Xqg!=o{BP6WXA8j}%dyR^QBuiRVHzV>LrwdDKGK z%dams*Egjs^KHb{a3%-qurge2wgn0D$I(@z8TFn#Z9qu+zWE&)_sN`>|149D`+MIAoIGP8Cn%C^w z@QKtfh%;31bxS-gvNJCd`{NXvJQ%xkSxL&0d!z7{Fn(vq&9A(;f?`6Cn;oof_AC(B qp^ZDGQ2@;8Sdm?ub_vf&q1}bKcW(N9@0f{Tf4oM&v)U2d-TwgJWB*J5 literal 0 HcmV?d00001 diff --git a/blocks/584802-0000000000000000000b47042b90c6a893e6e5cdef70c92beefb88f4c5fa5a69.bin b/blocks/584802-0000000000000000000b47042b90c6a893e6e5cdef70c92beefb88f4c5fa5a69.bin new file mode 100644 index 0000000000000000000000000000000000000000..4659c0a6ff1574baeeb046564d00f0b4c248c4a4 GIT binary patch literal 334 zcmZQza8UU8bI0*2r>9H;k`)E@u@5^F%ht$St4cG#Kz-EgDSKE>x@Hlh(93h z`q>9PMGVq+Bb;s-dR49ct{OX=S6-aq$!JWPCI8Qd1O? zDis{_N&@opa|{iQ-Z2<6DDd;l3HY@yH}}9U-b|$n30c3A72lhllxOGJG>b*`%K!Hg z-`OH2^zPWk0yW;4je%i{Jp%*CWG3c%L4T0AWZ6oQw;#Fc*JK+#@?90odR+PQy@=b= zCpy-^9Ho|}vPyB~+ehDI>oY@L-eleTofzF{`qujePD0!#xw F8UW-MXd?gs literal 0 HcmV?d00001 diff --git a/ci/block_evidence.py b/ci/block_evidence.py index 5bb4da5..fed6f8d 100644 --- a/ci/block_evidence.py +++ b/ci/block_evidence.py @@ -16,7 +16,7 @@ from collections.abc import Mapping, Sequence from typing import TypeVar -from bitcoin.core import CBlock, CoreMainParams, CTransaction, Hash as sha256d, b2lx, lx +from bitcoin.core import COIN, CBlock, CoreMainParams, CTransaction, Hash as sha256d, MoneyRange, b2lx, lx from bitcoin.core.script import ( CScript, CScriptInvalidError, CScriptOp, OP_1, OP_16, OP_CHECKSIG, OP_CHECKSIGVERIFY, OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY, @@ -179,6 +179,50 @@ def witness_sigops(program_script: bytes, witness: Sequence[bytes]) -> int: return 0 +def coinbase_amounts(block: CBlock, height: int, + previous_transactions: Mapping[bytes, CTransaction]) -> dict[str, int]: + """Compare coinbase value with mainnet subsidy plus authenticated input fees. + + The caller binds the height and supplies txid-verified external + transactions; earlier non-coinbase in-block outputs can also fund fees. + This does not prove historical unspentness, maturity or script validity. + Ambiguous spends and invalid amounts fail instead of lowering the allowance. + """ + subsidy = (50 * COIN) >> (height // CoreMainParams.SUBSIDY_HALVING_INTERVAL) + txids = [tx.GetTxid() for tx in block.vtx] + available = dict(previous_transactions) + spent = set() + fees = 0 + for index, tx in enumerate(block.vtx): + output_value = sum(output.nValue for output in tx.vout) + if any(not MoneyRange(output.nValue) for output in tx.vout) or not MoneyRange(output_value): + raise ValueError("output value outside money range") + if index == 0: + coinbase_value = output_value + continue + input_value = 0 + for txin in tx.vin: + txid, vout = txin.prevout.hash, txin.prevout.n + if (txid, vout) in spent: + raise ValueError("repeated input in fee evidence") + previous = available.get(txid) + if previous is None or vout >= len(previous.vout): + raise ValueError(f"missing previous output {b2lx(txid)}:{vout}") + value = previous.vout[vout].nValue + if not MoneyRange(value): + raise ValueError("previous output value outside money range") + input_value += value + spent.add((txid, vout)) + if not MoneyRange(input_value) or input_value < output_value: + raise ValueError("invalid transaction input value or negative fee") + fees += input_value - output_value + if not MoneyRange(fees): + raise ValueError("total fees outside money range") + available[txids[index]] = tx + return {"coinbase": coinbase_value, "subsidy": subsidy, "fees": fees, + "excess": coinbase_value - subsidy - fees} + + def sigop_cost(block: CBlock, previous_transactions: Mapping[bytes, CTransaction]) -> dict[str, int]: """Calculate legacy, P2SH and witness costs, requiring every prevout. diff --git a/ci/sanity-check.py b/ci/sanity-check.py index 0894709..f2f7d7a 100644 --- a/ci/sanity-check.py +++ b/ci/sanity-check.py @@ -22,7 +22,7 @@ from bitcoin.core.serialize import uint256_from_compact from block_evidence import ( - MAX_BLOCK_SIGOPS_COST, confirmed_at_or_after, establishes_rule, omitted_prevouts, + MAX_BLOCK_SIGOPS_COST, coinbase_amounts, confirmed_at_or_after, establishes_rule, omitted_prevouts, read_block, reuses_parent_transaction, sigop_cost, verify_witness_commitment, ) from prevouts import ( @@ -48,11 +48,14 @@ # Evidence paths: local = header/context only; body = complete block file; # sigops = body plus previous transactions; missing_parent = body plus API # evidence for the recorded outpoint; parent_txid_reuse = body plus an -# authenticated canonical parent txid list. Rule names and reject strings must +# authenticated canonical parent txid list; cb_amount = body plus canonical +# parent and fee prevouts. +# Rule names and reject strings must # match docs/schema.md. RULES = { "bad-txns-vout-toolarge": ("bad-txns-vout-toolarge", (), "body"), "bad-blk-sigops": ("bad-blk-sigops", (), "sigops"), + "bad-cb-amount": ("bad-cb-amount", ("coinbase_scriptsig_hex", "parent_kind"), "cb_amount"), "bad-txns-inputs-missingorspent": ("bad-txns-inputs-missingorspent", (), "body"), "missing_unconfirmed_parent": ("bad-txns-inputs-missingorspent", ("missing_prevout",), "missing_parent"), "already_confirmed_in_parent": ("bad-txns-inputs-missingorspent", @@ -317,6 +320,15 @@ def check_failure_evidence(record: dict[str, Any], block: CBlock | None, prevout parent_txids = load_parent_txids(record["prev_hash"], prevouts_dir, fetch_prevouts, apis) if not reuses_parent_transaction(block, parent_txids, record["context"]["parent_txid"]): raise ValueError("parent_txid is not a non-coinbase transaction in both the body and its parent") + if mode == "cb_amount": + require_canonical_parent(record, prevouts_dir, fetch_prevouts, apis) + previous = load_previous(block.vtx, prevouts_dir, fetch_prevouts, apis) + amounts = coinbase_amounts(block, record["height"], previous) + if amounts["excess"] <= 0: + raise ValueError("coinbase value does not exceed subsidy plus fees") + if fetch_prevouts: + print(f"{record['height']}: coinbase {amounts['coinbase']}, subsidy {amounts['subsidy']}, " + f"fees {amounts['fees']}, excess {amounts['excess']} sat", flush=True) if mode == "missing_parent": txid, vout = record["context"]["missing_prevout"].split(":") if (lx(txid), int(vout)) not in omitted_prevouts(block.vtx): diff --git a/ci/test_block_evidence.py b/ci/test_block_evidence.py index 3bc7592..b36fc7c 100644 --- a/ci/test_block_evidence.py +++ b/ci/test_block_evidence.py @@ -6,8 +6,8 @@ from bitcoin.core.script import CScript, CScriptWitness, OP_TRUE from block_evidence import ( - MAX_MONEY, confirmed_at_or_after, establishes_rule, omitted_prevouts, read_block, sha256d, - reuses_parent_transaction, sigop_count, witness_sigops, + MAX_MONEY, coinbase_amounts, confirmed_at_or_after, establishes_rule, omitted_prevouts, read_block, read_transaction, + reuses_parent_transaction, sha256d, sigop_count, witness_sigops, ) @@ -102,6 +102,49 @@ def test_parent_transaction_reuse_excludes_coinbases_and_absent_transactions(sel self.assertEqual(reuses_parent_transaction(body, parent, witness), expected) +class CoinbaseAmountChecks(unittest.TestCase): + def test_subsidy_boundaries(self): + """Require a strict overpayment, including halving and zero-subsidy boundaries.""" + for height, subsidy in ((209999, 5_000_000_000), (210000, 2_500_000_000), + (584802, 1_250_000_000), (64 * 210000, 0)): + for excess in (0, 1): + with self.subTest(height=height, excess=excess): + body = read_block(block(transaction(amount=subsidy + excess))) + self.assertEqual(coinbase_amounts(body, height, {}), + {"coinbase": subsidy + excess, "subsidy": subsidy, + "fees": 0, "excess": excess}) + + def test_authenticated_fees_and_in_block_spends(self): + """Account for external and earlier in-block outputs without fetching internal ones.""" + parent = read_transaction(transaction(prev_hash=b"\x11" * 32, vout=0, amount=100)[0]) + first = transaction(prev_hash=parent.GetTxid(), vout=0, amount=90) + second = transaction(prev_hash=sha256d(first[1]), vout=0, amount=80) + for excess in (0, 1): + with self.subTest(excess=excess): + body = read_block(block(transaction(amount=1_250_000_020 + excess), first, second)) + amounts = coinbase_amounts(body, 584802, {parent.GetTxid(): parent}) + self.assertEqual(amounts["fees"], 20) + self.assertEqual(amounts["excess"], excess) + + def test_unusable_fee_evidence_raises(self): + """Missing, repeated or negative-fee inputs cannot prove overpayment.""" + parent = read_transaction(transaction(prev_hash=b"\x11" * 32, vout=0, amount=100)[0]) + first = transaction(prev_hash=parent.GetTxid(), vout=0, amount=90) + second = transaction(prev_hash=sha256d(first[1]), vout=0, amount=80) + previous = {parent.GetTxid(): parent} + cb = transaction(amount=1_250_000_021) + cases = { + "missing": (block(cb, first), {}, "missing previous output"), + "missing vout": (block(cb, transaction(prev_hash=parent.GetTxid(), vout=1)), previous, "missing previous output"), + "double spend": (block(cb, first, transaction(prev_hash=parent.GetTxid(), vout=0, amount=80)), previous, "repeated input"), + "negative fee": (block(cb, transaction(prev_hash=parent.GetTxid(), vout=0, amount=101)), previous, "negative fee"), + "negative output": (block(transaction(amount=-1)), {}, "money range"), + } + for case, (raw, prevouts, error) in cases.items(): + with self.subTest(case=case), self.assertRaisesRegex(ValueError, error): + coinbase_amounts(read_block(raw), 584802, prevouts) + + class SigopChecks(unittest.TestCase): def test_legacy_multisig_accurate_count_and_pushed_bytes(self): """Check multisig counting modes, ignore pushed opcodes and stop at malformed pushes.""" diff --git a/ci/test_sanity_check.py b/ci/test_sanity_check.py index cc11794..46b23f0 100644 --- a/ci/test_sanity_check.py +++ b/ci/test_sanity_check.py @@ -114,6 +114,18 @@ def test_rule_context_required(self): del self.record["context"][field] self.assertTrue(any("requires" in p for p in self.validate())) + def test_coinbase_overpayment_evidence(self): + """Prove 584802 with no previous transactions, then both overpayments from the cached fee evidence.""" + records = {r["height"]: copy.deepcopy(r) for r in self.records if r["rule"] == "bad-cb-amount"} + self.record = records[584802] + self.copy_body(self.record) + cache = self.root / "empty-cache" + with patch.object(CHECK, "load_canonical_hash", return_value=self.record["prev_hash"]), \ + patch("prevouts.urlopen", side_effect=AssertionError("unnecessary download")): + self.assertEqual(self.validate(prevouts_dir=cache), []) + self.copy_body(records[197438]) + self.assertEqual(self.validate([records[197438], self.record]), []) + def test_sigops_requires_previous_transactions(self): """A complete sigops block still fails admission when previous transactions are missing.""" self.record = self.for_rule("bad-blk-sigops") diff --git a/data/invalid-blocks.jsonl b/data/invalid-blocks.jsonl index 04fdbc7..3a777d7 100644 --- a/data/invalid-blocks.jsonl +++ b/data/invalid-blocks.jsonl @@ -1,4 +1,5 @@ {"height":74638,"hash":"0000000000790ab3f22ec756ad43b6ab569abf0bddeb97c67a6f7b1470a7ec1c","header":"01000000846e2b968653ef0a25a92c12e8884d76919907df8e3079e665686000000000005eecb6808d6de56a05211483d86fc6c7d17cda46c3388dd0c8139e4114ba8e61751e684c0e80001ccf2fae01","prev_hash":"0000000000606865e679308edf079991764d88e8122ca9250aef5386962b6e84","nTime":1281891957,"core_reject_reason":"bad-txns-vout-toolarge","rule":"bad-txns-vout-toolarge","context":{"coinbase_scriptsig_hex":"040e80001c028f00","parent_kind":"canonical"},"observations":[{"channel":"p2p","source":"stale-blocks","provenance":"https://github.com/bitcoin-data/stale-blocks/pull/65"}]} +{"height":197438,"hash":"0000000000000307872ec2eb0eae2dca3ed9ce6af9e024412cb3ddfe8afd12a7","header":"02000000c4565285b10dce8c4b548fcf984b97c3a6aaaa686ade85b38c000000000000008cd835ddcd03bbd91c9c7d15b9d288b8cefb46c468b5d5594497d1715a737f77ebed4750bedf061ab3da1706","prev_hash":"000000000000008cb385de6a68aaaaa6c3974b98cf8f544b8cce0db1855256c4","nTime":1346891243,"core_reject_reason":"bad-cb-amount","rule":"bad-cb-amount","context":{"coinbase_scriptsig_hex":"033e03030f00456c6967697573005047ec540fc0fabe6d6d8b42ab39f683f027da81c497c9c38f29dd341a00df5e553f995fd846c3cd0a9a0800000000000000002f503253482f00","pool":"Eligius","pool_basis":"tag","parent_kind":"canonical"},"observations":[{"channel":"merge_mining","source":"merge-mining-research","provenance":"https://github.com/deadmanoz/merge-mining-research/blob/629039bc8023bdaaafd9470e29051f9acc43973c/data/validated-stales/ixcoin_validated_stales.csv#L50","child_chain":"ixcoin","child_height":91289,"child_block_hash":"77e32d1f06bb050248ecf3997f4a5d5246a66ef19176813f9c00a22afe5c17d3","child_block_time":1346890246,"child_header":"01010300f1d378600b2cb98d501284c612959bf27ad43c76e5a7bc7529b90a0b14ef67655e1be54a9991765be2334127f6436686a74487e5442236cdf8b59a3e05a6354806ea4750946f011b00000000"},{"channel":"scrape","source":"bitcoin-dev IRC","provenance":"https://buildingbitcoin.org/bitcoin-dev/log-2012-09-09.html"}]} {"height":225013,"hash":"000000000000037f2cc0769d4244cf50f1cace4ab76b0b4adb31010e10150708","header":"02000000386dc07a7e4776eb8e87e6a97cf8332b7b873ba8764d0bc206000000000000005ab4785c9cb7a514fe6bbe66800391cbc56400977161d43f9c9bb9bd1b7ac8087d543b514bd7031a63a27512","prev_hash":"0000000000000006c20b4d76a83b877b2b33f87ca9e6878eeb76477e7ac06d38","nTime":1362842749,"core_reject_reason":"bad-cb-height","rule":"bip34_v2_coinbase_height_mismatch","context":{"expected_nbits":"1a03d74b","coinbase_height":436459339,"coinbase_scriptsig_hex":"044bd7031a0173522cfabe6d6d5f96eead5ea22511ec2950557d0834f76cd860bbee47f1d5bb386270d4f183b80800000000000000","parent_kind":"canonical"},"observations":[{"channel":"merge_mining","source":"merge-mining-research","child_chain":"devcoin","child_height":80590,"provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/error-blocks/error_block_observations.csv#L2","child_block_hash":"25c0c320839d5fdfa2bea57d6335f212798dad156d243946cb6365e3b496488e","child_block_time":1362842673,"child_header":"01010400d172e1559fefaf57ec032d6aa0541215fb1749fbf27da89210cdf15e6c4de3280c99b52bbebad9660834f0a73cc954cd38e04e4492bb6dc6f3d84ea824145bcf31543b5191c3071b00000000"},{"channel":"merge_mining","source":"merge-mining-research","child_chain":"ixcoin","child_height":120330,"provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/error-blocks/error_block_observations.csv#L27","child_block_hash":"6214faa077468141f92a0588f78a3140743b3dc8af6ac7effc9fbc73661bae81","child_block_time":1362842672,"child_header":"01010300ef6f83bfd4c3e1a1d2e47b932bb9c61bfb5795edb602c95c08f19416757179d9e52d09588372602162839a72ae83a9a3d470c0cd676135a95533fa5138702b1830543b51728e021b00000000"},{"channel":"merge_mining","source":"merge-mining-research","child_chain":"namecoin","child_height":99370,"provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/error-blocks/error_block_observations.csv#L42","child_block_hash":"43aeacac4539943a530413ecd48eeea120544dca1c1a9f2718d6cca482f0a729","child_block_time":1362842196},{"channel":"merge_mining","source":"mergedmonitor","child_chain":"devcoin","provenance":"https://github.com/NStifter/mergedmonitor/blob/54344d4e355f73eb94bef8d391e8fb6e4a9323a6/fork-analysis/mergedmonitor/mergedmonitor.json"},{"channel":"merge_mining","source":"mergedmonitor","child_chain":"ixcoin","provenance":"https://github.com/NStifter/mergedmonitor/blob/54344d4e355f73eb94bef8d391e8fb6e4a9323a6/fork-analysis/mergedmonitor/mergedmonitor.json"},{"channel":"merge_mining","source":"mergedmonitor","child_chain":"namecoin","provenance":"https://github.com/NStifter/mergedmonitor/blob/54344d4e355f73eb94bef8d391e8fb6e4a9323a6/fork-analysis/mergedmonitor/mergedmonitor.json"}]} {"height":225015,"hash":"000000000000015437122b60d0a1d2ed7e1f98b5b292e886d6ca62042bba2035","header":"020000007b857cd06c12f2a8e032bc38215b8ebbbe387f3b1bd487a92600000000000000900b7044d905f7e58bfc9d98b5e298a86fdfb1e2ea86c892c010fceefc6568e43f573b514bd7031aea797c30","prev_hash":"0000000000000026a987d41b3b7f38bebb8e5b2138bc32e0a8f2126cd07c857b","nTime":1362843455,"core_reject_reason":"bad-cb-height","rule":"bip34_v2_coinbase_height_mismatch","context":{"expected_nbits":"1a03d74b","coinbase_height":436459339,"coinbase_scriptsig_hex":"044bd7031a025001522cfabe6d6d43629863b5b1d5de8916a8bd7cbd1918bc6543e246e7ba6e55bf745dcb513e2f0800000000000000","parent_kind":"canonical"},"observations":[{"channel":"merge_mining","source":"merge-mining-research","child_chain":"devcoin","child_height":80595,"provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/error-blocks/error_block_observations.csv#L3","child_block_hash":"4cb852207cf335969f2ec2cf65ffabb657818e4b65f87e97f52932ac46a28f8d","child_block_time":1362843422,"child_header":"01010400cf2a6264a20af2fb0b4d43af8d79115d54ef83980e149f255afad643d0d433202558e4f3bfea7775606c42f65c1e19ccfb4c3489ff7c9b96f9eeb1df43d946891e573b51cba5071b00000000"},{"channel":"merge_mining","source":"merge-mining-research","child_chain":"ixcoin","child_height":120333,"provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/error-blocks/error_block_observations.csv#L28","child_block_hash":"5b9a346a5060370d6aa8a0a3467c5563b38d62d2a2bae2017956c5e0222d5806","child_block_time":1362843421,"child_header":"01010300f1e2ef20771d69fe2d265356eca3dc7c178b270a940ddb5930992bdb609168c5695d33c7a85439a88244feac2772f8e13c82b6ab85f87294e9bb2bca93657bb81d573b51728e021b00000000"},{"channel":"merge_mining","source":"merge-mining-research","child_chain":"namecoin","child_height":99371,"provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/error-blocks/error_block_observations.csv#L43","child_block_hash":"0530563a96697ca4e83d6db1b5ef3071215cefc643467be5c4f5500f39adc3d4","child_block_time":1362842753},{"channel":"merge_mining","source":"mergedmonitor","child_chain":"devcoin","provenance":"https://github.com/NStifter/mergedmonitor/blob/54344d4e355f73eb94bef8d391e8fb6e4a9323a6/fork-analysis/mergedmonitor/mergedmonitor.json"},{"channel":"merge_mining","source":"mergedmonitor","child_chain":"ixcoin","provenance":"https://github.com/NStifter/mergedmonitor/blob/54344d4e355f73eb94bef8d391e8fb6e4a9323a6/fork-analysis/mergedmonitor/mergedmonitor.json"},{"channel":"merge_mining","source":"mergedmonitor","child_chain":"namecoin","provenance":"https://github.com/NStifter/mergedmonitor/blob/54344d4e355f73eb94bef8d391e8fb6e4a9323a6/fork-analysis/mergedmonitor/mergedmonitor.json"}]} {"height":225134,"hash":"00000000000003abc9b545f105aec0a14cab2b65665f967b2527b61bb25e21bd","header":"02000000fb061d4b8bf9481f83015cfab27775637b2dccd41b9897990b030000000000009092b803d258eb4204aa5ddd1b5cd30e0cc686482e7c9a9b9aa66c8bdeb49030ee233c514bd7031ae3c9a949","prev_hash":"000000000000030b9997981bd4cc2d7b637577b2fa5c01831f48f98b4b1d06fb","nTime":1362895854,"core_reject_reason":"bad-cb-height","rule":"bip34_v2_coinbase_height_mismatch","context":{"expected_nbits":"1a03d74b","coinbase_height":436459339,"coinbase_scriptsig_hex":"044bd7031a0163522cfabe6d6dbc4328f620ad2dc10be02522a7cc7f0ae498b549888f50859690fece2d306b320800000000000000","parent_kind":"canonical"},"observations":[{"channel":"merge_mining","source":"merge-mining-research","child_chain":"devcoin","child_height":80734,"provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/error-blocks/error_block_observations.csv#L4","child_block_hash":"28ddfb7730a86c3ae551339a757d50408dd6910efb3b8a27754aced594b8498c","child_block_time":1362895508,"child_header":"01010400204c0bbe2f827b762f384bca89f5fad1efb20d298a26d65e3d45911e2925dc8ff79f0421d2bdab5e4cde7032efe2ac5cf481e343bbb35bdf27d5746fe571ba9994223c51216e021b00000000"},{"channel":"merge_mining","source":"merge-mining-research","child_chain":"ixcoin","child_height":120574,"provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/error-blocks/error_block_observations.csv#L29","child_block_hash":"17ad05bb5c0fa486ded594f663e50f23ee20a24bcb99055669e8844af2f74505","child_block_time":1362895741,"child_header":"01010300fda1499bd7d06132f44b4cbeca4aeda85bb9977fcc0510cd7b499c285f5c215f792b856e4cd3c44f34fced7c600512f5c66577834a8253500cc07a3e3f8b69187d233c510303091b00000000"},{"channel":"merge_mining","source":"merge-mining-research","child_chain":"namecoin","child_height":99462,"provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/error-blocks/error_block_observations.csv#L44","child_block_hash":"5e76c749131b42cace33e8a4eb2abe4d01dacc8789f5960f983af725b5faa75c","child_block_time":1362895571},{"channel":"merge_mining","source":"mergedmonitor","child_chain":"devcoin","provenance":"https://github.com/NStifter/mergedmonitor/blob/54344d4e355f73eb94bef8d391e8fb6e4a9323a6/fork-analysis/mergedmonitor/mergedmonitor.json"},{"channel":"merge_mining","source":"mergedmonitor","child_chain":"ixcoin","provenance":"https://github.com/NStifter/mergedmonitor/blob/54344d4e355f73eb94bef8d391e8fb6e4a9323a6/fork-analysis/mergedmonitor/mergedmonitor.json"},{"channel":"merge_mining","source":"mergedmonitor","child_chain":"namecoin","provenance":"https://github.com/NStifter/mergedmonitor/blob/54344d4e355f73eb94bef8d391e8fb6e4a9323a6/fork-analysis/mergedmonitor/mergedmonitor.json"}]} @@ -42,6 +43,7 @@ {"height":544024,"hash":"0000000000000000001ac59b46b44a9e525bc03a5cd2e138a8ae684445fa6ed8","header":"000000e083bcaf0ad9fb201f6f888ee014d8c1e8c317213cb5ba1e000000000000000000fc3d782759e6ade1a1b211bff767cd07d7f33dc0c21f82c8d62359bc3aa2b31ac0fab25b1f5a271719a0fc34","prev_hash":"0000000000000000001ebab53c2117c3e8c1d814e08e886f1f20fbd90aafbc83","nTime":1538456256,"core_reject_reason":"bad-version","rule":"bip65_block_version_below_4","context":{"expected_nbits":"17275a1f","coinbase_height":544024,"coinbase_scriptsig_hex":"03184d0804c9fab25b612f4254432e434f4d2ffabe6d6dcea0fda9be365f0d78b66072ae5cf48ed7cb6338df96d4a951f49bcc9641a6710100000000000000fb0136c12081000000000000","pool":"BTC.COM","pool_basis":"tag","parent_kind":"canonical"},"observations":[{"channel":"merge_mining","source":"merge-mining-research","child_chain":"namecoin","child_height":419759,"provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/error-blocks/error_block_observations.csv#L74","child_block_hash":"cea0fda9be365f0d78b66072ae5cf48ed7cb6338df96d4a951f49bcc9641a671","child_block_time":1538455676},{"channel":"merge_mining","source":"merge-mining-research","child_chain":"rsk","child_height":793596,"provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/error-blocks/error_block_observations.csv#L81","child_block_hash":"9820cd4d8c71156858576c8fb33c1d26acf4a35f6759be6992d20aa34380854c","child_block_time":1538456260}]} {"height":544024,"hash":"0000000000000000001ffb5988298bfc9f528f9a47e6062ebe8a01177af25d21","header":"000000a083bcaf0ad9fb201f6f888ee014d8c1e8c317213cb5ba1e0000000000000000002ff9d73a3acc053757fc4f126dd404601687113d789ab1706af2ff45e44324d4a8eeb25b1f5a2717a2dcff2c","prev_hash":"0000000000000000001ebab53c2117c3e8c1d814e08e886f1f20fbd90aafbc83","nTime":1538453160,"core_reject_reason":"bad-version","rule":"bip65_block_version_below_4","context":{"expected_nbits":"17275a1f","coinbase_height":544024,"coinbase_scriptsig_hex":"03184d0804a9eeb25b622f4254432e434f4d2ffabe6d6d00b4b5e6ade353899dc765c9ea4101e089f70877b7d314d29fc9b7d0654fcf020100000000000000fb006d12d345000000000000","pool":"BTC.COM","pool_basis":"tag","parent_kind":"canonical"},"observations":[{"channel":"merge_mining","source":"merge-mining-research","child_chain":"namecoin","child_height":419757,"provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/error-blocks/error_block_observations.csv#L73","child_block_hash":"00b4b5e6ade353899dc765c9ea4101e089f70877b7d314d29fc9b7d0654fcf02","child_block_time":1538452868},{"channel":"merge_mining","source":"merge-mining-research","child_chain":"rsk","child_height":793505,"provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/error-blocks/error_block_observations.csv#L80","child_block_hash":"10c113540401f22983c36bfa6f83165c5b0986589a0653cd4ba41cec337dfac0","child_block_time":1538453154}]} {"height":544600,"hash":"000000000000000000188a6aecb603cb6a068ad236f925255a491124b5c5dc8a","header":"000000e0ac98ac0f58c139e1dca0a46d8fde38b1a734c61669d30a000000000000000000c5678277c2623de52e1b23786a24570ceea239df26ec3ea92bda7e865457ed062c8bb85b91c12517b20cd911","prev_hash":"0000000000000000000ad36916c634a7b138de8f6da4a0dce139c1580fac98ac","nTime":1538820908,"core_reject_reason":"bad-version","rule":"bip65_block_version_below_4","context":{"expected_nbits":"1725c191","coinbase_height":544600,"coinbase_scriptsig_hex":"03584f08042c8bb85b622f4254432e434f4d2ffabe6d6d88922b0299a396056945229bf094718c1388b6df2c4560845fa027e8942ca65d0100000000000000fd0069592843000000000000","pool":"BTC.COM","pool_basis":"tag","parent_kind":"canonical"},"observations":[{"channel":"merge_mining","source":"merge-mining-research","child_chain":"namecoin","child_height":420338,"provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/error-blocks/error_block_observations.csv#L75","child_block_hash":"88922b0299a396056945229bf094718c1388b6df2c4560845fa027e8942ca65d","child_block_time":1538820381},{"channel":"merge_mining","source":"merge-mining-research","child_chain":"rsk","child_height":804553,"provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/error-blocks/error_block_observations.csv#L82","child_block_hash":"9cb1fa3f08b969d76fabe6971c880416e0650bd9decdda956bb1101b036a12f3","child_block_time":1538820886}]} +{"height":584802,"hash":"0000000000000000000b47042b90c6a893e6e5cdef70c92beefb88f4c5fa5a69","header":"00004020f1f9b8c77a42e502101978707f5de1896176ac1f3b251b0000000000000000007f5a9b94bc04c945693178e32eeae20f5066d7cde08c72001bdd5842da314a7aadf7255d9b0d1f1700e4a56d","prev_hash":"0000000000000000001b253b1fac766189e15d7f7078191002e5427ac7b8f9f1","nTime":1562769325,"core_reject_reason":"bad-cb-amount","rule":"bad-cb-amount","context":{"coinbase_height":584802,"coinbase_scriptsig_hex":"0362ec081c4d696e656420627920416e74506f6f6c313132ee003300200f0c9c50fabe6d6dc0ba0d6922d0606afa6321ef35c91f070cb29a0425d4ffef18f70658908db8b6040000000000000033060000b43f0000","pool":"AntPool","pool_basis":"tag","parent_kind":"canonical"},"observations":[{"channel":"merge_mining","source":"merge-mining-research","provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/child-identity/elastos_child_identity.csv#L12","child_chain":"elastos","child_height":419444,"child_block_hash":"1ef720e35e301cbdd63681c7827abe8bf0953a9e8ead49d86dcb8a86b1e29a68","child_block_time":1562769172},{"channel":"scrape","source":"chainquery.com","provenance":"https://github.com/bitcoin-data/stale-blocks/commit/97db32bf74481da71d0893ac37152a3a9479424d"}]} {"height":649674,"hash":"00000000000000000008c80c1f8c101f8aa1fabd59d63ab1350bd1d5dba425e6","header":"00000020bf0f92c82f18ef43fa86c8037669db3d095d4375409d07000000000000000000b47cdd7f24671f05b94720902226f18383e0e2cb4dcaefbb40dbb138a70770009db86b5faa920e17b4ed6590","prev_hash":"000000000000000000079d4075435d093ddb697603c886fa43ef182fc8920fbf","nTime":1600895133,"core_reject_reason":"bad-cb-height","rule":"bip34_coinbase_height_missing","context":{"expected_nbits":"170e92aa","coinbase_scriptsig_hex":"fecae9090048617468185a489434ae20d115d61694f7ca019160c1be165bace94440d705171e1b871bb876a249290000000000","parent_kind":"canonical"},"observations":[{"channel":"merge_mining","source":"merge-mining-research","child_chain":"hathor","child_height":756587,"provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/error-blocks/error_block_observations.csv#L25","child_block_hash":"00000000000000000008c80c1f8c101f8aa1fabd59d63ab1350bd1d5dba425e6","child_block_time":1600895133}]} {"height":717696,"hash":"0000000000000000000045c5040bf46b4cd6c6f8f4004c149cd602e4e356e71c","header":"0000ff3f9acaa5d26d392ace656c2428c991b0a3d3d773845a1300000000000000000000cd79ee4e64b40a2bbf130ca47d2d3cb0315d26cb96425bcb7dd82f375e8c6e739743d961ab980b17262f8aa5","prev_hash":"00000000000000000000135a8473d7d3a3b091c928246c65ce2a396dd2a5ca9a","nTime":1641628567,"core_reject_reason":"bad-diffbits","rule":"nbits_retarget_not_applied","context":{"expected_nbits":"170b8c8b","coinbase_height":717696,"coinbase_scriptsig_hex":"0380f30a192f5669614254432f4d696e656420627920657373696265742f2cfabe6d6dc0edbc53e6583117e3fb0c174156ff34a95f1a1093bb03192bdd8b47f896cb9f10000000000000001071ffd417d8ab2bd883332eb005000000","pool":"ViaBTC","pool_basis":"tag","parent_kind":"canonical"},"observations":[{"channel":"merge_mining","source":"merge-mining-monitor","child_chain":"namecoin","child_height":593434,"child_block_hash":"d22cf8a7666d92e8a254aeba4b92def80e52aa30c62293ae05d79c967b086d7f","child_block_time":1641627165,"provenance":"https://mmm.deadmanoz.xyz/api/v1/block/0000000000000000000045c5040bf46b4cd6c6f8f4004c149cd602e4e356e71c"},{"channel":"merge_mining","source":"merge-mining-research","child_chain":"emercoin","child_height":518861,"provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/error-blocks/error_block_observations.csv#L22","child_block_hash":"4e16eeb9918708624ad75d072e87d609d983e980c737a0af5b421c3f4f7b3950","child_block_time":1641627605,"child_header":"08019a027023fa433164b011f9defc077112043feaddb6bc98a92c6314a4ca6667c3564edc7ab7b15018ebdceb93bcbf593da233ec220dd9a0523e4f055f5e0624ba33ecd53fd961b66e0e1700000000"},{"channel":"merge_mining","source":"merge-mining-research","child_chain":"syscoin","child_height":1336057,"provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/error-blocks/error_block_observations.csv#L84","child_block_hash":"489b69af1f76fc07eff93cc55833326b42e19a9c8568d7353512ee1441a32a25","child_block_time":1641627642}]} {"height":783426,"hash":"00000000000000000002ec935e245f8ae70fc68cc828f05bf4cfa002668599e4","header":"0000692bb7ccd9ee0d58f8638057eee7a04cc2329f7a89284124010000000000000000004865405dc5ca751cc6ef35ab36264563f64a3061668a0f9a671aefa05012cac223de27643e02061776764640","prev_hash":"00000000000000000001244128897a9f32c24ca0e7ee578063f8580deed9ccb7","nTime":1680334371,"core_reject_reason":"bad-blk-sigops","rule":"bad-blk-sigops","context":{"coinbase_height":783426,"coinbase_scriptsig_hex":"0342f40b2cfabe6d6d76eebeccd7ca22e72d1f7c18b9a3ae8c3f93c04072e77b94dfcf0f0dd560be4410000000f09f909f092f4632506f6f6c2f66000000000000000000000000000000000000000000000000000000000000000000000005007c000000","pool":"F2Pool","pool_basis":"tag","parent_kind":"canonical"},"observations":[{"channel":"merge_mining","source":"merge-mining-research","child_chain":"elastos","child_height":1395837,"provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/child-identity/elastos_child_identity.csv#L130","child_block_hash":"be374a919b4c352b5ca7ab11937a68cc615fc590573da33bfd32f7cbf5d8d98c","child_block_time":1680334370},{"channel":"merge_mining","source":"merge-mining-research","child_chain":"namecoin","child_height":658973,"provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/child-identity/namecoin_child_identity.csv#L1630","child_block_hash":"f6a77e2178f078dd1d305a6f64dde99070ac41be141460fd3b1f949cfd988917","child_block_time":1680334314,"child_header":"04010100a03332a4347f65d54933d041a7d892201083cd47acc6af603745da1dd9bfca792dbb347476d12b011a281314cdaa27a78faae760b94b31dccacf142ed920f1f7eadd276420040a1700000000"},{"channel":"merge_mining","source":"merge-mining-research","child_chain":"rsk","child_height":5178853,"provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/child-identity/rsk_child_identity.csv#L187","child_block_hash":"ba25dfd9a60d1bf4d3548929a774c77ee94c8f2fdb344620722acf3e3b1638f8","child_block_time":1680334360},{"channel":"merge_mining","source":"merge-mining-research","child_chain":"syscoin","child_height":1590668,"provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/child-identity/syscoin_child_identity.csv#L46","child_block_hash":"8c83c0e7b6879052aff6a1845d468766877dae4f052308c962343cc776c16c4b","child_block_time":1680334281},{"channel":"merge_mining","source":"merge-mining-research","child_chain":"xaya","child_height":4720941,"provenance":"https://github.com/deadmanoz/merge-mining-research/blob/f543b1f23c57be6840c7a2a44a59306b5d0180f7/data/validated-stales/xaya_validated_stales.csv#L32","child_block_hash":"8eb4d4f2930ca73e067cee8dedf1687c3a877885d329d71a7b1aa05111bd1e8a","child_block_time":1680334331,"child_header":"0000002055bd00186f9c269679bb0685a1217a6e2c7d9bd019517217b133da00c700eece7c31850e277a993f9368eb6eceba5cd5dfff32e4f4e2fca719bb22915e15345efbdd27640000000000000000"},{"channel":"p2p","source":"b10c","provenance":"https://b10c.me/observations/11-invalid-blocks-783426-and-784121/"}]} diff --git a/docs/notes.md b/docs/notes.md index 107fea2..bde05a3 100644 --- a/docs/notes.md +++ b/docs/notes.md @@ -8,7 +8,7 @@ Deeper per-block history is documented elsewhere; see the observation `provenanc A `.bin` can be replayed with `bitcoin-cli submitblock`, but what comes back depends on where the violation is caught. 74638 fails the context-free `CheckBlock` checks before anything is stored, so every replay returns `bad-txns-vout-toolarge` on any node. Its header alone is valid, though: `submitheader` accepts it (noted in ), since every header-level check passes and the violation lives entirely in the body. -The transaction-ordering blocks, 474294 and the 2023 sigops blocks fail in `ConnectBlock`, which a node only runs when it is about to extend its active chain with the block. +The transaction-ordering blocks, 474294, the two coinbase overpayments and the 2023 sigops blocks fail in `ConnectBlock`, which a node only runs when it is about to extend its active chain with the block. Replayed today they sit on a branch with less work than the tip, so a node seeing them fresh stores them after the context-free checks and never connects them: `submitblock` returns `inconclusive` and the block becomes a `valid-headers` chain tip. A node that already stores them returns `duplicate`, and only a node that attempted the connect at their original tip and marked them failed returns `duplicate-invalid` (the result reported in ). @@ -91,3 +91,24 @@ The 80-byte header comes from a blockchain.info block dump preserved in the [BTC The [dump's](https://github.com/crossclaim/btcrelay-sol/blob/1cf676d387c4514770b91e4ca15094194f446677/test/testdata/old_headers/fork/20150704/363731.json) 99 transaction IDs reproduce the header's merkle root, and its coinbase fields reserialize to the first of those IDs, which ties the recorded scriptSig to the header. The coinbase pays `1BwZeHJo7b7M2op7VDfYnsmcpXsUYEcVHm`, the address [mining-pools](https://github.com/bitcoin-data/mining-pools/blob/af720b67faa2f157264db33c644eb1b0fa95af5f/pools/btc-nuggets.json) lists for BTC Nuggets; the scriptSig tags are `/P2SH/` and `/stratumPool/`, so the attribution is by address. A [16 March 2017 bitcoin-dev message](https://gnusha.org/pi/bitcoindev/48d3940ab1a2bd53c6e056ce7fbcd361@cock.lu/) lists this hash among blocks a node rejected with `bad-version(0x00000002)`. +### 584802 - AntPool coinbase overpayment (2019) + +The [334-byte body](../blocks/584802-0000000000000000000b47042b90c6a893e6e5cdef70c92beefb88f4c5fa5a69.bin) contains only its coinbase, which pays 1326546691 satoshis against the 1250000000 subsidy: no fees, an excess of 76546691 satoshis (0.76546691 BTC). +Header hash, proof of work, merkle root, witness commitment and BIP34 height reproduce from the body, and the coinbase carries `Mined by AntPool112`. +Its parent is canonical 584801, `0000000000000000001b253b1fac766189e15d7f7078191002e5427ac7b8f9f1`, which CI checks against the API's block hash at that height. + +The header entered stale-blocks through the [2022 chainquery.com getchaintips import](https://github.com/bitcoin-data/stale-blocks/commit/97db32bf74481da71d0893ac37152a3a9479424d) and the body in commit `abee96d`, which does not record how it was acquired, so no P2P observation is claimed. +The binary is preserved byte-for-byte, SHA-256 `08e6fb81bc61db0836d8726f9fe40459fc5a9d3f3e64621a74b21b2af4d48df0`. +Elastos child 419444 independently witnesses the parent; its Research provenance records acquisition, not the verdict. + +### 197438 - Eligius coinbase overpayment (2012) + +The [1890-byte body](../blocks/197438-0000000000000307872ec2eb0eae2dca3ed9ce6af9e024412cb3ddfe8afd12a7.bin) holds the coinbase and one ordinary transaction. +The coinbase pays 5001000000 satoshis against the 5000000000 subsidy. +The transaction spends output 1 of `8d86cbc5bf98ae815b9f360d0ac208109a75ab7988fc33276fe1eebe46e7fd8f`, confirmed at canonical 197333 and worth 503413843 satoshis, and pays out exactly that, so the fee is zero and the excess is 1000000 satoshis (0.01 BTC). +The block predates BIP34, so the height is bound by the canonical parent at 197437, `000000000000008cb385de6a68aaaaa6c3974b98cf8f544b8cce0db1855256c4`, not by a coinbase prefix; the coinbase tag is `Eligius`. + +The body is a reconstruction: header and coinbase from the AuxPoW record in Ixcoin block 91289, the transaction from its later confirmation at canonical 197523; the two txids reproduce the merkle root. +Luke-Jr's node log, pasted to bitcoin-dev IRC on [9 September 2012](https://buildingbitcoin.org/bitcoin-dev/log-2012-09-09.html), reports `InvalidChainFound` for this block and three other Eligius blocks, 197701, 197705 and 197883, whose bodies remain missing. +Core's check then and now is the same subsidy-plus-fees comparison. +stale-blocks [PR #139](https://github.com/bitcoin-data/stale-blocks/pull/139) added the header as a stale block; it is invalid, not stale, and is removed there once this record is published. diff --git a/docs/schema.md b/docs/schema.md index b47be7c..0762b5d 100644 --- a/docs/schema.md +++ b/docs/schema.md @@ -6,7 +6,7 @@ Height is `prev + 1`, not a unique key: different blocks at the same height rema A block may enter the dataset only if its header meets its encoded PoW target and its named consensus failure has the evidence required below. Header/context rules use the supplied header and context. -Body rules require a complete block; sigops, missing-parent and parent-transaction reuse rules additionally require evidence fetched from public APIs or verified cache entries. +Body rules require a complete block; sigops, missing-parent, parent-transaction reuse and fee accounting rules additionally require evidence fetched from public APIs or verified cache entries. Observations document acquisition and incident history, but an explorer label or reported reject string cannot substitute for the evidence check. JSONL keeps each block's identity, optional context and repeated observations together. @@ -95,6 +95,7 @@ Core functions live in [bitcoin/bitcoin](https://github.com/bitcoin/bitcoin): | --- | --- | --- | | `bad-txns-vout-toolarge` | `bad-txns-vout-toolarge` | `CheckTransaction` | | `bad-blk-sigops` | `bad-blk-sigops` | `ConnectBlock` | +| `bad-cb-amount` | `bad-cb-amount` | `ConnectBlock` | | `bad-txns-inputs-missingorspent` | `bad-txns-inputs-missingorspent` | `ConnectBlock` via `CheckTxInputs` | | `missing_unconfirmed_parent` | `bad-txns-inputs-missingorspent` | `ConnectBlock` via `CheckTxInputs` | | `already_confirmed_in_parent` | `bad-txns-inputs-missingorspent` | `ConnectBlock` via `CheckTxInputs` | @@ -123,6 +124,7 @@ A provenance URL cannot bypass these requirements. | Rule | Required evidence and check | | --- | --- | | `bad-txns-vout-toolarge` | A complete block whose transactions contain an output above 21000000 BTC. | +| `bad-cb-amount` | A complete block extending the block a public API reports at the previous height, whose coinbase pays strictly more than the mainnet subsidy at that height plus fees calculated from authenticated previous transactions. A coinbase-only body has no fees to fetch. | | `bad-txns-inputs-missingorspent` | A complete block containing a spend of an existing output of a later transaction in that block. A spend of a parent transaction absent from the block uses `missing_unconfirmed_parent`. | | `missing_unconfirmed_parent` | A complete block extending the block a public API reports at the previous height. The `missing_prevout` outpoint must be spent by an input in the block and created by a transaction not in the block, and the API must currently report that transaction confirmed in another block at this height or later. Unconfirmed or absent status is not evidence. | | `already_confirmed_in_parent` | A complete block whose named `parent_txid` is a non-coinbase transaction in both that body and its canonical parent. The parent's ordered txid list must reproduce the merkle root of a hash-verified parent header, and the canonical hash at height minus one must equal `prev_hash`. Require `parent_kind=canonical` and body-derived coinbase fields with `coinbase_height` equal to the record height. | @@ -226,3 +228,16 @@ The cache retention and scheduled-workflow limits described above also apply to The checker considers only the immediate canonical parent, not older ancestors or the UTXO set, and does not execute scripts or replay historical `ConnectBlock`. Canonical hashes remain snapshots from their first fetch, as in the missing-parent check. + +## Coinbase amount evidence + +`bad-cb-amount` compares the sum of the coinbase outputs with the mainnet subsidy plus the block's fees. +The subsidy starts at 50 BTC and halves every 210000 blocks. +The height sets the subsidy, so the rule binds it as the missing-parent and parent-reuse rules do: the API's block hash at `height - 1`, cached as `height-{height-1}.hash`, must equal `prev_hash`. +No BIP34 prefix is required, which admits blocks from before that rule; a supplied `coinbase_height` must still match the scriptSig. + +A coinbase-only block has zero fees and needs no previous transactions. +Otherwise `ci/prevouts.py` loads every external input's transaction and verifies its txid before its output value is used; earlier transactions in the body supply internal outputs, and later ones and the coinbase cannot. +Fees are inputs minus outputs, never an explorer's fee field. +Missing outputs, repeated spends, money-range violations and negative fees are errors, and a coinbase that pays exactly the subsidy plus fees is not admitted. +Authenticated bytes establish output values, not historical unspentness, coinbase maturity or script validity; this is not a `ConnectBlock` replay.