Пример #1
0
    def find_primary(self, timeout=3, request_timeout=3):
        """
        Find the identity of the primary in the network and return its identity
        and the current term.
        """
        primary_id = None
        term = None

        for _ in range(timeout):
            for node in self.get_joined_nodes():
                with node.node_client(request_timeout=request_timeout) as c:
                    try:
                        res = c.do("getPrimaryInfo", {})
                        if res.error is None:
                            primary_id = res.result["primary_id"]
                            term = res.term
                            break
                        else:
                            assert (
                                res.error["code"]
                                == infra.jsonrpc.ErrorCode.TX_PRIMARY_UNKNOWN
                            ), "RPC error code is not TX_NOT_PRIMARY"
                    except TimeoutError:
                        pass
            if primary_id is not None:
                break
            time.sleep(1)

        if primary_id is None:
            raise PrimaryNotFound
        return (self._get_node_by_id(primary_id), term)
Пример #2
0
    def wait_for_all_nodes_to_catch_up(self, primary, timeout=3):
        """
        Wait for all nodes to have joined the network and globally replicated
        all transactions executed on the primary (including the transactions
        which added the nodes).
        """
        with primary.node_client() as c:
            res = c.do("getCommit", {})
            local_commit_leader = res.commit
            term_leader = res.term

        for _ in range(timeout):
            caught_up_nodes = []
            for node in self.get_joined_nodes():
                with node.node_client() as c:
                    resp = c.request("getCommit", {})
                    if resp.error is not None:
                        # Node may not have joined the network yet, try again
                        break
                    if (
                        resp.global_commit >= local_commit_leader
                        and resp.result["term"] == term_leader
                    ):
                        caught_up_nodes.append(node)
            if len(caught_up_nodes) == len(self.get_joined_nodes()):
                break
            time.sleep(1)
        assert len(caught_up_nodes) == len(
            self.get_joined_nodes()
        ), f"Only {len(caught_up_nodes)} (out of {len(self.get_joined_nodes())}) nodes have joined the network"
Пример #3
0
    def find_primary(self, timeout=3, request_timeout=3):
        """
        Find the identity of the primary in the network and return its identity
        and the current term.
        """
        primary_id = None
        term = None

        for _ in range(timeout):
            for node in self.get_joined_nodes():
                with node.node_client(request_timeout=request_timeout) as c:
                    try:
                        res = c.do("getPrimaryInfo", {})
                        if res.error is None:
                            primary_id = res.result["primary_id"]
                            term = res.term
                            break
                        else:
                            assert "Primary unknown" in res.error, res.error
                    except TimeoutError:
                        pass
            if primary_id is not None:
                break
            time.sleep(1)

        if primary_id is None:
            raise PrimaryNotFound
        return (self._get_node_by_id(primary_id), term)
Пример #4
0
    def find_primary(self, timeout=3, request_timeout=3):
        """
        Find the identity of the primary in the network and return its identity
        and the current view.
        """
        primary_id = None
        view = None

        end_time = time.time() + timeout
        while time.time() < end_time:
            for node in self.get_joined_nodes():
                with node.node_client(request_timeout=request_timeout) as c:
                    try:
                        res = c.get("getPrimaryInfo")
                        if res.error is None:
                            primary_id = res.result["primary_id"]
                            view = res.result["current_term"]
                            break
                        else:
                            assert "Primary unknown" in res.error, res.error
                    except infra.clients.CCFConnectionException:
                        pass
            if primary_id is not None:
                break
            time.sleep(0.1)

        if primary_id is None:
            raise PrimaryNotFound
        return (self._get_node_by_id(primary_id), view)
