async def reorg_chain(self, count): '''Handle a chain reorganisation. Count is the number of blocks to simulate a reorg, or None for a real reorg. This is passed in as self.reorg_count may change asynchronously. ''' if count < 0: logger.info('chain reorg detected') else: logger.info(f'faking a reorg of {count:,d} blocks') await self.flush(True) start, hex_hashes = await self._reorg_hashes(count) pairs = reversed(list(enumerate(hex_hashes, start=start))) await OnDiskBlock.prefetch_many(self.daemon, pairs, 'reorg') for hex_hash in reversed(hex_hashes): if hex_hash != hash_to_hex_str(self.state.tip): logger.error(f'block {hex_hash} is not tip; cannot back up') return block = await OnDiskBlock.streamed_block(hex_hash) if not block: break await self.run_with_lock(run_in_thread(self.backup_block, block)) logger.info(f'backed up to height {self.state.height:,d}') self.backed_up_event.set() self.backed_up_event.clear()
async def run_in_thread_shielded(self, func, *args): async with self.state_lock: return await asyncio.shield(run_in_thread(func, *args))