Skip to content

chore #353: upgrade tonic 0.12 → 0.13 to eliminate rand 0.8.5 transitive dependency - #361

Merged
JoshuaChi merged 2 commits into
mainfrom
chore/353-tonic-013
Apr 13, 2026
Merged

JoshuaChi merged 2 commits into
mainfrom
chore/353-tonic-013

Conversation

@JoshuaChi

@JoshuaChi JoshuaChi commented Apr 13, 2026 •

Copy link
Copy Markdown
Contributor

What Does This PR Do?

Upgrades tonic 0.12 → 0.13 to eliminate the rand 0.8.5 transitive
dependency that triggered security advisory RUSTSEC-2026-0097.

Type:

  • Bug Fix (with test)

Why Is This Needed?

tonic 0.12 pulls in tower 0.4, which depends on rand 0.8.5,
triggering RUSTSEC-2026-0097 (unsound ThreadRng aliasing under
custom logger). The advisory was previously suppressed via deny.toml
ignore. tonic 0.13 uses tower 0.5, which drops the rand dependency
entirely — this is the only clean fix.


Checklist

Required:

  • make test passes
  • Commits squashed to 1-2 logical units

Testing

How tested:

  • cargo check --all-features passes with zero warnings
  • cargo tree | grep "rand 0.8" returns empty
  • cargo deny check advisories passes with RUSTSEC-2026-0097 ignore removed

Does This Follow d-engine's Principles?

  • Solves a real problem for most users (not just my edge case)
  • Keeps implementation simple
  • Doesn't bloat the API surface

Reviewer Notes

All source changes are mechanical:

  • use tonic::async_trait → use async_trait::async_trait (41 files, tonic 0.13 removed this re-export)
  • tls feature → tls-ring (tonic 0.13 split TLS backends)
  • mut health_reporter → health_reporter (tonic-health 0.13 returns immutable)
  • embedded-bench: pre-existing SmallRng/gen/Alphanumeric API bug fixed by upgrading rand 0.8 → 0.9

No logic changes. No API surface changes.

Estimated review complexity:

  • Medium (< 300 lines)

Summary by CodeRabbit

  • Chores
    • Bumped gRPC framework to 0.13 with updated TLS provider and related build deps.
    • Upgraded benchmark and build dependencies (including rand and tonic-build).
    • Removed an advisory ignore so security reports will now surface the previously-suppressed advisory.
  • Refactor
    • Switched async trait macro imports to the dedicated async-trait crate for consistency.
  • Bug Fixes / Improvements
    • Prevented bounded-channel backpressure during snapshot streaming by draining ACK receivers.

@coderabbitai

coderabbitai Bot commented Apr 13, 2026 •

Copy link
Copy Markdown

Warning

Rate limit exceeded

@JoshuaChi has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 17 minutes and 56 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 17 minutes and 56 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 28aeb778-ef56-4c69-bd94-191f25765514

📥 Commits

Reviewing files that changed from the base of the PR and between 5fe9c7e and 9d99e63.

