From 46bebe6efdd69903fbb355e7e19b7f8f061957c7 Mon Sep 17 00:00:00 2001 From: deadmanoz <62584182+deadmanoz@users.noreply.github.com> Date: Mon, 21 Sep 2026 14:57:48 +0800 Subject: [PATCH] feat(dataset): admit four P2SH redeem-script failures with complete bodies 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. --- README.md | 4 +- ...e2de321db3e3396102ad5dcfe3b25f01a81f64.bin | Bin 0 -> 31258 bytes ...5bae4c7b8d56a9aca955a04c60856b31b11155.bin | Bin 0 -> 41258 bytes ...2eeec3f1fbf3c2c7299e7935c2b0f33b189651.bin | Bin 0 -> 7662 bytes ...4a5520d21b9d4f271a34012e96784b3b3168c5.bin | Bin 0 -> 4855 bytes ci/block_evidence.py | 35 ++++++++++++++++-- ci/sanity-check.py | 24 ++++++++---- ci/test_block_evidence.py | 23 +++++++++++- ci/test_sanity_check.py | 12 ++++++ data/invalid-blocks.jsonl | 4 ++ docs/notes.md | 15 ++++++++ docs/schema.md | 20 ++++++++-- 12 files changed, 120 insertions(+), 17 deletions(-) create mode 100644 blocks/173928-000000000000023df73ac98923e2de321db3e3396102ad5dcfe3b25f01a81f64.bin create mode 100644 blocks/173957-00000000000001bd778cffee5b5bae4c7b8d56a9aca955a04c60856b31b11155.bin create mode 100644 blocks/173998-00000000000003bf4a1e491c802eeec3f1fbf3c2c7299e7935c2b0f33b189651.bin create mode 100644 blocks/174605-000000000000068294db0526cb4a5520d21b9d4f271a34012e96784b3b3168c5.bin diff --git a/README.md b/README.md index 95fe77c..98de8bb 100644 --- a/README.md +++ b/README.md @@ -55,12 +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, transaction reuse from the canonical parent and coinbase overpayment directly. +CI checks output-value overflow, forward transaction spends, excessive sigop cost, transaction reuse from the canonical parent, coinbase overpayment and P2SH redeem-script failure directly. 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. +Sigops, missing-parent, parent-transaction reuse, fee accounting and P2SH 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/173928-000000000000023df73ac98923e2de321db3e3396102ad5dcfe3b25f01a81f64.bin b/blocks/173928-000000000000023df73ac98923e2de321db3e3396102ad5dcfe3b25f01a81f64.bin new file mode 100644 index 0000000000000000000000000000000000000000..7c16053f6029d67fa4962269b4168720b953d49c GIT binary patch literal 31258 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�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 literal 0 HcmV?d00001 diff --git a/blocks/173998-00000000000003bf4a1e491c802eeec3f1fbf3c2c7299e7935c2b0f33b189651.bin b/blocks/173998-00000000000003bf4a1e491c802eeec3f1fbf3c2c7299e7935c2b0f33b189651.bin new file mode 100644 index 0000000000000000000000000000000000000000..c2c7fa35c7e99cbce39ab334da2d7eccbd6ebc6d GIT binary patch literal 7662 zcmb`MWmr^Sw8oi1I+dYo07(H!=}sjiq@}xCVrXR;8Y!h4L_j)3kQ9&(kwzM%yW`HF z{`J$nU+#IH`E=IV=Uu;dt-bfz13*GTGI)5wzX4#e5vj9fD1>4bB(`TTBr{`S^rOOW z!Y?U^Ut5Mk*YK>0ER70UK_66V%+de(^U3hsZcpge)=_7$*Hb?gOfu2=Svg_=`~k%8 zf4y$t*ApjKn>&cd?nI#pBB`;Sf3~+jKRO0Wo-H-Ve17>*f3d5co}9Ycl{yJh7G$MW zUWID;XJ7|=Qxj`9c2h_DVyf*e7-Bd8I1Yyeai8=>A!xzsg$T8O*Sh7P5Nai1JrMx- z^ee0wAqf!y+z->{4hdVZP$7jlD}M_g+FHPKX#z74^@V;WTT#0aLIj4%aYzHf6jKh+ z?Q!+Vxf_d&Pg=Qm1xolMa{%RG92+6XqRxD}K(H2W)9i6o8BI84gkPxYoAr+@E`-#z z!Onq0huu&P&bI)GJ3A_NIQY&1AeE%<$Ia&CPj>gr7Y+#U=}`CX-Puby8Lu7N4}1kG z=_5Riml=`?=c217!uhn0?49}MN$`=lGZ`YiYaAA}Jw@FEyV3!Cj8z{)K)HEL5E*j> z>FZVZ94Ak`zmmnhw4XA*ddz+o!V;)ssKEniprK*IecptLa zqB6xWOc5jfFrmZDpJdhD%=V?9e-LuGKv7VBtuu8<= zf*H|JEaG0;X4c9jCW#?Mb?5?4KvQ^qd&%#Yk(~JgE(mZ{--;n51A|{_PyTV_n;b-k zJk&Y+ha{8yhZl^yZ$PW0a7Wf&$P>e*BRqR)CIF_AqfA!a&^5@`9D8QIEwugDGr%CE zH97O@obXV*pf{hXKaX6X@h%8IqDtjlrL3c5a2@fYU!FlId{l~)EFOlfdc7pH`m|}O zs#iW)v$N$HJ@0)Erh5$pr_mgpeC404>*bK(U3YCR6Z68eF&(R9q3`MqWbpDgfdfEF zE4yNuA0Nv;K&=jHCnW7`-f_v1Lso7$A%Pj29&Z5vCj@Jmy4AonEI&e5)4k;MKt<1& zfX=NnN^ACIpzkdJaZg`_tlRV$)fr~XE8?w7KIkX}$e*$1quCzAiUYEcDgH!I$e$Y} zCkm-q;QE%mc;$J-pSEuEF96E1UX&YfJ(q#3!9&crmWS91W){sKiqLke)=tFSE)j2v zc+4RSq(Q2``nHv`5@$w-BWR})gFurbNz0!Og%(kF0zfQ<2R%~CR+3Tq72v9mEwtq00ooL6r< zxZb*)my(7=x^R4nXnl5wUu6XaZ5|-blsXkQh0Rl7QrA@C-R>JBPcuzzl%gE z(g{c{@n#T1iOh8wVa3fM;kONksDUz5*h@y z5s|HomOzCKS)+be z7dX?XPO6d-gTr%UdpXE#{YhjDv$SV50HOE>IQ^3e`;Tcn2eVb+i@4tWmULxdx2OiO zY)}rYIKr4U65%Vtv{LV7V~IomxN&hZ16fPMDQ-?)y?;z2;-`uh@3~H1UEk@Z;Se49 z(!!st0P9F^+qx8vpu1FOlSEgDoKl>YO` z;)w`(3}!-?3Dno0@{N8HvhPCB4ASG2A!Q(E=1y^OXuq1(A5&mxLhu@MMD z)G(wSec$Bxi5oD5a$bIPQy_hmJqBE;^NeweRAXHDJKOk@h46F=;Vd&vG)S1F)jjH> z-4xDJARtP?VP`g-xi|-cU4>KDpsF##66J>c^N&Ms+H(GctkB+4U zn#@>4R}~CcljgPlrq@Vsw%8$cE>|yDo|80?@VacWv1@=LS^N<@4UMYfGzbXB9HK$y znz?+`!9T%1Oi?dvULNYTzla~neIdPmWg>hI3aKO$r`IS;~R{{>Z_3XBi*a&m@*!o zWHm_7NoMKM)5krd}x^mB;opG$NH(;X5R|i+Cq-ab+dtB63aOgR_2^i zrlx3Lnz)^9{eJ4NvdhfMiR>b7(crdPIDj=Bow%#TF97fl8dLwpRf_W#Ef6_C)91`)O zus;j4AcGRU)nwdlY;}bL(C7mHi73Hz>fRHh-n6E<=rz5o8M6V?qW=p3naSvpf?rvT zXH8y2-{NUQk<)cO`UTJ4vSve_C?QphJz|*OtI18)tE$l5mtO<@e2(HrYGi^(rg)o= zq93O|Ey1f>Qc{QSsY*~FanFg>$YI@|Yq|AlKepKf#Q#)wiHjG0+>mov1t*a0_TKYm zG{xo=M@`5@N3aA+3FXL zHN}o*q!)I=`@xi%F>E%RHG^S}2jf&~z0g zyVnJqM2W@nH&wF3#?JMCsqj0yLJ*Rf*djnND?==T@AAZ}ii#emJ(Mo$l5eK4B-~lC zD+t9xwCwLz`&e7SZMMPGD5rqbLte=xey3XYbKyYB85V#uqibdJ8NAhMMD}KIeVE@! zD&$Ul_Q8{S`_x40+FnF!@IWS5Mfig_Tr^7bnb#x#(H2FqmZVXIn-qSG8?{Wcu^(37 zD%(3=#`Q+&l9Up( zh&Zx`N>QP|HK)JyY9H&K5v+KwB~$EA#6bGiY#c*xw;IX%rMv^)C8u_F+}}zAkRzcs zs7b##a-Xw_XbrPD#8-+BFR~KyN#5&gy1cIe{0G4R#m{!g^DZ2dj1@-vH(K~@mi?2q zlBe51YMaR)JQSsH1fjU|=CkA46AQ~UHXy;gu5nJb1nxrozBwejxf|McS2zM9h99^U z7PCYQo)VUekZJ`|63p}{QXfMrU+E?FRg^o%RPO*21oCTKj*|Nhci4Nj>xCv1Y3xi3 zhHnI1F+R}WB0%z;y!~WC%q85Nwaj-3Dl8wW0nb%U5;?<7JZ<3#{xc=dCzKJz%>{^%l_yjc3zDz3N z2t$jWbI?R3aZ6*#Dax0JBO$JnnhGZe8q65=w*+r0XmHOd-lu5u+|Qvux`g9*Lzg-iY+FlsTB1UPEwVBA<)5xZBr zul!9>DDZuQ$emt=zJOJwL_`t%CNRP>PlR2-#PbANJ)C6li1wT)hvC}XS%*wr%DbQ) zZwLr}fc#-6Xph2AN)A=$Fi@G+{jQr0zwH*f*CIb!HC1l{qIc1!=}1RQk-OYGgQImk zVAAx$+rb5Fz)Kw1U8~9EIujgk^Hm@6`ROIX_*szGU7W8n4|p@ESfKO-Z_UWoif##D zZ0ScKtU(Y+K+DudQDgRE{-Mu3ZFjNpJhM;^R-8G6cY92Lh$zT=QE%yZ?KHJtR$x zu!sK*u+tqkfwjns$~=71$|fq~{sVr&UR4h`0mmNc(9>2KYpmBXExb!3iIwG2>Wb^# zZju)*F7y@NM(nA=dgl_zL+8N~SYfH=4;yK74CP1PCUC@PAXz@CY`G=C@%rLFhc7S` zPPYeTTuMCGe84xUn_3~t`LNcUG93D4alA z*s=eG<4lB1vbR5JTT$!?s*E>{a+(9X`HzEkX*u_>+){0HSwHT0TuEVKKSBxN2Lx?> zNn&)0x*q2BL9|-81iV{!N&nOUELaH;yLMs^%^)l)_1Nz{Sg>n_=l4&QT<@=~qC&Mr z?di7d9u}vGbg+!X|0RH2Qrl2goVAe@gGDK&7Z+CMphlaa{VGQ=0|!4$Tqtr+Jv96eu~JH6K#o@cC-t7A3DKj0|fIFp=s3+%EWu?sGF_1=7EMR z+|NpcgJ;O@J-0CJC^Uit_!OhvNUDZ|HR^P-ALl*k-_@2$>+IQqk&uiQeJ${0(uq>V z)NJwt{dg|^yQb@Fu^{!N`+M&Aol+pGfl)00Is$-+!IxdMV8~_ro1wJmz6AxQR0@Ch zH4>hA|51?=71T0>p3yGXh4y8ZFh z@7R{OO8+JGR#o0Eo5NTa?Qn*XBL9xJxg5d%DKT91Ag_-87Xh{y(j4&I=O$@&WRCiL zI&CtlT&&YHu`U;gf9ZG<`Oz6J&vj}Hb_PegNJxZ2*CCaJBL`QF5baxQglPHB`pC1+ z^@?bY?J;7zVM?*@giZrq2aZS+O1n^`jTD5TzeVr%=;n?mSgGP;hrbp+NmNw0)Ip=dX~Ul=p{9&LDPZ#KPKLojvJ4#dh;v z`NxY&T35#-L<4CnhY;Uzx2+_dbXJiqs$S&IekP~F+>b|W@WBCAOycxK?N7uP;q|82 zwX{af@_R+p$v+>uIZ~40EgD?7uc;h z7g%>XjqtOc3XG>n4F^IO{nnJ9{=OP$^$wCbkJ`MZbdL8(yQx-x*`RqZIK=;JVPF=! z@#=2gKP9ut-u?B0AdX1j!F%8-izOJ> zvPp{AV|LpndKLuJloB@X49uQC>W9X}S>mFKZ>$~SWm2|iBKlGJ3)JXbqzT5_NJ zhMB3f5omYx`9^y2N9ACc>?4HeU#ybq9|~?1a0&Q#(wqs zKIw>2t}d#T{0zeKEm@2_?8klEFt>#{KN&n|zPU?sZs-uUAM9;QQnQ_=8L^`S-;9GJ zLNd@wUl8H*p;iLC}L<~b-+yLoNWAg7@wDKX*o=v4q{kTthN)O(Nf zR;bxk_oP_|UpG1MQnf%Gqv|;$>F-zMwBDv@uIr2TCxPu49j<`QY#>@hpo?MJQ3OEw z82;tY#oLYW<`zPFtszDai@*+pFc)?>iDZ_PIF8Fdg?UA+FgcJ$Gz$Z*d%e7W9luaO zc&J523Z(Ez=MltsFM}B7*Ah$;hOeI*ACkg(&GRDBQH7yDv9fREwYq%b?xNzDPB;jj zVW>X{)liGhMl78SiTtynm~Xtt9`SQqiA?797e80UKf+D!xxfUG9PGoIvA^tP58D6} zKfFZ8Xk;M%ajcOwLHs}qd=_NpjYdx2%@wP(ZDr!ttrDzpR(~Dsz~(ogh3_1OAYdB? zl1UqB4x7qlTJutDAKWHsn(EsBvOWIuf!k*BcjLcxdGDpOKp?h=RLvtrYiX`?)*f`0 zf%oCKBjP`6^XI#bEP-G#qnIl1OC_bL7qnB2qbs_#ZJ7sq{1J#H1Co~y z(ip25L{)pyS}~C*5-D2BEnzx4ixt(wLzyQ3-Dlxs_zENI{uB&(i`if*I;yc%4=P{J z_p$lo(ovsU!mVka7ReAOZ!NL5kv7p3bu@v13d5h?&vhE+Xov3_n&+4Pi^xT8-m^*( zEhmb$k-5Vmy1@7q&*`sefXGtWINK^{ozClIT!tr7S-L{SJi_|bYML6XNPfH9KM??a z*JW%vwQCBs+S?woaV5`mmrWBLvRCf!alc%IGQ9R-jf#f5w)c*#QbF{x{(}RwKtb5F zc0!laDo=c1AKNwHqn^IP5`YHy8GRs8d@$l8*(ZUF(0(6HhwQr(f*$L-RALS+Zv^}a zZc|MDV)b7FpiIs~!U&zIp-l~!gBVcWj-6QptXNzU@4tvyan`dGItyXq6tl#6Il44g zWl4d*DI%|6@gZs9;FG`O9Vv0k$T`s@e!r2d%(Rvl?1wq7_<|BK&ab&gxwZ|BoY@UZ zQieoHVWQs9<(Ur9akOQtbt2*}C*y?`v2!QLno=_(y2-@<5ar09|-w7x3P;%+17^?dvOOyFh9BOD-h)nEjYbMJH(4ntc20dRN=(_>i259XKG^5Ayi z1)}kR5V~%gX{tngWdlp4n^AP@Eon%cm)23261+ zes_8_{`&p%`+Xme`{(ZS{d}IU=jZ)>e?Nx@002S|T1n2}ukh=L-F$W#SIn3x&zGx5 z^J#S0-*DGM&XQ%{Y*^Lx@9y(|n%T!t1BKRt8rozgGN9P$I%2&fjlaw(fs(haU z4|@ad^ItCv_7Wq&-Gk?*4LNSGx4+Bu=}-YBEY`F?B?I(sr7W%_=K> z+2Qw;xI6LWF(mxBFBD+}uX=ZYzHh@3$M2xg?)?l}%IR-X;HsJwEIFZ9@5kP;@S7?1 zskN^6jjXxy)Z&?R-WuC1QR#A!GmCy|gXT*e??N2sIr9K&9uk$w2IF{4{fgJU7$o+6 zQ6fjPq>rHBQvTY)rXX%m=q;!+5bWvb9#e=YGdr~m{a!MJ480&l9;14~DJ7WLus_SHZ6l?2mgYYG8{ePec&q94UgJ#DftmMlo=aq&zMKQF>eS zYZ%^>ul8K&&nAs$B}O2#Jk>vsvU$AEsDUIDAYNCoEo9ixXfyi7-{!coq@&Q2mxmrd zHvvGq-lE5XU3Sf*apjZO(PI<9N0wE(GRn&_aN@Dc1^>+_I2Y>tc-kRKmTqlJ7GA?v z+-0u5dCW+DSMcr=0u zg#p1Aa#=dns*_(NBhpnM4~M6zi3kFMfY+2F?~y|DRv;nRd_n%1naj#=$2bkYHPVi4 z#>j|9up$I+lkd)wcZi(UF1Vt@fo?yga|SrT#c#74V4FORhLLY&2T0FoOZ+0?&A5C( zKPj^X92hQN?9&08pXP5XX&hTF+U;-RgB#Gs*nAIrSbmQviXa9M*|w%`LtpRFO;^4i z!9Uab#{e>gVOB>cK{Y%sX4!nR!#%gEo!qK_7ObfO`C>l!V-UB)Avd8)K(LitC3uF< zl&S<$Db;pNv>Zv4=nQV+Z7|x~5Z8UBhya40t_}$F+>jvlt>adAf-Ak}nu;D27>JRl z!Q&UV;>lIP3b23RXYWcv*!duz)wtbe6XO-vpx4j$)1^Np&JNg|5&ND$dT@~Bt?xf9@+?Reu`lLU;!t8lc?No~yov#W=_XHl zHbQ*@$v(mvl3ZjP+ytB?67;R@#~Rh^`lyECSOY4T?wkr|7>v;(iUOM=Kp{7E3Uq05 z_S4&SJ@;M3FpC@3>!`VE`%0<~VId;*57UNEGpvudu8=9kS2*5a6$hLfXlxVsW8j;^ zx1HI*=uJw)mjd!$CoxY(3C)5F^T%QcP=&3gB zUQ@KYuG`8g9bTva1Op4KM=2;AQt}RG8$A^}LsR7-X|iMEi3~?wyO%tI5m*6jS97<= zj9wEC#xY8Wqx8a4c2)sE%-#`$-7n%?oojqP7KITN zEnaAM@e`f@^$eJFn&7x_&w%zgMYvnLXJJ9Gz1^JntI$4+n-f?8eh{JG0>abR((h=F zp9uE%pmfT+GiM}vB>xfc4B7|}7?SDO;o9o|l7`N|w{S=!TayFN%9y-E+i`ylHw|1B zs)FrdExd}b&a^8QNz2JP>g$tY#v-CrmNCz7p?3?0=|L9t*dc|1NPH@1e!<|I@TXfP zOiR!aRajVv%4OrRAI71vCh>UZ0VuN6h;RY0?K(3tMWdcw_S@~+2ILH!GQ8hH-ha^x z?`P!Qp%>yca&=RbM#c_tgfG&l2Kp8ja?3LN)m?8)84)v6_} ztNP5zaPnQF%S8$~I!Bi<+S7lcg48TLQ^KCZ5(;)RzY0?vLHli~;71PT>Y-6}1>grU zxM@_+8#<+d^;VDQYr~|4B=Wk(KxRf&{V%bOXuf-1HqeLqX1Ip_y)IJ$G5yebLL*!F zYI_!UwR^BqFJCq?HM7pz_IYL9ucVjwr3P@*{$G*;UGQ;p;kNynZ7d*>;ZS$SNzB-a zxU(F&o*Vj4QWXulPGU1N8RaTBN@QwS-E{~hg(6z9nUL2Dt@rY;~t97 z`$tvEN$s1zo$@J8pQ>F@El!AUl+U{D%Ih+Vo94VI*a4wEO=Ehw-jW8~ zV%3_m<@aHWa#ikaWy$g}?98-%m%4#qS+{NEA#%fY_b#(MjHzUi(a_V0TSDeKT7Z#! zzPX+7S5YXeU*`P3m49qJj_^FGvTK^v&ey)I7JLYt^LgNu&6XP%43 z)aE@Rxi2;biLeYT&G6>M4{qv7K{gBEmi|?b4ssP$LkrBqXQqsUh{{~S<>(cMV>Mp2 zHAOSH<{D%c2qp#GEFI-I>rLG!S}Ld6m8!4a1r;wE1x(&ffThh2U&Pj9YR40rSb95l+U;Qi^cL3b{JYFK{J8oA7*A^_WEN!0(mX5!bg1f^x2+eTHW zXNU!OrXSs@)%+^}G@xCn;f}a==i`9;we9DAmu{OhU8)j76&fe|yV@=bk>VEmb(ZAG z<*R>_kxsT1bmSXMDLOO|G7FT7SSc7aAX4th;OfG*p4KRM#TPoRiZ;zdy+`gjbyTu7 z{Xq#uVXY*J8$YD!&9MgbZt$by`Gz)vAz43XgklyPB0ozX=z)d%b7~ z&*DWp^}J4{xgQbR*ND4(`!H?CV`i*Mtc$pUGjPM8hVwFni98I_QzgK{xvNI7vC`?} zLGf8^vhc{!GVTvEJD~ApHYcrywt!;ZC>r)^DO=o_#v-J55E&zV4dbj8Aq@m`HPD$Q zJT>8sR8jUwq6qZ8etiMD>kvpcUp{mKfgU7bnXeIP=v0@^o_)OD^KGH*LvG%^AAM$N zDU`={X6jJ#S}KSK?(=NdHb#J&!cXTYBuGKkfoA}M{*>~&kUq(GdL8H@OfDNKg<}(d_%GRS0&8_)#D-b`}@sZ++>J1kO*!x zc%1It!he(QprN>#a=5huJls3qBzsERq;0hj;}{|3PW-C=je1Xc`HgoV`V+{Zc~44pk^L zwyoU7*L7f7Ln}Vu5n6_2HW8(oiz?5o!YoWr6PWYw?M^=TVKRLcgLX0kxi6zCl)kgQ zh_IvsFPd04`wW5P_I)fx#T(czl(u7xrEW$tV6w^iUI2EOt;{6;9qCdZj;w<~= z#Hg}-A|}cra6pM;4*PY|3G~o@bty(Dlxk#3qnzCMeqd8QdIWBo``y^+%La+qBvy1M z$0qX;8(C*9Vcu}ib_M5zV==d$Utd|rcE4u>egg;#?GljC<#IKm&7JFcsEGkKgf0DE zh}l=m6ps%z<^qN&La6dF(8?mGZPScqq#%;Po2EliuRwC}$z;yh>G#%b95kniaRCD! z=@)!9-?v$Ni2-^Y!Yf;JpubDUlr z-_aCiF>18n!a~OA+WhI`imU-uCfn(WioJ<<@8 zNX@bib!v+GCrcPJ1R-?`s#J(A<>c8 zK`L>!^XjmnNnGlsyxHBAWDo|Zow~YuVN5z?k|ncOTi%~;kXYwWb%5bL!nA2s>xZJW zKIu;@o4@3>@>D#&v)$O>dfCub$!rnJ-15YZw#z_a{LKK(=G3sT3#Wi5%OZ5{eoK*7 z>^19!I4m=D5uR*iV4_@Ys3xB4-o%)UOS)3VWw&sOngMu&V#|vuRHEGiB@%+(&WnN)h$6rsm4W)+7wD@Vd z%IYR`#T= z$ol>FY#1^ii-kvUpiAZ@H0sNcTD}hdUjx@zS21(j7uj|_t$b|2Dr3d@*LoIu(Qthf zpxI`3trfRxFZtB-h6xqCQEhX4<3VBTsV~-0nZsuR3>jXp14oOn28cx$CC!@Y`q{D= zvbzXqUR<8LfHW+R%nlG-I#3z849yWyoxLzF6QL51%q=XAxIhN5ESw~#^Lr>wNoQ(0 zUvq9CC&(IicsMsuH+>0uK)l5 literal 0 HcmV?d00001 diff --git a/ci/block_evidence.py b/ci/block_evidence.py index fed6f8d..556404e 100644 --- a/ci/block_evidence.py +++ b/ci/block_evidence.py @@ -1,7 +1,8 @@ """Read committed transactions for narrow, offline evidence checks. -This is not a consensus validator: no script execution, UTXO lookup or -historical chain reconstruction takes place here. +This is not a consensus validator: no UTXO lookup or historical chain +reconstruction takes place here, and the only script execution is the +library's evaluation of one named input for the P2SH rule. Transaction IDs and the merkle root bind the checked non-witness data to the Bitcoin header. Parsing consumes the entire file so truncation cannot satisfy a rule's requirement for a complete block body. @@ -16,7 +17,8 @@ from collections.abc import Mapping, Sequence from typing import TypeVar -from bitcoin.core import COIN, CBlock, CoreMainParams, CTransaction, Hash as sha256d, MoneyRange, b2lx, lx +from bitcoin.core import COIN, CBlock, CoreMainParams, CTransaction, Hash as sha256d, MoneyRange, ValidationError, b2lx, lx +from bitcoin.core.scripteval import SCRIPT_VERIFY_P2SH, VerifyScript, VerifySignature from bitcoin.core.script import ( CScript, CScriptInvalidError, CScriptOp, OP_1, OP_16, OP_CHECKSIG, OP_CHECKSIGVERIFY, OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY, @@ -115,6 +117,33 @@ def reuses_parent_transaction(block: CBlock, parent_txids: Sequence[str], txid: and any(not tx.is_coinbase() and tx.GetTxid() == target for tx in block.vtx[1:])) +def spending_input(transactions: Sequence[CTransaction], txid: bytes, vout: int) -> tuple[CTransaction, int]: + """Return the one non-coinbase input among these transactions that spends the outpoint.""" + spends = [(tx, index) for tx in transactions if not tx.is_coinbase() + for index, txin in enumerate(tx.vin) if txin.prevout.hash == txid and txin.prevout.n == vout] + if len(spends) != 1: + raise ValueError(f"outpoint {b2lx(txid)}:{vout} must be spent by exactly one input") + return spends[0] + + +def p2sh_spend_fails(tx: CTransaction, index: int, previous: CTransaction) -> bool: + """Require the input to pass without P2SH and fail once the redeem script is executed. + + VerifySignature binds the input to the previous transaction's output and + evaluates it with no flags; the caller authenticates that transaction by txid. + """ + try: + VerifySignature(previous, tx, index) + except ValidationError as error: + raise ValueError(f"input fails even without P2SH evaluation: {error}") from error + script_pubkey = previous.vout[tx.vin[index].prevout.n].scriptPubKey + try: + VerifyScript(tx.vin[index].scriptSig, script_pubkey, tx, index, flags=(SCRIPT_VERIFY_P2SH,)) + except ValidationError: + return True + return False + + def establishes_rule(block: CBlock, rule: str) -> bool: """Recognize only failures provable from these committed transactions. diff --git a/ci/sanity-check.py b/ci/sanity-check.py index f2f7d7a..ea53b7e 100644 --- a/ci/sanity-check.py +++ b/ci/sanity-check.py @@ -22,7 +22,8 @@ from bitcoin.core.serialize import uint256_from_compact from block_evidence import ( - MAX_BLOCK_SIGOPS_COST, coinbase_amounts, confirmed_at_or_after, establishes_rule, omitted_prevouts, + MAX_BLOCK_SIGOPS_COST, coinbase_amounts, confirmed_at_or_after, establishes_rule, omitted_prevouts, p2sh_spend_fails, + spending_input, read_block, reuses_parent_transaction, sigop_cost, verify_witness_commitment, ) from prevouts import ( @@ -34,7 +35,7 @@ REQUIRED = {"height", "hash", "header", "prev_hash", "nTime", "core_reject_reason", "rule"} CONTEXT_FIELDS = { "expected_nbits", "parent_mtp", "coinbase_height", "coinbase_scriptsig_hex", - "pool", "pool_basis", "parent_kind", "missing_prevout", "parent_txid", + "pool", "pool_basis", "parent_kind", "missing_prevout", "parent_txid", "failing_prevout", } OUTPOINT = re.compile(r"[0-9a-f]{64}:(?:0|[1-9][0-9]*)") OBSERVATION_REQUIRED = {"channel", "source", "provenance"} @@ -44,13 +45,14 @@ PARENT_KINDS = {"canonical", "stale", "invalid"} POOL_BASES = {"tag", "reported", "address"} POW_LIMIT = 0xFFFF << (8 * (0x1D - 3)) +BIP16_TIME = 1333238400 # 1 April 2012, when 2012 nodes began executing P2SH redeem scripts # 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; cb_amount = body plus canonical -# parent and fee prevouts. -# Rule names and reject strings must +# parent and fee prevouts; p2sh = body plus the spent output of the named +# input. Rule names and reject strings must # match docs/schema.md. RULES = { "bad-txns-vout-toolarge": ("bad-txns-vout-toolarge", (), "body"), @@ -60,6 +62,7 @@ "missing_unconfirmed_parent": ("bad-txns-inputs-missingorspent", ("missing_prevout",), "missing_parent"), "already_confirmed_in_parent": ("bad-txns-inputs-missingorspent", ("parent_txid", "parent_kind", "coinbase_height", "coinbase_scriptsig_hex"), "parent_txid_reuse"), + "p2sh_redeem_script_failure": ("block-script-verify-flag-failed", ("failing_prevout",), "p2sh"), "bip34_v2_coinbase_height_mismatch": ( "bad-cb-height", ("coinbase_height", "coinbase_scriptsig_hex"), "local"), "bip34_coinbase_height_mismatch": ( @@ -178,9 +181,9 @@ def check_context(record: dict[str, Any]) -> None: raise ValueError("pool_basis requires pool") if "parent_txid" in details: hex_value(details, "parent_txid", 32) - if "missing_prevout" in details and not ( - isinstance(details["missing_prevout"], str) and OUTPOINT.fullmatch(details["missing_prevout"])): - raise ValueError("missing_prevout must be txid:vout in lowercase hex") + for name in ("missing_prevout", "failing_prevout"): + if name in details and not (isinstance(details[name], str) and OUTPOINT.fullmatch(details[name])): + raise ValueError(f"{name} must be txid:vout in lowercase hex") if "parent_kind" in details and details["parent_kind"] not in tuple(PARENT_KINDS): raise ValueError(f"parent_kind must be one of {sorted(PARENT_KINDS)}") required = set(RULES[record["rule"]][1]) @@ -289,6 +292,8 @@ def check_local_evidence(record: dict[str, Any], header: CBlockHeader) -> None: raise ValueError("scriptSig has the correct BIP34 height prefix") if rule == "bip34_coinbase_height_missing" and script_height(script) is not None: raise ValueError("missing-height rule requires no decodable height prefix") + if rule == "p2sh_redeem_script_failure" and record["nTime"] < BIP16_TIME: + raise ValueError("P2SH rule requires nTime at or after BIP16 activation") if rule == "coinbase_scriptsig_length_above_100" and len(script) <= 100: raise ValueError("coinbase scriptSig must exceed 100 bytes") @@ -329,6 +334,11 @@ def check_failure_evidence(record: dict[str, Any], block: CBlock | None, prevout 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 == "p2sh": + txid, vout = record["context"]["failing_prevout"].split(":") + tx, index = spending_input(block.vtx, lx(txid), int(vout)) + if not p2sh_spend_fails(tx, index, load_transaction(txid, prevouts_dir, fetch_prevouts, apis)): + raise ValueError("named input does not fail P2SH evaluation") 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 b36fc7c..96fee66 100644 --- a/ci/test_block_evidence.py +++ b/ci/test_block_evidence.py @@ -6,10 +6,20 @@ from bitcoin.core.script import CScript, CScriptWitness, OP_TRUE from block_evidence import ( - MAX_MONEY, coinbase_amounts, confirmed_at_or_after, establishes_rule, omitted_prevouts, read_block, read_transaction, - reuses_parent_transaction, sha256d, sigop_count, witness_sigops, + MAX_MONEY, coinbase_amounts, confirmed_at_or_after, establishes_rule, omitted_prevouts, p2sh_spend_fails, read_block, + read_transaction, reuses_parent_transaction, sha256d, sigop_count, witness_sigops, ) +# The 123-byte spend included by 89 blocks in April to July 2012, and the transaction that funded it. +P2SH_SPEND = bytes.fromhex( + "01000000019dc23528f5a5f376da3f3f4efd45be8c5b551abdb8093940e0b313de459a53b00100000026255121029c7187ecea7f09146820075c3a8d" + "e5d33ffbc293b63228ea1667c8d3796aff3f51aeffffffff0130570500000000001976a9147288ca9e213c54cbb2094f00bcf33bfbce691dbb88ac00000000") +P2SH_FUNDING = bytes.fromhex( + "0100000001f6ea284ec7521f8a7d094a6cf4e6873098b90f90725ffd372b343189d7a4089c000000006c4930460221009d1055704950ab3b695c7215" + "0169e5a41ccd7757b15185dc298e85112ca7fea1022100e979474bae5d7cb44e5149af8b146eab1cb237646094c99eae07579981b2eeae0121025801" + "704c59321b645109931691c996a0ae797cf155a5ece34bdc065e6b5437a1ffffffff02fc0a0300000000001976a9145a3acbc7bbcc97c5ff16f5909c" + "9d7d3fadb293a888ac801a06000000000017a914e8c300c87986efa84c37c0519929019ef86eb5b48700000000") + def transaction(prev_hash=bytes(32), vout=0xffffffff, amount=1, witness=False): """Serialize a one-input, one-output transaction and its stripped form.""" @@ -82,6 +92,15 @@ def test_invalid_block_serialization(self): with self.subTest(case=case), self.assertRaises(ValueError): read_block(wire) + def test_p2sh_spend_passes_legacy_and_fails_p2sh(self): + """The 2012 spend fails only once the redeem script runs; a spend that fails regardless is not evidence.""" + spend, funding = read_transaction(P2SH_SPEND), read_transaction(P2SH_FUNDING) + self.assertEqual(spend.vin[0].prevout.hash, funding.GetTxid()) + self.assertTrue(p2sh_spend_fails(spend, 0, funding)) + wrong = CTransaction([CTxIn(spend.vin[0].prevout, CScript([b"\x51"]))], spend.vout) + with self.subTest(case="fails without P2SH"), self.assertRaisesRegex(ValueError, "even without P2SH"): + p2sh_spend_fails(wrong, 0, funding) + def test_parent_transaction_reuse_excludes_coinbases_and_absent_transactions(self): """The named witness must be a non-coinbase transaction present in both blocks.""" coinbase = transaction() diff --git a/ci/test_sanity_check.py b/ci/test_sanity_check.py index 902256f..f809421 100644 --- a/ci/test_sanity_check.py +++ b/ci/test_sanity_check.py @@ -219,6 +219,18 @@ def test_parent_reuse_requires_canonical_parent_and_matching_witness(self): (cache / f"height-{self.record['height'] - 1}.hash").write_text(parent) self.assertTrue(any("missing cached parent header" in p for p in self.validate(prevouts_dir=cache))) + def test_p2sh_failure_requires_named_spend_after_activation(self): + """Admit a P2SH body from cached evidence; reject an unspent outpoint, a pre-BIP16 time and a missing cache.""" + self.record = self.for_rule("p2sh_redeem_script_failure") + self.copy_body(self.record) + self.assertEqual(self.validate(), []) + with self.subTest(case="outpoint not spent"), patch.dict(self.record["context"], {"failing_prevout": "00" * 32 + ":0"}): + self.assertTrue(any("exactly one input" in p for p in self.validate())) + with self.subTest(case="before activation"), patch.object(CHECK, "BIP16_TIME", 2 ** 31): + self.assertTrue(any("BIP16 activation" in p for p in self.validate())) + with self.subTest(case="missing cache"): + self.assertTrue(any("missing cached" in p for p in self.validate(prevouts_dir=self.root / "empty"))) + def test_body_matches_claimed_evidence(self): """Bind the named failure and supplied coinbase scriptSig to the available body.""" self.record = self.for_rule("bad-txns-vout-toolarge") diff --git a/data/invalid-blocks.jsonl b/data/invalid-blocks.jsonl index 3a777d7..cf48879 100644 --- a/data/invalid-blocks.jsonl +++ b/data/invalid-blocks.jsonl @@ -1,4 +1,8 @@ {"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":173928,"hash":"000000000000023df73ac98923e2de321db3e3396102ad5dcfe3b25f01a81f64","header":"010000007c9c506afb390a2d2388588c790447f6d1065fa3e720bd56a106000000000000ed2ee7a93da92de85c3c433dce5be44ef368a7eaa2075adba237e7437226a44f35bd784f7e500a1a8a365d00","prev_hash":"00000000000006a156bd20e7a35f06d1f64704798c5888232d0a39fb6a509c7c","nTime":1333312821,"core_reject_reason":"block-script-verify-flag-failed","rule":"p2sh_redeem_script_failure","context":{"coinbase_scriptsig_hex":"1265636f406f7a636f2e696e202f503253482f0435bd784f0288142cfabe6d6d79789d63ff5b8fa4544dc0fb62998383ec1d79146b9ec89bb79c2aef3a3af2ba0100000000000000","pool":"OzCoin","pool_basis":"tag","parent_kind":"canonical","failing_prevout":"b0539a45de13b3e0403909b8bd1a555b8cbe45fd4e3f3fda76f3a5f52835c29d:1"},"observations":[{"channel":"merge_mining","source":"merge-mining-research","provenance":"https://github.com/deadmanoz/merge-mining-research/blob/629039bc8023bdaaafd9470e29051f9acc43973c/data/child-identity/namecoin_child_identity.csv#L163","child_chain":"namecoin","child_height":49691,"child_block_hash":"79789d63ff5b8fa4544dc0fb62998383ec1d79146b9ec89bb79c2aef3a3af2ba","child_block_time":1333312853},{"channel":"scrape","source":"blockchain.com","provenance":"https://web.archive.org/web/20120409062117id_/http://blockchain.info:80/block-index/202136"}]} +{"height":173957,"hash":"00000000000001bd778cffee5b5bae4c7b8d56a9aca955a04c60856b31b11155","header":"01000000da8dd3abd3104cf7b86cc7c85dfe0449e728a2a6ab6812a9a9060000000000002fc67cab928ab7767a7f19d10d33a96057031f562049d94c98c510a46db36ab0900d794f7e500a1a01f61748","prev_hash":"00000000000006a9a91268aba6a228e74904fe5dc8c76cb8f74c10d3abd38dda","nTime":1333333392,"core_reject_reason":"block-script-verify-flag-failed","rule":"p2sh_redeem_script_failure","context":{"coinbase_scriptsig_hex":"1265636f406f7a636f2e696e202f503253482f04900d794f02e2012cfabe6d6d4010fa4be6e64892c469796f0b9a26c7cb2602d58fdc6cd22e545b93189e27da0100000000000000","pool":"OzCoin","pool_basis":"tag","parent_kind":"canonical","failing_prevout":"b0539a45de13b3e0403909b8bd1a555b8cbe45fd4e3f3fda76f3a5f52835c29d:1"},"observations":[{"channel":"merge_mining","source":"merge-mining-research","provenance":"https://github.com/deadmanoz/merge-mining-research/blob/629039bc8023bdaaafd9470e29051f9acc43973c/data/child-identity/namecoin_child_identity.csv#L164","child_chain":"namecoin","child_height":49718,"child_block_hash":"4010fa4be6e64892c469796f0b9a26c7cb2602d58fdc6cd22e545b93189e27da","child_block_time":1333332848},{"channel":"scrape","source":"blockchain.com","provenance":"https://web.archive.org/web/20120409062147id_/http://blockchain.info:80/block-index/202222"}]} +{"height":173998,"hash":"00000000000003bf4a1e491c802eeec3f1fbf3c2c7299e7935c2b0f33b189651","header":"010000005e2ffb38eb012a6a3db86b26a9860aa796c49f269a290b09ce06000000000000437b7ec39f4bc8d2de5046215007a7cd8643d76f7f5c5cda8ba4ca7886ededf5c785794f7e500a1a3ee1de47","prev_hash":"00000000000006ce090b299a269fc496a70a86a9266bb83d6a2a01eb38fb2f5e","nTime":1333364167,"core_reject_reason":"block-script-verify-flag-failed","rule":"p2sh_redeem_script_failure","context":{"coinbase_scriptsig_hex":"70736a047e500a1a048e073a00522cfabe6d6dfaf5f62042f9e4bc45be832f5de3c8ba251b1fb5731f997bb0826857b1b4066701000000000000006e6d636269742e636f6dac1eeeed88","pool":"NMCbit","pool_basis":"tag","parent_kind":"canonical","failing_prevout":"b0539a45de13b3e0403909b8bd1a555b8cbe45fd4e3f3fda76f3a5f52835c29d:1"},"observations":[{"channel":"merge_mining","source":"merge-mining-research","provenance":"https://github.com/deadmanoz/merge-mining-research/blob/629039bc8023bdaaafd9470e29051f9acc43973c/data/child-identity/namecoin_child_identity.csv#L166","child_chain":"namecoin","child_height":49773,"child_block_hash":"faf5f62042f9e4bc45be832f5de3c8ba251b1fb5731f997bb0826857b1b40667","child_block_time":1333364075},{"channel":"scrape","source":"blockchain.com","provenance":"https://web.archive.org/web/20120409062156id_/http://blockchain.info:80/block-index/202359"}]} +{"height":174605,"hash":"000000000000068294db0526cb4a5520d21b9d4f271a34012e96784b3b3168c5","header":"010000008a5b519c7220e14a365bf1aa213d76ffd86026d72bf9e2a016000000000000006523afe67fa541a46218b5dc53cd1630c61ddcb197e4202b15a342e7ec79c9fe28bb7f4f7e500a1a9e93b2f5","prev_hash":"0000000000000016a0e2f92bd72660d8ff763d21aaf15b364ae120729c515b8a","nTime":1333771048,"core_reject_reason":"block-script-verify-flag-failed","rule":"p2sh_redeem_script_failure","context":{"coinbase_scriptsig_hex":"047e500a1a0177522cfabe6d6d591bc1f842bb323ad07c7d38c984b5a2da9422dcf907fbc6fca2a51e3e3c196e0100000000000000","parent_kind":"canonical","failing_prevout":"b0539a45de13b3e0403909b8bd1a555b8cbe45fd4e3f3fda76f3a5f52835c29d:1"},"observations":[{"channel":"merge_mining","source":"merge-mining-research","provenance":"https://github.com/deadmanoz/merge-mining-research/blob/629039bc8023bdaaafd9470e29051f9acc43973c/data/child-identity/namecoin_child_identity.csv#L172","child_chain":"namecoin","child_height":50516,"child_block_hash":"591bc1f842bb323ad07c7d38c984b5a2da9422dcf907fbc6fca2a51e3e3c196e","child_block_time":1333770799},{"channel":"scrape","source":"blockchain.com","provenance":"https://web.archive.org/web/20120409062031id_/http://blockchain.info:80/block-index/204692"}]} {"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"}]} diff --git a/docs/notes.md b/docs/notes.md index bde05a3..1ddb180 100644 --- a/docs/notes.md +++ b/docs/notes.md @@ -41,6 +41,21 @@ Core skips BIP30 checks below height 1983702 on the known mainnet chain after BI A 2026-09-15 sweep of all 1086 stale-blocks bodies at [be1e859](https://github.com/bitcoin-data/stale-blocks/commit/be1e8597615c3372aab9ca437a9cd554822b6870) found no other non-coinbase intersection among the 1073 bodies extending canonical parents; 13 extended noncanonical parents and were out of scope. A negative result does not establish that a block satisfies every consensus rule. +### 173928, 173957, 173998 and 174605 - P2SH redeem-script failure (2012) + +Each body includes the same 123-byte transaction, `4005d6bea3a93fb72f006d23e2685b85069d270cb57d15f0c057ef2d5e3f78d2`, which spends a pay-to-script-hash output funded at canonical 170054, `b0539a45de13b3e0403909b8bd1a555b8cbe45fd4e3f3fda76f3a5f52835c29d:1`, worth 400000 satoshis. +Its scriptSig pushes only the redeem script, a 1-of-1 `OP_CHECKMULTISIG`. +The pre-BIP16 template check hashes that push and compares it, 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 how the same transaction was included by many miners for months. +Core today reports `block-script-verify-flag-failed (Operation not valid with the current stack size)`. + +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. +They hold 67, 64, 23 and 14 transactions in 31258, 41258, 7662 and 4855 bytes. +CI fetches the funding transaction, checks its txid, and evaluates the named input with and without P2SH. +The blockchain.info block pages archived by the Wayback Machine in April 2012 list each block's transactions. +The [2 April 2012 bitcoin-dev log](https://buildingbitcoin.org/bitcoin-dev/log-2012-04-02.html) records the first `P2SH VerifySignature failed` rejections and the [4 April log](https://buildingbitcoin.org/bitcoin-dev/log-2012-04-04.html) preserves the transaction. +Eighty-five further blocks carry the same spend with authenticated inclusion proofs but no complete body; they need a proof-based admission path. + ### 74638 - value overflow (2010) `bad-txns-vout-toolarge` is the 2010 overflow incident ([CVE-2010-5139](https://en.bitcoin.it/wiki/Value_overflow_incident)). diff --git a/docs/schema.md b/docs/schema.md index a576033..ae20e6a 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, parent-transaction reuse and fee accounting rules additionally require evidence fetched from public APIs or verified cache entries. +Body rules require a complete block; sigops, missing-parent, parent-transaction reuse, fee accounting and P2SH 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. @@ -44,10 +44,11 @@ Context is shared across observations; adding another witness does not duplicate | `coinbase_height` | integer | Height decoded from the BIP34 scriptSig prefix. Required for a BIP34 height mismatch and `already_confirmed_in_parent`. | | `coinbase_scriptsig_hex` | string | Coinbase input scriptSig. Required for BIP34 failures, `coinbase_scriptsig_length_above_100` and `already_confirmed_in_parent`. | | `pool` | string | Pool the block is attributed to, when known. Requires `pool_basis`. | -| `pool_basis` | string | How the pool was identified: `tag` when the pool name appears as a tag in the coinbase scriptSig, `address` when the coinbase payout address is listed for the pool in [mining-pools](https://github.com/bitcoin-data/mining-pools), or `reported` when only a contemporaneous report names the pool. Required whenever `pool` is present and not allowed otherwise. Descriptive: CI checks the value, not the attribution. | +| `pool_basis` | string | How the pool was identified: `tag` when the coinbase scriptSig carries the pool's name or a tag [mining-pools](https://github.com/bitcoin-data/mining-pools) lists for it, `address` when the coinbase payout address is listed for the pool in [mining-pools](https://github.com/bitcoin-data/mining-pools), or `reported` when only a contemporaneous report names the pool. Required whenever `pool` is present and not allowed otherwise. Descriptive: CI checks the value, not the attribution. | | `parent_kind` | string | Chain status of the previous block: `canonical`, `stale`, or `invalid`. `invalid` means the previous block is in this dataset. Descriptive, except that the rules which look up the canonical block at the previous height (`missing_unconfirmed_parent`, `already_confirmed_in_parent`) reject any other value. | | `missing_prevout` | string | Outpoint as `txid:vout`, spent by a non-coinbase input whose transaction is not in the block. Required for `missing_unconfirmed_parent`. | | `parent_txid` | string | Lowercase 64-hex txid of a non-coinbase transaction in both the candidate and its canonical parent. Required for `already_confirmed_in_parent`. | +| `failing_prevout` | string | Outpoint as `txid:vout`, spent by the input whose P2SH evaluation fails. Required for `p2sh_redeem_script_failure`. | ## Optional `observations` array @@ -89,7 +90,7 @@ Core functions live in [bitcoin/bitcoin](https://github.com/bitcoin/bitcoin): - [src/consensus/tx_check.cpp](https://github.com/bitcoin/bitcoin/blob/master/src/consensus/tx_check.cpp): `CheckTransaction` - [src/consensus/tx_verify.cpp](https://github.com/bitcoin/bitcoin/blob/master/src/consensus/tx_verify.cpp): `CheckTxInputs`, `GetTransactionSigOpCost` - [src/script/script.cpp](https://github.com/bitcoin/bitcoin/blob/master/src/script/script.cpp): `GetSigOpCount` -- [src/script/interpreter.cpp](https://github.com/bitcoin/bitcoin/blob/master/src/script/interpreter.cpp): `CountWitnessSigOps` +- [src/script/interpreter.cpp](https://github.com/bitcoin/bitcoin/blob/master/src/script/interpreter.cpp): `CountWitnessSigOps`, `EvalScript` | `rule` | `core_reject_reason` | Typical Core check | | --- | --- | --- | @@ -99,6 +100,7 @@ Core functions live in [bitcoin/bitcoin](https://github.com/bitcoin/bitcoin): | `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` | +| `p2sh_redeem_script_failure` | `block-script-verify-flag-failed` | `ConnectBlock` via `CheckInputScripts` | | `bip34_v2_coinbase_height_mismatch` | `bad-cb-height` | `ContextualCheckBlock` | | `bip34_coinbase_height_mismatch` | `bad-cb-height` | `ContextualCheckBlock` | | `bip34_coinbase_height_missing` | `bad-cb-height` | `ContextualCheckBlock` | @@ -128,6 +130,7 @@ A provenance URL cannot bypass these requirements. | `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. | +| `p2sh_redeem_script_failure` | A complete block with header time at or after 1 April 2012 whose named `failing_prevout` is spent by exactly one input in the body. That input must pass script evaluation without P2SH and fail with it, checked against the authenticated previous transaction. | | `bad-blk-sigops` | A complete block at mainnet height 481824 or later, authenticated previous transactions for every external input, and calculated BIP16/BIP141 sigop cost above 80000. | | `bip34_v2_coinbase_height_mismatch` | Both coinbase context fields, decoded height matching the scriptSig, and a scriptSig that lacks the exact expected BIP34 prefix. Header version must be at least 2 and height below 227931. Applicability of the historical rolling-version threshold still requires review. | | `bip34_coinbase_height_mismatch` | Both coinbase context fields, decoded height matching the scriptSig, and a scriptSig that lacks the exact expected BIP34 prefix, at height 227931 or later. A non-minimal encoding of the right number also fails the prefix check. | @@ -240,3 +243,14 @@ Otherwise `ci/prevouts.py` loads every external input's transaction and verifies 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. + +## P2SH redeem script evidence + +`p2sh_redeem_script_failure` covers a spend of a pay-to-script-hash output that satisfies the pre-BIP16 template check but fails once the redeem script is executed. +Nodes of 2012 executed redeem scripts for blocks timestamped from 1 April 2012 (Unix time 1333238400), so the record's `nTime` must be at or after that time. +Bitcoin Core today applies P2SH from genesis, with one historical exception at block 170060 (`script_flag_exceptions` in `src/kernel/chainparams.cpp`), and reports the failure as `block-script-verify-flag-failed` with the script error in parentheses. + +`failing_prevout` names the spent output. +CI finds the one input in the body that spends it, fetches and authenticates the previous transaction through the sigops cache, and evaluates that input twice with python-bitcoinlib: `VerifySignature` binds it to the previous output and runs it with no flags, then `VerifyScript` runs it with `SCRIPT_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; it is not Bitcoin Core's interpreter and does not validate the other inputs in the block.