Skip to content

feat(sdk): add transport feature to dapi-grpc for types-only consumers - #4344

Open
PastaPastaPasta wants to merge 1 commit into
v4.2-devfrom
feat/dapi-grpc-transport-feature
Open

feat(sdk): add transport feature to dapi-grpc for types-only consumers#4344
PastaPastaPasta wants to merge 1 commit into
v4.2-devfrom
feat/dapi-grpc-transport-feature

Conversation

@PastaPastaPasta

@PastaPastaPasta PastaPastaPasta commented Aug 8, 2026

Copy link
Copy Markdown
Member

Issue being fixed or feature implemented

dapi-grpc unconditionally builds tonic with its native transport stack (channel + TLS roots) on non-wasm targets, so any consumer of just the message types or the proof-verification layer drags hyper/tokio/rustls/ring/tower into its dependency tree even when it never opens a connection. drive-proof-verifier is the concrete case: a fully synchronous crate that pays for a networking stack it cannot use. For embedders that vendor and audit every dependency (Dash Core's platform GUI — PastaPastaPasta/dash#67 — plus explorers and other own-transport clients), that's ~120 crates of pure supply-chain overhead.

The wasm target already proves the crate works with codegen-only tonic; this makes the same cut expressible on native.

First slice of #4335, split out per its "happy to split" note — this is the prerequisite commit the rest of that series builds on.

What was done?

  • New opt-in transport cargo feature on dapi-grpc carrying tonic's channel/transport/tls-* features (the same client/server-style feature split tenderdash-proto already has). The base tonic dependency drops to codegen. It is deliberately not a default: cargo features are not target-scoped, so a default-on transport would force tonic's transport stack onto wasm32 consumers riding defaults (thepastaclaw's blocker — fixed).
  • build.rs drives tonic-build's build_transport from CARGO_FEATURE_TRANSPORT, never on wasm32.
  • Consumers needing the native transport opt in explicitly: rs-dapi-client (target-scoped to non-wasm; its wasm side uses tonic-web-wasm-client), dash-sdk (via its default feature), drive-abci via server (which now implies transport). wasm-sdk and other wasm consumers need no changes — defaults are wasm-safe.
  • CI: a PR-time step checks the types-only graphs and fails if hyper/rustls/tower leaks into drive-proof-verifier's native tree or wasm-sdk's wasm32 tree; drive-proof-verifier joins the nightly per-feature check matrix (the matrix enumerates features from Cargo.toml, so the new transport feature is covered there automatically).

drive-proof-verifier itself needs zero changes — its standalone tree just drops from 407 to 339 crates: hyper, h2, rustls, ring, tower and the rest of the transport stack disappear. What remains of tonic's codegen core is a sync-only tokio slice via tokio-stream (so the tree is transport-free, not tokio-free — documented as such).

Types-only consumption:

dapi-grpc = { default-features = false, features = ["platform", "client"] }

How Has This Been Tested?

Breaking Changes

None for SDK users (dash-sdk enables dapi-grpc/transport in its defaults) or any in-repo consumer. External native consumers depending on dapi-grpc directly with default features and calling generated connect() methods must add features = ["transport"] — the failure mode is a clear missing-method error naming the gap, versus the previous state where external wasm consumers got an unbuildable tokio/mio graph with no indication why. wasm consumers are strictly better off: defaults now build on wasm32.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation
  • I have assigned this pull request to a milestone (for repository code-owners and collaborators only)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added optional network transport and TLS support for native Rust clients.
    • Enabled transport support by default in the Rust SDK.
    • Preserved transport-free compatibility for WebAssembly builds.
  • Tests

    • Added validation to ensure transport dependencies are excluded from transport-free and WebAssembly configurations.
    • Expanded nightly feature checks to include the gRPC package.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds an explicit transport feature to dapi-grpc, enables conditional tonic transport generation, configures native consumers, and adds CI checks for transport-free dependency trees.

Changes

Transport Feature Cut

Layer / File(s) Summary
Feature and consumer configuration
packages/dapi-grpc/Cargo.toml, packages/rs-dapi-client/Cargo.toml, packages/rs-sdk/Cargo.toml
dapi-grpc defines a non-default transport feature. Native rs-dapi-client enables it without default features. rs-sdk includes it in its default features.
Conditional tonic code generation
packages/dapi-grpc/build.rs
The build script tracks CARGO_FEATURE_TRANSPORT and enables generated transport support only for non-wasm32 targets when the feature is enabled.
Feature configuration validation
.github/workflows/tests-rs-workspace.yml, .github/workflows/tests-rs-nightly-long-running.yml
CI validates transport-free builds, checks dependency trees for transport crates, and adds dapi-grpc to the nightly feature matrix.

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

Suggested reviewers: quantumexplorer, lklimek, shumkov

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding a transport feature to dapi-grpc for types-only consumers.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/dapi-grpc-transport-feature

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

@PastaPastaPasta
PastaPastaPasta force-pushed the feat/dapi-grpc-transport-feature branch from b184fa1 to 49e8a05 Compare August 8, 2026 16:56
@thepastaclaw

thepastaclaw commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

⛔ Blockers found — Opus deferred (commit 74991e4)
Canonical validated blockers: 1

@PastaPastaPasta PastaPastaPasta left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

self; LGTM

@codecov

codecov Bot commented Aug 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.62%. Comparing base (7a7ec9f) to head (74991e4).
⚠️ Report is 1 commits behind head on v4.2-dev.

Additional details and impacted files
@@            Coverage Diff            @@
##           v4.2-dev    #4344   +/-   ##
=========================================
  Coverage     87.62%   87.62%           
=========================================
  Files          2704     2704           
  Lines        345206   345206           
=========================================
  Hits         302473   302473           
  Misses        42733    42733           
Components Coverage Δ
dpp 88.86% <ø> (ø)
drive 86.25% <ø> (ø)
drive-abci 89.66% <ø> (ø)
sdk ∅ <ø> (∅)
dapi-client ∅ <ø> (∅)
platform-version ∅ <ø> (∅)
platform-value 92.88% <ø> (ø)
platform-wallet ∅ <ø> (∅)
drive-proof-verifier 48.02% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Preliminary review — Codex only

The transport-free native configuration works, but making transport a target-independent default breaks the previously supported default WASM configuration of the public dapi-grpc crate. The types-only documentation also overstates the dependency reduction by claiming Tokio is absent when tonic's codegen graph still includes it.
Source: reviewer backends gpt-5.6-sol (Codex general and Codex rust-quality); final verifier backend gpt-5.6-sol (Codex); orchestration-only openclaw-agent/cliproxy/gpt-5.6-sol (not reviewer evidence).

Validated blockers were found in the Codex precheck. Opus is deferred until a fresh Codex revalidation clears the blocker gate.

Review provenance

  • Codex reviewers: gpt-5.6-sol — general (completed), gpt-5.6-sol — rust-quality (completed)
  • Verifier: gpt-5.6-sol — verifier
  • Sonnet: not run (deferred by blocker gate)

🔴 1 blocking | 🟡 1 suggestion(s)

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `packages/dapi-grpc/Cargo.toml`:
- [BLOCKING] packages/dapi-grpc/Cargo.toml:17: Default features now make dapi-grpc fail to compile on WASM
  Cargo features are not target-scoped, so adding `transport` to the crate's defaults forwards tonic's channel, transport, TLS, and ring features to the active wasm32 tonic dependency as well as the native one. The target check in `build.rs` only prevents generation of `connect()` methods; it cannot disable dependency features already selected by Cargo. At this exact head, the wasm32 dependency graph contains `dapi-grpc -> tonic -> tokio -> mio` together with hyper, rustls, and ring, and the default wasm32 check attempts to compile those unsupported dependencies. The base revision enabled transport features only under `cfg(not(target_arch = "wasm32"))`, so default WASM consumers did not have this graph. Updating `wasm-sdk` repairs one in-repository consumer but leaves external WASM consumers using `dapi-grpc` defaults broken. Preserve WASM-safe public defaults by activating transport through a genuinely non-WASM mechanism, or remove it from the defaults and have native network consumers enable it explicitly.
- [SUGGESTION] packages/dapi-grpc/Cargo.toml:29-33: Types-only feature documentation incorrectly promises no Tokio dependency
  The transport-free graph still contains `tonic -> tokio-stream -> tokio`, which is also acknowledged in the PR description as a sync-only Tokio slice. Claiming there is "no hyper/tokio in the dependency tree" is therefore inaccurate and can mislead embedders using this feature specifically to audit their dependency closure. Document that the networking and TLS transport stack is disabled while tonic's codegen dependencies, including its minimal Tokio slice, remain.

Comment thread packages/dapi-grpc/Cargo.toml Outdated

[features]
default = ["core", "platform", "client"]
default = ["core", "platform", "client", "transport"]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🔴 Blocking: Default features now make dapi-grpc fail to compile on WASM

Cargo features are not target-scoped, so adding transport to the crate's defaults forwards tonic's channel, transport, TLS, and ring features to the active wasm32 tonic dependency as well as the native one. The target check in build.rs only prevents generation of connect() methods; it cannot disable dependency features already selected by Cargo. At this exact head, the wasm32 dependency graph contains dapi-grpc -> tonic -> tokio -> mio together with hyper, rustls, and ring, and the default wasm32 check attempts to compile those unsupported dependencies. The base revision enabled transport features only under cfg(not(target_arch = "wasm32")), so default WASM consumers did not have this graph. Updating wasm-sdk repairs one in-repository consumer but leaves external WASM consumers using dapi-grpc defaults broken. Preserve WASM-safe public defaults by activating transport through a genuinely non-WASM mechanism, or remove it from the defaults and have native network consumers enable it explicitly.

source: ['codex']

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Valid — fixed in 74991e4. You're right that cargo features aren't target-scoped and the build.rs gate only affects codegen, not dependency selection. transport is no longer a default feature: defaults are now wasm-safe (verified: cargo check -p dapi-grpc --target wasm32-unknown-unknown with defaults builds), the wasm-sdk workaround is reverted, and native networked consumers enable the feature explicitly (dash-sdk carries it in its own defaults, so SDK users are unchanged).


🤖 Posted autonomously by Claude on behalf of pasta.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Resolved in this update — Default features now make dapi-grpc fail to compile on WASM no longer present.

Auto-resolved by the review system based on the latest commit diff. If you believe this was closed in error, reopen the thread.

Comment thread packages/dapi-grpc/Cargo.toml Outdated
Comment on lines +29 to +33
# Networked tonic client: `connect()` on generated clients, TLS roots. Without
# this feature the crate provides message types and transport-generic client
# stubs only — no hyper/tokio in the dependency tree. Types-only consumers
# (proof verification, embedders with their own transport) build with
# `default-features = false, features = ["platform", "client"]`.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🟡 Suggestion: Types-only feature documentation incorrectly promises no Tokio dependency

The transport-free graph still contains tonic -> tokio-stream -> tokio, which is also acknowledged in the PR description as a sync-only Tokio slice. Claiming there is "no hyper/tokio in the dependency tree" is therefore inaccurate and can mislead embedders using this feature specifically to audit their dependency closure. Document that the networking and TLS transport stack is disabled while tonic's codegen dependencies, including its minimal Tokio slice, remain.

Suggested change
# Networked tonic client: `connect()` on generated clients, TLS roots. Without
# this feature the crate provides message types and transport-generic client
# stubs only — no hyper/tokio in the dependency tree. Types-only consumers
# (proof verification, embedders with their own transport) build with
# `default-features = false, features = ["platform", "client"]`.
# Networked tonic client: `connect()` on generated clients, TLS roots. Without
# this feature the crate provides message types and transport-generic client
# stubs only. Tonic's codegen graph still includes tokio-stream and a minimal
# Tokio slice, but its hyper/rustls transport stack is not enabled. Types-only
# consumers build with
# `default-features = false, features = ["platform", "client"]`.

source: ['codex']

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Also valid — the comment overpromised. Reworded in 74991e4 along the lines you suggested: the transport/TLS stack is disabled, while tonic's codegen graph keeps tokio-stream and a minimal Tokio slice.


🤖 Posted autonomously by Claude on behalf of pasta.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Resolved in this update — Types-only feature documentation incorrectly promises no Tokio dependency no longer present.

Auto-resolved by the review system based on the latest commit diff. If you believe this was closed in error, reopen the thread.

dapi-grpc unconditionally built tonic with its native transport stack
(channel + TLS roots) on non-wasm targets, so any consumer of the message
types or proof-verification layers (drive-proof-verifier) dragged
hyper/rustls and the tokio networking stack into its dependency tree even
when it never opens a connection. The wasm target already proves the crate
works with codegen-only tonic.

Add an opt-in 'transport' cargo feature carrying tonic's
channel/transport/tls features, mirroring the client/server feature split
tenderdash-proto already has. It is deliberately NOT a default feature:
cargo features are not target-scoped, so a default-on transport would force
tonic's transport stack onto wasm32 consumers riding defaults, where it
does not build. build.rs drives tonic-build's build_transport from
CARGO_FEATURE_TRANSPORT (never on wasm32). Native networked consumers
enable it explicitly: rs-dapi-client (target-scoped to non-wasm), dash-sdk
(default feature, so SDK users are unchanged), and drive-abci via server
(which now implies transport). wasm-sdk and other wasm consumers need no
changes.

drive-proof-verifier needs no changes and its standalone tree drops from
407 to 339 crates: hyper, h2, rustls, ring, tower and the rest of the
transport stack disappear; what remains of tonic's codegen core is a
sync-only tokio slice via tokio-stream.

Types-only consumption is simply the default; embedders with their own
transport depend on:
  dapi-grpc = { default-features = false, features = ["platform", "client"] }
(default-features = false remains advisable for wasm and keeps the feature
set explicit.)
@PastaPastaPasta
PastaPastaPasta force-pushed the feat/dapi-grpc-transport-feature branch from 49e8a05 to 74991e4 Compare August 8, 2026 18:16

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Preliminary review — Codex only

The two prior findings are fixed: dapi-grpc defaults are now transport-free, and the documentation accurately describes the remaining minimal Tokio dependency. One new blocker remains because dash-sdk's target-independent defaults directly re-enable tonic's native transport stack on WASM, even though native builds already receive that feature through rs-dapi-client's target-scoped dependency.
Source: Codex reviewers gpt-5.6-sol (general and rust-quality); final verifier gpt-5.6-sol (Codex). Orchestration-only: openclaw-agent/cliproxy/gpt-5.6-sol (not reviewer evidence).

Validated blockers were found in the Codex precheck. Opus is deferred until a fresh Codex revalidation clears the blocker gate.

Review provenance

  • Codex reviewers: gpt-5.6-sol — general (completed), gpt-5.6-sol — rust-quality (completed)
  • Verifier: gpt-5.6-sol — verifier
  • Sonnet: not run (deferred by blocker gate)

🔴 1 blocking

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `packages/rs-sdk/Cargo.toml`:
- [BLOCKING] packages/rs-sdk/Cargo.toml:75-81: Dash SDK defaults still enable native transport on WASM
  Cargo features are not target-scoped, so `dapi-grpc/transport` in dash-sdk's default feature set enables tonic's channel, transport, TLS, and ring features when dash-sdk is built for `wasm32-unknown-unknown`. The dependency graph attributes these features directly to `dapi-grpc feature "transport" -> dash-sdk feature "default"`, and `cargo check -p dash-sdk --target wasm32-unknown-unknown --locked` reaches mio's explicit `This wasm target is unsupported by mio` error while also attempting to compile ring. The build-script target check only suppresses generated `connect()` methods and cannot remove dependency features already selected by Cargo. The new CI assertion misses this configuration because wasm-sdk depends on dash-sdk with `default-features = false`. Remove the forwarding from dash-sdk's defaults; native dash-sdk builds already receive `dapi-grpc/transport` through rs-dapi-client's non-WASM dependency, while WASM builds will remain transport-free.

Comment on lines 76 to 81
"mocks",
"offline-testing",
"dapi-grpc/client",
"dapi-grpc/transport",
"token_reward_explanations",
]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🔴 Blocking: Dash SDK defaults still enable native transport on WASM

Cargo features are not target-scoped, so dapi-grpc/transport in dash-sdk's default feature set enables tonic's channel, transport, TLS, and ring features when dash-sdk is built for wasm32-unknown-unknown. The dependency graph attributes these features directly to dapi-grpc feature "transport" -> dash-sdk feature "default", and cargo check -p dash-sdk --target wasm32-unknown-unknown --locked reaches mio's explicit This wasm target is unsupported by mio error while also attempting to compile ring. The build-script target check only suppresses generated connect() methods and cannot remove dependency features already selected by Cargo. The new CI assertion misses this configuration because wasm-sdk depends on dash-sdk with default-features = false. Remove the forwarding from dash-sdk's defaults; native dash-sdk builds already receive dapi-grpc/transport through rs-dapi-client's non-WASM dependency, while WASM builds will remain transport-free.

Suggested change
"mocks",
"offline-testing",
"dapi-grpc/client",
"dapi-grpc/transport",
"token_reward_explanations",
]
default = [
"mocks",
"offline-testing",
"dapi-grpc/client",
"token_reward_explanations",
]

source: ['codex']

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.

2 participants