def test_add_minor_block_request_list(self): id1 = Identity.create_random_identity() acc1 = Address.create_from_identity(id1, full_shard_key=0) with ClusterContext(2, acc1) as clusters: shard_state = clusters[0].get_shard_state(0b10) coinbase_amount = (shard_state.env.quark_chain_config.shards[ shard_state.full_shard_id].COINBASE_AMOUNT // 2) b1 = shard_state.get_tip().create_block_to_append() evm_state = shard_state.run_block(b1) coinbase_amount_map = TokenBalanceMap(evm_state.block_fee_tokens) coinbase_amount_map.add({ shard_state.env.quark_chain_config.genesis_token: coinbase_amount }) b1.finalize(evm_state=evm_state, coinbase_amount_map=coinbase_amount_map) add_result = call_async(clusters[0].master.add_raw_minor_block( b1.header.branch, b1.serialize())) self.assertTrue(add_result) # Make sure the xshard list is not broadcasted to the other shard self.assertFalse(clusters[0].get_shard_state( 0b11).contain_remote_minor_block_hash(b1.header.get_hash())) self.assertTrue( clusters[0].master.root_state.is_minor_block_validated( b1.header.get_hash())) # Make sure another cluster received the new block assert_true_with_timeout(lambda: clusters[0].get_shard_state( 0b10).contain_block_by_hash(b1.header.get_hash())) assert_true_with_timeout( lambda: clusters[1].master.root_state.is_minor_block_validated( b1.header.get_hash()))
def _tip_gen(shard_state): coinbase_amount = (shard_state.env.quark_chain_config.shards[ shard_state.full_shard_id].COINBASE_AMOUNT // 2) b = shard_state.get_tip().create_block_to_append() evm_state = shard_state.run_block(b) coinbase_amount_map = TokenBalanceMap(evm_state.block_fee_tokens) coinbase_amount_map.add( {shard_state.env.quark_chain_config.genesis_token: coinbase_amount}) b.finalize(evm_state=evm_state, coinbase_amount_map=coinbase_amount_map) return b
def test_shard_synchronizer_with_fork(self): id1 = Identity.create_random_identity() acc1 = Address.create_from_identity(id1, full_shard_key=0) with ClusterContext(2, acc1) as clusters: # shutdown cluster connection clusters[1].peer.close() block_list = [] # cluster 0 has 13 blocks added shard_state0 = clusters[0].get_shard_state(0b10) coinbase_amount = (shard_state0.env.quark_chain_config.shards[ shard_state0.full_shard_id].COINBASE_AMOUNT // 2) for i in range(13): block = shard_state0.get_tip().create_block_to_append() evm_state = shard_state0.run_block(block) coinbase_amount_map = TokenBalanceMap( evm_state.block_fee_tokens) coinbase_amount_map.add({ shard_state0.env.quark_chain_config.genesis_token: coinbase_amount }) block.finalize(evm_state=evm_state, coinbase_amount_map=coinbase_amount_map) add_result = call_async(clusters[0].master.add_raw_minor_block( block.header.branch, block.serialize())) self.assertTrue(add_result) block_list.append(block) self.assertEqual( clusters[0].get_shard_state(0b10).header_tip.height, 13) # cluster 1 has 12 blocks added shard_state0 = clusters[1].get_shard_state(0b10) coinbase_amount = (shard_state0.env.quark_chain_config.shards[ shard_state0.full_shard_id].COINBASE_AMOUNT // 2) for i in range(12): block = shard_state0.get_tip().create_block_to_append() evm_state = shard_state0.run_block(block) coinbase_amount_map = TokenBalanceMap( evm_state.block_fee_tokens) coinbase_amount_map.add({ shard_state0.env.quark_chain_config.genesis_token: coinbase_amount }) block.finalize(evm_state=evm_state, coinbase_amount_map=coinbase_amount_map) add_result = call_async(clusters[1].master.add_raw_minor_block( block.header.branch, block.serialize())) self.assertTrue(add_result) self.assertEqual( clusters[1].get_shard_state(0b10).header_tip.height, 12) # reestablish cluster connection call_async(clusters[1].network.connect( "127.0.0.1", clusters[0].master.env.cluster_config.SIMPLE_NETWORK. BOOTSTRAP_PORT, )) # a new block from cluster 0 will trigger sync in cluster 1 shard_state0 = clusters[0].get_shard_state(0b10) coinbase_amount = (shard_state0.env.quark_chain_config.shards[ shard_state0.full_shard_id].COINBASE_AMOUNT // 2) block = shard_state0.get_tip().create_block_to_append() evm_state = shard_state0.run_block(block) coinbase_amount_map = TokenBalanceMap(evm_state.block_fee_tokens) coinbase_amount_map.add({ shard_state0.env.quark_chain_config.genesis_token: coinbase_amount }) block.finalize(evm_state=evm_state, coinbase_amount_map=coinbase_amount_map) add_result = call_async(clusters[0].master.add_raw_minor_block( block.header.branch, block.serialize())) self.assertTrue(add_result) block_list.append(block) # expect cluster 1 has all the blocks from cluter 0 and # has the same tip as cluster 0 for block in block_list: assert_true_with_timeout( lambda: clusters[1].slave_list[0].shards[Branch(0b10)]. state.contain_block_by_hash(block.header.get_hash())) assert_true_with_timeout( lambda: clusters[1].master.root_state. is_minor_block_validated(block.header.get_hash())) self.assertEqual( clusters[1].get_shard_state(0b10).header_tip, clusters[0].get_shard_state(0b10).header_tip, )
def test_add_root_block_request_list(self): id1 = Identity.create_random_identity() acc1 = Address.create_from_identity(id1, full_shard_key=0) with ClusterContext(2, acc1) as clusters: # shutdown cluster connection clusters[1].peer.close() # add blocks in cluster 0 block_header_list = [clusters[0].get_shard_state(2 | 0).header_tip] shard_state0 = clusters[0].get_shard_state(0b10) coinbase_amount = (shard_state0.env.quark_chain_config.shards[ shard_state0.full_shard_id].COINBASE_AMOUNT // 2) for i in range(7): b1 = shard_state0.get_tip().create_block_to_append() evm_state = shard_state0.run_block(b1) coinbase_amount_map = TokenBalanceMap( evm_state.block_fee_tokens) coinbase_amount_map.add({ shard_state0.env.quark_chain_config.genesis_token: coinbase_amount }) b1.finalize(evm_state=evm_state, coinbase_amount_map=coinbase_amount_map) add_result = call_async(clusters[0].master.add_raw_minor_block( b1.header.branch, b1.serialize())) self.assertTrue(add_result) block_header_list.append(b1.header) block_header_list.append( clusters[0].get_shard_state(2 | 1).header_tip) shard_state0 = clusters[0].get_shard_state(0b11) coinbase_amount = (shard_state0.env.quark_chain_config.shards[ shard_state0.full_shard_id].COINBASE_AMOUNT // 2) b2 = shard_state0.get_tip().create_block_to_append() evm_state = shard_state0.run_block(b2) coinbase_amount_map = TokenBalanceMap(evm_state.block_fee_tokens) coinbase_amount_map.add({ shard_state0.env.quark_chain_config.genesis_token: coinbase_amount }) b2.finalize(evm_state=evm_state, coinbase_amount_map=coinbase_amount_map) add_result = call_async(clusters[0].master.add_raw_minor_block( b2.header.branch, b2.serialize())) self.assertTrue(add_result) block_header_list.append(b2.header) # add 1 block in cluster 1 shard_state1 = clusters[1].get_shard_state(0b11) coinbase_amount = (shard_state1.env.quark_chain_config.shards[ shard_state1.full_shard_id].COINBASE_AMOUNT // 2) b3 = shard_state1.get_tip().create_block_to_append() evm_state = shard_state1.run_block(b3) coinbase_amount_map = TokenBalanceMap(evm_state.block_fee_tokens) coinbase_amount_map.add({ shard_state1.env.quark_chain_config.genesis_token: coinbase_amount }) b3.finalize(evm_state=evm_state, coinbase_amount_map=coinbase_amount_map) add_result = call_async(clusters[1].master.add_raw_minor_block( b3.header.branch, b3.serialize())) self.assertTrue(add_result) self.assertEqual(clusters[1].get_shard_state(0b11).header_tip, b3.header) # reestablish cluster connection call_async(clusters[1].network.connect( "127.0.0.1", clusters[0].master.env.cluster_config.SIMPLE_NETWORK. BOOTSTRAP_PORT, )) root_block1 = clusters[0].master.root_state.create_block_to_mine( block_header_list, acc1) call_async(clusters[0].master.add_root_block(root_block1)) # Make sure the root block tip of local cluster is changed self.assertEqual(clusters[0].master.root_state.tip, root_block1.header) # Make sure the root block tip of cluster 1 is changed assert_true_with_timeout( lambda: clusters[1].master.root_state.tip == root_block1. header, 2) # Minor block is downloaded self.assertEqual(b1.header.height, 7) assert_true_with_timeout(lambda: clusters[1].get_shard_state(0b10). header_tip == b1.header) # The tip is overwritten due to root chain first consensus assert_true_with_timeout(lambda: clusters[1].get_shard_state(0b11). header_tip == b2.header)