Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
11 changes: 10 additions & 1 deletion .github/workflows/tests-rs-nightly-long-running.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,16 @@ jobs:
fail-fast: false
matrix:
package:
[dash-sdk, rs-dapi-client, rs-dapi, dapi-grpc, dpp, drive-abci, drive-proof-verifier]
[
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
29 changes: 19 additions & 10 deletions .github/workflows/tests-rs-workspace.yml
Original file line number Diff line number Diff line change
Expand Up @@ -193,20 +193,29 @@ jobs:
cargo install cargo-machete 2>/dev/null || true
cargo machete

# The transport-free cut is how embedders with their own networking
# The transport-free cuts are how embedders with their own networking
# (Dash Core's platform GUI, explorers) consume verification: feature
# unification hides transport 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 cut
# 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
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
cargo check -p dash-platform-queries --locked
# Native graphs: assert the networking transport stack stays out.
# `tonic` itself is present (dapi-grpc's generated client types) but
# without its transport feature — which is exactly what the absence
# of hyper/rustls/tower proves. tokio is deliberately NOT asserted
# absent: dash-context-provider depends on dash-async, which uses it
# on native targets, and that edge predates the queries-crate split.
for native_package in drive-proof-verifier dash-platform-queries; do
for banned in hyper rustls tower; do
if cargo tree -p "$native_package" -e normal -i "$banned" 2>/dev/null | grep -q .; then
echo "::error::$banned leaked into $native_package's dependency tree"
exit 1
fi
done
done
for banned in hyper rustls tower mio; do
for wasm_package in dash-sdk wasm-sdk; do
Expand Down
18 changes: 18 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
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@
ARG SCCACHE_BUCKET
ARG AWS_PROFILE
ARG SCCACHE_REGION
ARG SCCACHE_S3_KEY_PREFIX

Check warning on line 216 in Dockerfile

View workflow job for this annotation

GitHub Actions / Build Docker images (RS-DAPI, rs-dapi, rs-dapi) / Build RS-DAPI image

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "SCCACHE_S3_KEY_PREFIX") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 216 in Dockerfile

View workflow job for this annotation

GitHub Actions / Build Docker images (Dashmate helper, dashmate-helper, dashmate-helper) / Build Dashmate helper image

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "SCCACHE_S3_KEY_PREFIX") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 216 in Dockerfile

View workflow job for this annotation

GitHub Actions / Build Docker images (Drive, drive, drive-abci, SDK_TEST_DATA=true ) / Build Drive image

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "SCCACHE_S3_KEY_PREFIX") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ARG SCCACHE_ENDPOINT

# Generate sccache configuration variables and save them to /root/env
Expand Down Expand Up @@ -415,6 +415,7 @@
packages/wasm-dpp2 \
packages/wasm-drive-verify \
packages/rs-dapi-client \
packages/dash-platform-queries \
packages/rs-sdk \
packages/rs-sdk-ffi \
packages/rs-unified-sdk-ffi \
Expand Down Expand Up @@ -541,6 +542,7 @@
packages/wasm-dpp2 \
packages/wasm-drive-verify \
packages/rs-dapi-client \
packages/dash-platform-queries \
packages/rs-sdk \
packages/rs-sdk-ffi \
packages/rs-unified-sdk-ffi \
Expand Down Expand Up @@ -690,6 +692,7 @@
packages/rs-dash-platform-macros \
packages/rs-drive \
packages/rs-drive-proof-verifier \
packages/dash-platform-queries \
packages/rs-sdk \
packages/rs-sdk-trusted-context-provider \
# Common
Expand Down Expand Up @@ -962,6 +965,7 @@
packages/wasm-dpp2 \
packages/wasm-drive-verify \
packages/rs-dapi-client \
packages/dash-platform-queries \
packages/rs-sdk \
packages/rs-sdk-ffi \
packages/rs-unified-sdk-ffi \
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
53 changes: 53 additions & 0 deletions packages/dash-platform-queries/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
[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]
dapi-grpc = { path = "../dapi-grpc", default-features = false, features = [
"platform",
"client",
] }
dash-context-provider = { path = "../rs-context-provider", default-features = false }
Comment thread
PastaPastaPasta marked this conversation as resolved.
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",
]
57 changes: 57 additions & 0 deletions packages/dash-platform-queries/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# 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.
Comment thread
PastaPastaPasta marked this conversation as resolved.
Outdated

