def _initialize_chain(self):
    'Initialize a pre-mined blockchain for use by the test.'

    def create_cachedir(cachedir):
        if os.path.isdir(cachedir):
            shutil.rmtree(cachedir)
        os.makedirs(cachedir)

    def copy_cachedir(origin, destination, num_nodes=MAX_NODES):
        for i in range(num_nodes):
            from_dir = get_datadir_path(origin, i)
            to_dir = get_datadir_path(destination, i)
            shutil.copytree(from_dir, to_dir)
            initialize_datadir(destination, i)

    def clone_cache_from_node_1(cachedir, from_num=4):
        " Clones cache subdir from node 1 to nodes from 'from_num' to MAX_NODES"

        def copy_and_overwrite(from_path, to_path):
            if os.path.exists(to_path):
                shutil.rmtree(to_path)
            shutil.copytree(from_path, to_path)
        assert (from_num < MAX_NODES)
        node_0_datadir = os.path.join(get_datadir_path(cachedir, 0), 'regtest')
        for i in range(from_num, MAX_NODES):
            node_i_datadir = os.path.join(get_datadir_path(cachedir, i), 'regtest')
            for subdir in ['blocks', 'chainstate', 'sporks']:
                copy_and_overwrite(os.path.join(node_0_datadir, subdir), os.path.join(node_i_datadir, subdir))
            initialize_datadir(cachedir, i)

    def cachedir_valid(cachedir):
        for i in range(MAX_NODES):
            if (not os.path.isdir(get_datadir_path(cachedir, i))):
                return False
        return (not os.path.exists(os.path.join(get_datadir_path(cachedir, 0), '.incomplete')))

    def clean_cache_subdir(cachedir):
        os.remove(os.path.join(get_datadir_path(cachedir, 0), '.incomplete'))

        def cache_path(n, *paths):
            return os.path.join(get_datadir_path(cachedir, n), 'regtest', *paths)
        for i in range(MAX_NODES):
            for entry in os.listdir(cache_path(i)):
                if (entry not in ['wallet.dat', 'chainstate', 'blocks', 'sporks', 'backups']):
                    os.remove(cache_path(i, entry))

    def clean_cache_dir():
        if os.path.isdir(self.options.cachedir):
            if cachedir_valid(self.options.cachedir):
                powcachedir = os.path.join(self.options.cachedir, 'pow')
                self.log.info(('Found old cachedir. Migrating to %s' % str(powcachedir)))
                copy_cachedir(self.options.cachedir, powcachedir)
            for entry in os.listdir(self.options.cachedir):
                if (entry != 'pow'):
                    entry_path = os.path.join(self.options.cachedir, entry)
                    if os.path.isfile(entry_path):
                        os.remove(entry_path)
                    elif os.path.isdir(entry_path):
                        shutil.rmtree(entry_path)
        else:
            os.makedirs(self.options.cachedir)

    def start_nodes_from_dir(ddir, num_nodes=MAX_NODES):
        self.log.info(('Starting %d nodes...' % num_nodes))
        for i in range(num_nodes):
            datadir = initialize_datadir(ddir, i)
            if (i == 0):
                open(os.path.join(datadir, '.incomplete'), 'a').close()
            args = [os.getenv('BITCOIND', 't_notesd'), '-spendzeroconfchange=1', '-server', '-keypool=1', ('-datadir=' + datadir), '-discover=0']
            self.nodes.append(TestNode(i, ddir, extra_args=[], rpchost=None, timewait=self.rpc_timewait, binary=None, stderr=None, mocktime=self.mocktime, coverage_dir=None))
            self.nodes[i].args = args
            self.start_node(i)
            self.log.info(('Node %d started.' % i))
        self.log.info('Nodes started. Waiting for RPC connections...')
        for node in range(4):
            self.nodes[node].wait_for_rpc_connection()
        self.log.info('Connecting nodes')
        connect_nodes_clique(self.nodes)

    def stop_and_clean_cache_dir(ddir):
        self.stop_nodes()
        self.nodes = []
        self.log.info('Copying cache dir to non-started nodes')
        clone_cache_from_node_1(ddir)
        self.log.info('Cleaning up.')
        clean_cache_subdir(ddir)

    def generate_pow_cache():
        create_cachedir(powcachedir)
        self.log.info("Creating 'PoW-chain': 200 blocks")
        start_nodes_from_dir(powcachedir, 4)
        self.log.info('Mining 200 blocks')
        self.enable_mocktime()
        block_time = (self.mocktime - (331 * 60))
        for i in range(2):
            for peer in range(4):
                for j in range(25):
                    set_node_times(self.nodes, block_time)
                    self.nodes[peer].generate(1)
                    block_time += 60
                self.sync_blocks()
        self.log.info('Stopping nodes')
        stop_and_clean_cache_dir(powcachedir)
        self.log.info('---> pow cache created')
        self.disable_mocktime()
    assert (self.num_nodes <= MAX_NODES)
    clean_cache_dir()
    powcachedir = os.path.join(self.options.cachedir, 'pow')
    is_powcache_valid = cachedir_valid(powcachedir)
    if (not is_powcache_valid):
        self.log.info('PoW-CACHE NOT FOUND or INVALID.')
        self.log.info('Creating new cached blockchain data.')
        generate_pow_cache()
    else:
        self.log.info('CACHE FOUND.')
    self.log.info(('Copying datadir from %s to %s' % (powcachedir, self.options.tmpdir)))
    copy_cachedir(powcachedir, self.options.tmpdir, self.num_nodes)