Пример #5
0
    def wait_for_all_nodes_to_catch_up(self, primary, timeout=3):
        """
        Wait for all nodes to have joined the network and globally replicated
        all transactions globally executed on the primary (including transactions
        which added the nodes).
        """
        end_time = time.time() + timeout
        while time.time() < end_time:
            with primary.node_client() as c:
                resp = c.get("getCommit")
                commit_leader = resp.result["commit"]
                term_leader = resp.result["term"]
                if commit_leader != 0:
                    break
            time.sleep(0.1)
        assert (
            commit_leader != 0
        ), f"Primary {primary.node_id} has not made any progress yet (term: {term_leader}, commit: {commit_leader})"

        while time.time() < end_time:
            caught_up_nodes = []
            for node in self.get_joined_nodes():
                with node.node_client() as c:
                    resp = c.get(
                        "tx",
                        {
                            "view": term_leader,
                            "seqno": commit_leader
                        },
                    )
                    if resp.error is not None:
                        # Node may not have joined the network yet, try again
                        break
                    status = TxStatus(resp.result["status"])
                    if status == TxStatus.Committed:
                        caught_up_nodes.append(node)
                    elif status == TxStatus.Invalid:
                        raise RuntimeError(
                            f"Node {node.node_id} reports transaction ID {term_leader}.{commit_leader} is invalid and will never be committed"
                        )
                    else:
                        pass

            if len(caught_up_nodes) == len(self.get_joined_nodes()):
                break
            time.sleep(0.1)
        assert len(caught_up_nodes) == len(
            self.get_joined_nodes()
        ), f"Only {len(caught_up_nodes)} (out of {len(self.get_joined_nodes())}) nodes have joined the network"
Пример #6
0
 def wait_for_node_commit_sync(self, timeout=3):
     """
     Wait for commit level to get in sync on all nodes. This is expected to
     happen once CFTR has been established, in the absence of new transactions.
     """
     for _ in range(timeout):
         commits = []
         for node in self.get_joined_nodes():
             with node.node_client() as c:
                 r = c.request("getCommit", {})
                 commits.append(r.commit)
         if [commits[0]] * len(commits) == commits:
             break
         time.sleep(1)
     assert [commits[0]] * len(commits) == commits, "All nodes at the same commit"
Пример #7
0
 def wait_for_state(self, node, state, timeout=3):
     for _ in range(timeout):
         try:
             with node.node_client() as c:
                 r = c.request("getSignedIndex", {})
                 if r.result["state"] == state:
                     break
         except ConnectionRefusedError:
             pass
         time.sleep(1)
     else:
         raise TimeoutError(
             f"Timed out waiting for public ledger to be read on node {node.node_id}"
         )
     if state == "partOfNetwork":
         self.status = ServiceStatus.OPEN
Пример #8
0
 def wait_for_state(self, node, state, timeout=3):
     end_time = time.time() + timeout
     while time.time() < end_time:
         try:
             with node.node_client() as c:
                 r = c.get("getSignedIndex")
                 if r.result["state"] == state:
                     break
         except ConnectionRefusedError:
             pass
         time.sleep(0.1)
     else:
         raise TimeoutError(
             f"Timed out waiting for state {state} on node {node.node_id}")
     if state == "partOfNetwork":
         self.status = ServiceStatus.OPEN
Пример #9
0
 def wait_for_node_commit_sync(self, consensus, timeout=3):
     """
     Wait for commit level to get in sync on all nodes. This is expected to
     happen once CFTR has been established, in the absence of new transactions.
     """
     end_time = time.time() + timeout
     while time.time() < end_time:
         commits = []
         for node in self.get_joined_nodes():
             with node.node_client() as c:
                 r = c.get("commit")
                 commits.append(f"{r.view}.{r.seqno}")
         if [commits[0]] * len(commits) == commits:
             break
         time.sleep(0.1)
     expected = [commits[0]] * len(commits)
     assert expected == commits, f"{commits} != {expected}"
Пример #10
0
 def wait_for_node_commit_sync(self, consensus, timeout=3):
     """
     Wait for commit level to get in sync on all nodes. This is expected to
     happen once CFTR has been established, in the absence of new transactions.
     """
     for _ in range(timeout):
         commits = []
         for node in self.get_joined_nodes():
             with node.node_client() as c:
                 r = c.request("getCommit", {})
                 commits.append(r.commit)
         if [commits[0]] * len(commits) == commits:
             break
         time.sleep(1)
     # in pbft getCommit increments the commit version, so commits will not be the same
     # but they should be in ascending order
     assert ([commits[0]] * len(commits) == commits if consensus == "raft"
             else sorted(commits) == commits), "All nodes in sync"