Repository: Chia-Network/chia-blockchain
File: tools/validate_rpcs.py (Python)

Code before:
    async with get_any_service_client(FullNodeRpcClient, root_path, rpc_port) as (
        node_client,
        config,
    ):
        blockchain_state: dict[str, Any] = await node_client.get_blockchain_state()
        if blockchain_state is None or blockchain_state["peak"] is None:
            # Peak height is required for the cache.
            print("No blockchain found. Exiting.")
            return
        peak_height = blockchain_state["peak"].height
        assert peak_height is not None, "Blockchain peak height is None"
        if end_height is None:
            end_height = peak_height

        print("Connected to Full Node")

        height_to_hash_bytes: bytes = await get_height_to_hash_bytes(root_path=root_path, config=config)

        print("block header hashes loaded from height-to-hash file.")

        # Set initial values for the loop

        in_flight: set[asyncio.Task[None]] = set()
        completed_requests: int = 0
        # measure time for performance measurement per segment
        cycle_start: float = time.time()
        # also measure time for the whole process
        start_time: float = cycle_start
        # blocks to check again
        repeat_list: set[int] = set()

        def add_tasks_for_height(height: int) -> None:
            block_header_hash = get_block_hash_from_height(height, height_to_hash_bytes)
            # Create tasks for each RPC call based on the flags
            if spends_with_conditions:
                in_flight.add(
                    create_referenced_task(
                        node_spends_with_conditions(node_client, block_header_hash, height, repeat_list)
                    )
                )
            if block_spends:
                in_flight.add(
                    create_referenced_task(node_block_spends(node_client, block_header_hash, height, repeat_list))
                )
            if additions_and_removals:
                in_flight.add(
                    create_referenced_task(node_additions_removals(node_client, block_header_hash, height, repeat_list))
                )

        for i in range(start_height, end_height + 1):
            add_tasks_for_height(height=i)

Review comment (suggestion):
minor thing, but this should be:
```suggestion
        cycle_start: float = time.monotonic()
```

Code after:
            print("No blockchain found. Exiting.")
            return
        peak_height = blockchain_state["peak"].height
        assert peak_height is not None, "Blockchain peak height is None"
        if end_height is None:
            end_height = peak_height

        print("Connected to Full Node")

        height_to_hash_bytes: bytes = await get_height_to_hash_bytes(root_path=root_path, config=config)

        print("block header hashes loaded from height-to-hash file.")

        # Set initial values for the loop

        pipeline: set[asyncio.Task[None]] = set()
        completed_requests: int = 0
        # measure time for performance measurement per segment
        cycle_start: float = time.monotonic()
        # also measure time for the whole process
        start_time: float = cycle_start

        def add_tasks_for_height(height: int) -> None:
            block_header_hash = get_block_hash_from_height(height, height_to_hash_bytes)
            # Create tasks for each RPC call based on the flags
            if spends_with_conditions:
                pipeline.add(
                    create_referenced_task(node_spends_with_conditions(node_client, block_header_hash, height))
                )
            if block_spends:
                pipeline.add(create_referenced_task(node_block_spends(node_client, block_header_hash, height)))
            if additions_and_removals:
                pipeline.add(create_referenced_task(node_additions_removals(node_client, block_header_hash, height)))

        for i in range(start_height, end_height + 1):
            add_tasks_for_height(height=i)
            # Make Status Updates.
            if len(pipeline) >= pipeline_depth:
                done, pipeline = await asyncio.wait(pipeline, return_when=asyncio.FIRST_COMPLETED)
                completed_requests += len(done)
                now = time.monotonic()
                if cycle_start + 5 < now:
                    time_taken = now - cycle_start
                    print(
                        f"Processed {completed_requests} RPCs in {time_taken:.2f}s, "
                        f"{time_taken / completed_requests:.4f}s per RPC "
                        f"({i - start_height} Blocks completed out of {end_height - start_height})"
                    )
                    completed_requests = 0
                    cycle_start = now