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
21 changes: 21 additions & 0 deletions .github/workflows/tests-rs-workspace.yml
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,27 @@ 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 transport stack stays out of the
# proof-verification tree.
- 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
if cargo tree -p wasm-sdk --target wasm32-unknown-unknown -e normal -i "$banned" 2>/dev/null | grep -q .; then
echo "::error::$banned leaked into wasm-sdk's wasm32 dependency tree"
exit 1
fi
done

- name: Detect immutable structure changes
if: github.event_name == 'pull_request'
run: |
Expand Down
21 changes: 21 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
28 changes: 19 additions & 9 deletions packages/dapi-grpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ rust-version.workspace = true
license = "MIT"

[features]
default = ["core", "platform", "client"]
default = ["core", "platform", "client", "transport"]
# Internal Drive endpoints. Used by DAPI
drive = ["platform"]
core = []
Expand All @@ -26,12 +26,29 @@ tenderdash-proto = []
# Client support.
client = ["platform"]

# 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"]`.
# wasm32 consumers must use `default-features = false` (as rs-dapi-client and
# wasm-sdk do): tonic's transport stack does not build on wasm, and 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 +72,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
18 changes: 18 additions & 0 deletions packages/dapi-grpc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
//! 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 native transport: `connect()` on generated clients, TLS roots. Pulls hyper/tokio. Default-on. |
//! | `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 networking stack in the dependency tree. wasm32 consumers must use
//! `default-features = false` — tonic's transport does not build there.

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",
]
49 changes: 49 additions & 0 deletions packages/dash-platform-queries/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# 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 dependency**: no `rs-dapi-client`, no tokio runtime, no tonic
transport stack. `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