コード例 #1
0
    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))
コード例 #2
0
    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)
コード例 #3
0
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
コード例 #4
0
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}
コード例 #5
0
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}
コード例 #6
0
    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))
コード例 #7
0
ファイル: handler.py プロジェクト: PhillipNguyen2/lace
def _create_asset(payload, signer, timestamp, state):
    """Creates a history and initial touchpoint for an asset. 

    The position in the tree is determined by the addressing method used.  LaceTP identifies an 
    asset with a 6 character hash of the transaction family, followed by a single character to 
    indicate an agent(2), asset(1) or history(0).  All touchpoints have this single character set
    to asset(1).  Between this character and the last four (59 chars) is a random hash of an rfid.  
    The final four characters indicate the touchpoint index.  The index can never be zero as that 
    is reserved for the history.  The touchpoint can wrap around zero.
    """

    _verify_agent(state, signer)

    rfid = payload.rfid


    asset_address = addressing.make_asset_address(rfid)
    asset_container = _get_container(state, asset_address)

    if any(asset.rfid == rfid for asset in asset_container.entries):
        raise InvalidTransaction(
                'Asset already exists')

    # Create the asset and extend the asset container.
    
    asset = Asset(
        rfid    = payload.rfid,
        size    = payload.size,
        sku     = payload.sku, 
    )

    asset_container.entries.extend([asset])

    # Create the history for the asset.

    history_address = addressing.make_history_address(rfid)
    history_container = _get_container(state, history_address)

    if any(history.rfid == rfid for history in history_container.entries):
        raise InvalidTransaction(
                'History already exists for asset that didn\'t...')

    history = History(
        rfid = rfid,
        curr_touchpoint_index = INITIAL_TOUCHPOINT_INDEX,
        has_wrapped = False,
    )
    
    history.reporter_list.extend([
        Reporter(
            public_key          = signer,
            authorization_level = DEFAULT_AUTH_LEVEL, # Default for now.
        )
    ])
    
    # Extend the history container
    history_container.entries.extend([history])

    # Create the initial touchpoint

    touchpoint_address = addressing.make_touchpoint_address(rfid, INITIAL_TOUCHPOINT_INDEX)
    touchpoint_container = _get_container(state, touchpoint_address)

    touchpoint = TouchPoint(
        longitude = payload.longitude,
        latitude = payload.latitude,
        timestamp = timestamp,
        reporter_index = INITIAL_REPORTER_INDEX,
    )

    # Extend touchpoint container.
    touchpoint_container.entries.extend([touchpoint])

    # Set the state for the asset and its history.
    _set_container(state, asset_address, asset_container)
    _set_container(state, history_address, history_container)
    _set_container(state, touchpoint_address, touchpoint_container)  
コード例 #8
0
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)}