Ejemplo n.º 1
0
async def query(args):
    env = Env()
    db = DB(env)
    coin = env.coin

    await db._open_dbs(False)

    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
        for n, (tx_hash, height) in enumerate(db.get_history(hashX, limit),
                                              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
        for n, utxo in enumerate(db.get_utxos(hashX, limit), 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 is None:
            print('No UTXOs found')
        balance = db.get_balance(hashX)
        print(f'Balance: {coin.decimal_value(balance):,f} {coin.SHORTNAME}')
Ejemplo n.º 2
0
def main():
    env = Env()
    bp = DB(env)
    coin = env.coin
    if len(sys.argv) == 1:
        count_entries(bp.hist_db, bp.utxo_db)
        return
    argc = 1
    try:
        limit = int(sys.argv[argc])
        argc += 1
    except Exception:
        limit = 10
    for addr in sys.argv[argc:]:
        print('Address: ', addr)
        hashX = coin.address_to_hashX(addr)

        for n, (tx_hash, height) in enumerate(bp.get_history(hashX, limit)):
            print('History #{:d}: hash: {} height: {:d}'.format(
                n + 1, hash_to_hex_str(tx_hash), height))
        n = None
        for n, utxo in enumerate(bp.get_utxos(hashX, limit)):
            print('UTXOs #{:d}: hash: {} pos: {:d} height: {:d} value: {:d}'.
                  format(n + 1, hash_to_hex_str(utxo.tx_hash), utxo.tx_pos,
                         utxo.height, utxo.value))
        if n is None:
            print('No UTXOs')
        balance = bp.get_balance(hashX)
        print('Balance: {} {}'.format(coin.decimal_value(balance),
                                      coin.SHORTNAME))
Ejemplo n.º 3
0
    async def serve(self, shutdown_event):
        '''Start the RPC server and wait for the mempool to synchronize.  Then
        start serving external clients.
        '''
        if not (0, 7, 1) <= aiorpcx_version < (0, 8):
            raise RuntimeError('aiorpcX version 0.7.x required with x >= 1')

        env = self.env
        min_str, max_str = env.coin.SESSIONCLS.protocol_min_max_strings()
        self.logger.info(f'software version: {electrumx.version}')
        self.logger.info(f'aiorpcX version: {version_string(aiorpcx_version)}')
        self.logger.info(f'supported protocol versions: {min_str}-{max_str}')
        self.logger.info(f'event loop policy: {env.loop_policy}')
        self.logger.info(f'reorg limit is {env.reorg_limit:,d} blocks')

        notifications = Notifications()
        Daemon = env.coin.DAEMON
        BlockProcessor = env.coin.BLOCK_PROCESSOR

        daemon = Daemon(env.coin, env.daemon_url)
        db = DB(env)
        bp = BlockProcessor(env, db, daemon, notifications)

        # Set ourselves up to implement the MemPoolAPI
        self.height = daemon.height
        self.cached_height = daemon.cached_height
        self.mempool_hashes = daemon.mempool_hashes
        self.raw_transactions = daemon.getrawtransactions
        self.lookup_utxos = db.lookup_utxos
        self.on_mempool = notifications.on_mempool
        MemPoolAPI.register(Controller)
        mempool = MemPool(env.coin, self)

        session_mgr = SessionManager(env, db, bp, daemon, mempool,
                                     notifications, shutdown_event)

        # Test daemon authentication, and also ensure it has a cached
        # height.  Do this before entering the task group.
        await daemon.height()

        caught_up_event = Event()
        serve_externally_event = Event()
        synchronized_event = Event()
        async with TaskGroup() as group:
            await group.spawn(session_mgr.serve(serve_externally_event))
            await group.spawn(bp.fetch_and_process_blocks(caught_up_event))
            await caught_up_event.wait()
            await group.spawn(db.populate_header_merkle_cache())
            await group.spawn(mempool.keep_synchronized(synchronized_event))
            await synchronized_event.wait()
            serve_externally_event.set()
Ejemplo n.º 4
0
    async def serve(self, shutdown_event):
        '''Start the RPC server and wait for the mempool to synchronize.  Then
        start serving external clients.
        '''
        if not (0, 22) <= aiorpcx_version < (0, 23):
            raise RuntimeError('aiorpcX version 0.22.x is required')

        env = self.env
        min_str, max_str = env.coin.SESSIONCLS.protocol_min_max_strings()
        self.logger.info(f'software version: {electrumx.version}')
        self.logger.info(f'aiorpcX version: {version_string(aiorpcx_version)}')
        self.logger.info(f'supported protocol versions: {min_str}-{max_str}')
        self.logger.info(f'event loop policy: {env.loop_policy}')
        self.logger.info(f'reorg limit is {env.reorg_limit:,d} blocks')

        notifications = Notifications()
        Daemon = env.coin.DAEMON
        BlockProcessor = env.coin.BLOCK_PROCESSOR

        async with Daemon(env.coin, env.daemon_url) as daemon:
            db = DB(env)
            bp = BlockProcessor(env, db, daemon, notifications)

            # Set notifications up to implement the MemPoolAPI
            def get_db_height():
                return db.db_height

            notifications.height = daemon.height
            notifications.db_height = get_db_height
            notifications.cached_height = daemon.cached_height
            notifications.mempool_hashes = daemon.mempool_hashes
            notifications.raw_transactions = daemon.getrawtransactions
            notifications.lookup_utxos = db.lookup_utxos
            MemPoolAPI.register(Notifications)
            mempool = MemPool(env.coin, notifications)

            session_mgr = SessionManager(env, db, bp, daemon, mempool,
                                         shutdown_event)

            # Test daemon authentication, and also ensure it has a cached
            # height.  Do this before entering the task group.
            await daemon.height()

            caught_up_event = Event()
            mempool_event = Event()

            async def wait_for_catchup():
                await caught_up_event.wait()
                await group.spawn(db.populate_header_merkle_cache())
                await group.spawn(mempool.keep_synchronized(mempool_event))

            async with TaskGroup() as group:
                await group.spawn(
                    session_mgr.serve(notifications, mempool_event))
                await group.spawn(bp.fetch_and_process_blocks(caught_up_event))
                await group.spawn(wait_for_catchup())

                async for task in group:
                    if not task.cancelled():
                        task.result()
Ejemplo n.º 5
0
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}')
Ejemplo n.º 6
0
def compact_history():
    if sys.version_info < (3, 6):
        raise RuntimeError('Python >= 3.6 is required to run ElectrumX')

    environ['DAEMON_URL'] = ''   # Avoid Env erroring out
    env = Env()
    db = DB(env)

    assert not db.first_sync
    history = db.history
    # Continue where we left off, if interrupted
    if history.comp_cursor == -1:
        history.comp_cursor = 0

    history.comp_flush_count = max(history.comp_flush_count, 1)
    limit = 8 * 1000 * 1000

    while history.comp_cursor != -1:
        history._compact_history(limit)

    # When completed also update the UTXO flush count
    db.set_flush_count(history.flush_count)
Ejemplo n.º 7
0
def run_test(db_dir):
    environ.clear()
    environ['DB_DIRECTORY'] = db_dir
    environ['DAEMON_URL'] = ''
    environ['COIN'] = 'BitcoinCash'
    env = Env()
    history = DB(env).history
    # Test abstract compaction
    check_hashX_compaction(history)
    # Now test in with random data
    histories = create_histories(history)
    check_written(history, histories)
    compact_history(history)
    check_written(history, histories)
Ejemplo n.º 8
0
async def run_test(db_dir):
    environ.clear()
    environ['DB_DIRECTORY'] = db_dir
    environ['DAEMON_URL'] = ''
    environ['COIN'] = 'Bitcoin'
    db = DB(Env())
    await db.open_for_serving()
    history = db.history

    # Test abstract compaction
    check_hashX_compaction(history)
    # Now test in with random data
    histories = create_histories(history)
    check_written(history, histories)
    compact_history(history)
    check_written(history, histories)