Skip to content
Merged
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
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 (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/

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/
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",
]
70 changes: 70 additions & 0 deletions packages/dash-platform-queries/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# 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 every moved
item at its historical path, so most imports keep compiling unchanged — but
the extraction is not fully source-compatible. Depending on what it uses,
downstream code may need to:

- import the `dash_sdk::platform::DocumentQuerySdk` extension trait to keep
calling `DocumentQuery::new_with_data_contract_id`, which fetches the
contract and therefore needs `&Sdk`;
- handle `dash_platform_queries::Error` — `DocumentQuery`'s fallible
methods now return it instead of `dash_sdk::Error`. `?` call sites keep
compiling via `From`; explicit return types and direct variant matches
need a conversion;
- implement the `dash_sdk::platform::WireQuery` marker trait
(`impl WireQuery for MyCustomRequest {}`) for custom `TransportRequest`
types used with the blanket `Query` impl.

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

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