示例#1
0
    def answer_proposal(self, record_id, receiving_agent, role, response):
        payload = _make_sc_payload(action=SCPayload.ANSWER_PROPOSAL,
                                   answer_proposal=AnswerProposalAction(
                                       record_id=record_id,
                                       receiving_agent=receiving_agent,
                                       role=role,
                                       response=response))

        proposal_address = addressing.make_proposal_address(
            record_id, receiving_agent)

        record_address = addressing.make_record_address(record_id)

        property_address_range = addressing.make_property_address_range(
            record_id)

        return self._create_transaction(
            payload,
            inputs=[
                proposal_address,
                record_address,
                property_address_range,
                addressing.RECORD_TYPE_ADDRESS_RANGE,
            ],
            outputs=[
                proposal_address,
                record_address,
                property_address_range,
            ],
        )
示例#2
0
    def revoke_reporter(self, record_id, reporter_id, properties):
        payload = _make_sc_payload(action=SCPayload.REVOKE_REPORTER,
                                   revoke_reporter=RevokeReporterAction(
                                       record_id=record_id,
                                       reporter_id=reporter_id,
                                       properties=properties))

        record_address = addressing.make_record_address(record_id)

        proposal_address = addressing.make_proposal_address(
            record_id, reporter_id)

        property_addresses = [
            addressing.make_property_address(record_id, property_name)
            for property_name in properties
        ]

        return self._create_transaction(
            payload,
            inputs=[
                record_address,
                proposal_address,
                *property_addresses,
            ],
            outputs=[
                proposal_address,
                *property_addresses,
            ],
        )
示例#3
0
    def create_proposal(self,
                        record_id,
                        receiving_agent,
                        role,
                        properties=None):
        if properties is None:
            properties = []

        payload = _make_sc_payload(action=SCPayload.CREATE_PROPOSAL,
                                   create_proposal=CreateProposalAction(
                                       record_id=record_id,
                                       receiving_agent=receiving_agent,
                                       role=role,
                                       properties=properties))

        proposal_address = addressing.make_proposal_address(
            record_id, receiving_agent)

        receiving_address = addressing.make_agent_address(receiving_agent)

        record_address = addressing.make_record_address(record_id)

        return self._create_transaction(
            payload,
            inputs=[
                proposal_address,
                record_address,
                receiving_address,
                self.signer_address,
            ],
            outputs=[proposal_address],
        )
示例#4
0
def _create_proposal(payload, signer, timestamp, state):
    record_id, receiving_agent, role, properties = \
        payload.record_id, payload.receiving_agent, \
        payload.role, payload.properties

    # Verify both agents
    _verify_agent(state, signer)
    _verify_agent(state, receiving_agent)

    proposal_address = addressing.make_proposal_address(
        record_id, receiving_agent)
    proposal_container = _get_container(state, proposal_address)

    open_proposals = [
        proposal for proposal in proposal_container.entries
        if proposal.status == Proposal.OPEN
    ]

    for proposal in open_proposals:
        if (proposal.receiving_agent == receiving_agent
                and proposal.role == role and proposal.record_id == record_id):
            raise InvalidTransaction('Proposal already exists')

    record, _, _ = _get_record(state, record_id)

    if record.final:
        raise InvalidTransaction('Record is final')

    if role == Proposal.OWNER or role == Proposal.REPORTER:
        if not _is_owner(record, signer):
            raise InvalidTransaction('Must be owner')

    if role == Proposal.CUSTODIAN:
        if not _is_custodian(record, signer):
            raise InvalidTransaction('Must be custodian')

    proposal = Proposal(
        record_id=record_id,
        timestamp=timestamp,
        issuing_agent=signer,
        receiving_agent=receiving_agent,
        role=role,
        properties=properties,
        status=Proposal.OPEN,
    )

    proposal_container.entries.extend([proposal])
    proposal_container.entries.sort(key=lambda prop: (
        prop.record_id,
        prop.receiving_agent,
        prop.timestamp,
    ))

    _set_container(state, proposal_address, proposal_container)
示例#5
0
def _answer_proposal(payload, signer, timestamp, state):
    record_id, receiving_agent, role, response = \
        payload.record_id, payload.receiving_agent, \
        payload.role, payload.response

    proposal_address = addressing.make_proposal_address(
        record_id, receiving_agent)
    proposal_container = _get_container(state, proposal_address)

    try:
        proposal = next(
            proposal
            for proposal in proposal_container.entries
            if (proposal.status == Proposal.OPEN
                and proposal.receiving_agent == receiving_agent
                and proposal.role == role)
        )
    except StopIteration:
        raise InvalidTransaction(
            'No such open proposal')

    if response == AnswerProposalAction.CANCEL:
        if proposal.issuing_agent != signer:
            raise InvalidTransaction(
                'Only the issuing agent can cancel')

        proposal.status = Proposal.CANCELED

    elif response == AnswerProposalAction.REJECT:
        if proposal.receiving_agent != signer:
            raise InvalidTransaction(
                'Only the receiving agent can reject')

        proposal.status = Proposal.REJECTED

    elif response == AnswerProposalAction.ACCEPT:
        if proposal.receiving_agent != signer:
            raise InvalidTransaction(
                'Only the receiving agent can accept')

        proposal.status = _accept_proposal(state, signer, proposal, timestamp)

    _set_container(state, proposal_address, proposal_container)