## 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`](../rs-context-provider), and verifies every response
proof with [`drive-proof-verifier`](../rs-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 with wire
encoding for both request versions.
- Aggregate proof helpers (count/sum/average/ranked) shared with `dash-sdk`.
- DPNS username helpers — label normalization/validation and the
convertibility/contested checks shared with `dash-sdk`.
- `transition::validation` — structural validation for state transitions
ahead of signing.

Wire-request decoding (`DocumentQuery::try_from_request`), request-driven
proof verification, and pure DPNS/DashPay document builders arrive in the
next slice of this series.

## 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`.

"Transport-free" means no networking stack, not an async-runtime-free graph:
`tokio` is still reachable on native targets through
`dash-context-provider` → `dash-async`, exactly as it already was for
`drive-proof-verifier` before this crate existed. `tonic` is present too, but
only for `dapi-grpc`'s generated message/client types — its transport feature
stays off, which is what the `hyper`/`rustls`/`tower` assertions prove. On
`wasm32-unknown-unknown` none of that is pulled in; the wasm assertions in the
same CI step also ban `mio`.
47 changes: 47 additions & 0 deletions packages/dash-platform-queries/src/block_info_from_metadata.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use crate::Error;
use dapi_grpc::platform::v0::ResponseMetadata;
use dpp::block::block_info::BlockInfo;
use dpp::block::epoch::MAX_EPOCH;
use drive::error::proof::ProofError;

/// Constructs a `BlockInfo` structure from the provided response metadata. This function
/// translates metadata received from a platform response into a format that is specific to the
/// application's needs, particularly focusing on block-related information. It ensures that
/// the epoch value from the metadata does not exceed `MAX_EPOCH`,
/// as this is a constraint for the `Epoch` type used in the `BlockInfo` structure.
///
/// # Parameters
/// - `response_metadata`: A reference to `ResponseMetadata` obtained from a platform response.
/// This metadata includes various block-related information such as time in milliseconds,
/// height, core chain locked height, and epoch.
///
/// # Returns
/// If successful, returns `Ok(BlockInfo)` where `BlockInfo` contains:
/// - `time_ms`: The timestamp of the block in milliseconds.
/// - `height`: The height of the block.
/// - `core_height`: The core chain locked height, indicating the height of the block in the core blockchain that is considered final and securely linked to this block.
/// - `epoch`: The epoch number, converted to an `Epoch` struct via a 16-bit number.
///
/// # Errors
/// Returns an error if:
/// - The `epoch` value in the response metadata exceeds `MAX_EPOCH`. This is considered a data validity error as it indicates Platform returned an unexpectedly high epoch number.
///
/// The function encapsulates errors into the application's own `Error` type, providing a unified interface for error handling across the application.
pub fn block_info_from_metadata(response_metadata: &ResponseMetadata) -> Result<BlockInfo, Error> {
if response_metadata.epoch > MAX_EPOCH as u32 {
return Err(
drive::error::Error::Proof(ProofError::InvalidMetadata(format!(
"platform returned an epoch {} that was higher than the maximum allowed epoch",
response_metadata.epoch
)))
.into(),
);
}

Ok(BlockInfo {
time_ms: response_metadata.time_ms,
height: response_metadata.height,
core_height: response_metadata.core_chain_locked_height,
epoch: (response_metadata.epoch as u16).try_into()?,
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
//! [`DocumentAverage`]: drive_proof_verifier::DocumentAverage
//! [`DocumentSplitAverages`]: drive_proof_verifier::DocumentSplitAverages

use crate::platform::documents::document_query::DocumentQuery;
use crate::documents::document_query::DocumentQuery;
use dapi_grpc::platform::v0::{GetDocumentsResponse, Proof, ResponseMetadata};
use dapi_grpc::platform::VersionedGrpcResponse;
use dash_context_provider::ContextProvider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
//! [`DocumentCount`]: drive_proof_verifier::DocumentCount
//! [`DocumentSplitCounts`]: drive_proof_verifier::DocumentSplitCounts

use crate::platform::documents::document_query::DocumentQuery;
use crate::documents::document_query::DocumentQuery;
use dapi_grpc::platform::v0::{GetDocumentsResponse, Proof, ResponseMetadata};
use dapi_grpc::platform::VersionedGrpcResponse;
use dash_context_provider::ContextProvider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,8 @@
//! absent branch — same forward-compat for absence proofs as count)
//! contribute 0 to both axes via `filter_map(|e| e.<field>)`.

use crate::platform::documents::average_proof_helpers::{
assert_select_is_avg, verify_average_query,
};
use crate::platform::documents::document_query::DocumentQuery;
use crate::platform::Fetch;
use crate::documents::average_proof_helpers::{assert_select_is_avg, verify_average_query};
use crate::documents::document_query::DocumentQuery;
use dapi_grpc::platform::v0::{GetDocumentsResponse, Proof, ResponseMetadata};
use dash_context_provider::ContextProvider;
use dpp::dashcore::Network;
Expand Down Expand Up @@ -101,11 +98,6 @@ impl FromProof<DocumentQuery> for DocumentAverage {
}
}

impl Fetch for DocumentAverage {
type Query = super::document_query::DocumentQuery;
type Request = dapi_grpc::platform::v0::GetDocumentsRequest;
}

#[cfg(test)]
mod tests {
//! Unit tests for the AVG fold. The fold logic is extracted
Expand Down
Loading
Loading