Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/package-filters/rs-packages-direct.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ rs-dapi-client:
platform-encryption:
- packages/rs-platform-encryption/**

dash-platform-queries:
- packages/dash-platform-queries/**

dash-sdk:
- packages/rs-sdk/**

Expand Down
4 changes: 4 additions & 0 deletions .github/package-filters/rs-packages-no-workflows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,13 @@ rs-dapi-client: &dapi_client
platform-encryption: &platform_encryption
- packages/rs-platform-encryption/**

dash-platform-queries: &platform_queries
- packages/dash-platform-queries/**

dash-sdk: &sdk
- packages/rs-drive-proof-verifier/**
- packages/rs-sdk/**
- *platform_queries
- *dash_async
- *context_provider
- *sdk_trusted_context_provider
Expand Down
5 changes: 5 additions & 0 deletions .github/package-filters/rs-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,15 @@ platform-encryption: &platform_encryption
- .github/workflows/tests*
- packages/rs-platform-encryption/**

dash-platform-queries: &platform_queries
- .github/workflows/tests*
- packages/dash-platform-queries/**

dash-sdk: &sdk
- .github/workflows/tests*
- packages/rs-drive-proof-verifier/**
- packages/rs-sdk/**
- *platform_queries
- *dash_async
- *context_provider
- *sdk_trusted_context_provider
Expand Down
12 changes: 11 additions & 1 deletion .github/workflows/tests-rs-nightly-long-running.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,17 @@ jobs:
strategy:
fail-fast: false
matrix:
package: [dash-sdk, rs-dapi-client, rs-dapi, dapi-grpc, dpp, drive-abci]
package:
[
dash-sdk,
rs-dapi-client,
rs-dapi,
dapi-grpc,
dpp,
drive-abci,
drive-proof-verifier,
dash-platform-queries,
]
steps:
- name: Check out repo
uses: actions/checkout@v4
Expand Down
25 changes: 25 additions & 0 deletions .github/workflows/tests-rs-workspace.yml
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,31 @@ jobs:
cargo install cargo-machete 2>/dev/null || true
cargo machete

# The transport-free cuts are how embedders with their own networking
# (Dash Core's platform GUI, explorers) consume verification: feature
# unification hides regressions in whole-workspace builds, so check the
# standalone graphs and assert the networking stack stays out of the
# proof-verification tree (native) and out of wasm builds.
- name: Check transport-free feature cuts
run: |
cargo check -p dapi-grpc --no-default-features --features core,platform,client --locked
cargo check -p drive-proof-verifier --locked
cargo check -p dash-platform-queries --locked
for banned in hyper rustls tower; do
if cargo tree -p drive-proof-verifier -e normal -i "$banned" 2>/dev/null | grep -q .; then
echo "::error::$banned leaked into drive-proof-verifier's dependency tree"
exit 1
fi
done
for banned in hyper rustls tower mio; do
for wasm_package in dash-sdk wasm-sdk; do
if cargo tree -p "$wasm_package" --target wasm32-unknown-unknown -e normal -i "$banned" 2>/dev/null | grep -q .; then
echo "::error::$banned leaked into $wasm_package's wasm32 dependency tree"
exit 1
fi
done
done

- name: Detect immutable structure changes
if: github.event_name == 'pull_request'
run: |
Expand Down
20 changes: 20 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ members = [
"packages/wasm-dpp2",
"packages/rs-dapi-client",
"packages/rs-dash-async",
"packages/dash-platform-queries",
"packages/rs-sdk",
"packages/strategy-tests",
"packages/simple-signer",
Expand Down
1 change: 1 addition & 0 deletions packages/check-features/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ fn main() {
("rs-drive", vec![]),
("rs-drive-proof-verifier", vec![]),
("rs-platform-wallet", vec![]),
("dash-platform-queries", vec![]),
];

for (specific_crate, to_ignore) in crates {
Expand Down
27 changes: 19 additions & 8 deletions packages/dapi-grpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,30 @@ tenderdash-proto = []
# Client support.
client = ["platform"]

# Networked tonic client: `connect()` on generated clients, TLS roots.
# Deliberately NOT in the default set: 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. 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. Native
# networked consumers enable this explicitly (rs-dapi-client does so through
# its non-wasm dependency); the wasm codegen path never emits `connect()`.
transport = [
"tonic/channel",
"tonic/transport",
"tonic/tls-native-roots",
"tonic/tls-webpki-roots",
"tonic/tls-ring",
]

# Build tonic server code. Includes all client features and adds server-specific dependencies.
server = [
"platform",
"tenderdash-proto/server",
"client",
"drive",
"transport",
"tonic/router",
]

Expand All @@ -55,14 +73,7 @@ tonic = { version = "0.14.2", features = ["codegen"], default-features = false }
getrandom = { version = "0.2", features = ["js"] }

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
tonic = { version = "0.14.2", features = [
"codegen",
"channel",
"transport",
"tls-native-roots",
"tls-webpki-roots",
"tls-ring",
], default-features = false }
tonic = { version = "0.14.2", features = ["codegen"], default-features = false }

[build-dependencies]
tonic-prost-build = { version = "0.14.2" }
Expand Down
13 changes: 11 additions & 2 deletions packages/dapi-grpc/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ fn generate_code(typ: ImplType, output_base: &Path) {

println!("cargo:rerun-if-changed=./protos");
println!("cargo:rerun-if-env-changed=CARGO_FEATURE_SERDE");
println!("cargo:rerun-if-env-changed=CARGO_FEATURE_TRANSPORT");
println!("cargo:rerun-if-env-changed=CARGO_CFG_TARGET_ARCH");
println!("cargo:rerun-if-env-changed=DAPI_GRPC_OUT_DIR");
}
Expand Down Expand Up @@ -416,15 +417,23 @@ enum ImplType {
impl ImplType {
// Configure the builder based on the implementation type.
pub fn configure(&self, builder: Builder) -> Builder {
// The `transport` cargo feature controls whether generated clients get
// the `connect()` convenience impls over tonic's own channel. Without
// it, clients are still generated but stay generic over the caller's
// transport. Never enabled for wasm32, where tonic transport does not
// build. Note: cfg!(target_arch) in a build script reflects the HOST,
// so the target must be read from CARGO_CFG_TARGET_ARCH.
let transport = std::env::var("CARGO_FEATURE_TRANSPORT").is_ok()
&& std::env::var("CARGO_CFG_TARGET_ARCH").map(|arch| arch != "wasm32") == Ok(true);
match self {
Self::Server => builder
.build_client(true)
.build_server(true)
.build_transport(true),
.build_transport(transport),
Self::Client => builder
.build_client(true)
.build_server(false)
.build_transport(true),
.build_transport(transport),
Self::Wasm => builder
.build_client(true)
.build_server(false)
Expand Down
19 changes: 19 additions & 0 deletions packages/dapi-grpc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
//! Protobuf message types and generated gRPC stubs for DAPI.
//!
//! # Feature flags
//!
//! | feature | meaning |
//! |---|---|
//! | `core` / `platform` / `drive` | which proto surfaces are generated |
//! | `client` | generate client stubs (generic over the transport) |
//! | `transport` | tonic's opt-in native transport: `connect()` on generated clients and TLS roots. Pulls the hyper/rustls transport stack. |
//! | `server` | generate server stubs; implies `client`, `drive`, `transport` |
//! | `serde` / `mocks` | serde derives / dump-and-replay support |
//!
//! Types-only consumers (proof verification, embedders with their own
//! transport) build with `default-features = false, features = ["platform",
//! "client"]` and get message types plus transport-generic client stubs with
//! no native networking stack in the dependency tree. The default feature set
//! is also wasm32-safe; native consumers that call generated `connect()`
//! methods must enable `transport` explicitly.

pub use prost::Message;

#[cfg(feature = "core")]
Expand Down
54 changes: 54 additions & 0 deletions packages/dash-platform-queries/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
[package]
name = "dash-platform-queries"
description = "Transport-free query building and proof decoding core shared by Dash Platform SDK embedders"
version.workspace = true
edition = "2021"
rust-version.workspace = true
license = "MIT"

[features]
default = []
mocks = [
"dep:serde",
"dep:serde_json",
"dapi-grpc/mocks",
"drive/serde",
"dpp/serde-conversion",
]

[dependencies]
ciborium = { version = "0.2.2" }
dapi-grpc = { path = "../dapi-grpc", default-features = false, features = [
"platform",
"client",
] }
dash-context-provider = { path = "../rs-context-provider", default-features = false }
dash-platform-macros = { path = "../rs-dash-platform-macros" }
dpp = { path = "../rs-dpp", default-features = false, features = [
"platform-value-cbor",
"state-transitions",
"state-transition-validation",
] }
drive = { path = "../rs-drive", default-features = false, features = [
"verify",
] }
drive-proof-verifier = { path = "../rs-drive-proof-verifier", default-features = false }
hex = { version = "0.4.3" }
serde = { version = "1.0.219", default-features = false, features = [
"rc",
], optional = true }
serde_json = { version = "1.0", optional = true }
thiserror = "2.0.17"
tracing = { version = "0.1.41" }

[dev-dependencies]
dpp = { path = "../rs-dpp", default-features = false, features = [
"fixtures-and-mocks",
] }

[package.metadata.cargo-machete]
ignored = [
# Used inside the `dash_platform_macros::Mockable` derive expansion under
# the `mocks` feature; machete cannot see through proc-macro output.
"serde_json",
]
50 changes: 50 additions & 0 deletions packages/dash-platform-queries/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# dash-platform-queries

Transport-free query core of the Dash Platform SDK.

This crate carries the pieces of `dash-sdk` that build queries, encode them
onto the wire format, and decode/verify proved responses — with **no
transport implementation**: no `rs-dapi-client` and no tonic native
channel/TLS stack. Shared generated types and context-provider utilities
remain dependencies. `dash-sdk` depends on it and re-exports everything at
the historical paths, so SDK users need no changes.

## Who this is for

Embedders that bring their own transport and trust context and only need the
verification/query layer:

- **Dash Core's platform GUI** — fetches over its own gRPC-Web transport,
serves quorum keys from its locally synced LLMQ state via a
[`ContextProvider`], and verifies every response proof with
[`drive-proof-verifier`].
- Block explorers, Electrum-style servers, hardware-wallet tooling — anything
that talks to DAPI its own way but must not trust responses.

If you want networking, retries, and a managed connection pool, use
`dash-sdk` — it consumes this crate internally.

## What's here

- [`documents::DocumentQuery`] — rich document query builder, wire
encoding for both request versions, and decoding **from** the wire request
(`DocumentQuery::try_from_request`) using the same proto conversions the
server (`drive-abci`) uses, so client and server cannot drift.
- `documents::verify_documents_response` — request-driven proof verification
for document queries, delegating to `drive-proof-verifier`'s `FromProof`.
- Aggregate proof helpers (count/sum/average/ranked) shared with `dash-sdk`.
- Pure DPNS builders — `build_dpns_preorder_and_domain_documents`, label
normalization/validation — and pure DashPay contact-request document
assembly (`dashpay::build_contact_request_document`); crypto material is
supplied by the caller, keys never enter this crate.
- `transition::validation` and document-transition helpers
(`ensure_entropy_matches_document_id`, `prepare_document_for_transition`).

## Feature flags

- `mocks` — serde support for the types used in dump/replay test vectors
(forwarded by `dash-sdk`'s `mocks`).

The dependency tree is checked in CI to stay free of the transport stack
(`hyper`, `rustls`, `tower`); see the "Check transport-free feature cuts"
step in `.github/workflows/tests-rs-workspace.yml`.
Loading
Loading