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, ], )
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)
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)
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
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)