def _apply_proposal(self, public_key, proposal_data, context):
        asset_proposal = AssetProposal()
        asset_proposal.ParseFromString(proposal_data)
        asset = Asset()
        asset.ParseFromString(asset_proposal.asset)
        proposal_id = self.asset_address(asset)

        approval_threshold = self._get_approval_threshold(context)
        if approval_threshold > 1:
            asset_candidates = self._get_candidates(context)
            existing_candidate = _first(
                asset_candidates.candidates,
                lambda candidate: candidate.proposal_id == proposal_id)

            if existing_candidate is not None:
                raise InvalidTransaction(
                    'Duplicate proposal for {}'.format(
                        asset_proposal.type))

            record = AssetCandidate.VoteRecord(
                public_key=public_key,
                vote=AssetCandidate.VoteRecord.VOTE_ACCEPT)
            asset_candidates.candidates.add(
                proposal_id=proposal_id,
                proposal=asset_proposal,
                votes=[record])
            self._set_candidates(context, asset_candidates)
        else:
            _set_asset(context, proposal_id, asset)
            LOGGER.debug('Set asset {}'.format(proposal_id))
    def _apply_vote(self, public_key, authorized_keys, vote_data, context):
        """Apply an ACCEPT or REJECT vote to a proposal"""
        asset_vote = AssetVote()
        asset_vote.ParseFromString(vote_data)
        proposal_id = asset_vote.proposal_id

        asset_candidates = self._get_candidates(context)
        candidate = _first(
            asset_candidates.candidates,
            lambda candidate: candidate.proposal_id == proposal_id)

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

        approval_threshold = self._get_approval_threshold(context)

        vote_record = _first(candidate.votes,
                             lambda record: record.public_key == public_key)

        if vote_record is not None:
            raise InvalidTransaction(
                '{} has already voted'.format(public_key))

        candidate_index = _index_of(asset_candidates.candidates, candidate)

        candidate.votes.add(
            public_key=public_key,
            vote=asset_vote.vote)

        accepted_count = 0
        rejected_count = 0
        for vote_record in candidate.votes:
            if vote_record.vote == AssetVote.VOTE_ACCEPT:
                accepted_count += 1
            elif vote_record.vote == AssetVote.VOTE_REJECT:
                rejected_count += 1

        LOGGER.debug(
            "Vote tally accepted {} rejected {}"
            .format(accepted_count, rejected_count))

        asset = Asset()
        asset.ParseFromString(candidate.proposal.asset)

        if accepted_count >= approval_threshold:
            _set_asset(context, proposal_id, asset)
            LOGGER.debug("Consensus to create {}".format(proposal_id))
            del asset_candidates.candidates[candidate_index]
            self._set_candidates(context, asset_candidates)
        elif rejected_count >= approval_threshold or \
                (rejected_count + accepted_count) == len(authorized_keys):
            LOGGER.debug(
                'Proposal for {} was rejected'.format(proposal_id))
            del asset_candidates.candidates[candidate_index]
            self._set_candidates(context, asset_candidates)
        else:
            LOGGER.debug('Vote recorded for {}'.format(proposal_id))
            self._set_candidates(context, asset_candidates)
def __asset_cache(prime):
    """Prime (value) lookup for resource asset"""
    res = __get_list_data(asset_addresser.family_ns_hash)
    resource = None
    for entry in res['data']:
        er = Asset()
        er.ParseFromString(entry['data'])
        if prime == er.value:
            resource = er
            break
    return resource
    def apply(self, transaction, context):
        txn_header = transaction.header
        public_key = txn_header.signer_public_key
        asset_payload = AssetPayload()
        asset_payload.ParseFromString(transaction.payload)

        auth_keys = self._get_auth_keys(context)

        if auth_keys and public_key not in auth_keys:
            raise InvalidTransaction(
                '{} is not authorized to change asset'.format(public_key))

        if asset_payload.action == AssetPayload.ACTION_GENESIS:
            asset = Asset()
            asset.ParseFromString(asset_payload.data)
            _set_asset(context, self.asset_address(asset), asset)
        elif asset_payload.action == AssetPayload.ACTION_DIRECT:
            asset = Asset()
            asset.ParseFromString(asset_payload.data)
            _set_asset(context, self.asset_address(asset), asset)
        elif asset_payload.action == AssetPayload.ACTION_PROPOSE:
            return self._apply_proposal(
                public_key,
                asset_payload.data,
                context)
        elif asset_payload.action == AssetPayload.ACTION_VOTE:
            return self._apply_vote(
                public_key,
                auth_keys,
                asset_payload.data,
                context)
        elif asset_payload.action == AssetPayload.ACTION_UNSET:
            return self._apply_unset_vote(
                public_key,
                auth_keys,
                asset_payload.data,
                context)
        else:
            raise InvalidTransaction(
                "'Payload action not recognized {}".
                format(asset_payload.action))
def __decode_asset_proposals(address, data):
    """Decode a proposals address"""
    proposals = AssetCandidates()
    proposals.ParseFromString(data)
    asset = Asset()
    data = []
    for candidate in proposals.candidates:
        msg = MessageToDict(candidate)
        asset.ParseFromString(candidate.proposal.asset)
        msg['proposal']['asset'] = MessageToDict(asset)
        for voter in msg['votes']:
            voter['publicKey'] = key_owner(voter['publicKey'])
        data.append(msg)
    return {'family': 'asset', 'type': 'proposal', 'data': data}
def decode_asset_list(address=None):
    """List of assets not including proposals"""
    targetadd = address if address else asset_addresser.family_ns_hash
    results = __get_list_data(targetadd)['data']
    data = []
    for element in results:
        asset = Asset()
        asset.ParseFromString(element['data'])
        am = MessageToDict(asset)
        data.append({
            'link':
            element['address'],
            'type':
            'asset',
            'system':
            asset.system,
            'name':
            asset.key,
            'value':
            asset.value,
            'properties':
            am["properties"] if "properties" in am else []
        })
    return {'family': 'asset', 'data': data}
def decode_asset(address):
    """Decode a asset address"""
    data = __get_leaf_data(address)['data']
    asset = Asset()
    asset.ParseFromString(data)
    return {'family': 'asset', 'data': MessageToDict(asset)}