# Path: electrumx/lib/util.py
# class ConnectionLogger(logging.LoggerAdapter):
# class CompactFormatter(logging.Formatter):
# class cachedproperty(object):
# class LogicalFile(object):
#     def process(self, msg, kwargs):
#     def format(self, record):
# def make_logger(name, *, handler, level):
# def class_logger(path, classname):
#     def __init__(self, f):
#     def __get__(self, obj, type_):
# def formatted_time(t, sep=' '):
# def deep_getsizeof(obj):
#     def size(o):
# def subclasses(base_class, strict=True):
#     def select(obj):
# def chunks(items, size):
# def resolve_limit(limit):
# def bytes_to_int(be_bytes):
# def int_to_bytes(value):
# def increment_byte_string(bs):
#     def __init__(self, prefix, digits, file_size):
#     def read(self, start, size=-1):
#     def write(self, start, b):
#     def open_file(self, start, create):
# def open_file(filename, create=False):
# def open_truncate(filename):
# def address_string(address):
# def protocol_tuple(s):
# def version_string(ptuple):
# def protocol_version(client_req, min_tuple, max_tuple):
# def pack_varint(n):
# def pack_varbytes(data):
# 
# Path: electrumx/lib/util.py
# class ConnectionLogger(logging.LoggerAdapter):
# class CompactFormatter(logging.Formatter):
# class cachedproperty(object):
# class LogicalFile(object):
#     def process(self, msg, kwargs):
#     def format(self, record):
# def make_logger(name, *, handler, level):
# def class_logger(path, classname):
#     def __init__(self, f):
#     def __get__(self, obj, type_):
# def formatted_time(t, sep=' '):
# def deep_getsizeof(obj):
#     def size(o):
# def subclasses(base_class, strict=True):
#     def select(obj):
# def chunks(items, size):
# def resolve_limit(limit):
# def bytes_to_int(be_bytes):
# def int_to_bytes(value):
# def increment_byte_string(bs):
#     def __init__(self, prefix, digits, file_size):
#     def read(self, start, size=-1):
#     def write(self, start, b):
#     def open_file(self, start, create):
# def open_file(filename, create=False):
# def open_truncate(filename):
# def address_string(address):
# def protocol_tuple(s):
# def version_string(ptuple):
# def protocol_version(client_req, min_tuple, max_tuple):
# def pack_varint(n):
# def pack_varbytes(data):
# 
# Path: electrumx/lib/hash.py
# def hash_to_hex_str(x):
#     '''Convert a big-endian binary hash to displayed hex string.
# 
#     Display form of a binary hash is reversed and converted to hex.
#     '''
#     return bytes(reversed(x)).hex()
# 
# HASHX_LEN = 11


import array
import ast
import bisect
import time
from collections import defaultdict
from electrumx.lib import util
from electrumx.lib.util import (
    pack_be_uint16, pack_le_uint64, unpack_be_uint16_from, unpack_le_uint64,
)
from electrumx.lib.hash import hash_to_hex_str, HASHX_LEN
                puts = {}
                for key, hist in self.db.iterator(prefix=hashX, reverse=True):
                    a = array.array('Q')
                    a.frombytes(b''.join(item + bytes(3) for item in chunks(hist, 5)))
                    # Remove all history entries >= tx_count
                    idx = bisect_left(a, tx_count)
                    nremoves += len(a) - idx
                    if idx > 0:
                        puts[key] = hist[:5 * idx]
                        break
                    deletes.append(key)

                for key in deletes:
                    batch.delete(key)
                for key, value in puts.items():
                    batch.put(key, value)
            self.write_state(batch)

        self.logger.info(f'backing up removed {nremoves:,d} history entries')

    def get_txnums(self, hashX, limit=1000):
        '''Generator that returns an unpruned, sorted list of tx_nums in the
        history of a hashX.  Includes both spending and receiving
        transactions.  By default yields at most 1000 entries.  Set
        limit to None to get them all.  '''
        limit = util.resolve_limit(limit)
        chunks = util.chunks
        for _key, hist in self.db.iterator(prefix=hashX):
            for tx_numb in chunks(hist, 5):
                if limit == 0:

