예제 #1
0
    def vote_using_majority(self,
                            remote_node,
                            proposal,
                            wait_for_global_commit=True):
        # This function assumes that the proposal has just been proposed and
        # that at most, only the proposer has already voted for it when
        # proposing it
        majority_count = int(len(self.get_active_members()) / 2 + 1)

        for member in self.get_active_members():
            if proposal.votes_for >= majority_count:
                break

            # If the proposer has already voted for the proposal when it
            # was proposed, skip voting
            if (proposal.proposer_id == member.member_id
                    and proposal.has_proposer_voted_for):
                continue

            response = member.vote(
                remote_node,
                proposal,
                accept=True,
                wait_for_global_commit=wait_for_global_commit,
            )
            assert response.status_code == http.HTTPStatus.OK.value
            proposal.state = infra.proposal.ProposalState(
                response.body["state"])
            proposal.increment_votes_for()

        if proposal.state is not ProposalState.Accepted:
            raise infra.proposal.ProposalNotAccepted(proposal)
        return proposal
예제 #2
0
파일: consortium.py 프로젝트: lynshi/CCF
    def vote_using_majority(self,
                            remote_node,
                            proposal,
                            ballot,
                            wait_for_global_commit=True,
                            timeout=3):
        response = None

        if proposal.state != ProposalState.ACCEPTED:
            active_members = self.get_active_members()
            majority_count = int(len(self.get_active_members()) / 2 + 1)

            for member in active_members:
                if proposal.votes_for >= majority_count:
                    break

                response = member.vote(remote_node, proposal, ballot)
                if response.status_code != http.HTTPStatus.OK.value:
                    raise infra.proposal.ProposalNotAccepted(proposal)
                proposal.state = infra.proposal.ProposalState(
                    response.body.json()["state"])
                proposal.increment_votes_for(member.service_id)

        if response is None:
            if proposal.view is None or proposal.seqno is None:
                raise RuntimeError(
                    "Don't know what to wait for - no target TxID")
            seqno = proposal.seqno
            view = proposal.view
        else:
            seqno = response.seqno
            view = response.view

        # Wait for proposal completion to be committed, even if no votes are issued
        if wait_for_global_commit:
            with remote_node.client() as c:
                infra.commit.wait_for_commit(c, seqno, view, timeout=timeout)

        if proposal.state == ProposalState.ACCEPTED:
            proposal.set_completed(seqno, view)
        else:
            LOG.error(
                json.dumps(self.get_proposal(remote_node,
                                             proposal.proposal_id),
                           indent=2))
            raise infra.proposal.ProposalNotAccepted(proposal)

        return proposal