예제 #1
0
    def _apply_vote(self, pubkey, config_vote_data, authorized_keys, state):
        config_vote = ConfigVote()
        config_vote.ParseFromString(config_vote_data)
        proposal_id = config_vote.proposal_id

        config_candidates = _get_config_candidates(state)
        candidate = _first(
            config_candidates.candidates,
            lambda candidate: candidate.proposal_id == proposal_id)

        if candidate is None:
            raise InvalidTransaction(
                "Proposal {} does not exist.".format(proposal_id))

        candidate_index = _index_of(config_candidates.candidates, candidate)

        approval_threshold = _get_approval_threshold(state)

        vote_record = _first(candidate.votes,
                             lambda record: record.public_key == pubkey)
        if vote_record is not None:
            raise InvalidTransaction(
                '{} has already voted'.format(pubkey))

        candidate.votes.add(
            public_key=pubkey,
            vote=config_vote.vote)

        accepted_count = 0
        rejected_count = 0
        for vote_record in candidate.votes:
            if vote_record.vote == ConfigVote.ACCEPT:
                accepted_count += 1
            elif vote_record.vote == ConfigVote.REJECT:
                rejected_count += 1

        if accepted_count >= approval_threshold:
            _set_config_value(state,
                              candidate.proposal.setting,
                              candidate.proposal.value)
            del config_candidates.candidates[candidate_index]
        elif rejected_count >= approval_threshold or \
                (rejected_count + accepted_count) == len(authorized_keys):
            LOGGER.debug('Proposal for %s was rejected',
                         candidate.proposal.setting)
            del config_candidates.candidates[candidate_index]
        else:
            LOGGER.debug('Vote recorded for %s',
                         candidate.proposal.setting)

        _save_config_candidates(state, config_candidates)
예제 #2
0
    def create_vote_proposal(self, proposal_id, setting, vote):
        vote = ConfigVote(proposal_id=proposal_id, vote=vote)
        payload = ConfigPayload(action=ConfigPayload.VOTE,
                                data=vote.SerializeToString())

        return self._create_tp_process_request(setting, payload)