Initialize a pre-mined blockchain for use by the test.
def _initialize_chain(self):
    

    def create_cachedir(cachedir):
        if os.path.isdir(cachedir):
            shutil.rmtree(cachedir)
        os.makedirs(cachedir)

    def copy_cachedir(origin, destination, num_nodes=MAX_NODES):
        for i in range(num_nodes):
            from_dir = get_datadir_path(origin, i)
            to_dir = get_datadir_path(destination, i)
            shutil.copytree(from_dir, to_dir)
            initialize_datadir(destination, i)

    def clone_cache_from_node_1(cachedir, from_num=4):
        " Clones cache subdir from node 1 to nodes from 'from_num' to MAX_NODES"

        def copy_and_overwrite(from_path, to_path):
            if os.path.exists(to_path):
                shutil.rmtree(to_path)
            shutil.copytree(from_path, to_path)
        assert (from_num < MAX_NODES)
        node_0_datadir = os.path.join(get_datadir_path(cachedir, 0), 'regtest')
        for i in range(from_num, MAX_NODES):
            node_i_datadir = os.path.join(get_datadir_path(cachedir, i), 'regtest')
            for subdir in ['blocks', 'chainstate', 'sporks']:
                copy_and_overwrite(os.path.join(node_0_datadir, subdir), os.path.join(node_i_datadir, subdir))
            initialize_datadir(cachedir, i)

    def cachedir_valid(cachedir):
        for i in range(MAX_NODES):
            if (not os.path.isdir(get_datadir_path(cachedir, i))):
                return False
        return (not os.path.exists(os.path.join(get_datadir_path(cachedir, 0), '.incomplete')))

    def clean_cache_subdir(cachedir):
        os.remove(os.path.join(get_datadir_path(cachedir, 0), '.incomplete'))

        def cache_path(n, *paths):
            return os.path.join(get_datadir_path(cachedir, n), 'regtest', *paths)
        for i in range(MAX_NODES):
            for entry in os.listdir(cache_path(i)):
                if (entry not in ['wallet.dat', 'chainstate', 'blocks', 'sporks', 'backups']):
                    os.remove(cache_path(i, entry))

    def clean_cache_dir():
        if os.path.isdir(self.options.cachedir):
            if cachedir_valid(self.options.cachedir):
                powcachedir = os.path.join(self.options.cachedir, 'pow')
                self.log.info(('Found old cachedir. Migrating to %s' % str(powcachedir)))
                copy_cachedir(self.options.cachedir, powcachedir)
            for entry in os.listdir(self.options.cachedir):
                if (entry != 'pow'):
                    entry_path = os.path.join(self.options.cachedir, entry)
                    if os.path.isfile(entry_path):
                        os.remove(entry_path)
                    elif os.path.isdir(entry_path):
                        shutil.rmtree(entry_path)
        else:
            os.makedirs(self.options.cachedir)

    def start_nodes_from_dir(ddir, num_nodes=MAX_NODES):
        self.log.info(('Starting %d nodes...' % num_nodes))
        for i in range(num_nodes):
            datadir = initialize_datadir(ddir, i)
            if (i == 0):
                open(os.path.join(datadir, '.incomplete'), 'a').close()
            args = [os.getenv('BITCOIND', 't_notesd'), '-spendzeroconfchange=1', '-server', '-keypool=1', ('-datadir=' + datadir), '-discover=0']
            self.nodes.append(TestNode(i, ddir, extra_args=[], rpchost=None, timewait=self.rpc_timewait, binary=None, stderr=None, mocktime=self.mocktime, coverage_dir=None))
            self.nodes[i].args = args
            self.start_node(i)
            self.log.info(('Node %d started.' % i))
        self.log.info('Nodes started. Waiting for RPC connections...')
        for node in range(4):
            self.nodes[node].wait_for_rpc_connection()
        self.log.info('Connecting nodes')
        connect_nodes_clique(self.nodes)

    def stop_and_clean_cache_dir(ddir):
        self.stop_nodes()
        self.nodes = []
        self.log.info('Copying cache dir to non-started nodes')
        clone_cache_from_node_1(ddir)
        self.log.info('Cleaning up.')
        clean_cache_subdir(ddir)

    def generate_pow_cache():
        create_cachedir(powcachedir)
        self.log.info("Creating 'PoW-chain': 200 blocks")
        start_nodes_from_dir(powcachedir, 4)
        self.log.info('Mining 200 blocks')
        self.enable_mocktime()
        block_time = (self.mocktime - (331 * 60))
        for i in range(2):
            for peer in range(4):
                for j in range(25):
                    set_node_times(self.nodes, block_time)
                    self.nodes[peer].generate(1)
                    block_time += 60
                self.sync_blocks()
        self.log.info('Stopping nodes')
        stop_and_clean_cache_dir(powcachedir)
        self.log.info('---> pow cache created')
        self.disable_mocktime()
    assert (self.num_nodes <= MAX_NODES)
    clean_cache_dir()
    powcachedir = os.path.join(self.options.cachedir, 'pow')
    is_powcache_valid = cachedir_valid(powcachedir)
    if (not is_powcache_valid):
        self.log.info('PoW-CACHE NOT FOUND or INVALID.')
        self.log.info('Creating new cached blockchain data.')
        generate_pow_cache()
    else:
        self.log.info('CACHE FOUND.')
    self.log.info(('Copying datadir from %s to %s' % (powcachedir, self.options.tmpdir)))
    copy_cachedir(powcachedir, self.options.tmpdir, self.num_nodes)