Skip to content

Commit 3da51c3

Browse files
refactor(drive-abci): extract v1 document-query wire decoders into platform-query-wire
Pure move: the wire-proto -> drive-type decoders for the v1 getDocuments surface now live in a new packages/rs-platform-query-wire micro-crate (crate name platform-query-wire) behind a neutral DecodeError { InvalidArgument, Unsupported }, and drive-abci's v1/conversions.rs becomes a thin adapter mapping DecodeError onto its QueryError surface with the exact same message strings (including the aggregate ORDER BY arm, which maps Unsupported onto QuerySyntaxError::Unsupported). No behavior change to server request decoding. The decode of a wire request into a rich query is an equivalence contract at a trust boundary: a client-side proof verifier must interpret a request exactly as the server does, or a proof could verify against a different query than the server answered. Hosting the shared decoders in a neutral crate lets both rs-drive-abci and (in a follow-up) the client-side SDK decoders run the same functions, without making the consensus server depend on SDK-branded code: the new crate's dependencies (dapi-grpc platform+client without transport, dpp, drive/verify, thiserror) are a strict subset of what drive-abci already carries.
1 parent 658aec5 commit 3da51c3

16 files changed

Lines changed: 280 additions & 96 deletions

File tree

‎.github/package-filters/rs-packages-direct.yml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ simple-signer:
8383
strategy-tests:
8484
- packages/strategy-tests/**
8585

86+
platform-query-wire:
87+
- packages/rs-platform-query-wire/**
88+
8689
drive-abci:
8790
- packages/rs-drive-abci/**
8891

‎.github/package-filters/rs-packages-no-workflows.yml‎

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,25 @@ strategy-tests: &strategy-tests
8686
- *simple-signer
8787
- *drive
8888

89+
dapi-grpc: &dapi_grpc
90+
- packages/rs-platform-version/**
91+
- packages/rs-dash-platform-macros/**
92+
- packages/dapi-grpc/src/**
93+
- packages/dapi-grpc/protos/**
94+
- packages/dapi-grpc/build.rs
95+
- packages/dapi-grpc/Cargo.toml
96+
97+
platform-query-wire: &platform_query_wire
98+
- packages/rs-platform-query-wire/**
99+
- *drive
100+
- *dapi_grpc
101+
89102
drive-abci:
90103
- packages/rs-drive-abci/**
91104
- *drive
92105
- *simple-signer
93106
- *strategy-tests
107+
- *platform_query_wire
94108

95109
dash-async: &dash_async
96110
- packages/rs-dash-async/**
@@ -106,14 +120,6 @@ rs-sdk-trusted-context-provider: &sdk_trusted_context_provider
106120
- *context_provider
107121
- *dpp
108122

109-
dapi-grpc: &dapi_grpc
110-
- packages/rs-platform-version/**
111-
- packages/rs-dash-platform-macros/**
112-
- packages/dapi-grpc/src/**
113-
- packages/dapi-grpc/protos/**
114-
- packages/dapi-grpc/build.rs
115-
- packages/dapi-grpc/Cargo.toml
116-
117123
rs-dapi:
118124
- packages/rs-dapi/**
119125
- *dapi_grpc

‎.github/package-filters/rs-packages.yml‎

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,28 @@ strategy-tests: &strategy-tests
102102
- *simple-signer
103103
- *drive
104104

105+
dapi-grpc: &dapi_grpc
106+
- .github/workflows/tests*
107+
- packages/rs-platform-version/**
108+
- packages/rs-dash-platform-macros/**
109+
- packages/dapi-grpc/src/**
110+
- packages/dapi-grpc/protos/**
111+
- packages/dapi-grpc/build.rs
112+
- packages/dapi-grpc/Cargo.toml
113+
114+
platform-query-wire: &platform_query_wire
115+
- .github/workflows/tests*
116+
- packages/rs-platform-query-wire/**
117+
- *drive
118+
- *dapi_grpc
119+
105120
drive-abci:
106121
- .github/workflows/tests*
107122
- packages/rs-drive-abci/**
108123
- *drive
109124
- *simple-signer
110125
- *strategy-tests
126+
- *platform_query_wire
111127

112128
dash-async: &dash_async
113129
- .github/workflows/tests*
@@ -126,15 +142,6 @@ rs-sdk-trusted-context-provider: &sdk_trusted_context_provider
126142
- *context_provider
127143
- *dpp
128144

129-
dapi-grpc: &dapi_grpc
130-
- .github/workflows/tests*
131-
- packages/rs-platform-version/**
132-
- packages/rs-dash-platform-macros/**
133-
- packages/dapi-grpc/src/**
134-
- packages/dapi-grpc/protos/**
135-
- packages/dapi-grpc/build.rs
136-
- packages/dapi-grpc/Cargo.toml
137-
138145
rs-dapi-client: &dapi_client
139146
- .github/workflows/tests*
140147
- packages/rs-dapi-client/**

‎.github/workflows/tests-rs-workspace.yml‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,13 +203,14 @@ jobs:
203203
cargo check -p dapi-grpc --no-default-features --features core,platform,client --locked
204204
cargo check -p drive-proof-verifier --locked
205205
cargo check -p dash-platform-queries --locked
206+
cargo check -p platform-query-wire --locked
206207
# Native graphs: assert the networking transport stack stays out.
207208
# `tonic` itself is present (dapi-grpc's generated client types) but
208209
# without its transport feature — which is exactly what the absence
209210
# of hyper/rustls/tower proves. tokio is deliberately NOT asserted
210211
# absent: dash-context-provider depends on dash-async, which uses it
211212
# on native targets, and that edge predates the queries-crate split.
212-
for native_package in drive-proof-verifier dash-platform-queries; do
213+
for native_package in platform-query-wire drive-proof-verifier dash-platform-queries; do
213214
for banned in hyper rustls tower; do
214215
if cargo tree -p "$native_package" -e normal -i "$banned" 2>/dev/null | grep -q .; then
215216
echo "::error::$banned leaked into $native_package's dependency tree"
@@ -344,6 +345,7 @@ jobs:
344345
--package rs-dapi-client \
345346
--package platform-serialization \
346347
--package dapi-grpc \
348+
--package platform-query-wire \
347349
--package json-schema-compatibility-validator \
348350
--package dashpay-contract \
349351
--package dpns-contract \

‎Cargo.lock‎

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ members = [
77
"packages/rs-dash-platform-macros",
88
"packages/rs-dpp",
99
"packages/rs-drive",
10+
"packages/rs-platform-query-wire",
1011
"packages/rs-platform-value",
1112
"packages/rs-platform-serialization",
1213
"packages/rs-platform-serialization-derive",

‎Dockerfile‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ COPY --parents \
387387
packages/rs-platform-serialization-derive \
388388
packages/rs-platform-version \
389389
packages/rs-platform-versioning \
390+
packages/rs-platform-query-wire \
390391
packages/rs-platform-value-convertible \
391392
packages/rs-platform-wallet-ffi \
392393
packages/rs-drive-abci \
@@ -515,6 +516,7 @@ COPY --parents \
515516
packages/rs-platform-serialization-derive \
516517
packages/rs-platform-version \
517518
packages/rs-platform-versioning \
519+
packages/rs-platform-query-wire \
518520
packages/rs-platform-value-convertible \
519521
packages/rs-platform-wallet-ffi \
520522
packages/rs-drive-abci \
@@ -681,6 +683,7 @@ COPY --parents \
681683
packages/rs-platform-serialization-derive \
682684
packages/rs-platform-version \
683685
packages/rs-platform-versioning \
686+
packages/rs-platform-query-wire \
684687
packages/rs-platform-value-convertible \
685688
packages/rs-platform-wallet-ffi \
686689
packages/rs-unified-sdk-ffi \
@@ -939,6 +942,7 @@ COPY --parents \
939942
packages/rs-platform-serialization-derive \
940943
packages/rs-platform-version \
941944
packages/rs-platform-versioning \
945+
packages/rs-platform-query-wire \
942946
packages/rs-platform-value-convertible \
943947
packages/rs-platform-wallet-ffi \
944948
packages/rs-drive-abci \

‎packages/rs-drive-abci/Cargo.toml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ dapi-grpc = { path = "../dapi-grpc", default-features = false, features = [
4242
"server",
4343
"platform",
4444
] }
45+
platform-query-wire = { path = "../rs-platform-query-wire", default-features = false, features = [
46+
"server",
47+
] }
4548
tracing-subscriber = { version = "0.3.22", default-features = false, features = [
4649
"env-filter",
4750
"ansi",

‎packages/rs-drive-abci/src/error/query.rs‎

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use dpp::ProtocolError;
55
use drive::error::proof::ProofError;
66
use drive::error::query::QuerySyntaxError as SyntaxError;
77
use drive::error::Error as DriveError;
8+
use platform_query_wire::proto_conversions::DecodeError as WireDecodeError;
89
use prost::DecodeError;
910
use tenderdash_abci::proto::abci::ResponseException;
1011

@@ -71,10 +72,56 @@ pub enum QueryError {
7172
ResourceExhausted(String),
7273
}
7374

75+
/// Wire-decode failures from the shared `platform-query-wire` decoders.
76+
/// `InvalidArgument` is malformed wire input; `Unsupported` is a well-formed
77+
/// shape the decoder deliberately refuses (e.g. `ORDER BY` on aggregate
78+
/// keys) and surfaces as `QuerySyntaxError::Unsupported`, the same variant
79+
/// the v1 handler's `not_yet_implemented` path uses. Both carry the message
80+
/// string through unchanged.
81+
impl From<WireDecodeError> for QueryError {
82+
fn from(error: WireDecodeError) -> Self {
83+
match error {
84+
WireDecodeError::InvalidArgument(msg) => QueryError::InvalidArgument(msg),
85+
WireDecodeError::Unsupported(msg) => QueryError::Query(SyntaxError::Unsupported(msg)),
86+
}
87+
}
88+
}
89+
7490
impl From<QueryError> for ResponseException {
7591
fn from(value: QueryError) -> Self {
7692
Self {
7793
error: value.to_string(),
7894
}
7995
}
8096
}
97+
98+
#[cfg(test)]
99+
mod tests {
100+
use super::*;
101+
102+
/// The shared decoder's two variants map onto distinct `QueryError`
103+
/// surfaces and the message text is preserved verbatim. A decoder that
104+
/// later reclassifies a malformed shape as `Unsupported` (or vice versa)
105+
/// changes what clients see, so the mapping is pinned here.
106+
#[test]
107+
fn wire_decode_error_mapping_preserves_variant_and_message() {
108+
let invalid: QueryError = WireDecodeError::InvalidArgument("bad where".to_string()).into();
109+
assert!(
110+
matches!(&invalid, QueryError::InvalidArgument(msg) if msg == "bad where"),
111+
"unexpected: {invalid:?}"
112+
);
113+
114+
let unsupported: QueryError = WireDecodeError::Unsupported(
115+
"ORDER BY on aggregate keys is not yet implemented".to_string(),
116+
)
117+
.into();
118+
assert!(
119+
matches!(
120+
&unsupported,
121+
QueryError::Query(SyntaxError::Unsupported(msg))
122+
if msg == "ORDER BY on aggregate keys is not yet implemented"
123+
),
124+
"unexpected: {unsupported:?}"
125+
);
126+
}
127+
}

‎packages/rs-drive-abci/src/query/document_query/v1/dispatch/chained.rs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use crate::error::query::QueryError;
1212
use crate::error::Error;
1313
use crate::platform_types::platform::Platform;
1414
use crate::platform_types::platform_state::PlatformState;
15-
use crate::query::document_query::v1::conversions;
1615
use crate::query::response_metadata::CheckpointUsed;
1716
use crate::query::QueryValidationResult;
1817
use dapi_grpc::platform::v0::get_documents_request::get_documents_request_v1::{
@@ -36,6 +35,7 @@ use dpp::version::PlatformVersion;
3635
use drive::error::query::QuerySyntaxError;
3736
use drive::query::DriveDocumentQuery;
3837
use drive::util::grove_operations::GroveDBToUse;
38+
use platform_query_wire::proto_conversions as conversions;
3939

4040
impl<C> Platform<C> {
4141
/// Serve a chained-mode v1 request. Runs before select routing:
@@ -120,11 +120,11 @@ impl<C> Platform<C> {
120120

121121
let where_clauses = match conversions::where_clauses_from_proto(proto_where_clauses) {
122122
Ok(c) => c,
123-
Err(e) => return Ok(QueryValidationResult::new_with_error(e)),
123+
Err(e) => return Ok(QueryValidationResult::new_with_error(e.into())),
124124
};
125125
let order_by_clauses = match conversions::order_clauses_from_proto(proto_order_by) {
126126
Ok(c) => c,
127-
Err(e) => return Ok(QueryValidationResult::new_with_error(e)),
127+
Err(e) => return Ok(QueryValidationResult::new_with_error(e.into())),
128128
};
129129

130130
let (_, contract_fetch_info) = check_validation_result_with_data!(

0 commit comments

Comments
 (0)