Skip to content

refactor(attestation-types): move DstackAttestation, Collateral, QuoteBytes into the no-dcap-qvl crate - #3246

Merged
jackson-harris-iii merged 0 commit into
feat/attestation-types-splitfrom
feat/attestation-types-collateral-quote-move
Aug 1, 2026
Merged

refactor(attestation-types): move DstackAttestation, Collateral, QuoteBytes into the no-dcap-qvl crate#3246
jackson-harris-iii merged 0 commit into
feat/attestation-types-splitfrom
feat/attestation-types-collateral-quote-move

Conversation

@pbeza

@pbeza pbeza commented May 15, 2026

Copy link
Copy Markdown
Contributor

Closes #3268

Pure crate split, no behavior change. Stacked on #3245. Sets up the next PR to drop dcap-qvl from mpc-contract's WASM build graph (currently mpc-contract -> mpc-attestation -> attestation -> dcap-qvl).

What moves into attestation-types

  • DstackAttestation — the wasm-friendly bundle struct (quote, collateral, tcb_info). No methods on the struct itself; the dcap_qvl::verify::verify entry point is a trait method on the attestation side.
  • Collateral — field-for-field mirror of dcap_qvl::QuoteCollateralV3. Borsh wire layout matches the upstream type when dcap-qvl is built with its borsh feature, so on-chain state that previously stored an attestation::collateral::Collateral (newtype around dcap_qvl::QuoteCollateralV3) decodes into this type byte-identical without migration.
  • QuoteBytes — unchanged.

What stays in attestation

  • DstackVerify trait + impl DstackVerify for DstackAttestation, which is the one and only dcap_qvl::verify::verify call site. Defined as a trait because inherent impls on foreign types are forbidden in Rust.
  • collateral_from_dcap / collateral_to_dcap free functions for converting between dcap_qvl::QuoteCollateralV3 and the mirror. Used by off-chain code (tee-authority's PCCS fetch path, integration tests) and re-exported through mpc_attestation so the call sites don't need to add a direct attestation dep.

Why a trait instead of an inherent method

The DstackAttestation struct lives in attestation-types. The verify method requires dcap-qvl (heavy crypto closure). Rust forbids inherent impls on foreign types. A trait lets the verify method be added from attestation (which has the dcap-qvl dep) to a type defined in attestation-types (which doesn't).

Callers using dstack_attestation.verify(...) syntax now need to bring DstackVerify into scope. mpc-attestation does this internally; no other consumers were affected.

Drive-bys

  • IntoContractType<Collateral> / IntoInterfaceType<dtos::Collateral> impls in mpc-contract and mpc-node simplified to direct field assignment (no more Collateral::from(QuoteCollateralV3 { ... })).
  • attestation crate's deps pruned: drops borsh, derive_more, serde, hex, thiserror (no longer used after the body shrank to the trait + conversion helpers); serde_json moved to dev-deps.

WASM size impact

Non-reproducible release-contract profile: 1,470,007 → 1,471,144 bytes (+1,137 bytes / 0.07%). Negligible. The next PR drops dcap-qvl from the contract entirely.

Follow-up

Next PR (C2b): feature-gate mpc-attestation's attestation dep behind local-verify, refactor submit_participant_info to delegate to the verifier contract via Promise + callback, and confirm dcap-qvl drops out of mpc-contract's WASM build graph.

@jackson-harris-iii
jackson-harris-iii force-pushed the feat/attestation-types-collateral-quote-move branch from 7fbf80c to 93c9ab5 Compare August 1, 2026 11:22
@jackson-harris-iii
jackson-harris-iii merged commit 93c9ab5 into feat/attestation-types-split Aug 1, 2026
363 of 421 checks passed
@jackson-harris-iii
jackson-harris-iii force-pushed the feat/attestation-types-split branch from 6d62b22 to 93c9ab5 Compare August 1, 2026 11:22
@jackson-harris-iii
jackson-harris-iii deleted the feat/attestation-types-collateral-quote-move branch August 1, 2026 11:22
andrei-near pushed a commit that referenced this pull request Aug 1, 2026
…back verifier integration

Headline WASM size impact (non-reproducible release-contract profile):

  main baseline:              1,470,007 bytes
  PR C2b (dcap-qvl removed):  1,066,917 bytes
  Delta:                       -403,090 bytes  (-27.4%)

`dcap-qvl`, `ring`, `webpki`, and `x509-cert` are no longer in
`mpc-contract`'s wasm32 dep graph (verified via cargo tree
--target wasm32-unknown-unknown -e no-proc-macro).

Architecture

`submit_participant_info` now dispatches by attestation variant:

- Attestation::Mock — synchronous in-contract validation, same as
  before; returns PromiseOrValue::Value(()).
- Attestation::Dstack — extracts (quote, collateral), stashes a
  PendingAttestation, schedules a cross-contract Promise to
  tee-verifier.near's verify_quote, then resumes in the new
  on_attestation_verified callback with the parsed VerifiedReport.
  The callback runs the post-DCAP checks (RTMR3 replay, app_compose
  validation, image-hash / launcher-hash matching) against fresh
  allowlists from TeeState, then inserts into stored_attestations or
  refunds the deposit on failure. Re-submissions while a prior is
  in flight are rejected (no silent overwrite + deposit loss).

mpc-attestation

- Attestation::verify split into:
  * extract_dcap_inputs(&Attestation) -> Option<(QuoteBytes, Collateral)>
  * finish_verify(&Attestation, &VerifiedReport, ...) -> Result<VerifiedAttestation, _>
- attestation crate dep gated behind new `local-verify` feature.
  mpc-contract doesn't enable it; off-chain consumers (tee-authority,
  attestation-cli) do.
- DstackVerify::verify (the dcap-qvl-using call) stays in the
  attestation crate as a trait method on the now-foreign
  DstackAttestation struct.

mpc-contract state shape

- New pending_attestations: IterableMap<AccountId, PendingAttestation>
  field. Storage prefix StorageKey::PendingAttestations (appended;
  back-compat preserved).
- v3_9_1_state migration initializes pending_attestations empty.

Per-network verifier account

- VERIFIER_ACCOUNT_ID hardcoded: tee-verifier.near (mainnet default)
  or tee-verifier.testnet (cfg(not(feature = "mainnet"))).
- Sandbox builds disable default features to opt into testnet name.

Known follow-up in this same PR

Compile passes for wasm32 (mpc-contract proper). Tests across
mpc-contract, attestation-cli, tee-authority, and mpc-attestation/tests
still call the deleted Attestation::verify / TeeState::add_participant
APIs. Fixing them mechanically is the next commit on this branch.

Stacked on #3246.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants