# Update 16-19
Over the past weeks, I’ve been developing the Perf Protocol for libp2p, a tool designed to measure performance under varied conditions. Inspired by an initial draft for QUIC, the protocol has been tailored for libp2p to provide flexibility in testing data transfer.
The protocol enables the client to specify the data volume it wants to send and receive, allowing customized testing for specific performance scenarios. It focuses on two primary benchmarks:
- **Throughput**: Measures the data transfer speed between the client and server, helping gauge network efficiency.
- **Handshakes per Second**: Assesses how many connections can be established within a given timeframe, evaluating connection setup performance.
For security, the protocol is not recommended to be enabled publicly by default, though it can be safeguarded through peer authentication.
here is the PR for the same:- [Link](https://github.com/NethermindEth/dotnet-libp2p/pull/109)
The code defines a performance testing protocol (`PerfProtocol`) for data transfer in a libp2p network, with a focus on reporting data transfer metrics and handling both reading and writing operations. Here's a breakdown of key elements:
1. **`ReportingStream` Class**:
- This class wraps a `Stream` and tracks the amount of data read in bytes, updating every second.
- Each second, it logs the bytes read in JSON format, reporting intermediary download metrics (`DownloadBytes`) without affecting the underlying stream’s behavior.
- `UpdateReport` updates the amount of data read, calculates the elapsed time, and logs the data if more than one second has passed.
2. **`PerfProtocol` Class**:
- Implements `IProtocol` for handling large data transfers, focusing on measuring and reporting the transferred data volume.
- **`DialAsync`**: Acts as a data receiver that reads an initial 8-byte message (indicating how many bytes will be received), then calls `DrainStreamAsync` to process and log received data.
- **`ListenAsync`**: Acts as a data sender, sending an initial message with a specific data size and then sending data for the receiver to process.
- **`SendBytesAsync`**: Sends data in chunks (64KB), logging every second how many bytes have been sent. This function returns `false` if there’s a write error, and `true` upon success.
- **`DrainStreamAsync`**: Reads data from the `ReportingStream` (wrapped around the actual stream) and tracks the total received bytes for reporting.
The protocol uses `ReportingStream` to transparently monitor and log data throughput, making it suitable for performance benchmarking by generating real-time metrics on data upload and download in a structured format.