class BuiltinDriver: @property def type(self): return 'builtin' def __init__(self): self.mongo_cli = MongodbClient( host=FLAGS.mongo_bytom_host, port=FLAGS.mongo_bytom_port) self.mongo_cli.use_db(FLAGS.mongo_bytom) # Sorted by balance, top 1000 def get_rank_address(self): address_info = self.mongo_cli.get_many( table=FLAGS.address_info, n=100, items={ 'address': 1, 'balance': 1, 'txs': 1, '_id': 0}, sort_key='balance', ascend=False ) result = self._show_rank_info(address_info) return result def _show_rank_info(self, lists): if not isinstance(lists, list): return None height = self.mongo_cli.get(FLAGS.db_status).get('height') total_btm = get_total_btm(height) result = [] for n in range(len(lists)): bal = lists[n]['balance'] info = { 'rank': n + 1, 'address': lists[n]['address'], 'balance': bal, 'percentage': float(bal) / total_btm, 'tx_count': len(lists[n]['txs']) } result.append(info) return result
class BuiltinDriver: @property def type(self): return 'builtin' def __init__(self): self.mongo_cli = MongodbClient(host=FLAGS.mongo_bytom_host, port=FLAGS.mongo_bytom_port) self.mongo_cli.use_db(FLAGS.mongo_bytom) def request(self, attribute, content): if attribute == 'asset': asset_info = self.mongo_cli.get_one(table=FLAGS.asset_info, cond={'asset_id': content}) return self._show_asset( asset_info) if asset_info is not None else {} return None @staticmethod def _show_asset(asset_info): asset_info.pop('_id') return asset_info
class BuiltinDriver: @property def type(self): return 'builtin' def __init__(self): self.logger = current_app.logger self.mongo_cli = MongodbClient(host=FLAGS.mongo_bytom_host, port=FLAGS.mongo_bytom_port) self.mongo_cli.use_db(FLAGS.mongo_bytom) self.block_manager = BlockManager() def request_tx_info(self, tx_hash): try: tx = self.get_tx_by_hash(remove_0x(tx_hash)) if tx is None: raise Exception("Transaction not found!") tx_info = self._show_tx(tx) except Exception, e: self.logger.error("tx.driver.builtin Error: %s" % str(e)) raise Exception(e) return tx_info
class BuiltinDriver: @property def type(self): return 'builtin' def __init__(self): self.logger = current_app.logger self.mongo_cli = MongodbClient(host=FLAGS.mongo_bytom_host, port=FLAGS.mongo_bytom_port) self.mongo_cli.use_db(FLAGS.mongo_bytom) def request_block_info(self, arg): try: hash_or_height = remove_0x(arg) if len(hash_or_height) == 64: return self.get_block_by_hash(hash_or_height) elif hash_or_height.isdigit() and int(hash_or_height) >= 0: return self.get_block_by_height(hash_or_height) else: return None except Exception, e: self.logger.error( "Block.BuiltinDriver.request_block_info Error: %s" % str(e)) raise Exception("request_block_info error: %s", e)
class ChainStats: def __init__(self): self.mongo_cli = MongodbClient(host=FLAGS.mongo_bytom_host, port=FLAGS.mongo_bytom_port) self.mongo_cli.use_db(flags.FLAGS.mongo_bytom)
class BuiltinDriver: @property def type(self): return 'builtin' def __init__(self): self.mongo_cli = MongodbClient(host=FLAGS.mongo_bytom_host, port=FLAGS.mongo_bytom_port) self.mongo_cli.use_db(FLAGS.mongo_bytom) def request_asset_info(self, asset_id, page=1, tag='txs'): asset_object = self.mongo_cli.get_one(table=FLAGS.asset_info, cond={FLAGS.asset_id: asset_id}) asset_info = self._show_asset(asset_object, page, tag) return asset_info @staticmethod def max_pages(num): return max(1, (num - 1) / 10 + 1) def list_assets(self, page=1): asset_num = self.mongo_cli.get_size(table=FLAGS.asset_info) page_max = self.max_pages(asset_num) page = min(page, page_max) skip = (page - 1) * 10 asset_objects = self.mongo_cli.get_many(table=FLAGS.asset_info, cond={}, n=10, sort_key='block_height', ascend=False, skip=skip) assets = [ self._show_asset_base_info(asset_object) for asset_object in asset_objects ] result = { 'asset_num': asset_num, 'assets': assets, 'page': page, 'pages': page_max } return result def _show_asset_base_info(self, asset_object): fields = [ 'asset_id', 'amount', 'asset_definition', 'code', 'issue_by', 'retire' ] result = {field: asset_object.get(field) for field in fields} result['issue_timestamp'] = self._get_tx_timestamp( asset_object.get('issue_by')) result['update_timestamp'] = self._get_block_timestamp( asset_object.get('block_hash')) result['tx_num'] = len(asset_object.get('txs')) result['holder_num'] = len(asset_object.get('balances')) return result def _show_asset(self, asset_object, page, tag='txs'): if asset_object is None: return {} result = self._show_asset_base_info(asset_object) tag = 'txs' if tag not in ['txs', 'balances'] else tag page_max = self.max_pages(len(asset_object.get(tag))) page = min(page_max, page) result['info'] = self._get_txs_info( asset_object.get('txs'), page) if tag == 'txs' else self._get_balances_info( asset_object.get('balances'), page) result['page'] = page result['pages'] = page_max return result def _get_txs_info(self, tx_ids, page): start = (page - 1) * 10 end = page * 10 tx_ids.reverse() tx_ids = tx_ids[start:end] txs = [ self.mongo_cli.get_one(flags.FLAGS.transaction_info, cond={'id': tx_id}) for tx_id in tx_ids ] info = [self.normalize_tx(tx) for tx in txs] return info def _get_balances_info(self, balances, page): start = (page - 1) * 10 end = page * 10 info = [{'address': k, 'balance': v} for k, v in balances.items()] info.sort(key=lambda e: e['balance'], reverse=True) return info[start:end] def normalize_tx(self, tx): fields = [ 'block_hash', 'block_height', 'id', 'inputs', 'outputs', 'size', 'status_fail', 'time_range', 'version' ] result = {field: tx.get(field) for field in fields} result['timestamp'] = self._get_block_timestamp(tx.get('block_hash')) return result def _get_block_timestamp(self, index): cond = {'height': index} if isinstance(index, int) else {'hash': index} timestamp = self.mongo_cli.get_one(table=FLAGS.block_info, cond=cond, fields={ 'timestamp': True }).get('timestamp') return timestamp def _get_tx_timestamp(self, tx_id): block_hash = self.mongo_cli.get_one(table=FLAGS.transaction_info, cond={ 'id': tx_id }, fields={ 'block_hash': True }).get('block_hash') return self._get_block_timestamp(block_hash)
class BuiltinDriver: @property def type(self): return 'builtin' def __init__(self): self.logger = current_app.logger self.mongo_cli = MongodbClient(host=FLAGS.mongo_bytom_host, port=FLAGS.mongo_bytom_port) self.mongo_cli.use_db(FLAGS.mongo_bytom) def search(self, info): # info = info.strip() info_copy = info info = info.strip().lower() try: if HEIGHT_RE.match(info): return {'type': 'block', 'value': info} if ADDRESS_RE.match(info): return {'type': 'address', 'value': info} hash_value = remove_0x(info) if LEN_64_RE.match(hash_value): block = self.search_block_by_hash(hash_value) if block: return {'type': 'block', 'value': hash_value} transaction = self.search_tx_by_hash(hash_value) if transaction: return {'type': 'tx', 'value': hash_value} asset = self.search_asset_by_id(hash_value) if asset: return {'type': 'asset', 'value': hash_value} asset_id_list = self.search_asset_by_definition(info_copy) if len(asset_id_list) > 0: return {'type': 'asset_list', 'value': asset_id_list} return None except Exception as e: self.logger.error("Search.bytom.BuiltinDriver.search Error: %s" % str(e)) def search_block_by_height(self, height): return self.mongo_cli.get_one(table=FLAGS.block_info, cond={FLAGS.block_height: height}) def search_block_by_hash(self, block_hash): return self.mongo_cli.get_one(table=FLAGS.block_info, cond={FLAGS.block_id: block_hash}) def search_tx_by_hash(self, tx_hash): return self.mongo_cli.get_one(table=FLAGS.transaction_info, cond={FLAGS.tx_id: tx_hash}) def search_asset_by_id(self, asset_id): asset_dict = self.mongo_cli.get_one(table=FLAGS.asset_info, cond={FLAGS.asset_id: asset_id}) return asset_dict def search_asset_by_definition(self, definition): asset_list = self.mongo_cli.get_many(table=FLAGS.asset_info, cond={ '$or': [{ 'asset_definition.name': definition }, { 'asset_definition.symbol': definition }] }, items={ 'asset_id': True, '_id': False }) id_list = [asset.get('asset_id') for asset in asset_list] return id_list
class BuiltinDriver: @property def type(self): return 'builtin' def __init__(self): self.mongo_cli = MongodbClient(host=FLAGS.mongo_bytom_host, port=FLAGS.mongo_bytom_port) self.mongo_cli.use_db(FLAGS.mongo_bytom) def request_address_info(self, addr, page=1): addr_object = self.mongo_cli.get_one(table=FLAGS.address_info, cond={FLAGS.address: addr}) addr_info = self._show_addr(addr_object, page) return addr_info def _show_addr(self, addr, page): if addr is None: return { 'balance': 0, 'sent': 0, 'recv': 0, 'tx_num': 0, 'txs': [], 'asset_balance': {} } fields = ['balance', 'sent', 'recv', 'asset_balances'] result = {} for field in fields: result[field] = addr[field] start = (page - 1) * 10 if start >= len(addr['txs']): raise Exception('page exceed the maximum') end = page * 10 if end >= len(addr['txs']): end = len(addr['txs']) addr['txs'].reverse() tx_ids = addr['txs'][start:end] txs = [] for tx_id in tx_ids: tx = self.mongo_cli.get_one(flags.FLAGS.transaction_info, cond={'id': tx_id}) txs.append(self.normalize_tx(tx)) result['txs'] = txs result['tx_num'] = len(addr['txs']) result['no_page'] = page result['pages'] = len(addr['txs']) / 10 + 1 return result def normalize_tx(self, tx): fields = [ 'block_hash', 'block_height', 'id', 'inputs', 'outputs', 'size', 'status_fail', 'time_range', 'version' ] result = {} for field in fields: result[field] = tx[field] block = self.mongo_cli.get_one( table=FLAGS.block_info, cond={FLAGS.block_height: int(tx.get('block_height'))}) if block: result['timestamp'] = block.get('timestamp') return result