Ejemplo n.º 1
0
    async def batch_broadcast_xshard_tx_list(
        self,
        block_hash_to_xshard_list_and_prev_root_height: Dict[bytes,
                                                             Tuple[List, int]],
        source_branch: Branch,
    ):
        branch_to_add_xshard_tx_list_request_list = dict()
        for (
                block_hash,
                x_shard_list_and_prev_root_height,
        ) in block_hash_to_xshard_list_and_prev_root_height.items():
            xshard_tx_list = x_shard_list_and_prev_root_height[0]
            prev_root_height = x_shard_list_and_prev_root_height[1]
            branch_to_add_xshard_tx_list_request = self.__get_branch_to_add_xshard_tx_list_request(
                block_hash, xshard_tx_list, prev_root_height)
            for branch, request in branch_to_add_xshard_tx_list_request.items(
            ):
                if branch == source_branch or not is_neighbor(
                        branch,
                        source_branch,
                        len(
                            self.env.quark_chain_config.
                            get_initialized_full_shard_ids_before_root_height(
                                prev_root_height)),
                ):
                    check(
                        len(request.tx_list.tx_list) == 0,
                        "there shouldn't be xshard list for non-neighbor shard ({} -> {})"
                        .format(source_branch.value, branch.value),
                    )
                    continue

                branch_to_add_xshard_tx_list_request_list.setdefault(
                    branch, []).append(request)

        rpc_futures = []
        for branch, request_list in branch_to_add_xshard_tx_list_request_list.items(
        ):
            if branch in self.shards:
                for request in request_list:
                    self.shards[
                        branch].state.add_cross_shard_tx_list_by_minor_block_hash(
                            request.minor_block_hash, request.tx_list)

            batch_request = BatchAddXshardTxListRequest(request_list)
            for (
                    slave_conn
            ) in self.slave_connection_manager.get_connections_by_full_shard_id(
                    branch.get_full_shard_id()):
                future = slave_conn.write_rpc_request(
                    ClusterOp.BATCH_ADD_XSHARD_TX_LIST_REQUEST, batch_request)
                rpc_futures.append(future)
        responses = await asyncio.gather(*rpc_futures)
        check(all([response.error_code == 0 for _, response, _ in responses]))
Ejemplo n.º 2
0
    async def broadcast_xshard_tx_list(self, block, xshard_tx_list, prev_root_height):
        """ Broadcast x-shard transactions to their recipient shards """

        block_hash = block.header.get_hash()
        branch_to_add_xshard_tx_list_request = self.__get_branch_to_add_xshard_tx_list_request(
            block_hash, xshard_tx_list, prev_root_height
        )
        rpc_futures = []
        for branch, request in branch_to_add_xshard_tx_list_request.items():
            if branch == block.header.branch or not is_neighbor(
                block.header.branch,
                branch,
                len(
                    self.env.quark_chain_config.get_initialized_full_shard_ids_before_root_height(
                        prev_root_height
                    )
                ),
            ):
                check(
                    len(request.tx_list.tx_list) == 0,
                    "there shouldn't be xshard list for non-neighbor shard ({} -> {})".format(
                        block.header.branch.value, branch.value
                    ),
                )
                continue

            if branch in self.shards:
                self.shards[branch].state.add_cross_shard_tx_list_by_minor_block_hash(
                    block_hash, request.tx_list
                )

            for (
                slave_conn
            ) in self.slave_connection_manager.get_connections_by_full_shard_id(
                branch.get_full_shard_id()
            ):
                future = slave_conn.write_rpc_request(
                    ClusterOp.ADD_XSHARD_TX_LIST_REQUEST, request
                )
                rpc_futures.append(future)
        responses = await asyncio.gather(*rpc_futures)
        check(all([response.error_code == 0 for _, response, _ in responses]))
Ejemplo n.º 3
0
 def test_is_neighbor_same_chain_id(self):
     b1 = Branch(2 << 16 | 2 | 1)
     b2 = Branch(2 << 16 | 2 | 0)
     self.assertTrue(is_neighbor(b1, b2, 33))
Ejemplo n.º 4
0
 def test_not_neighbor_diff_chain_id_and_diff_shard_id(self):
     b1 = Branch(1 << 16 | 2 | 0)
     b2 = Branch(3 << 16 | 2 | 1)
     self.assertFalse(is_neighbor(b1, b2, 33))
Ejemplo n.º 5
0
 def test_is_neighbor_small_shard_size(self):
     b1 = Branch(1 << 16 | 2 | 0)
     b2 = Branch(3 << 16 | 2 | 1)
     self.assertTrue(is_neighbor(b1, b2, 32))
Ejemplo n.º 6
0
 def test_is_neighbor_same_shard_id(self):
     b1 = Branch(1 << 16 | 2 | 1)
     b2 = Branch(3 << 16 | 2 | 1)
     self.assertTrue(is_neighbor(b1, b2, 33))
Ejemplo n.º 7
0
 def test_is_neighbor_small_shard_size(self):
     b1 = Branch.create(32, 0)
     b2 = Branch.create(32, 7)
     self.assertTrue(is_neighbor(b1, b2))
Ejemplo n.º 8
0
 def test_raise_same_shard_id(self):
     b1 = Branch.create(64, 5)
     b2 = Branch.create(64, 5)
     with self.assertRaises(AssertionError):
         is_neighbor(b1, b2)
Ejemplo n.º 9
0
 def test_raise_different_shard_size(self):
     b1 = Branch.create(64, 4)
     b2 = Branch.create(32, 5)
     with self.assertRaises(AssertionError):
         is_neighbor(b1, b2)
Ejemplo n.º 10
0
 def test_not_neighbor_two_bit_difference(self):
     b1 = Branch.create(64, 4)
     b2 = Branch.create(64, 7)
     self.assertFalse(is_neighbor(b1, b2))
Ejemplo n.º 11
0
 def test_is_neighbor_one_bit_difference(self):
     b1 = Branch.create(64, 5)
     b2 = Branch.create(64, 7)
     self.assertTrue(is_neighbor(b1, b2))