@@ -74,6 +74,10 @@ def serialize(self, with_witness=False):
74
74
def normal_serialize (self ):
75
75
return super ().serialize ()
76
76
77
+
78
+ DUPLICATE_COINBASE_SCRIPT_SIG = b'\x01 \x78 ' # Valid for block at height 120
79
+
80
+
77
81
class FullBlockTest (BitcoinTestFramework ):
78
82
def set_test_params (self ):
79
83
self .num_nodes = 1
@@ -96,6 +100,13 @@ def run_test(self):
96
100
self .spendable_outputs = []
97
101
98
102
# Create a new block
103
+ b_dup_cb = self .next_block ('dup_cb' )
104
+ b_dup_cb .vtx [0 ].vin [0 ].scriptSig = DUPLICATE_COINBASE_SCRIPT_SIG
105
+ b_dup_cb .vtx [0 ].rehash ()
106
+ duplicate_tx = b_dup_cb .vtx [0 ]
107
+ b_dup_cb = self .update_block ('dup_cb' , [])
108
+ self .send_blocks ([b_dup_cb ])
109
+
99
110
b0 = self .next_block (0 )
100
111
self .save_spendable_output ()
101
112
self .send_blocks ([b0 ])
@@ -750,7 +761,7 @@ def run_test(self):
750
761
751
762
# Test a few invalid tx types
752
763
#
753
- # -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17 )
764
+ # -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 ()
754
765
# \-> ??? (17)
755
766
#
756
767
@@ -776,35 +787,59 @@ def run_test(self):
776
787
777
788
# reset to good chain
778
789
self .move_tip (57 )
779
- b60 = self .next_block (60 , spend = out [ 17 ] )
790
+ b60 = self .next_block (60 )
780
791
self .send_blocks ([b60 ], True )
781
792
self .save_spendable_output ()
782
793
783
- # Test BIP30
794
+ # Test BIP30 (reject duplicate)
784
795
#
785
- # -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17 )
786
- # \-> b61 (18 )
796
+ # -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 ()
797
+ # \-> b61 ()
787
798
#
788
799
# Blocks are not allowed to contain a transaction whose id matches that of an earlier,
789
800
# not-fully-spent transaction in the same chain. To test, make identical coinbases;
790
801
# the second one should be rejected.
791
802
#
792
803
self .log .info ("Reject a block with a transaction with a duplicate hash of a previous transaction (BIP30)" )
793
804
self .move_tip (60 )
794
- b61 = self .next_block (61 , spend = out [ 18 ] )
795
- b61 .vtx [0 ].vin [0 ].scriptSig = b60 . vtx [ 0 ]. vin [ 0 ]. scriptSig # Equalize the coinbases
805
+ b61 = self .next_block (61 )
806
+ b61 .vtx [0 ].vin [0 ].scriptSig = DUPLICATE_COINBASE_SCRIPT_SIG
796
807
b61 .vtx [0 ].rehash ()
797
808
b61 = self .update_block (61 , [])
798
- assert_equal (b60 . vtx [ 0 ] .serialize (), b61 .vtx [0 ].serialize ())
809
+ assert_equal (duplicate_tx .serialize (), b61 .vtx [0 ].serialize ())
799
810
self .send_blocks ([b61 ], success = False , reject_reason = 'bad-txns-BIP30' , reconnect = True )
800
811
812
+ # Test BIP30 (allow duplicate if spent)
813
+ #
814
+ # -> b57 (16) -> b60 ()
815
+ # \-> b_spend_dup_cb (b_dup_cb) -> b_dup_2 ()
816
+ #
817
+ self .move_tip (57 )
818
+ b_spend_dup_cb = self .next_block ('spend_dup_cb' )
819
+ tx = CTransaction ()
820
+ tx .vin .append (CTxIn (COutPoint (duplicate_tx .sha256 , 0 )))
821
+ tx .vout .append (CTxOut (0 , CScript ([OP_TRUE ])))
822
+ self .sign_tx (tx , duplicate_tx )
823
+ tx .rehash ()
824
+ b_spend_dup_cb = self .update_block ('spend_dup_cb' , [tx ])
825
+
826
+ b_dup_2 = self .next_block ('dup_2' )
827
+ b_dup_2 .vtx [0 ].vin [0 ].scriptSig = DUPLICATE_COINBASE_SCRIPT_SIG
828
+ b_dup_2 .vtx [0 ].rehash ()
829
+ b_dup_2 = self .update_block ('dup_2' , [])
830
+ assert_equal (duplicate_tx .serialize (), b_dup_2 .vtx [0 ].serialize ())
831
+ assert_equal (self .nodes [0 ].gettxout (txid = duplicate_tx .hash , n = 0 )['confirmations' ], 119 )
832
+ self .send_blocks ([b_spend_dup_cb , b_dup_2 ], success = True )
833
+ # The duplicate has less confirmations
834
+ assert_equal (self .nodes [0 ].gettxout (txid = duplicate_tx .hash , n = 0 )['confirmations' ], 1 )
835
+
801
836
# Test tx.isFinal is properly rejected (not an exhaustive tx.isFinal test, that should be in data-driven transaction tests)
802
837
#
803
- # -> b39 (11 ) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17 )
804
- # \-> b62 (18)
838
+ # -> b_spend_dup_cb (b_dup_cb ) -> b_dup_2 ( )
839
+ # \-> b62 (18)
805
840
#
806
841
self .log .info ("Reject a block with a transaction with a nonfinal locktime" )
807
- self .move_tip (60 )
842
+ self .move_tip ('dup_2' )
808
843
b62 = self .next_block (62 )
809
844
tx = CTransaction ()
810
845
tx .nLockTime = 0xffffffff # this locktime is non-final
@@ -817,11 +852,11 @@ def run_test(self):
817
852
818
853
# Test a non-final coinbase is also rejected
819
854
#
820
- # -> b39 (11 ) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17 )
821
- # \-> b63 (-)
855
+ # -> b_spend_dup_cb (b_dup_cb ) -> b_dup_2 ( )
856
+ # \-> b63 (-)
822
857
#
823
858
self .log .info ("Reject a block with a coinbase transaction with a nonfinal locktime" )
824
- self .move_tip (60 )
859
+ self .move_tip ('dup_2' )
825
860
b63 = self .next_block (63 )
826
861
b63 .vtx [0 ].nLockTime = 0xffffffff
827
862
b63 .vtx [0 ].vin [0 ].nSequence = 0xDEADBEEF
@@ -837,14 +872,14 @@ def run_test(self):
837
872
# What matters is that the receiving node should not reject the bloated block, and then reject the canonical
838
873
# block on the basis that it's the same as an already-rejected block (which would be a consensus failure.)
839
874
#
840
- # -> b39 (11 ) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17 ) -> b64 (18)
841
- # \
842
- # b64a (18)
875
+ # -> b_spend_dup_cb (b_dup_cb ) -> b_dup_2 ( ) -> b64 (18)
876
+ # \
877
+ # b64a (18)
843
878
# b64a is a bloated block (non-canonical varint)
844
879
# b64 is a good block (same as b64 but w/ canonical varint)
845
880
#
846
881
self .log .info ("Accept a valid block even if a bloated version of the block has previously been sent" )
847
- self .move_tip (60 )
882
+ self .move_tip ('dup_2' )
848
883
regular_block = self .next_block ("64a" , spend = out [18 ])
849
884
850
885
# make it a "broken_block," with non-canonical serialization
@@ -870,7 +905,7 @@ def run_test(self):
870
905
node .disconnect_p2ps ()
871
906
self .reconnect_p2p ()
872
907
873
- self .move_tip (60 )
908
+ self .move_tip ('dup_2' )
874
909
b64 = CBlock (b64a )
875
910
b64 .vtx = copy .deepcopy (b64a .vtx )
876
911
assert_equal (b64 .hash , b64a .hash )
@@ -882,7 +917,7 @@ def run_test(self):
882
917
883
918
# Spend an output created in the block itself
884
919
#
885
- # -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17 ) -> b64 (18) -> b65 (19)
920
+ # -> b_dup_2 ( ) -> b64 (18) -> b65 (19)
886
921
#
887
922
self .log .info ("Accept a block with a transaction spending an output created in the same block" )
888
923
self .move_tip (64 )
@@ -895,8 +930,8 @@ def run_test(self):
895
930
896
931
# Attempt to spend an output created later in the same block
897
932
#
898
- # -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19)
899
- # \-> b66 (20)
933
+ # -> b64 (18) -> b65 (19)
934
+ # \-> b66 (20)
900
935
self .log .info ("Reject a block with a transaction spending an output created later in the same block" )
901
936
self .move_tip (65 )
902
937
b66 = self .next_block (66 )
@@ -907,8 +942,8 @@ def run_test(self):
907
942
908
943
# Attempt to double-spend a transaction created in a block
909
944
#
910
- # -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19)
911
- # \-> b67 (20)
945
+ # -> b64 (18) -> b65 (19)
946
+ # \-> b67 (20)
912
947
#
913
948
#
914
949
self .log .info ("Reject a block with a transaction double spending a transaction created in the same block" )
@@ -922,8 +957,8 @@ def run_test(self):
922
957
923
958
# More tests of block subsidy
924
959
#
925
- # -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20)
926
- # \-> b68 (20)
960
+ # -> b64 (18) -> b65 (19) -> b69 (20)
961
+ # \-> b68 (20)
927
962
#
928
963
# b68 - coinbase with an extra 10 satoshis,
929
964
# creates a tx that has 9 satoshis from out[20] go to fees
@@ -949,8 +984,8 @@ def run_test(self):
949
984
950
985
# Test spending the outpoint of a non-existent transaction
951
986
#
952
- # -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20)
953
- # \-> b70 (21)
987
+ # -> b65 (19) -> b69 (20)
988
+ # \-> b70 (21)
954
989
#
955
990
self .log .info ("Reject a block containing a transaction spending from a non-existent input" )
956
991
self .move_tip (69 )
@@ -965,8 +1000,8 @@ def run_test(self):
965
1000
966
1001
# Test accepting an invalid block which has the same hash as a valid one (via merkle tree tricks)
967
1002
#
968
- # -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20) -> b72 (21)
969
- # \-> b71 (21)
1003
+ # -> b65 (19) -> b69 (20) -> b72 (21)
1004
+ # \-> b71 (21)
970
1005
#
971
1006
# b72 is a good block.
972
1007
# b71 is a copy of 72, but re-adds one of its transactions. However, it has the same hash as b72.
@@ -994,8 +1029,8 @@ def run_test(self):
994
1029
995
1030
# Test some invalid scripts and MAX_BLOCK_SIGOPS
996
1031
#
997
- # -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20) -> b72 (21)
998
- # \-> b** (22)
1032
+ # -> b69 (20) -> b72 (21)
1033
+ # \-> b** (22)
999
1034
#
1000
1035
1001
1036
# b73 - tx with excessive sigops that are placed after an excessively large script element.
0 commit comments