async def test_primary_isolation_from_replicas(self, bft_network, tracker):
        '''
        Isolate the from the other replicas, wait for view change and ensure the system is still able to make progress
        '''
        bft_network.start_all_replicas()
        await trio.sleep(SKVBC_INIT_GRACE_TIME)
        await bft_network.init_preexec_count()
        with net.PrimaryIsolatingAdversary(bft_network) as adversary:
            read_client = bft_network.random_client()

            start_block = await tracker.get_last_block_id(read_client)

            await adversary.interfere()

            await self.issue_tracked_ops_to_the_system(bft_network, tracker)

            expected_next_primary = 1
            await bft_network.wait_for_view(
                replica_id=random.choice(
                    bft_network.all_replicas(without={0})),
                expected=lambda v: v == expected_next_primary,
                err_msg="Make sure view change has been triggered.")

            await self.issue_tracked_ops_to_the_system(bft_network, tracker)

            last_block = await tracker.get_last_block_id(read_client)
            assert last_block > start_block
示例#2
0
    async def test_single_vc_primary_isolated(self, bft_network):
        """
        The goal of this test is to check the view change
        workflow in case the primary is up, but its outgoing
        communication is intercepted by an adversary.

        1) Given a BFT network,
        2) Insert an adversary that isolates the primary's outgoing communication
        3) Send a batch of write requests.
        4) Verify the BFT network eventually transitions to the next view.
        """
        with net.PrimaryIsolatingAdversary(bft_network) as adversary:
            bft_network.start_all_replicas()
            skvbc = kvbc.SimpleKVBCProtocol(bft_network)

            initial_primary = 0
            await bft_network.wait_for_view(
                replica_id=initial_primary,
                expected=lambda v: v == initial_primary,
                err_msg="Make sure we are in the initial view "
                "before isolating the primary.")

            await adversary.interfere()
            expected_next_primary = 1

            await self._send_random_writes(skvbc)

            await bft_network.wait_for_view(
                replica_id=random.choice(
                    bft_network.all_replicas(without={0})),
                expected=lambda v: v == expected_next_primary,
                err_msg="Make sure view change has been triggered.")

            skvbc.read_your_writes(self)
示例#3
0
    async def test_single_vc_primary_isolated(self, bft_network, tracker):
        """
        The goal of this test is to check the view change
        workflow in case the primary is up, but its outgoing
        communication is intercepted by an adversary.

        1) Given a BFT network,
        2) Insert an adversary that isolates the primary's outgoing communication
        3) Send a batch of write requests.
        4) Verify the BFT network eventually transitions to the next view.
        5) Perform a "read-your-writes" check in the new view
        """
        bft_network.start_all_replicas()
        with net.PrimaryIsolatingAdversary(bft_network) as adversary:
            initial_primary = 0
            await bft_network.wait_for_view(
                replica_id=initial_primary,
                expected=lambda v: v == initial_primary,
                err_msg="Make sure we are in the initial view "
                "before isolating the primary.")

            await adversary.interfere()
            expected_next_primary = 1

            await self._send_random_writes(tracker)

            await bft_network.wait_for_view(
                replica_id=random.choice(
                    bft_network.all_replicas(without={0})),
                expected=lambda v: v == expected_next_primary,
                err_msg="Make sure view change has been triggered.")

            await self._wait_for_read_your_writes_success(tracker)

            await tracker.run_concurrent_ops(100)
示例#4
0
    async def test_checkpoint_propagation_after_primary_isolation(
            self, bft_network):
        """
        Here we isolate primary, verify view change, trigger a checkpoint,
        verify checkpoint creation and propagation in the scenario.
        1) Given a BFT network, make sure all nodes are up
        2) Isolate the primary
        3) Send a batch of write requests to trigger view change, verify view change
        4) Send sufficient number of client requests to trigger checkpoint protocol
        5) Make sure checkpoint is propagated to all the nodes except the isolated primary
           in the new view
        """
        with net.PrimaryIsolatingAdversary(bft_network) as adversary:
            bft_network.start_all_replicas()
            skvbc = kvbc.SimpleKVBCProtocol(bft_network)

            n = bft_network.config.n
            self.assertEqual(len(bft_network.procs), n,
                             "Make sure all replicas are up initially.")

            initial_primary = 0

            await bft_network.wait_for_view(
                replica_id=initial_primary,
                expected=lambda v: v == initial_primary,
                err_msg="Make sure we are in the initial view "
                "before isolating the primary.")

            checkpoint_before = await bft_network.wait_for_checkpoint(
                replica_id=initial_primary)

            await adversary.interfere()

            expected_next_primary = initial_primary + 1

            # send a batch of write requests to trigger view change
            await self._send_random_writes(skvbc)

            # verify view change has been triggered for all the nodes except the initial primary
            for replica in bft_network.all_replicas(without={initial_primary}):
                current_view = await bft_network.wait_for_view(
                    replica_id=replica,
                    expected=lambda v: v == expected_next_primary,
                    err_msg="Make sure view change has been triggered.")

                self.assertEqual(current_view, expected_next_primary)

            await skvbc.fill_and_wait_for_checkpoint(
                initial_nodes=bft_network.all_replicas(),
                checkpoint_num=1,
                verify_checkpoint_persistency=False)

            # verify checkpoint propagation to all the nodes except the the initial primary
            for replica in bft_network.all_replicas(without={initial_primary}):
                checkpoint_after = await bft_network.wait_for_checkpoint(
                    replica_id=replica,
                    expected_checkpoint_num=checkpoint_before + 1)

                self.assertEqual(checkpoint_after, checkpoint_before + 1)