⛔ Files ignored due to path filters (6)
  • Cargo.lock is excluded by !**/*.lock
  • d-engine-proto/src/generated/d_engine.client.rs is excluded by !**/generated/**
  • d-engine-proto/src/generated/d_engine.server.cluster.rs is excluded by !**/generated/**
  • d-engine-proto/src/generated/d_engine.server.election.rs is excluded by !**/generated/**
  • d-engine-proto/src/generated/d_engine.server.replication.rs is excluded by !**/generated/**
  • d-engine-proto/src/generated/d_engine.server.storage.rs is excluded by !**/generated/**
📒 Files selected for processing (48)
  • Cargo.toml
  • benches/embedded-bench/Cargo.toml
  • benches/embedded-bench/src/main.rs
  • d-engine-client/src/mock_rpc_service.rs
  • d-engine-core/Cargo.toml
  • d-engine-core/src/commit_handler/default_commit_handler.rs
  • d-engine-core/src/commit_handler/mod.rs
  • d-engine-core/src/election/election_handler.rs
  • d-engine-core/src/election/mod.rs
  • d-engine-core/src/membership.rs
  • d-engine-core/src/network/mod.rs
  • d-engine-core/src/purge/default_executor.rs
  • d-engine-core/src/purge/mod.rs
  • d-engine-core/src/raft_role/candidate_state.rs
  • d-engine-core/src/raft_role/follower_state.rs
  • d-engine-core/src/raft_role/leader_state.rs
  • d-engine-core/src/raft_role/learner_state.rs
  • d-engine-core/src/raft_role/role_state.rs
  • d-engine-core/src/replication/mod.rs
  • d-engine-core/src/replication/replication_handler.rs
  • d-engine-core/src/state_machine_handler/default_state_machine_handler.rs
  • d-engine-core/src/state_machine_handler/mod.rs
  • d-engine-core/src/storage/buffered_raft_log.rs
  • d-engine-core/src/storage/raft_log.rs
  • d-engine-core/src/storage/state_machine.rs
  • d-engine-core/src/storage/state_machine_test.rs
  • d-engine-core/src/storage/storage_engine.rs
  • d-engine-core/src/storage/storage_engine_test.rs
  • d-engine-core/src/test_utils/mock/mock_rpc_service.rs
  • d-engine-proto/Cargo.toml
  • d-engine-server/Cargo.toml
  • d-engine-server/src/membership/raft_membership.rs
  • d-engine-server/src/network/grpc/grpc_transport.rs
  • d-engine-server/src/network/grpc/mod.rs
  • d-engine-server/src/network/health_checker.rs
  • d-engine-server/src/network/health_monitor.rs
  • d-engine-server/src/storage/adaptors/file/file_engine_test.rs
  • d-engine-server/src/storage/adaptors/file/file_state_machine.rs
  • d-engine-server/src/storage/adaptors/file/file_state_machine_test.rs
  • d-engine-server/src/storage/adaptors/file/file_storage_engine.rs
  • d-engine-server/src/storage/adaptors/file/file_storage_engine_test.rs
  • d-engine-server/src/storage/adaptors/rocksdb/rocksdb_state_machine.rs
  • d-engine-server/src/storage/adaptors/rocksdb/rocksdb_state_machine_test.rs
  • d-engine-server/src/storage/adaptors/rocksdb/rocksdb_storage_engine.rs
  • d-engine-server/src/storage/adaptors/rocksdb/rocksdb_storage_engine_test.rs
  • d-engine-server/src/storage/adaptors/rocksdb/rocksdb_unified_engine_test.rs
  • d-engine-server/src/test_utils/mock/mock_rpc_service.rs
  • deny.toml
📝 Walkthrough

Walkthrough

Upgrades gRPC-related workspace dependencies to 0.13 (tonic, tonic-health, tonic-build), bumps rand in benches, replaces use tonic::async_trait with use async_trait::async_trait across many modules, adjusts health_reporter mutability bindings, adds background draining of snapshot ACK receivers in follower/learner, and removes an advisory ignore in deny.toml.

Changes

Cohort / File(s) Summary
Workspace deps & build
Cargo.toml, d-engine-proto/Cargo.toml, d-engine-core/Cargo.toml, d-engine-server/Cargo.toml
Bumped tonic/tonic-health/tonic-build to 0.13 (changed tonic features: tls → tls-ring), and switched some tonic-health entries to workspace = true.
Benchmark deps & RNG logic
benches/embedded-bench/Cargo.toml, benches/embedded-bench/src/main.rs
Upgraded rand 0.8 → 0.9; moved Alphanumeric import to rand::distr, switched RNG init from SmallRng::from_entropy() + rng.gen() to SmallRng::from_os_rng() + rng.random().
async_trait import migration
d-engine-core/src/..., d-engine-server/src/... (many files, e.g., commit_handler/*, election/*, raft_role/*, storage/*, replication/*, state_machine_handler/*, network/*, tests, adaptors, etc.)
Replaced use tonic::async_trait; with use async_trait::async_trait; across modules so #[async_trait] resolves to the standalone crate.
Snapshot ACK handling (raft roles)
d-engine-core/src/raft_role/follower_state.rs, .../learner_state.rs
Changed ACK channel handling: keep receiver (mut ack_rx) and spawn a background task that continuously drains ack_rx to avoid bounded-channel backpressure during InstallSnapshotChunk streaming.
Health reporter mutability
d-engine-client/src/mock_rpc_service.rs, d-engine-core/src/test_utils/mock/mock_rpc_service.rs, d-engine-server/src/network/grpc/mod.rs, d-engine-server/src/test_utils/mock/mock_rpc_service.rs
Removed mut binding when destructuring health_reporter(); subsequent set_serving/set_not_serving calls unchanged.
Configuration cleanup
deny.toml
Removed an advisory ignore entry for RUSTSEC-2026-0097 (rand/tower advisory).

Sequence Diagram(s)

sequenceDiagram
  participant Leader
  participant Follower as Follower/Learner
  participant SnapshotApplier as SnapshotApply
  participant AckDrain as ACK-Drain-Task

  Leader->>Follower: InstallSnapshotChunk (stream of chunks)
  Follower->>SnapshotApplier: apply_snapshot_stream_from_leader(chunk)
  SnapshotApplier-->>Follower: per-chunk result (await)
  Follower->>Leader: send ACK (ack_tx.try_send or send)
  Note right of Follower: spawn ACK-Drain-Task to continuously recv from ack_rx
  AckDrain->>Follower: drain ack_rx (prevent backpressure)
  Leader-->>Follower: continue streaming next chunk
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Possibly related issues

Possibly related PRs

Poem

🐰 Hopped through crates with nimble paws,

tonic raised, and async trait applause.
ACKs drained gently, no backpressure fright,
Rand refreshed for a brighter night.
A rabbit cheers — the build takes flight! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main objective: upgrading tonic from 0.12 to 0.13 to eliminate a transitive rand 0.8.5 dependency that triggered a security advisory.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/353-tonic-013

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 and usage tips.

@JoshuaChi
JoshuaChi force-pushed the chore/353-tonic-013 branch from 5fe9c7e to f1131e4 Compare April 13, 2026 11:06
…ive dependency

tower 0.4 (pulled in by tonic 0.12) depended on rand 0.8.5, triggering
RUSTSEC-2026-0097. tonic 0.13 uses tower 0.5 which drops rand entirely.

- tonic/tonic-health/tonic-build: 0.12 → 0.13
- tls feature renamed: `tls` → `tls-ring` (tonic 0.13 breaking change)
- Replace `use tonic::async_trait` with `use async_trait::async_trait`
  across 41 files (removed in tonic 0.13)
- Remove mut on health_reporter (now returns immutable in tonic-health 0.13)
- Remove RUSTSEC-2026-0097 ignore from deny.toml
- Fix embedded-bench: rand 0.8 → 0.9, migrate SmallRng/gen/Alphanumeric API
…large snapshots

With _ack_rx dropped, process_snapshot_stream's ack_tx.send().await blocks
once the 32-slot buffer fills on chunk 33+, hanging the entire snapshot
install. Spawn a drain task so ack_tx never backpressures.
@JoshuaChi
JoshuaChi force-pushed the chore/353-tonic-013 branch from f1131e4 to 9d99e63 Compare April 13, 2026 11:07
@codecov

codecov Bot commented Apr 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.33333% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
d-engine-core/src/raft_role/learner_state.rs 0.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@JoshuaChi
JoshuaChi merged commit 87fc748 into main Apr 13, 2026
8 of 9 checks passed
@JoshuaChi
JoshuaChi deleted the chore/353-tonic-013 branch April 13, 2026 11:37
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