示例#1
0
def test_LogicalFile(tmpdir):
    prefix = os.path.join(tmpdir, 'log')
    L = util.LogicalFile(prefix, 2, 6)
    with pytest.raises(FileNotFoundError):
        L.open_file(0, create=False)

    # Check L.open creates a file
    with L.open_file(8, create=True) as f:
        pass
    with util.open_file(prefix + '01') as f:
        pass

    L.write(0, b'987')
    assert L.read(0, -1) == b'987'
    assert L.read(0, 4) == b'987'
    assert L.read(1, 1) == b'8'

    L.write(0, b'01234567890')
    assert L.read(0, -1) == b'01234567890'
    assert L.read(5, -1) == b'567890'
    with util.open_file(prefix + '01') as f:
        assert f.read(-1) == b'67890'

    # Test file boundary
    L.write(0, b'957' * 6)
    assert L.read(0, -1) == b'957' * 6
示例#2
0
def test_open_fns(tmpdir):
    tmpfile = os.path.join(tmpdir, 'file1')
    with pytest.raises(FileNotFoundError):
        util.open_file(tmpfile)
    with util.open_file(tmpfile, create=True) as f:
        f.write(b'56')
    with util.open_file(tmpfile) as f:
        assert f.read(3) == b'56'

    # Test open_truncate truncates and creates
    with util.open_truncate(tmpfile) as f:
        assert f.read(3) == b''
    tmpfile = os.path.join(tmpdir, 'file2')
    with util.open_truncate(tmpfile) as f:
        assert f.read(3) == b''
示例#3
0
    async def _open_dbs(self, for_sync: bool, compacting: bool):
        assert self.utxo_db is None

        # First UTXO DB
        self.utxo_db = self.db_class('utxo', for_sync)
        if self.utxo_db.is_new:
            self.logger.info('created new database')
            self.logger.info('creating metadata directory')
            os.mkdir('meta')
            with util.open_file('COIN', create=True) as f:
                f.write(f'ElectrumX databases and metadata for '
                        f'{self.coin.NAME} {self.coin.NET}'.encode())
            if not self.coin.STATIC_BLOCK_HEADERS:
                self.headers_offsets_file.write(0, b'\0\0\0\0\0\0\0\0')
        else:
            self.logger.info(f'opened UTXO DB (for sync: {for_sync})')
        self.read_utxo_state()

        # Then history DB
        self.utxo_flush_count = self.history.open_db(self.db_class, for_sync,
                                                     self.utxo_flush_count,
                                                     compacting)
        self.clear_excess_undo_info()

        # Read TX counts (requires meta directory)
        await self._read_tx_counts()
示例#4
0
    def open_dbs(self):
        '''Open the databases.  If already open they are closed and re-opened.

        When syncing we want to reserve a lot of open files for the
        synchronization.  When serving clients we want the open files for
        serving network connections.
        '''
        def log_reason(message, is_for_sync):
            reason = 'sync' if is_for_sync else 'serving'
            self.logger.info('{} for {}'.format(message, reason))

        # Assume we're serving until we find out otherwise
        for for_sync in [False, True]:
            if self.utxo_db:
                if self.utxo_db.for_sync == for_sync:
                    return
                log_reason('closing DB to re-open', for_sync)
                self.utxo_db.close()
                self.history.close_db()

            # Open DB and metadata files.  Record some of its state.
            self.utxo_db = self.db_class('utxo', for_sync)
            if self.utxo_db.is_new:
                self.logger.info('created new database')
                self.logger.info('creating metadata directory')
                os.mkdir('meta')
                with util.open_file('COIN', create=True) as f:
                    f.write(
                        'ElectrumX databases and metadata for {} {}'.format(
                            self.coin.NAME, self.coin.NET).encode())
            else:
                log_reason('opened DB', self.utxo_db.for_sync)

            self.read_utxo_state()
            if self.first_sync == self.utxo_db.for_sync:
                break

        # Open history DB, clear excess history
        self.utxo_flush_count = self.history.open_db(self.db_class, for_sync,
                                                     self.utxo_flush_count)
        self.clear_excess_undo_info()

        self.logger.info('DB version: {:d}'.format(self.db_version))
        self.logger.info('coin: {}'.format(self.coin.NAME))
        self.logger.info('network: {}'.format(self.coin.NET))
        self.logger.info('height: {:,d}'.format(self.db_height))
        self.logger.info('tip: {}'.format(hash_to_str(self.db_tip)))
        self.logger.info('tx count: {:,d}'.format(self.db_tx_count))
        if self.first_sync:
            self.logger.info('sync time so far: {}'.format(
                util.formatted_time(self.wall_time)))
示例#5
0
 def read_raw_block(self, height):
     '''Returns a raw block read from disk.  Raises FileNotFoundError
     if the block isn't on-disk.'''
     with util.open_file(self.raw_block_path(height)) as f:
         return f.read(-1)
示例#6
0
 def __enter__(self):
     self.block_file = open_file(self.filename(self.hex_hash, self.height))
     self.header = self._read(80)
     return self