Ejemplo n.º 1
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)
Ejemplo n.º 2
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)
Ejemplo n.º 3
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,
            ],
        )
Ejemplo 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
Ejemplo 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)