Skip to content

feat: add chainbench grpc subcommand for Solana Yellowstone gRPC benchmarks#121

Open
CSFeo wants to merge 1 commit into
chainstacklabs:mainfrom
CSFeo:feat/grpc-integration
Open

feat: add chainbench grpc subcommand for Solana Yellowstone gRPC benchmarks#121
CSFeo wants to merge 1 commit into
chainstacklabs:mainfrom
CSFeo:feat/grpc-integration

Conversation

@CSFeo

@CSFeo CSFeo commented Jul 15, 2026

Copy link
Copy Markdown

What

Adds a chainbench grpc subcommand for benchmarking Solana Yellowstone (Geyser)
gRPC endpoints, and bundles the chainbench-grpc
tool into the Docker image so it works out of the box.

chainbench grpc latency    --url URL --token TOKEN
chainbench grpc race       -u URL1 -t T1 -u URL2 -t T2 --transactions 5000
chainbench grpc throughput --url URL --token TOKEN --duration 60
chainbench grpc slots      --url URL --token TOKEN --target-slots 100
chainbench grpc full       ...
chainbench grpc latency --help    # rendered by the binary

How it works

  • chainbench/grpc.py — a Click subgroup with the five modes (race,
    latency, throughput, slots, full). It's a thin pass-through: it
    subprocess-invokes the bundled chainbench-grpc binary, forwards stdout /
    stderr and the exit code, and passes flags after the mode straight to the
    binary (which owns its own validation and --help). If the binary isn't on
    PATH it raises a clear ClickException.
  • chainbench/main.py — registers the subgroup (+4 lines).
  • Dockerfile — a Rust build stage compiles chainbench-grpc from a pinned
    tag (v0.4.0; protoc is vendored by the crate) and copies the binary to
    /usr/local/bin in the prod image.
  • README.md — documents the new command.

Testing

  • black --check, isort --check, flake8, mypy — clean on the changed files.
  • Verified end-to-end locally: installed ChainBench in a venv, put the built
    chainbench-grpc binary on PATH, and confirmed chainbench grpc <mode>
    shells out to it (correct output + exit codes; graceful "not found" message
    when the binary is absent).

Notes for maintainers

  • This introduces a build-time dependency on the (now public) CSFeo/chainbench-grpc
    repo, pinned to tag v0.4.0 via the CHAINBENCH_GRPC_REF build arg.
  • Follow-ups worth deciding: moving chainbench-grpc under the chainstacklabs
    org, and the published image / Docker Hub ownership.
  • The grpc command output is the tool's own (console/JSON/CSV/HTML); it is not
    normalized into the Locust report format.

Summary by CodeRabbit

  • New Features

    • Added chainbench grpc commands for race, latency, throughput, slots, and full benchmarking modes.
    • Supports forwarding additional command-line options to the underlying benchmark tool.
    • Docker images now include the bundled chainbench-grpc executable.
  • Documentation

    • Added usage instructions, supported modes, examples, and local installation guidance to the README.

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@CSFeo, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 27 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e3342028-7ebf-4b37-bde9-8aa2a84f4a74

📥 Commits

Reviewing files that changed from the base of the PR and between 64da86e and 7e40a12.

📒 Files selected for processing (4)
  • Dockerfile
  • README.md
  • chainbench/grpc.py
  • chainbench/main.py
📝 Walkthrough

Walkthrough

Changes

The PR adds chainbench grpc with supported benchmark modes, forwards mode arguments to the chainbench-grpc binary, builds and bundles that binary in Docker, and documents usage and installation requirements.

gRPC benchmark integration

Layer / File(s) Summary
CLI wrapper and command registration
chainbench/grpc.py, chainbench/main.py
Adds mode-specific Click commands that locate chainbench-grpc, forward arguments, preserve its exit code, and register the grpc group with the main CLI.
Docker build and runtime packaging
Dockerfile
Builds the Rust binary from a pinned repository reference and copies it into the production image’s executable path.
Command usage documentation
README.md
Documents supported modes, argument forwarding, example commands, and installation outside Docker.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant grpc_wrapper
  participant chainbench_grpc
  CLI->>grpc_wrapper: invoke grpc mode with arguments
  grpc_wrapper->>grpc_wrapper: locate chainbench-grpc on PATH
  grpc_wrapper->>chainbench_grpc: execute mode and forwarded arguments
  chainbench_grpc-->>grpc_wrapper: return exit code
  grpc_wrapper-->>CLI: exit with binary return code
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding a new grpc subcommand for Solana Yellowstone gRPC benchmarks.
Description check ✅ Passed The description is detailed and covers changes, implementation, testing, and notes, though it does not use the exact template headings.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
chainbench/grpc.py (1)

31-31: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Catch OSError for robust binary execution.

While shutil.which ensures the binary exists and is marked as executable, subprocess.run can still raise an OSError (e.g., ENOEXEC due to a CPU architecture mismatch if a user downloads the wrong local binary). Catching this exception and raising a click.ClickException provides a cleaner user experience than a raw Python traceback.

🛠️ Proposed refactor to handle execution errors gracefully
-    completed = subprocess.run([exe, mode, *args])
+    try:
+        completed = subprocess.run([exe, mode, *args])
+    except OSError as e:
+        raise click.ClickException(f"Failed to execute `{exe}`: {e}")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@chainbench/grpc.py` at line 31, Update the subprocess.run invocation in the
binary execution flow to catch OSError, including execution failures such as
incompatible binaries, and raise a click.ClickException with a clear error
message instead of exposing the raw traceback. Preserve the existing command
arguments and successful execution behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@chainbench/grpc.py`:
- Line 31: Update the subprocess.run invocation in the binary execution flow to
catch OSError, including execution failures such as incompatible binaries, and
raise a click.ClickException with a clear error message instead of exposing the
raw traceback. Preserve the existing command arguments and successful execution
behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e2d0096b-3629-490d-81d8-a08a120d0d99

📥 Commits

Reviewing files that changed from the base of the PR and between 5d56c2d and 64da86e.

📒 Files selected for processing (4)
  • Dockerfile
  • README.md
  • chainbench/grpc.py
  • chainbench/main.py

…nchmarks

Integrate the chainbench-grpc tool as a CLI invocation inside the ChainBench
Docker image (per the Solana gRPC benchmarking initiative).

- chainbench/grpc.py: `chainbench grpc <race|latency|throughput|slots|full>`
  Click subgroup. Thin pass-through — shells out to the bundled `chainbench-grpc`
  binary, forwards stdout/stderr + exit code; flags after the mode go straight to
  the binary (it owns its own validation and --help). Clear error if not on PATH.
- chainbench/main.py: register the subgroup.
- Dockerfile: Rust build stage builds chainbench-grpc from a pinned tag (v0.4.0)
  and copies the binary onto PATH in the prod image (protoc is vendored).
- README: document the new `grpc` command.

Tested: black/isort/flake8/mypy clean; the subcommand shells out to the real
binary end to end (verified locally), with correct exit codes and a graceful
"binary not found" message.
@CSFeo CSFeo force-pushed the feat/grpc-integration branch from 64da86e to 7e40a12 Compare July 15, 2026 01:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant