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()))
Exemple #2
0
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)