@@ -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 ])
@@ -758,7 +769,7 @@ def run_test(self):
758
769
759
770
# Test a few invalid tx types
760
771
#
761
- # -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17 )
772
+ # -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 ()
762
773
# \-> ??? (17)
763
774
#
764
775
@@ -784,35 +795,59 @@ def run_test(self):
784
795
785
796
# reset to good chain
786
797
self .move_tip (57 )
787
- b60 = self .next_block (60 , spend = out [ 17 ] )
798
+ b60 = self .next_block (60 )
788
799
self .send_blocks ([b60 ], True )
789
800
self .save_spendable_output ()
790
801
791
- # Test BIP30
802
+ # Test BIP30 (reject duplicate)
792
803
#
793
- # -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17 )
794
- # \-> b61 (18 )
804
+ # -> b39 (11) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 ()
805
+ # \-> b61 ()
795
806
#
796
807
# Blocks are not allowed to contain a transaction whose id matches that of an earlier,
797
808
# not-fully-spent transaction in the same chain. To test, make identical coinbases;
798
809
# the second one should be rejected.
799
810
#
800
811
self .log .info ("Reject a block with a transaction with a duplicate hash of a previous transaction (BIP30)" )
801
812
self .move_tip (60 )
802
- b61 = self .next_block (61 , spend = out [ 18 ] )
803
- b61 .vtx [0 ].vin [0 ].scriptSig = b60 . vtx [ 0 ]. vin [ 0 ]. scriptSig # Equalize the coinbases
813
+ b61 = self .next_block (61 )
814
+ b61 .vtx [0 ].vin [0 ].scriptSig = DUPLICATE_COINBASE_SCRIPT_SIG
804
815
b61 .vtx [0 ].rehash ()
805
816
b61 = self .update_block (61 , [])
806
- assert_equal (b60 . vtx [ 0 ] .serialize (), b61 .vtx [0 ].serialize ())
817
+ assert_equal (duplicate_tx .serialize (), b61 .vtx [0 ].serialize ())
807
818
self .send_blocks ([b61 ], success = False , reject_reason = 'bad-txns-BIP30' , reconnect = True )
808
819
820
+ # Test BIP30 (allow duplicate if spent)
821
+ #
822
+ # -> b57 (16) -> b60 ()
823
+ # \-> b_spend_dup_cb (b_dup_cb) -> b_dup_2 ()
824
+ #
825
+ self .move_tip (57 )
826
+ b_spend_dup_cb = self .next_block ('spend_dup_cb' )
827
+ tx = CTransaction ()
828
+ tx .vin .append (CTxIn (COutPoint (duplicate_tx .sha256 , 0 )))
829
+ tx .vout .append (CTxOut (0 , CScript ([OP_TRUE ])))
830
+ self .sign_tx (tx , duplicate_tx )
831
+ tx .rehash ()
832
+ b_spend_dup_cb = self .update_block ('spend_dup_cb' , [tx ])
833
+
834
+ b_dup_2 = self .next_block ('dup_2' )
835
+ b_dup_2 .vtx [0 ].vin [0 ].scriptSig = DUPLICATE_COINBASE_SCRIPT_SIG
836
+ b_dup_2 .vtx [0 ].rehash ()
837
+ b_dup_2 = self .update_block ('dup_2' , [])
838
+ assert_equal (duplicate_tx .serialize (), b_dup_2 .vtx [0 ].serialize ())
839
+ assert_equal (self .nodes [0 ].gettxout (txid = duplicate_tx .hash , n = 0 )['confirmations' ], 119 )
840
+ self .send_blocks ([b_spend_dup_cb , b_dup_2 ], success = True )
841
+ # The duplicate has less confirmations
842
+ assert_equal (self .nodes [0 ].gettxout (txid = duplicate_tx .hash , n = 0 )['confirmations' ], 1 )
843
+
809
844
# Test tx.isFinal is properly rejected (not an exhaustive tx.isFinal test, that should be in data-driven transaction tests)
810
845
#
811
- # -> b39 (11 ) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17 )
812
- # \-> b62 (18)
846
+ # -> b_spend_dup_cb (b_dup_cb ) -> b_dup_2 ( )
847
+ # \-> b62 (18)
813
848
#
814
849
self .log .info ("Reject a block with a transaction with a nonfinal locktime" )
815
- self .move_tip (60 )
850
+ self .move_tip ('dup_2' )
816
851
b62 = self .next_block (62 )
817
852
tx = CTransaction ()
818
853
tx .nLockTime = 0xffffffff # this locktime is non-final
@@ -825,11 +860,11 @@ def run_test(self):
825
860
826
861
# Test a non-final coinbase is also rejected
827
862
#
828
- # -> b39 (11 ) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17 )
829
- # \-> b63 (-)
863
+ # -> b_spend_dup_cb (b_dup_cb ) -> b_dup_2 ( )
864
+ # \-> b63 (-)
830
865
#
831
866
self .log .info ("Reject a block with a coinbase transaction with a nonfinal locktime" )
832
- self .move_tip (60 )
867
+ self .move_tip ('dup_2' )
833
868
b63 = self .next_block (63 )
834
869
b63 .vtx [0 ].nLockTime = 0xffffffff
835
870
b63 .vtx [0 ].vin [0 ].nSequence = 0xDEADBEEF
@@ -845,14 +880,14 @@ def run_test(self):
845
880
# What matters is that the receiving node should not reject the bloated block, and then reject the canonical
846
881
# block on the basis that it's the same as an already-rejected block (which would be a consensus failure.)
847
882
#
848
- # -> b39 (11 ) -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17 ) -> b64 (18)
849
- # \
850
- # b64a (18)
883
+ # -> b_spend_dup_cb (b_dup_cb ) -> b_dup_2 ( ) -> b64 (18)
884
+ # \
885
+ # b64a (18)
851
886
# b64a is a bloated block (non-canonical varint)
852
887
# b64 is a good block (same as b64 but w/ canonical varint)
853
888
#
854
889
self .log .info ("Accept a valid block even if a bloated version of the block has previously been sent" )
855
- self .move_tip (60 )
890
+ self .move_tip ('dup_2' )
856
891
regular_block = self .next_block ("64a" , spend = out [18 ])
857
892
858
893
# make it a "broken_block," with non-canonical serialization
@@ -878,7 +913,7 @@ def run_test(self):
878
913
node .disconnect_p2ps ()
879
914
self .reconnect_p2p ()
880
915
881
- self .move_tip (60 )
916
+ self .move_tip ('dup_2' )
882
917
b64 = CBlock (b64a )
883
918
b64 .vtx = copy .deepcopy (b64a .vtx )
884
919
assert_equal (b64 .hash , b64a .hash )
@@ -890,7 +925,7 @@ def run_test(self):
890
925
891
926
# Spend an output created in the block itself
892
927
#
893
- # -> b42 (12) -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17 ) -> b64 (18) -> b65 (19)
928
+ # -> b_dup_2 ( ) -> b64 (18) -> b65 (19)
894
929
#
895
930
self .log .info ("Accept a block with a transaction spending an output created in the same block" )
896
931
self .move_tip (64 )
@@ -903,8 +938,8 @@ def run_test(self):
903
938
904
939
# Attempt to spend an output created later in the same block
905
940
#
906
- # -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19)
907
- # \-> b66 (20)
941
+ # -> b64 (18) -> b65 (19)
942
+ # \-> b66 (20)
908
943
self .log .info ("Reject a block with a transaction spending an output created later in the same block" )
909
944
self .move_tip (65 )
910
945
b66 = self .next_block (66 )
@@ -915,8 +950,8 @@ def run_test(self):
915
950
916
951
# Attempt to double-spend a transaction created in a block
917
952
#
918
- # -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19)
919
- # \-> b67 (20)
953
+ # -> b64 (18) -> b65 (19)
954
+ # \-> b67 (20)
920
955
#
921
956
#
922
957
self .log .info ("Reject a block with a transaction double spending a transaction created in the same block" )
@@ -930,8 +965,8 @@ def run_test(self):
930
965
931
966
# More tests of block subsidy
932
967
#
933
- # -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20)
934
- # \-> b68 (20)
968
+ # -> b64 (18) -> b65 (19) -> b69 (20)
969
+ # \-> b68 (20)
935
970
#
936
971
# b68 - coinbase with an extra 10 satoshis,
937
972
# creates a tx that has 9 satoshis from out[20] go to fees
@@ -957,8 +992,8 @@ def run_test(self):
957
992
958
993
# Test spending the outpoint of a non-existent transaction
959
994
#
960
- # -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20)
961
- # \-> b70 (21)
995
+ # -> b65 (19) -> b69 (20)
996
+ # \-> b70 (21)
962
997
#
963
998
self .log .info ("Reject a block containing a transaction spending from a non-existent input" )
964
999
self .move_tip (69 )
@@ -973,8 +1008,8 @@ def run_test(self):
973
1008
974
1009
# Test accepting an invalid block which has the same hash as a valid one (via merkle tree tricks)
975
1010
#
976
- # -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20) -> b72 (21)
977
- # \-> b71 (21)
1011
+ # -> b65 (19) -> b69 (20) -> b72 (21)
1012
+ # \-> b71 (21)
978
1013
#
979
1014
# b72 is a good block.
980
1015
# b71 is a copy of 72, but re-adds one of its transactions. However, it has the same hash as b72.
@@ -1002,8 +1037,8 @@ def run_test(self):
1002
1037
1003
1038
# Test some invalid scripts and MAX_BLOCK_SIGOPS
1004
1039
#
1005
- # -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20) -> b72 (21)
1006
- # \-> b** (22)
1040
+ # -> b69 (20) -> b72 (21)
1041
+ # \-> b** (22)
1007
1042
#
1008
1043
1009
1044
# b73 - tx with excessive sigops that are placed after an excessively large script element.
0 commit comments