#!/usr/bin/env python3 # # Copyright (c) 2016-2018, Neil Booth # # All rights reserved. # # See the file "LICENCE" for information about the copyright # and warranty status of this software. '''Script to query the database for debugging purposes. Not currently documented; might become easier to use in future. ''' import argparse import asyncio import sys from electrumx import Env from electrumx.server.db import DB from electrumx.lib.hash import hash_to_hex_str, Base58Error async def print_stats(hist_db, utxo_db): count = 0 for key in utxo_db.iterator(prefix=b'u', include_value=False): count += 1 print(f'UTXO count: {utxos}') count = 0 for key in utxo_db.iterator(prefix=b'h', include_value=False): count += 1 print(f'HashX count: {count}') hist = 0 hist_len = 0 for key, value in hist_db.iterator(prefix=b'H'): hist += 1 hist_len += len(value) // 4 print(f'History rows {hist:,d} entries {hist_len:,d}') def arg_to_hashX(coin, arg): try: script = bytes.fromhex(arg) print(f'Script: {arg}') return coin.hashX_from_script(script) except ValueError: pass try: hashX = coin.address_to_hashX(arg) print(f'Address: {arg}') return hashX except Base58Error: print(f'Ingoring unknown arg: {arg}') return None async def query(args): env = Env() db = DB(env) coin = env.coin await db.open_for_serving() if not args.scripts: await print_stats(db.hist_db, db.utxo_db) return limit = args.limit for arg in args.scripts: hashX = arg_to_hashX(coin, arg) if not hashX: continue n = None history = await db.limited_history(hashX, limit=limit) for n, (tx_hash, height) in enumerate(history, start=1): print(f'History #{n:,d}: height {height:,d} ' f'tx_hash {hash_to_hex_str(tx_hash)}') if n is None: print('No history found') n = None utxos = await db.all_utxos(hashX) for n, utxo in enumerate(utxos, start=1): print(f'UTXO #{n:,d}: tx_hash {hash_to_hex_str(utxo.tx_hash)} ' f'tx_pos {utxo.tx_pos:,d} height {utxo.height:,d} ' f'value {utxo.value:,d}') if n == limit: break if n is None: print('No UTXOs found') balance = sum(utxo.value for utxo in utxos) print(f'Balance: {coin.decimal_value(balance):,f} {coin.SHORTNAME}') def main(): default_limit = 10 parser = argparse.ArgumentParser( 'query.py', description='Invoke with COIN and DB_DIRECTORY set in the ' 'environment as they would be invoking electrumx_server' ) parser.add_argument('-l', '--limit', metavar='limit', type=int, default=10, help=f'maximum number of entries to ' f'return (default: {default_limit})') parser.add_argument('scripts', nargs='*', default=[], type=str, help='hex scripts to query') args = parser.parse_args() loop = asyncio.get_event_loop() loop.run_until_complete(query(args)) if __name__ == '__main__': main()