def test_create_shard_at_different_height(self):
    acc1 = Address.create_random_account(0)
    id1 = (((0 << 16) | 1) | 0)
    id2 = (((1 << 16) | 1) | 0)
    genesis_root_heights = {id1: 1, id2: 2}
    with ClusterContext(1, acc1, chain_size=2, shard_size=1, genesis_root_heights=genesis_root_heights) as clusters:
        master = clusters[0].master
        self.assertIsNone(clusters[0].get_shard(id1))
        self.assertIsNone(clusters[0].get_shard(id2))
        root0 = call_async(master.get_next_block_to_mine(acc1, branch_value=None))
        self.assertEqual(root0.header.height, 1)
        self.assertEqual(len(root0.minor_block_header_list), 0)
        self.assertEqual(root0.header.coinbase_amount_map.balance_map[master.env.quark_chain_config.genesis_token], master.env.quark_chain_config.ROOT.COINBASE_AMOUNT)
        call_async(master.add_root_block(root0))
        self.assertIsNotNone(clusters[0].get_shard(id1))
        self.assertIsNone(clusters[0].get_shard(id2))
        shard_state = clusters[0].get_shard(id1).state
        self.assertEqual(shard_state.header_tip.hash_prev_root_block, root0.header.get_hash())
        self.assertEqual(shard_state.get_tip().meta.xshard_tx_cursor_info, XshardTxCursorInfo(1, 0, 0))
        self.assertEqual(shard_state.get_token_balance(acc1.recipient, shard_state.env.quark_chain_config.genesis_token), 1000000)
        root1 = call_async(master.get_next_block_to_mine(acc1, branch_value=None))
        self.assertEqual(len(root1.minor_block_header_list), 1)
        self.assertEqual(root1.header.coinbase_amount_map.balance_map[master.env.quark_chain_config.genesis_token], (master.env.quark_chain_config.ROOT.COINBASE_AMOUNT + root1.minor_block_header_list[0].coinbase_amount_map.balance_map[master.env.quark_chain_config.genesis_token]))
        self.assertEqual(root1.minor_block_header_list[0], shard_state.header_tip)
        call_async(master.add_root_block(root1))
        self.assertIsNotNone(clusters[0].get_shard(id1))
        self.assertIsNotNone(clusters[0].get_shard(id2))
        mblock = shard_state.create_block_to_mine()
        self.assertEqual(mblock.meta.xshard_tx_cursor_info, XshardTxCursorInfo((root1.header.height + 1), 0, 0))
        call_async(clusters[0].get_shard(id1).add_block(mblock))
        self.assertEqual(shard_state.get_token_balance(acc1.recipient, shard_state.env.quark_chain_config.genesis_token), ((root1.header.coinbase_amount_map.balance_map[shard_state.env.quark_chain_config.genesis_token] + root0.header.coinbase_amount_map.balance_map[shard_state.env.quark_chain_config.genesis_token]) + 1000000))
        self.assertEqual(mblock.header.coinbase_amount_map.balance_map[shard_state.env.quark_chain_config.genesis_token], (shard_state.shard_config.COINBASE_AMOUNT // 2))
        root2 = call_async(master.get_next_block_to_mine(acc1, branch_value=None))
        self.assertEqual(len(root2.minor_block_header_list), 2)
def test_create_shard_at_different_height(self):
    acc1 = Address.create_random_account(0)
    id1 = (((0 << 16) | 1) | 0)
    id2 = (((1 << 16) | 1) | 0)
    genesis_root_heights = {id1: 1, id2: 2}
    with ClusterContext(1, acc1, chain_size=2, shard_size=1, genesis_root_heights=genesis_root_heights) as clusters:
        master = clusters[0].master
        self.assertIsNone(clusters[0].get_shard(id1))
        self.assertIsNone(clusters[0].get_shard(id2))
        root0 = call_async(master.get_next_block_to_mine(acc1, branch_value=None))
        self.assertEqual(root0.header.height, 1)
        self.assertEqual(len(root0.minor_block_header_list), 0)
        self.assertEqual(root0.header.coinbase_amount_map.balance_map[master.env.quark_chain_config.genesis_token], master.env.quark_chain_config.ROOT.COINBASE_AMOUNT)
        call_async(master.add_root_block(root0))
        self.assertIsNotNone(clusters[0].get_shard(id1))
        self.assertIsNone(clusters[0].get_shard(id2))
        shard_state = clusters[0].get_shard(id1).state
        self.assertEqual(shard_state.header_tip.hash_prev_root_block, root0.header.get_hash())
        self.assertEqual(shard_state.get_tip().meta.xshard_tx_cursor_info, XshardTxCursorInfo(1, 0, 0))
        self.assertEqual(shard_state.get_token_balance(acc1.recipient, shard_state.env.quark_chain_config.genesis_token), 1000000)
        root1 = call_async(master.get_next_block_to_mine(acc1, branch_value=None))
        self.assertEqual(len(root1.minor_block_header_list), 1)
        self.assertEqual(root1.header.coinbase_amount_map.balance_map[master.env.quark_chain_config.genesis_token], (master.env.quark_chain_config.ROOT.COINBASE_AMOUNT + root1.minor_block_header_list[0].coinbase_amount_map.balance_map[master.env.quark_chain_config.genesis_token]))
        self.assertEqual(root1.minor_block_header_list[0], shard_state.header_tip)
        call_async(master.add_root_block(root1))
        self.assertIsNotNone(clusters[0].get_shard(id1))
        self.assertIsNotNone(clusters[0].get_shard(id2))
        mblock = shard_state.create_block_to_mine()
        self.assertEqual(mblock.meta.xshard_tx_cursor_info, XshardTxCursorInfo((root1.header.height + 1), 0, 0))
        call_async(clusters[0].get_shard(id1).add_block(mblock))
        self.assertEqual(shard_state.get_token_balance(acc1.recipient, shard_state.env.quark_chain_config.genesis_token), ((root1.header.coinbase_amount_map.balance_map[shard_state.env.quark_chain_config.genesis_token] + root0.header.coinbase_amount_map.balance_map[shard_state.env.quark_chain_config.genesis_token]) + 1000000))
        self.assertEqual(mblock.header.coinbase_amount_map.balance_map[shard_state.env.quark_chain_config.genesis_token], (shard_state.shard_config.COINBASE_AMOUNT // 2))
        root2 = call_async(master.get_next_block_to_mine(acc1, branch_value=None))
        self.assertEqual(len(root2.minor_block_header_list), 2)