1515# limitations under the License.
1616
1717from hashlib import blake2b
18+ from scalecodec .base import ScaleBytes , RuntimeConfiguration , ScaleDecoder
1819from test_framework .mintlayer import mintlayer_hash
1920from test_framework .test_framework import BitcoinTestFramework
2021from test_framework .util import (
2122 assert_equal ,
2223)
23-
24- import random , scalecodec
24+ import random
2525
2626GENESIS_POOL_ID = "123c4c600097c513e088b9be62069f0c74c7671c523c8e3469a1c3f14b7ea2c4"
2727GENESIS_STAKE_PRIVATE_KEY = "8717e6946febd3a33ccdc3f3a27629ec80c33461c33a0fc56b4836fcedd26638"
3333 "e9f3cd7b78d45750afd17292031373fddb5e7a8090db51221038f5e05f29998e"
3434)
3535
36- block_input_data_obj = scalecodec . base . RuntimeConfiguration ().create_scale_object ('GenerateBlockInputData' )
37- outpoint_obj = scalecodec . base . RuntimeConfiguration ().create_scale_object ('OutPoint' )
38- signed_transaction_obj = scalecodec . base . RuntimeConfiguration ().create_scale_object ('SignedTransaction' )
39- transaction_obj = scalecodec . base . RuntimeConfiguration ().create_scale_object ('TransactionV1' )
36+ block_input_data_obj = RuntimeConfiguration ().create_scale_object ('GenerateBlockInputData' )
37+ outpoint_obj = RuntimeConfiguration ().create_scale_object ('OutPoint' )
38+ signed_transaction_obj = RuntimeConfiguration ().create_scale_object ('SignedTransaction' )
39+ transaction_obj = RuntimeConfiguration ().create_scale_object ('TransactionV1' )
4040
4141class GeneratePoSBlocksTest (BitcoinTestFramework ):
4242 def set_test_params (self ):
4343 self .setup_clean_chain = True
4444 self .num_nodes = 1
4545 self .extra_args = [["--chain-pos-netupgrades=true" ]]
4646
47- def block_height (self , n ):
48- tip = self .nodes [n ].chainstate_best_block_id ()
49- return self .nodes [n ].chainstate_block_height_in_main_chain (tip )
50-
51- def assert_tip (self , expected ):
52- tip = self .nodes [0 ].chainstate_best_block_id ()
53- block = self .nodes [0 ].chainstate_get_block (tip )
54- assert_equal (block , expected )
47+ def assert_chain (self , block , previous_tip ):
48+ assert_equal (block ["header" ]["header" ]["prev_block_id" ][2 :], previous_tip )
5549
56- def hex_to_dec_array (self , hex_string ):
57- return [int (hex_string [i :i + 2 ], 16 ) for i in range (0 , len (hex_string ), 2 )]
50+ def assert_height (self , expected_height , expected_block ):
51+ block_id = self .nodes [0 ].chainstate_block_id_at_height (expected_height )
52+ block = self .nodes [0 ].chainstate_get_block (block_id )
53+ assert_equal (block , expected_block )
5854
59- def generate_block (self , block_input_data , transactions ):
60- old_block_height = self .block_height (0 )
55+ def assert_pos_consensus (self , block ):
56+ if block ["header" ]["header" ]["consensus_data" ].get ("PoS" ) is None :
57+ raise AssertionError ("Block {} was not PoS" .format (block_hex ))
6158
62- block = self .nodes [0 ].blockprod_generate_block (block_input_data , transactions )
63- self .nodes [0 ].chainstate_submit_block (block )
59+ def assert_tip (self , expected_block ):
60+ tip = self .nodes [0 ].chainstate_best_block_id ()
61+ block = self .nodes [0 ].chainstate_get_block (tip )
62+ assert_equal (block , expected_block )
6463
65- assert_equal (self .block_height (0 ), old_block_height + 1 )
66- self .assert_tip (block )
64+ def block_height (self , n ):
65+ tip = self .nodes [n ].chainstate_best_block_id ()
66+ return self .nodes [n ].chainstate_block_height_in_main_chain (tip )
6767
68- def previous_block_id (self ):
68+ def generate_block (self , expected_height , block_input_data , transactions ):
6969 previous_block_id = self .nodes [0 ].chainstate_best_block_id ()
70- return self .hex_to_dec_array (previous_block_id )
70+ block_hex = self .nodes [0 ].blockprod_generate_block (block_input_data , transactions )
71+ block_hex_array = bytearray .fromhex (block_hex )
72+ block = ScaleDecoder .get_decoder_class ('BlockV1' , ScaleBytes (block_hex_array )).decode ()
7173
72- def pack_transaction (self , transaction ):
73- transaction_encoded = signed_transaction_obj .encode (transaction ).to_hex ()[2 :]
74- transaction_id = scalecodec .ScaleBytes (
75- mintlayer_hash (transaction_obj .encode (transaction ["transaction" ]).data )
76- ).to_hex ()[2 :]
74+ self .nodes [0 ].chainstate_submit_block (block_hex )
7775
78- return ( transaction_encoded , transaction_id )
79-
80- def genesis_pool_id ( self ):
81- return self .hex_to_dec_array ( GENESIS_POOL_ID )
76+ self . assert_tip ( block_hex )
77+ self . assert_height ( expected_height , block_hex )
78+ self . assert_pos_consensus ( block )
79+ self .assert_chain ( block , previous_block_id )
8280
8381 def generate_pool_id (self , transaction_id ):
8482 kernel_input_outpoint = outpoint_obj .encode ({
@@ -88,8 +86,6 @@ def generate_pool_id(self, transaction_id):
8886 "index" : 0 ,
8987 }).to_hex ()[2 :]
9088
91- outpoint = self .hex_to_dec_array (kernel_input_outpoint )
92-
9389 # Include PoolId pre-image suffix of [0, 0, 0, 0]
9490 blake2b_hasher = blake2b ()
9591 blake2b_hasher .update (bytes .fromhex (kernel_input_outpoint ))
@@ -98,6 +94,42 @@ def generate_pool_id(self, transaction_id):
9894 # Truncate output to match Rust's split()
9995 return self .hex_to_dec_array (blake2b_hasher .hexdigest ()[:64 ])
10096
97+ def genesis_pool_id (self ):
98+ return self .hex_to_dec_array (GENESIS_POOL_ID )
99+
100+ def hex_to_dec_array (self , hex_string ):
101+ return [int (hex_string [i :i + 2 ], 16 ) for i in range (0 , len (hex_string ), 2 )]
102+
103+ def new_stake_keys (self ):
104+ new_stake_private_key_hex = self .nodes [0 ].test_functions_new_private_key ()
105+ new_stake_private_key = self .stake_private_key (new_stake_private_key_hex [2 :])
106+
107+ new_stake_public_key_hex = self .nodes [0 ].test_functions_public_key_from_private_key (new_stake_private_key_hex )
108+ new_stake_public_key = self .stake_public_key (new_stake_public_key_hex [2 :])
109+
110+ return (new_stake_private_key , new_stake_public_key )
111+
112+ def new_vrf_keys (self ):
113+ new_vrf_private_key_hex = self .nodes [0 ].test_functions_new_vrf_private_key ()
114+ new_vrf_private_key = self .vrf_private_key (new_vrf_private_key_hex [2 :])
115+
116+ new_vrf_public_key_hex = self .nodes [0 ].test_functions_vrf_public_key_from_private_key (new_vrf_private_key_hex )
117+ new_vrf_public_key = self .vrf_public_key (new_vrf_public_key_hex [2 :])
118+
119+ return (new_vrf_private_key , new_vrf_public_key )
120+
121+ def pack_transaction (self , transaction ):
122+ transaction_encoded = signed_transaction_obj .encode (transaction ).to_hex ()[2 :]
123+ transaction_id = ScaleBytes (
124+ mintlayer_hash (transaction_obj .encode (transaction ["transaction" ]).data )
125+ ).to_hex ()[2 :]
126+
127+ return (transaction_encoded , transaction_id )
128+
129+ def previous_block_id (self ):
130+ previous_block_id = self .nodes [0 ].chainstate_best_block_id ()
131+ return self .hex_to_dec_array (previous_block_id )
132+
101133 def stake_private_key (self , stake_private_key ):
102134 return {
103135 "key" : {
@@ -134,24 +166,6 @@ def vrf_public_key(self, vrf_public_key):
134166 },
135167 }
136168
137- def new_stake_keys (self ):
138- new_stake_private_key_hex = self .nodes [0 ].test_functions_new_private_key ()
139- new_stake_private_key = self .stake_private_key (new_stake_private_key_hex [2 :])
140-
141- new_stake_public_key_hex = self .nodes [0 ].test_functions_public_key_from_private_key (new_stake_private_key_hex )
142- new_stake_public_key = self .stake_public_key (new_stake_public_key_hex [2 :])
143-
144- return (new_stake_private_key , new_stake_public_key )
145-
146- def new_vrf_keys (self ):
147- new_vrf_private_key_hex = self .nodes [0 ].test_functions_new_vrf_private_key ()
148- new_vrf_private_key = self .vrf_private_key (new_vrf_private_key_hex [2 :])
149-
150- new_vrf_public_key_hex = self .nodes [0 ].test_functions_vrf_public_key_from_private_key (new_vrf_private_key_hex )
151- new_vrf_public_key = self .vrf_public_key (new_vrf_public_key_hex [2 :])
152-
153- return (new_vrf_private_key , new_vrf_public_key )
154-
155169 def run_test (self ):
156170 #
157171 # Transfer Genesis UTXO to AnyoneCanSpend
@@ -227,7 +241,7 @@ def run_test(self):
227241 }
228242
229243 (transfer_transaction_encoded , transfer_transaction_id ) = self .pack_transaction (transfer_transaction )
230- self .generate_block (block_input_data , [transfer_transaction_encoded ])
244+ self .generate_block (1 , block_input_data , [transfer_transaction_encoded ])
231245
232246 #
233247 # Create the new stake pool using the AnyoneCanSpend transaction
@@ -306,7 +320,7 @@ def run_test(self):
306320 }
307321
308322 (create_new_pool_transaction_encoded , create_new_pool_transaction_id ) = self .pack_transaction (create_new_pool_transaction )
309- self .generate_block (block_input_data , [create_new_pool_transaction_encoded ])
323+ self .generate_block (2 , block_input_data , [create_new_pool_transaction_encoded ])
310324
311325 #
312326 # Stake many blocks with the new stake pool
@@ -335,7 +349,7 @@ def run_test(self):
335349 ],
336350 }
337351
338- for _ in range (1 , random .randint (1 ,100 )):
352+ for i in range (0 , random .randint (10 ,100 )):
339353 block_input_data = block_input_data_obj .encode ({
340354 "PoS" : {
341355 "stake_private_key" : new_stake_private_key ,
@@ -350,7 +364,7 @@ def run_test(self):
350364 }
351365 }).to_hex ()[2 :]
352366
353- self .generate_block (block_input_data , [])
367+ self .generate_block (3 + i , block_input_data , [])
354368
355369 kernel_input_outpoint = {
356370 "id" : {
0 commit comments