# Path: feemodel/util.py
# class StoppableThread(threading.Thread):
# class WorkerThread(threading.Thread):
# class BlockingProxy(Proxy):
# class CacheProxy(BlockingProxy):
# class BatchProxy(CacheProxy):
# class DataSample(object):
# class Function(object):
# class DiscreteFunction(Function):
# class StepFunction(Function):
# class BlockMetadata(object):
#     def __init__(self):
#     def run(self):
#     def stop(self):
#     def is_stopped(self):
#     def sleep(self, secs):
#     def context_start(self):
#     def get_stop_object(self):
#     def auto_restart(interval):
#         def decorator(fn):
#             def looped_fn(self, *args, **kwargs):
# def logexceptions(fn):
#     def logged_fn(*args, **kwargs):
#     def __init__(self, workfn):
#     def run(self):
#     def put(self, *args):
#     def stop(self):
#     def __init__(self):
#     def _call(self, *args):
#     def close(self):
#     def __init__(self, maxblocks=10, maxhashes=1000):
#     def getcache(self, d, key, maxitems, default_fn):
#     def getblock(self, blockhash):
#     def getblockhash(self, blockheight):
#     def poll_mempool(self):
#     def __init__(self, datapoints=None):
#     def add_datapoints(self, datapoints):
#     def calc_stats(self):
#     def get_percentile(self, p, weights=None):
#     def __len__(self):
#     def __repr__(self):
#     def __init__(self, x, y):
#     def __call__(self, x0, use_upper=False, use_lower=False):
#     def inv(self, y0, use_upper=False, use_lower=False):
#     def addpoint(self, xi, yi):
#     def __getitem__(self, idx):
#     def __str__(self):
#     def __len__(self):
#     def __iter__(self):
#     def __copy__(self):
#     def __call__(self, x0):
#     def inv(self, y0):
#     def __call__(self, x0):
#     def approx(self, percenterror=0.05, percentstep=0.05):
#     def _get_maxerror(self, previdx, curridx, f):
#     def __copy__(self):
#     def __init__(self, height):
#     def get_poolname(self):
#     def __repr__(self):
# def save_obj(obj, filename, protocol=2):
# def load_obj(filename):
# def get_coinbase_info(blockheight):
# def get_hashesperblock(blockheight):
# def get_block_timestamp(blockheight):
# def get_block_size(blockheight):
# def get_block_name(blockheight):
# def get_feerate(rawentry):
# def round_random(f):
# def interpolate(x0, x, y):
# def cumsum_gen(iterable, base=0, mapfn=lambda x: x):
#     STOP = StopIteration()


import unittest
import decimal
import itertools
from time import time
from feemodel.util import CacheProxy, BlockingProxy, proxy
        else:
            txid = rawmempool.keys()[0]
            self.assertTrue(txid.isalnum())
            entry = rawmempool[txid]
            self.assertTrue(
                isinstance(entry['currentpriority'], decimal.Decimal))
            self.assertTrue(
                isinstance(entry['startingpriority'], decimal.Decimal))
            self.assertTrue(isinstance(entry['fee'], decimal.Decimal))
            self.assertTrue(
                all([_txid.isalnum() for _txid in entry['depends']]))
            self.assertTrue(isinstance(entry['height'], int))
            self.assertTrue(isinstance(entry['size'], int))
            self.assertTrue(isinstance(entry['time'], int))


class CacheProxyTest(unittest.TestCase):

    def setUp(self):
        self.cacheproxy = CacheProxy(maxblocks=10)
        self.proxy = BlockingProxy()

    def test_accuracy(self):
        for idx, height in enumerate(itertools.cycle(range(333931, 333954))):
            if idx == 20:
                break
            cache_hash = self.cacheproxy.getblockhash(height)
            normal_hash = self.proxy.getblockhash(height)
            self.assertEqual(cache_hash, normal_hash)
            cache_block = self.cacheproxy.getblock(cache_hash)

