async def _display_stats(self) -> None: last_head = await self.wait(self.db.coro_get_canonical_head()) timer = Timer() while self.is_operational: await self.sleep(5) self.logger.debug( "(in progress, queued, max size) of headers, bodies, receipts: %r", [(q.num_in_progress(), len(q), q._maxsize) for q in ( self.header_queue, self._block_body_tasks, self._receipt_tasks, )], ) head = await self.wait(self.db.coro_get_canonical_head()) if head == last_head: continue else: block_num_change = head.block_number - last_head.block_number last_head = head self.logger.info( "Advanced by %d blocks in %0.1f seconds, new head: #%d", block_num_change, timer.pop_elapsed(), head.block_number)
class ChainSyncPerformanceTracker: def __init__(self, head: BlockHeader) -> None: # The `head` from the previous time we reported stats self.prev_head = head # The latest `head` we have synced self.latest_head = head # A `Timer` object to report elapsed time between reports self.timer = Timer() # EMA of the blocks per second self.blocks_per_second_ema = EMA(initial_value=0, smoothing_factor=0.05) # EMA of the transactions per second self.transactions_per_second_ema = EMA(initial_value=0, smoothing_factor=0.05) # Number of transactions processed self.num_transactions = 0 def record_transactions(self, count: int) -> None: self.num_transactions += count def set_latest_head(self, head: BlockHeader) -> None: self.latest_head = head def report(self) -> ChainSyncStats: elapsed = self.timer.pop_elapsed() num_blocks = self.latest_head.block_number - self.prev_head.block_number blocks_per_second = num_blocks / elapsed transactions_per_second = self.num_transactions / elapsed self.blocks_per_second_ema.update(blocks_per_second) self.transactions_per_second_ema.update(transactions_per_second) stats = ChainSyncStats( prev_head=self.prev_head, latest_head=self.latest_head, elapsed=elapsed, num_blocks=num_blocks, blocks_per_second=self.blocks_per_second_ema.value, num_transactions=self.num_transactions, transactions_per_second=self.transactions_per_second_ema.value, ) # reset the counters self.num_transactions = 0 self.prev_head = self.latest_head return stats