def revoke_reporter(self, record_id, reporter_id, properties):
        payload = _make_tt_payload(action=TTPayload.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,
            ],
        )
Esempio n. 2
0
def _make_new_property_page(state, timestamp, record_id, property_name, value,
                            page_number):
    page_address = addressing.make_property_address(record_id, property_name,
                                                    page_number)

    page_container = _get_container(state, page_address)

    page = PropertyPage(
        name=property_name,
        record_id=record_id,
    )

    if value:
        page.reported_values.extend([
            _make_new_reported_value(
                reporter_index=0,
                timestamp=timestamp,
                prop=value,
            )
        ])

    page_container.entries.extend([page])
    page_container.entries.sort(key=lambda page: page.name)

    _set_container(state, page_address, page_container)
Esempio n. 3
0
def _make_new_property(state, record_id, property_name, data_type, signer):
    property_address = addressing.make_property_address(
        record_id, property_name, 0)

    property_container = _get_container(state, property_address)

    new_prop = Property(
        name=property_name,
        record_id=record_id,
        data_type=data_type,
        reporters=[
            Property.Reporter(
                public_key=signer,
                authorized=True,
                index=0,
            )
        ],
        current_page=1,
        wrapped=False,
    )

    property_container.entries.extend([new_prop])
    property_container.entries.sort(key=lambda prop: prop.name)

    _set_container(state, property_address, property_container)
Esempio n. 4
0
def _get_property(state, record_id, property_name):
    ''' Return property, property_container, property_address '''
    property_address = addressing.make_property_address(
        record_id, property_name)

    property_container = _get_container(state, property_address)

    try:
        prop = next(prop for prop in property_container.entries
                    if prop.name == property_name)
    except StopIteration:
        raise InvalidTransaction('Property does not exist')

    return prop, property_container, property_address
Esempio n. 5
0
def _update_properties(payload, signer, timestamp, state):
    '''
    * Check that the record is not final
    * Check that the signer is an authorized reporter
    * Check that the types are correct
    '''
    # Check that the record is not final
    record_id = payload.record_id
    record, _, _ = _get_record(state, record_id)

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

    updates = payload.properties

    for update in updates:
        name, data_type = update.name, update.data_type
        property_address = addressing.make_property_address(record_id, name)
        property_container = _get_container(state, property_address)

        try:
            prop = next(prop for prop in property_container.entries
                        if prop.name == name)
        except StopIteration:
            raise InvalidTransaction('Record does not have property')

        try:
            reporter_index = next(
                reporter.index for reporter in prop.reporters
                if reporter.public_key == signer and reporter.authorized)
        except StopIteration:
            raise InvalidTransaction('Reporter is not authorized')

        if data_type != prop.data_type:
            raise InvalidTransaction('Update has wrong type')

        page_number = prop.current_page
        page_address = addressing.make_property_address(
            record_id, name, page_number)
        page_container = _get_container(state, page_address)

        try:
            page = next(page for page in page_container.entries
                        if page.name == name)
        except StopIteration:
            raise InternalError('Property page does not exist')

        reported_value = _make_new_reported_value(
            reporter_index=reporter_index,
            timestamp=timestamp,
            prop=update,
        )

        page.reported_values.extend([reported_value])
        page.reported_values.sort(
            key=lambda val: (val.timestamp, val.reporter_index))

        _set_container(state, page_address, page_container)

        # increment page if needed

        if len(page.reported_values) >= PROPERTY_PAGE_MAX_LENGTH:
            new_page_number = (page_number +
                               1 if page_number + 1 <= TOTAL_PROPERTY_PAGE_MAX
                               else 1)

            new_page_address = addressing.make_property_address(
                record_id, name, new_page_number)

            new_page_container = _get_container(state, new_page_address)

            try:
                new_page = next(page for page in new_page_container.entries
                                if page.name == name)

                del new_page.reported_values[:]

            except StopIteration:
                new_page = PropertyPage(
                    name=name,
                    record_id=record_id,
                )

                new_page_container.entries.extend([new_page])

            _set_container(state, new_page_address, new_page_container)

            # increment the property's page number (or wrap back to 1)

            prop.current_page = new_page_number

            if new_page_number == 1 and not prop.wrapped:
                prop.wrapped = True

            _set_container(state, property_address, property_container)