# Path: feemodel/util.py
# class StoppableThread(threading.Thread):
# class WorkerThread(threading.Thread):
# class BlockingProxy(Proxy):
# class CacheProxy(BlockingProxy):
# class BatchProxy(CacheProxy):
# class DataSample(object):
# class Function(object):
# class DiscreteFunction(Function):
# class StepFunction(Function):
# class BlockMetadata(object):
#     def __init__(self):
#     def run(self):
#     def stop(self):
#     def is_stopped(self):
#     def sleep(self, secs):
#     def context_start(self):
#     def get_stop_object(self):
#     def auto_restart(interval):
#         def decorator(fn):
#             def looped_fn(self, *args, **kwargs):
# def logexceptions(fn):
#     def logged_fn(*args, **kwargs):
#     def __init__(self, workfn):
#     def run(self):
#     def put(self, *args):
#     def stop(self):
#     def __init__(self):
#     def _call(self, *args):
#     def close(self):
#     def __init__(self, maxblocks=10, maxhashes=1000):
#     def getcache(self, d, key, maxitems, default_fn):
#     def getblock(self, blockhash):
#     def getblockhash(self, blockheight):
#     def poll_mempool(self):
#     def __init__(self, datapoints=None):
#     def add_datapoints(self, datapoints):
#     def calc_stats(self):
#     def get_percentile(self, p, weights=None):
#     def __len__(self):
#     def __repr__(self):
#     def __init__(self, x, y):
#     def __call__(self, x0, use_upper=False, use_lower=False):
#     def inv(self, y0, use_upper=False, use_lower=False):
#     def addpoint(self, xi, yi):
#     def __getitem__(self, idx):
#     def __str__(self):
#     def __len__(self):
#     def __iter__(self):
#     def __copy__(self):
#     def __call__(self, x0):
#     def inv(self, y0):
#     def __call__(self, x0):
#     def approx(self, percenterror=0.05, percentstep=0.05):
#     def _get_maxerror(self, previdx, curridx, f):
#     def __copy__(self):
#     def __init__(self, height):
#     def get_poolname(self):
#     def __repr__(self):
# def save_obj(obj, filename, protocol=2):
# def load_obj(filename):
# def get_coinbase_info(blockheight):
# def get_hashesperblock(blockheight):
# def get_block_timestamp(blockheight):
# def get_block_size(blockheight):
# def get_block_name(blockheight):
# def get_feerate(rawentry):
# def round_random(f):
# def interpolate(x0, x, y):
# def cumsum_gen(iterable, base=0, mapfn=lambda x: x):
#     STOP = StopIteration()


# Path: feemodel/tests/test_jsonrpc.py
import unittest
import decimal
import itertools
from time import time
from feemodel.util import CacheProxy, BlockingProxy, proxy

        else:
            txid = rawmempool.keys()[0]
            self.assertTrue(txid.isalnum())
            entry = rawmempool[txid]
            self.assertTrue(
                isinstance(entry['currentpriority'], decimal.Decimal))
            self.assertTrue(
                isinstance(entry['startingpriority'], decimal.Decimal))
            self.assertTrue(isinstance(entry['fee'], decimal.Decimal))
            self.assertTrue(
                all([_txid.isalnum() for _txid in entry['depends']]))
            self.assertTrue(isinstance(entry['height'], int))
            self.assertTrue(isinstance(entry['size'], int))
            self.assertTrue(isinstance(entry['time'], int))


class CacheProxyTest(unittest.TestCase):

    def setUp(self):
        self.cacheproxy = CacheProxy(maxblocks=10)
        self.proxy = BlockingProxy()

    def test_accuracy(self):
        for idx, height in enumerate(itertools.cycle(range(333931, 333954))):
            if idx == 20:
                break
            cache_hash = self.cacheproxy.getblockhash(height)
            normal_hash = self.proxy.getblockhash(height)
            self.assertEqual(cache_hash, normal_hash)
            cache_block = self.cacheproxy.getblock(cache_hash)

            normal_block = self.proxy.getblock(normal_hash)