feat(sdk): add transport-free CXX bindings for C++ embedders - #4620
Draft
PastaPastaPasta wants to merge 1 commit into
Draft
feat(sdk): add transport-free CXX bindings for C++ embedders#4620PastaPastaPasta wants to merge 1 commit into
PastaPastaPasta wants to merge 1 commit into
Conversation
packages/rs-platform-cxx (crate dash-platform-cxx) is the C++ embedding surface Dash Core's platform GUI consumes: proof verification over (request bytes, response bytes), DPP identity/document decoding, and state-transition construction with signing delegated to a C++ digest callback so private keys never cross the FFI. It is a thin cxx bridge over the workspace's own crates rather than a reimplementation: verification is drive-proof-verifier's FromProof impls (including the new request-driven FromProof<GetDocumentsRequest>), document assembly is dash-platform-queries' shared DPNS/DashPay builders, and signing implements dpp's Signer trait over the callback, exactly as rs-sdk-ffi does for Swift. Trust boundary, since every input byte comes from an untrusted node and GroveDB replay necessarily runs before the quorum signature check: every extern Rust entry point runs under catch_unwind (cxx turns Result::Err into rust::Error but a panic reaching its shim aborts the embedding process); request/response bytes are capped before prost decoding; set_context records the network's Platform LLMQ type and any proof naming another quorum type is refused before a key lookup, so keys the embedder pushes for other purposes can never sign Platform state; a response claiming an unknown protocol version is refused instead of verified under a guessed one; the signer refuses non-ECDSA key types it cannot produce signatures for; transitions are structure-validated (as dash-sdk does before broadcast) and built under the network's protocol version from set_context rather than this build's latest. Packaging follows the workspace's FFI crates: build.rs stages the generated bridge header, the cxx runtime header and the hand-written signer.h under target/<profile>/include/, so consumers vendor from the workspace root and install that tree plus the static archive. There is no nested manifest or second lockfile. Tests replay drive-proof-verifier's proof-vector corpus directly (the crate's own copies were byte-identical) and cover tampered signature/quorum/block-id/grovedb bytes, every signed metadata field, non-Platform quorum type, unknown protocol version, request/proof identity mismatch, wrong-shape proof, oversized and garbage input; tests/cxx_smoke.cc links and runs against the staged interface from C++ in CI.
Contributor
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueThanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This was referenced Sep 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue being fixed or feature implemented
Third and last PR of the transport-free-embedder series; stacked on #4619 (review the last commit,
feat(sdk): add transport-free CXX bindings for C++ embedders). Supersedes #4416. Draft until #4619 merges.Dash Core's platform GUI (dashpay/dash#7512, #7623 onward) currently carries a private Rust/CXX bridge and pins individual Platform crates. This crate gives Platform ownership of that embedding surface: proof verification, DPP decoding and state-transition construction for an application that owns its own DAPI transport, quorum-key sync and private keys.
The earlier #4416 was withdrawn after review found (a) a malicious
getDocumentsresponse could abort the embedding process before the quorum signature was checked (fixed upstream in #4618), (b)cxxturns a Rust panic into a deterministic process abort and nothing caught them, (c) a second lockfile understandalone/that had already drifted from the workspace pin so the documented--lockedbuild failed, and (d) ~600 lines of test vectors duplicating the proof-verifier corpus.What was done?
packages/rs-platform-cxx(dash-platform-cxx), a thincxxbridge over the workspace's own crates: verification isdrive-proof-verifier'sFromProofimpls including #4619'sFromProof<GetDocumentsRequest>; document assembly isdash-platform-queries' builders; signing is dpp'sSignertrait implemented over a C++ digest callback (WalletSigner) so private keys never cross the FFI; quorum keys and system contracts come from aContextProviderthe embedder feeds from its synced LLMQ state.Trust boundary (every byte is untrusted DAPI output, and grovedb replay necessarily precedes the signature check):
extern "Rust"entry point runs undercatch_unwindand reports a panic asrust::Error;build.rsrefusespanic = "abort"builds, where that guard would be compiled out;verify::MAX_MESSAGE_BYTESbefore decoding; asset-lock transaction/islock bytes at 2 MiB;set_context(network, platform_quorum_type, protocol_version, activation_height)records the network's Platform LLMQ type; a proof naming any other quorum type is refused before its key is looked up, so keys the embedder pushes for other purposes can never sign Platform state.update_quorum_keysreplaces the whole set;set_context, notPlatformVersion::latest();ensure_valid_state_transition_structuredash-sdkruns before broadcast.Packaging follows the workspace's FFI crates: an ordinary member with no nested lockfile (embedders
cargo vendorfrom the root andcargo build -p dash-platform-cxx),build.rsstagesinclude/dash/platform/{ffi.h,signer.h}andinclude/rust/cxx.hundertarget/<profile>/the wayrs-sdk-ffistages its cbindgen header,cxx = "1.0"unpinned.cxxrather than cbindgen because the surface is dominated by nested byte vectors and fallible calls; the README states that trade-off.How Has This Been Tested?
../rs-drive-proof-verifier/tests/vectors: identity nonce, contract nonce, contested active/finished/absent) plus negatives for tampered signature, unknown quorum hash, non-Platform quorum type, tampered block-id hash, tampered grovedb proof, each signed metadata field individually, unknown protocol version, request/proof identity mismatch, wrong-shape proof, oversized and garbage input; byte-exact state-transition builds against the rs-dpp-generated vectors plus non-ECDSA key, wrong signature size, invalid DPNS label refused before signing, signer refusal; decoders incl. oversized input.scripts/cxx-smoke.sh(in CI) compilestests/cxx_smoke.ccagainst the staged headers and archive and runs it: context setup, garbage input throwsrust::Errorrather than aborting, and all fivest_build_*builders driven through the real bridge with a decliningWalletSigner.cargo clippy --all-targets --all-features -- -D warningsandcargo machete: clean. The transport-free CI cut assertshyper/rustls/towerstay out of the crate's tree.Breaking Changes
None for the workspace (new crate). For the Dash Core consumer of the withdrawn #4416:
set_contextgained two parameters andupdate_quorum_keyslost its per-call type;standalone/andinstall.share gone (install from the stagedinclude/andlibdash_platform_cxx.a).Checklist:
For repository code-owners and collaborators only