def _get_wal_writer(self, precommit_data: 'PrecommitData', is_calc_period_start_block: bool): wal_writer: 'WriteAheadLogWriter' = WriteAheadLogWriter( precommit_data.revision, max_log_count=2, block=precommit_data.block, instant_block_hash=precommit_data.block.hash) wal_writer.open(self.log_path) state_wal: 'StateWAL' = StateWAL(precommit_data.block_batch) revision: int = precommit_data.rc_db_revision if is_calc_period_start_block else -1 tx_index: int = IconScoreContext.storage.rc.get_tx_index( is_calc_period_start_block) iiss_wal: 'IissWAL' = IissWAL(precommit_data.rc_block_batch, tx_index, revision) return wal_writer, state_wal, iiss_wal
def run(self, icx_db: 'KeyValueDatabase', rc_db: 'KeyValueDatabase', revision: int, prev_block: 'Block', block_batch: 'BlockBatch', iiss_wal: 'IissWAL', is_calc_period_start_block: bool, instant_block_hash: bytes): """Backup the previous block state :param icx_db: :param rc_db: :param revision: :param prev_block: the latest confirmed block height during commit :param block_batch: :param iiss_wal: :param is_calc_period_start_block: :param instant_block_hash: :return: """ Logger.debug(tag=TAG, msg="backup() start") path: str = self._get_backup_file_path(prev_block.height) Logger.info(tag=TAG, msg=f"backup_file_path={path}") writer = WriteAheadLogWriter(revision, max_log_count=2, block=prev_block, instant_block_hash=instant_block_hash) writer.open(path) if is_calc_period_start_block: writer.write_state(WALBackupState.CALC_PERIOD_END_BLOCK.value) self._backup_rc_db(writer, rc_db, iiss_wal) self._backup_state_db(writer, icx_db, block_batch) writer.close() Logger.debug(tag=TAG, msg="backup() end")
def test_invalid_magic_key(self): revision = Revision.IISS.value log_count = 2 instant_block_hash = create_block_hash() writer = WriteAheadLogWriter(revision, log_count, self.block, instant_block_hash) writer.open(self.path) writer.close() # Make the magic key invalid with open(self.path, "rb+") as f: ret = f.write(b"iwal") assert ret == 4 reader = WriteAheadLogReader() with pytest.raises(IllegalFormatException): reader.open(self.path)
def test_out_of_header_size(self): revision = Revision.IISS.value log_count = 2 instant_block_hash = create_block_hash() writer = WriteAheadLogWriter(revision=revision, max_log_count=log_count, block=self.block, instant_block_hash=instant_block_hash) writer.open(self.path) writer.close() f = open(self.path, "rb+") f.truncate(_HEADER_SIZE - 4) f.close() reader = WriteAheadLogReader() with pytest.raises(IllegalFormatException): reader.open(self.path)
def test_invalid_version(self): revision = Revision.IISS.value log_count = 2 instant_block_hash = create_block_hash() writer = WriteAheadLogWriter(revision, log_count, self.block, instant_block_hash) writer.open(self.path) writer.close() # Make the version invalid with open(self.path, "rb+") as f: f.seek(_OFFSET_VERSION) version = 0xFFFFFFFF ret = f.write(version.to_bytes(4, "big")) assert ret == 4 reader = WriteAheadLogReader() with pytest.raises(IllegalFormatException): reader.open(self.path)
def test_writer_and_reader(self): revision = Revision.IISS.value log_count = 2 instant_block_hash = create_block_hash() writer = WriteAheadLogWriter(revision, log_count, self.block, instant_block_hash) writer.open(self.path) writer.write_state(WALState.CALC_PERIOD_START_BLOCK.value, add=False) writer.write_walogable(WALogableData(self.log_data[0])) writer.write_state(WALState.WRITE_RC_DB.value, add=True) writer.write_walogable(WALogableData(self.log_data[1])) writer.write_state(WALState.WRITE_STATE_DB.value, add=True) state = (WALState.WRITE_RC_DB | WALState.WRITE_STATE_DB).value writer.write_state(state, add=False) writer.close() reader = WriteAheadLogReader() reader.open(self.path) assert reader.magic_key == _MAGIC_KEY assert reader.version == _FILE_VERSION assert reader.revision == revision assert reader.state == state assert reader.log_count == log_count assert reader.block == self.block assert reader.instant_block_hash == instant_block_hash for i in range(len(self.log_data)): data = {} for key, value in reader.get_iterator(i): data[key] = value assert data == self.log_data[i] assert id(data) != id(self.log_data[i]) reader.close()