def remove_block(self, block_hash): # Retrieve block block = Block.query(self.db_session).filter_by(hash=block_hash).first() # Revert event processors for event in Event.query(self.db_session).filter_by(block_id=block.id): for processor_class in ProcessorRegistry().get_event_processors(event.module_id, event.event_id): event_processor = processor_class(block, event, None) event_processor.accumulation_revert(self.db_session) # Revert extrinsic processors for extrinsic in Extrinsic.query(self.db_session).filter_by(block_id=block.id): for processor_class in ProcessorRegistry().get_extrinsic_processors(extrinsic.module_id, extrinsic.call_id): extrinsic_processor = processor_class(block, extrinsic) extrinsic_processor.accumulation_revert(self.db_session) # Revert block processors for processor_class in ProcessorRegistry().get_block_processors(): block_processor = processor_class(block) block_processor.accumulation_revert(self.db_session) # Delete events for item in Event.query(self.db_session).filter_by(block_id=block.id): self.db_session.delete(item) # Delete extrinsics for item in Extrinsic.query(self.db_session).filter_by(block_id=block.id): self.db_session.delete(item) # Delete block self.db_session.delete(block)
def get_item(self, item_id): if '-' in item_id: st = item_id.split("-") return Event.query(self.session).filter_by(event_idx=int(st[2]), block_id=int(st[1]), shard_num=int( st[0])).first() else: return Event.query( self.session).filter_by(id=item_id.split('-')[0]).first()
def apply_filters(self, query, params): if params.get('filter[address]'): if len(params.get('filter[address]')) == 64: account_id = params.get('filter[address]') else: try: account_id = ss58_decode(params.get('filter[address]'), settings.SUBSTRATE_ADDRESS_TYPE) except ValueError: return query.filter(False) search_index = SearchIndex.query(self.session).filter( SearchIndex.index_type_id.in_([ settings.SEARCH_INDEX_BALANCETRANSFER, settings.SEARCH_INDEX_CLAIMS_CLAIMED, settings.SEARCH_INDEX_BALANCES_DEPOSIT, settings.SEARCH_INDEX_STAKING_REWARD ]), SearchIndex.account_id == account_id).order_by( SearchIndex.sorting_value.desc()) query = Event.query(self.session).filter( tuple_(Event.block_id, Event.event_idx).in_( [[s.block_id, s.event_idx] for s in search_index])).order_by(Event.block_id.desc()) return query
def get_relationships(self, include_list, item): relationships = {} if 'extrinsics' in include_list: relationships['extrinsics'] = Extrinsic.query( self.session).filter_by( block_id=item.bid, shard_num=item.shard_num).order_by('extrinsic_idx') if 'transactions' in include_list: relationships['transactions'] = Extrinsic.query( self.session).filter_by( block_id=item.bid, signed=1, shard_num=item.shard_num).order_by('extrinsic_idx') if 'inherents' in include_list: relationships['inherents'] = Extrinsic.query(self.session).filter( Extrinsic.block_id == item.bid, Extrinsic.signed == 0, Extrinsic.shard_num == item.shard_num, Extrinsic.module_id != 'relay').order_by('extrinsic_idx') if 'relay' in include_list: relationships['relay'] = Extrinsic.query(self.session).filter( Extrinsic.block_id == item.bid, Extrinsic.signed == 0, Extrinsic.shard_num == item.shard_num, Extrinsic.module_id == 'relay').order_by('extrinsic_idx') if 'events' in include_list: relationships['events'] = Event.query(self.session).filter_by( block_id=item.bid, system=0, shard_num=item.shard_num).order_by('event_idx') if 'logs' in include_list: relationships['logs'] = Log.query(self.session).filter_by( block_id=item.bid, shard_num=item.shard_num).order_by('log_idx') return relationships
def get_relationships(self, include_list, item): relationships = {} if 'events' in include_list: relationships['events'] = Event.query(self.session).filter_by( block_id=item.block_id, extrinsic_idx=item.extrinsic_idx).order_by('event_idx') return relationships
def rebuild_search_index(self): self.db_session.execute('truncate table {}'.format( SearchIndex.__tablename__)) for block in Block.query( self.db_session).order_by('id').yield_per(1000): extrinsic_lookup = {} block._accounts_new = [] block._accounts_reaped = [] for extrinsic in Extrinsic.query(self.db_session).filter_by( block_id=block.id).order_by('extrinsic_idx'): extrinsic_lookup[extrinsic.extrinsic_idx] = extrinsic # Add search index for signed extrinsics if extrinsic.address: search_index = SearchIndex( index_type_id=settings.SEARCH_INDEX_SIGNED_EXTRINSIC, block_id=block.id, extrinsic_idx=extrinsic.extrinsic_idx, account_id=extrinsic.address) search_index.save(self.db_session) # Process extrinsic processors for processor_class in ProcessorRegistry( ).get_extrinsic_processors(extrinsic.module_id, extrinsic.call_id): extrinsic_processor = processor_class( block=block, extrinsic=extrinsic, substrate=self.substrate) extrinsic_processor.process_search_index(self.db_session) for event in Event.query(self.db_session).filter_by( block_id=block.id).order_by('event_idx'): extrinsic = None if event.extrinsic_idx is not None: try: extrinsic = extrinsic_lookup[event.extrinsic_idx] except (IndexError, KeyError): extrinsic = None for processor_class in ProcessorRegistry( ).get_event_processors(event.module_id, event.event_id): event_processor = processor_class( block, event, extrinsic, metadata=self.metadata_store.get( block.spec_version_id), substrate=self.substrate) event_processor.process_search_index(self.db_session) self.db_session.commit()
def sequence_block(self, block, parent_block_data=None, parent_sequenced_block_data=None): sequenced_block = BlockTotal(id=block.id) # Process block processors for processor_class in ProcessorRegistry().get_block_processors(): block_processor = processor_class(block, sequenced_block, substrate=self.substrate) block_processor.sequencing_hook(self.db_session, parent_block_data, parent_sequenced_block_data) extrinsics = Extrinsic.query(self.db_session).filter_by( block_id=block.id).order_by('extrinsic_idx') for extrinsic in extrinsics: # Process extrinsic processors for processor_class in ProcessorRegistry( ).get_extrinsic_processors(extrinsic.module_id, extrinsic.call_id): extrinsic_processor = processor_class(block, extrinsic, substrate=self.substrate) extrinsic_processor.sequencing_hook( self.db_session, parent_block_data, parent_sequenced_block_data) events = Event.query( self.db_session).filter_by(block_id=block.id).order_by('event_idx') # Process event processors for event in events: extrinsic = None if event.extrinsic_idx is not None: try: extrinsic = extrinsics[event.extrinsic_idx] except IndexError: extrinsic = None for processor_class in ProcessorRegistry().get_event_processors( event.module_id, event.event_id): event_processor = processor_class(block, event, extrinsic, substrate=self.substrate) event_processor.sequencing_hook(self.db_session, parent_block_data, parent_sequenced_block_data) sequenced_block.save(self.db_session) return sequenced_block
def get_relationships(self, include_list, item): relationships = {} if 'attributes' in include_list: relationships['attributes'] = RuntimeEventAttribute.query(self.session).filter_by( runtime_event_id=item.id).order_by('id') if 'recent_events' in include_list: relationships['recent_events'] = Event.query(self.session).filter_by( event_id=item.event_id, module_id=item.module_id).order_by(Event.block_id.desc())[:10] return relationships
def rebuild_search_index(self, search_index_type_id): if search_index_type_id == SEARCH_INDEX_SLASHED_ACCOUNT: for event in Event.query(self.db_session).filter_by( module_id='staking', event_id='Slash'): processor = SlashEventProcessor(block=event.block, event=event) processor.process_search_index(self.db_session) self.db_session.commit() elif search_index_type_id == SEARCH_INDEX_BALANCETRANSFER: for event in Event.query(self.db_session).filter_by( module_id='balances', event_id='Transfer'): processor = BalancesTransferProcessor(block=event.block, event=event) processor.process_search_index(self.db_session) self.db_session.commit() else: raise NotImplementedError( 'Not supported search index {}'.format(search_index_type_id))
def serialize_item(self, item): data = item.serialize() runtime_call = RuntimeCall.query(self.session).filter_by( module_id=item.module_id, call_id=item.call_id, spec_version=item.spec_version_id).first() data['attributes']['documentation'] = runtime_call.documentation block = Block.query(self.session).get(item.block_id) if block.datetime: data['attributes']['datetime'] = block.datetime.replace( tzinfo=pytz.UTC).isoformat() else: data['attributes']['datetime'] = None if item.account: data['attributes']['account'] = item.account.serialize() if item.params: item.params = self.check_params(item.params, item.serialize_id()) if item.error: # Retrieve ExtrinsicFailed event extrinsic_failed_event = Event.query(self.session).filter_by( block_id=item.block_id, event_id='ExtrinsicFailed').first() # Retrieve runtime error if extrinsic_failed_event: if 'Module' in extrinsic_failed_event.attributes[0]['value']: error = RuntimeErrorMessage.query(self.session).filter_by( module_index=extrinsic_failed_event.attributes[0] ['value']['Module']['index'], index=extrinsic_failed_event.attributes[0]['value'] ['Module']['error'], spec_version=item.spec_version_id).first() if error: data['attributes'][ 'error_message'] = error.documentation elif 'BadOrigin' in extrinsic_failed_event.attributes[0][ 'value']: data['attributes']['error_message'] = 'Bad origin' elif 'CannotLookup' in extrinsic_failed_event.attributes[0][ 'value']: data['attributes']['error_message'] = 'Cannot lookup' return data
def process_reorg_block(self, block): model = ReorgBlock(**block.asdict()) model.save(self.db_session) for extrinsic in Extrinsic.query( self.db_session).filter_by(block_id=block.id): model = ReorgExtrinsic(block_hash=block.hash, **extrinsic.asdict()) model.save(self.db_session) for event in Event.query(self.db_session).filter_by(block_id=block.id): model = ReorgEvent(block_hash=block.hash, **event.asdict()) model.save(self.db_session) for log in Log.query(self.db_session).filter_by(block_id=block.id): model = ReorgLog(block_hash=block.hash, **log.asdict()) model.save(self.db_session)
def get_relationships(self, include_list, item): relationships = {} if 'extrinsics' in include_list: relationships['extrinsics'] = Extrinsic.query(self.session).filter_by(block_id=item.id).order_by( 'extrinsic_idx') if 'transactions' in include_list: relationships['transactions'] = Extrinsic.query(self.session).filter_by(block_id=item.id, signed=1).order_by( 'extrinsic_idx') if 'inherents' in include_list: relationships['inherents'] = Extrinsic.query(self.session).filter_by(block_id=item.id, signed=0).order_by( 'extrinsic_idx') if 'events' in include_list: relationships['events'] = Event.query(self.session).filter_by(block_id=item.id, system=0).order_by( 'event_idx') if 'logs' in include_list: relationships['logs'] = Log.query(self.session).filter_by(block_id=item.id).order_by( 'log_idx') return relationships
def serialize_item(self, item): data = item.serialize() runtime_call = RuntimeCall.query(self.session).filter_by( module_id=item.module_id, call_id=item.call_id, spec_version=item.spec_version_id).first() data['attributes']['documentation'] = runtime_call.documentation block = Block.query(self.session).get(item.block_id) data['attributes']['datetime'] = block.datetime.replace( tzinfo=pytz.UTC).isoformat() if item.account: data['attributes']['account'] = item.account.serialize() if item.error: # Retrieve ExtrinsicFailed event extrinsic_failed_event = Event.query(self.session).filter_by( block_id=item.block_id, event_id='ExtrinsicFailed').first() # Retrieve runtime error if extrinsic_failed_event and 'Module' in extrinsic_failed_event.attributes[ 0]['value']: error = RuntimeErrorMessage.query(self.session).filter_by( module_id=item.module_id, index=extrinsic_failed_event.attributes[0]['value'] ['Module']['error'], spec_version=item.spec_version_id).first() if error: data['attributes']['error_message'] = error.documentation return data
def get_item(self, item_id): return Event.query(self.session).get(item_id.split('-'))
def on_post(self, req, resp): blockHash = None if req.media.get('block_id'): substrate = SubstrateInterface(url=SUBSTRATE_RPC_URL, address_type=SUBSTRATE_ADDRESS_TYPE, type_registry_preset=TYPE_REGISTRY) blockHash = substrate.get_block_hash(req.media.get('block_id')) elif req.media.get('block_hash'): blockHash = req.media.get('block_hash') else: resp.status = falcon.HTTP_BAD_REQUEST resp.media = { 'errors': ['Either blockHash or block_id should be supplied'] } if blockHash: resp.status = falcon.HTTP_200 block = Block.query( self.session).filter(Block.hash == blockHash).first() blockTotal = BlockTotal.query( self.session).filter(BlockTotal.id == block.id).first() author = ss58_encode( blockTotal.author.replace('0x', '') ) if blockTotal is not None and blockTotal.author is not None else None if block: blockInfo = {} blockInfo["timestamp"] = block.datetime.strftime( "%Y-%m-%d %H:%M:%S") blockInfo["block_hash"] = block.hash blockInfo["block_id"] = block.id blockInfo["parent_id"] = block.id - 1 if block.id > 0 else 0 blockInfo["child_id"] = block.id + 1 blockInfo["parent_hash"] = block.parent_hash blockInfo["state_root"] = block.state_root blockInfo["extrinsic_root"] = block.extrinsics_root blockInfo["validator"] = author blockInfo["count_extrinsic"] = block.count_extrinsics blockInfo["count_event"] = block.count_events blockInfo["count_log"] = block.count_log # blockInfo["age"] = time.mktime(block.datetime.timetuple()) blockInfo["age"] = block.datetime.strftime("%Y-%m-%d %H:%M:%S") # 获取和区块相关的交易信息 extrinsics = Extrinsic.query( self.session).filter(Extrinsic.block_id == block.id).all() extrinsicsObj = [ { "extrinsic_id": '{}-{}'.format(block.id, extrinsic.extrinsic_idx), "hash": extrinsic.extrinsic_hash if extrinsic.extrinsic_hash else None, # "age": time.mktime(block.datetime.timetuple()), "age": block.datetime.strftime("%Y-%m-%d %H:%M:%S"), "result": extrinsic.success, # "address": extrinsic.address if extrinsic.address else None, # "module": extrinsic.module_id, # "fee": None, # "nonce": extrinsic.nonce if extrinsic.nonce else None, # "call": extrinsic.call_id, "operation": '{}({})'.format(extrinsic.module_id, extrinsic.call_id), "params": extrinsic.params # "signature": extrinsic.signature if extrinsic.signature else None } for extrinsic in extrinsics ] # 获取和区块相关的日志信息 logs = Log.query( self.session).filter(Log.block_id == block.id).all() logsObj = [{ "log_id": '{}-{}'.format(block.id, log.log_idx), "block_id": block.id, "type": log.type, "data": log.data['value'] } for log in logs] # 获取和区块相关的事件信息 events = Event.query( self.session).filter(Event.block_id == block.id).all() eventObj = [{ "id": '{}-{}'.format(block.id, event.event_idx), "block_id": block.id, "block_hash": block.hash, "module_id": event.module_id, "event_id": event.event_id, "attributes": event.attributes, "operation": '{}({})'.format(event.module_id, event.event_id), "desc": self.getEventDesc(event.module_id, event.event_id), "hash": self.getEventHash(block.id, event.extrinsic_idx) } for event in events] resp.media = { 'status': 'success', 'data': { "block_info": blockInfo, "extrinsics": extrinsicsObj, "logs": logsObj, "events": eventObj } } else: resp.status = falcon.HTTP_404 resp.media = {'result': 'Block not found'}
def get_query(self): return Event.query(self.session).filter( Event.module_id == 'balances', Event.event_id == 'Transfer').order_by(Event.block_id.desc())
def get_item(self, item_id): if len(item_id.split('-')) != 2: return None return Event.query(self.session).get(item_id.split('-'))
def get_query(self): return Event.query(self.session).order_by(Event.block_id.desc())
def on_get(self, req, resp): resp.status = falcon.HTTP_200 extrinsicId = req.params.get('extrinsic_id') if extrinsicId is None: resp.status = falcon.HTTP_BAD_REQUEST resp.media = {'errors': ['Invalid extrinsic id']} split = extrinsicId.split("-") if split is None or len(split) != 2: resp.status = falcon.HTTP_BAD_REQUEST resp.media = {'errors': ['Invalid extrinsic id']} blockId = split[0] extrinsicIdx = split[1] extrinsic = Extrinsic.extrinsic_by_id(self.session, blockId, extrinsicIdx).first() print(extrinsic.extrinsic_idx) extrinsicDetailInfo = {} if extrinsic is not None: extrinsicDetailInfo["extrinsic_id"] = '{}-{}'.format( extrinsic.block_id, extrinsic.extrinsic_idx) extrinsicDetailInfo["block_id"] = extrinsic.block_id extrinsicDetailInfo["extrinsic_idx"] = extrinsic.extrinsic_idx extrinsicDetailInfo["hash"] = "0x{}".format( extrinsic.extrinsic_hash) if extrinsic.extrinsic_hash else None extrinsicDetailInfo["age"] = extrinsic.datetime.strftime( "%Y-%m-%d %H:%M:%S") extrinsicDetailInfo["result"] = extrinsic.success extrinsicDetailInfo["operation"] = '{}({})'.format( extrinsic.module_id, extrinsic.call_id) extrinsicDetailInfo["module_id"] = extrinsic.module_id extrinsicDetailInfo["call_id"] = extrinsic.call_id extrinsicDetailInfo[ "module_name"] = extrinsic.module_name.capitalize() extrinsicDetailInfo["call_name"] = extrinsic.call_name.capitalize() extrinsicDetailInfo["call_desc"] = extrinsic.call_desc extrinsicDetailInfo["nonce"] = int( extrinsic.nonce) if extrinsic.nonce else None extrinsicDetailInfo[ "signature"] = extrinsic.signature if extrinsic.signature else None extrinsicDetailInfo["params"] = extrinsic.params extrinsicDetailInfo["from"] = extrinsic.address.replace( '0x', '') if extrinsic.address else None extrinsicDetailInfo["from_addr"] = ss58_encode( extrinsic.address.replace('0x', '')) if extrinsic.address else None params = json.loads(extrinsic.params) for param in params: name = param.get('name') if name == 'dest': toAddr = ss58_encode(param.get('value').replace('0x', '')) extrinsicDetailInfo['to'] = param.get('value').replace( '0x', '') extrinsicDetailInfo['to_addr'] = toAddr elif name == 'value': coin = param.get('value') / 1000000000000 # 转换为单位 Unit extrinsicDetailInfo['coin'] = coin # 获取和区块相关的事件信息 events = Event.query(self.session).filter( Event.block_id == extrinsic.block_id).all() eventObj = [{ "id": '{}-{}'.format(extrinsic.block_id, event.event_idx), "block_id": extrinsic.block_id, "module_id": event.module_id, "event_id": event.event_id, "attributes": event.attributes, "operation": '{}({})'.format(event.module_id, event.event_id), "desc": self.getEventDesc(event.module_id, event.event_id), "hash": self.getEventHash(extrinsic.block_id, event.extrinsic_idx) } for event in events] resp.media = { 'status': 'success', 'data': { "extrinsic_detail": extrinsicDetailInfo, "events": eventObj, "event_count": len(eventObj) } }
def on_get(self, req, resp, network_id=None): resp.status = falcon.HTTP_200 # TODO make caching more generic for custom resources cache_key = '{}-{}'.format(req.method, req.url) console_handler = logging.StreamHandler() console_handler.setLevel('INFO') logger = logging.getLogger('yee') logger.setLevel('DEBUG') logger.addHandler(console_handler) # logger.info(cache_key) response = self.cache_region.get(cache_key, self.cache_expiration_time) if response is NO_VALUE: best_block = Block.query(self.session).filter_by( id=self.session.query(func.max(Block.id)).one()[0]).first() total_signed_extrinsics = Extrinsic.query( self.session).filter_by(signed=1).count() total_accounts = Account.query(self.session).filter_by().count() # total_events = Event.query(self.session).count() event = Event.query(self.session).filter_by( id=self.session.query(func.max(Event.id)).one()[0]).first() if event is None: eventid = 0 else: eventid = event.id if best_block: substrate = SubstrateInterface( SUBSTRATE_RPC_URL, metadata_version=SUBSTRATE_METADATA_VERSION) print(substrate.get_ShardCount()) response = self.get_jsonapi_response(data={ 'type': 'networkstats', 'id': network_id, 'attributes': { 'best_block': best_block.id, 'total_signed_extrinsics': total_signed_extrinsics, 'total_events': eventid, 'total_events_module': int(best_block.id), 'total_blocks': 'N/A', 'total_accounts': total_accounts, 'total_runtimes': Runtime.query(self.session).count(), 'shard_count': int(substrate.get_ShardCount(), 16) } }, ) else: response = self.get_jsonapi_response(data={ 'type': 'networkstats', 'id': network_id, 'attributes': { 'best_block': 0, 'total_signed_extrinsics': 0, 'total_events': 0, 'total_events_module': 0, 'total_blocks': 'N/A', 'total_accounts': 0, 'total_runtimes': 0 } }, ) self.cache_region.set(cache_key, response) resp.set_header('X-Cache', 'MISS') else: resp.set_header('X-Cache', 'HIT') resp.media = response
def get_query(self): return Event.query(self.session).filter( Event.system == False).order_by(Event.block_id.desc())