# Path: electrumx/lib/util.py
# class ConnectionLogger(logging.LoggerAdapter):
# class CompactFormatter(logging.Formatter):
# class cachedproperty(object):
# class LogicalFile(object):
#     def process(self, msg, kwargs):
#     def format(self, record):
# def make_logger(name, *, handler, level):
# def class_logger(path, classname):
#     def __init__(self, f):
#     def __get__(self, obj, type_):
# def formatted_time(t, sep=' '):
# def deep_getsizeof(obj):
#     def size(o):
# def subclasses(base_class, strict=True):
#     def select(obj):
# def chunks(items, size):
# def resolve_limit(limit):
# def bytes_to_int(be_bytes):
# def int_to_bytes(value):
# def increment_byte_string(bs):
#     def __init__(self, prefix, digits, file_size):
#     def read(self, start, size=-1):
#     def write(self, start, b):
#     def open_file(self, start, create):
# def open_file(filename, create=False):
# def open_truncate(filename):
# def address_string(address):
# def protocol_tuple(s):
# def version_string(ptuple):
# def protocol_version(client_req, min_tuple, max_tuple):
# def pack_varint(n):
# def pack_varbytes(data):
# 
# Path: electrumx/lib/util.py
# class ConnectionLogger(logging.LoggerAdapter):
# class CompactFormatter(logging.Formatter):
# class cachedproperty(object):
# class LogicalFile(object):
#     def process(self, msg, kwargs):
#     def format(self, record):
# def make_logger(name, *, handler, level):
# def class_logger(path, classname):
#     def __init__(self, f):
#     def __get__(self, obj, type_):
# def formatted_time(t, sep=' '):
# def deep_getsizeof(obj):
#     def size(o):
# def subclasses(base_class, strict=True):
#     def select(obj):
# def chunks(items, size):
# def resolve_limit(limit):
# def bytes_to_int(be_bytes):
# def int_to_bytes(value):
# def increment_byte_string(bs):
#     def __init__(self, prefix, digits, file_size):
#     def read(self, start, size=-1):
#     def write(self, start, b):
#     def open_file(self, start, create):
# def open_file(filename, create=False):
# def open_truncate(filename):
# def address_string(address):
# def protocol_tuple(s):
# def version_string(ptuple):
# def protocol_version(client_req, min_tuple, max_tuple):
# def pack_varint(n):
# def pack_varbytes(data):
# 
# Path: electrumx/lib/hash.py
# def hash_to_hex_str(x):
#     '''Convert a big-endian binary hash to displayed hex string.
# 
#     Display form of a binary hash is reversed and converted to hex.
#     '''
#     return bytes(reversed(x)).hex()
# 
# HASHX_LEN = 11


# Path: electrumx/server/history.py
import array
import ast
import bisect
import time
from collections import defaultdict
from electrumx.lib import util
from electrumx.lib.util import (
    pack_be_uint16, pack_le_uint64, unpack_be_uint16_from, unpack_le_uint64,
)
from electrumx.lib.hash import hash_to_hex_str, HASHX_LEN

                puts = {}
                for key, hist in self.db.iterator(prefix=hashX, reverse=True):
                    a = array.array('Q')
                    a.frombytes(b''.join(item + bytes(3) for item in chunks(hist, 5)))
                    # Remove all history entries >= tx_count
                    idx = bisect_left(a, tx_count)
                    nremoves += len(a) - idx
                    if idx > 0:
                        puts[key] = hist[:5 * idx]
                        break
                    deletes.append(key)

                for key in deletes:
                    batch.delete(key)
                for key, value in puts.items():
                    batch.put(key, value)
            self.write_state(batch)

        self.logger.info(f'backing up removed {nremoves:,d} history entries')

    def get_txnums(self, hashX, limit=1000):
        '''Generator that returns an unpruned, sorted list of tx_nums in the
        history of a hashX.  Includes both spending and receiving
        transactions.  By default yields at most 1000 entries.  Set
        limit to None to get them all.  '''
        limit = util.resolve_limit(limit)
        chunks = util.chunks
        for _key, hist in self.db.iterator(prefix=hashX):
            for tx_numb in chunks(hist, 5):
                if limit == 0:

                    return