def render_GET(self, request): """ Get request /decode_tx/ that returns the tx decoded, if success Expects 'hex_tx' as GET parameter :rtype: string (json) """ request.setHeader(b'content-type', b'application/json; charset=utf-8') set_cors(request, 'GET') parsed = parse_get_arguments(request.args, ARGS) if not parsed['success']: return get_missing_params_msg(parsed['missing']) try: tx_bytes = bytes.fromhex(parsed['args']['hex_tx']) tx = tx_or_block_from_bytes(tx_bytes) tx.storage = self.manager.tx_storage data = get_tx_extra_data(tx) except ValueError: data = {'success': False, 'message': 'Invalid hexadecimal data'} except struct.error: data = {'success': False, 'message': 'Could not decode transaction'} return json.dumps(data, indent=4).encode('utf-8')
def render_GET(self, request): """ Get request to /dashboard-tx/ that return a list of blocks and tx We expect two GET parameters: 'block' and 'tx' 'block': int that indicates de quantity of blocks I should return 'tx': int that indicates de quantity of tx I should return :rtype: string (json) """ request.setHeader(b'content-type', b'application/json; charset=utf-8') set_cors(request, 'GET') parsed = parse_get_arguments(request.args, ARGS) if not parsed['success']: return get_missing_params_msg(parsed['missing']) # Get quantity for each try: block_count = int(parsed['args']['block']) except ValueError: return json.dumps({ 'success': False, 'message': 'Invalid parameter, cannot convert to int: block' }).encode('utf-8') try: tx_count = int(parsed['args']['tx']) except ValueError: return json.dumps({ 'success': False, 'message': 'Invalid parameter, cannot convert to int: tx' }).encode('utf-8') # Restrict counts block_count = min(block_count, settings.MAX_DASHBOARD_COUNT) tx_count = min(tx_count, settings.MAX_DASHBOARD_COUNT) transactions, _ = self.manager.tx_storage.get_newest_txs( count=tx_count) serialized_tx = [tx.to_json_extended() for tx in transactions] blocks, _ = self.manager.tx_storage.get_newest_blocks( count=block_count) serialized_blocks = [block.to_json_extended() for block in blocks] data = { 'success': True, 'transactions': serialized_tx, 'blocks': serialized_blocks, } return json.dumps(data, indent=4).encode('utf-8')
def render_GET(self, request): """ Get request to /tips-histogram/ that return the number of tips between two timestamp We expect two GET parameters: 'begin' and 'end' 'begin': int that indicates the beginning of the interval 'end': int that indicates the end of the interval :rtype: string (json) """ request.setHeader(b'content-type', b'application/json; charset=utf-8') set_cors(request, 'GET') parsed = parse_get_arguments(request.args, ARGS) if not parsed['success']: return json.dumps({ 'success': False, 'message': 'Missing parameter: {}'.format(parsed['missing']) }).encode('utf-8') args = parsed['args'] # Get quantity for each try: begin = int(args['begin']) except ValueError: return json.dumps({ 'success': False, 'message': 'Invalid parameter, cannot convert to int: begin' }).encode('utf-8') try: end = int(args['end']) except ValueError: return json.dumps({ 'success': False, 'message': 'Invalid parameter, cannot convert to int: end' }).encode('utf-8') v = [] for timestamp in range(begin, end + 1): tx_tips = self.manager.tx_storage.get_tx_tips(timestamp) v.append((timestamp, len(tx_tips))) return json.dumps({'success': True, 'tips': v}).encode('utf-8')
def render_GET(self, request: 'Request') -> bytes: """ Get request /block_at_height/ that returns a block at height in parameter 'height': int, the height of block to get :rtype: string (json) """ assert self.manager.tx_storage.indexes is not None request.setHeader(b'content-type', b'application/json; charset=utf-8') set_cors(request, 'GET') # Height parameter is required parsed = parse_get_arguments(request.args, ['height']) if not parsed['success']: return get_missing_params_msg(parsed['missing']) args = parsed['args'] # Height parameter must be an integer try: height = int(args['height']) except ValueError: return json.dumps({ 'success': False, 'message': 'Invalid \'height\' parameter, expected an integer' }).encode('utf-8') # Get hash of the block with the height block_hash = self.manager.tx_storage.indexes.height.get(height) # If there is no block in the index with this height, block_hash will be None if block_hash is None: return json.dumps({ 'success': False, 'message': 'No block with height {}.'.format(height) }).encode('utf-8') block = self.manager.tx_storage.get_transaction(block_hash) data = {'success': True, 'block': block.to_json_extended()} return json.dumps(data, indent=4).encode('utf-8')
def render_GET(self, request: Request) -> bytes: """ GET request for /push_tx/ Expects 'hex_tx' as args parameter that is the hex representation of the whole tx :rtype: string (json) This resource will be deprecated soon """ request.setHeader(b'content-type', b'application/json; charset=utf-8') set_cors(request, 'GET') parsed = parse_get_arguments(request.args, ARGS) if not parsed['success']: data = { 'success': False, 'message': 'Missing hexadecimal data', 'can_force': False } return json_dumpb(data) data = parsed['args'] data['force'] = b'force' in request.args and request.args[b'force'][ 0].decode('utf-8') == 'true' return self.handle_push_tx(data)
def get_list_tx(self, request): """ Get parameter from request.args and return list of blocks/txs 'type': 'block' or 'tx', to indicate if we should return a list of blocks or tx 'count': int, to indicate the quantity of elements we should return 'hash': string, the hash reference we are in the pagination 'timestamp': int, the timestamp reference we are in the pagination 'page': 'previous' or 'next', to indicate if the user wants after or before the hash reference """ parsed = parse_get_arguments(request.args, GET_LIST_ARGS) if not parsed['success']: return get_missing_params_msg(parsed['missing']) args = parsed['args'] error = None try: count = min(int(args['count']), settings.MAX_TX_COUNT) except ValueError: error = {'success': False, 'message': 'Invalid \'count\' parameter, expected an integer'} type_tx = args['type'] if type_tx != 'tx' and type_tx != 'block': error = {'success': False, 'message': 'Invalid \'type\' parameter, expected \'block\' or \'tx\''} if error: return json.dumps(error).encode('utf-8') ref_hash = None page = '' if b'hash' in request.args: ref_hash = request.args[b'hash'][0].decode('utf-8') parsed = parse_get_arguments(request.args, ['timestamp', 'page']) if not parsed['success']: return get_missing_params_msg(parsed['missing']) try: ref_timestamp = int(parsed['args']['timestamp']) except ValueError: return json.dumps({ 'success': False, 'message': 'Invalid \'timestamp\' parameter, expected an integer' }).encode('utf-8') page = parsed['args']['page'] if page != 'previous' and page != 'next': return json.dumps({ 'success': False, 'message': 'Invalid \'page\' parameter, expected \'previous\' or \'next\'' }).encode('utf-8') if type_tx == 'block': if page == 'previous': elements, has_more = self.manager.tx_storage.get_newer_blocks_after( ref_timestamp, bytes.fromhex(ref_hash), count) else: elements, has_more = self.manager.tx_storage.get_older_blocks_after( ref_timestamp, bytes.fromhex(ref_hash), count) else: if page == 'previous': elements, has_more = self.manager.tx_storage.get_newer_txs_after( ref_timestamp, bytes.fromhex(ref_hash), count) else: elements, has_more = self.manager.tx_storage.get_older_txs_after( ref_timestamp, bytes.fromhex(ref_hash), count) else: if type_tx == 'block': elements, has_more = self.manager.tx_storage.get_newest_blocks(count=count) else: elements, has_more = self.manager.tx_storage.get_newest_txs(count=count) serialized = [element.to_json_extended() for element in elements] data = {'transactions': serialized, 'has_more': has_more} return json.dumps(data, indent=4).encode('utf-8')
def render_GET(self, request: Request) -> bytes: """ GET request for /thin_wallet/token_history/ Expects as GET parameter of the queried token: - 'id': uid of token whose history is being requested - 'count': int, to indicate the quantity of elements we should return - 'hash': string, the hash reference we are in the pagination - 'timestamp': int, the timestamp reference we are in the pagination - 'page': 'previous' or 'next', to indicate if the user wants after or before the hash reference :rtype: string (json) """ request.setHeader(b'content-type', b'application/json; charset=utf-8') set_cors(request, 'GET') if not self.manager.tx_storage.tokens_index: request.setResponseCode(503) return json.dumps({'success': False}).encode('utf-8') parsed = parse_get_arguments(request.args, ARGS) if not parsed['success']: return get_missing_params_msg(parsed['missing']) if b'id' not in request.args: return get_missing_params_msg('id') try: token_uid = bytes.fromhex(parsed['args']['id']) except (ValueError, AttributeError): return json.dumps({'success': False, 'message': 'Invalid token id'}).encode('utf-8') try: count = min(int(parsed['args']['count']), settings.MAX_TX_COUNT) except ValueError: return json.dumps({ 'success': False, 'message': 'Invalid \'count\' parameter, expected an int' }).encode('utf-8') if b'hash' in request.args: parsed = parse_get_arguments(request.args, ['timestamp', 'page', 'hash']) if not parsed['success']: return get_missing_params_msg(parsed['missing']) try: hash_bytes = bytes.fromhex(parsed['args']['hash']) except ValueError: return json.dumps({ 'success': False, 'message': 'Invalid \'hash\' parameter, could not decode hexadecimal' }).encode('utf-8') page = parsed['args']['page'] if page != 'previous' and page != 'next': return json.dumps({ 'success': False, 'message': 'Invalid \'page\' parameter, expected \'previous\' or \'next\'' }).encode('utf-8') try: ref_timestamp = int(parsed['args']['timestamp']) except ValueError: return json.dumps({ 'success': False, 'message': 'Invalid \'timestamp\' parameter, expected an int' }).encode('utf-8') if page == 'previous': elements, has_more = self.manager.tx_storage.tokens_index.get_newer_transactions( token_uid, ref_timestamp, hash_bytes, count) else: elements, has_more = self.manager.tx_storage.tokens_index.get_older_transactions( token_uid, ref_timestamp, hash_bytes, count) else: elements, has_more = self.manager.tx_storage.tokens_index.get_newest_transactions(token_uid, count) transactions = [self.manager.tx_storage.get_transaction(element) for element in elements] serialized = [tx.to_json_extended() for tx in transactions] data = { 'success': True, 'transactions': serialized, 'has_more': has_more, } return json.dumps(data).encode('utf-8')