Skip to content

fix(support): replace monolithic JSON ciphertext requests #1917

Description

@hmzakhalid

Problem

The CRISP server sends every ciphertext to the support server in one JSON request:

CRISP server
  -> POST /run_compute
  -> ciphertext_inputs: [(0x<full ciphertext>, index), ...]

The support endpoint extracts web::Json<ComputeRequest> without a custom JsonConfig. Actix therefore applies its default 2,097,152-byte limit.

A secure-8192 ciphertext is approximately 356 KB in binary form. The JSON API hex-encodes it, which approximately doubles it to 713 KB. As a result:

  • about 3 secure inputs can exceed the current request limit;
  • 500 inputs produce approximately 356 MB of JSON;
  • 1,000 inputs produce approximately 713 MB of JSON.

This blocks realistic CRISP rounds before the RISC Zero guest starts. Raising the JSON limit is not a safe final fix because the sender, HTTP client, Actix extractor, deserializer, and compute process can hold redundant copies of the same data in memory.

This is separate from the RISC Zero stdin encoding issue. The guest now receives raw bincode instead of a second 32-bit-word encoding, but the CRISP-server-to-support-server hop still uses monolithic JSON.

Current code

  • examples/CRISP/server/src/server/program_server_request.rs serializes all ciphertexts as hex in ComputeRequest.
  • crates/support/types/src/lib.rs decodes the same monolithic request.
  • crates/support/app/src/main.rs accepts it as web::Json<ComputeRequest>.

Required design

Replace the monolithic JSON ciphertext array with a bounded transport. The preferred production flow is a small computation manifest that names the ordered Avail-backed input objects. The support server retrieves the bytes and verifies the same commitments and metadata that the guest commits to.

A binary streaming or multipart endpoint can be retained for local development, but it must have explicit limits and must not materialize a hex-expanded copy of the complete round.

Do not solve this only by increasing Actix's JSON limit.

Acceptance criteria

  • The request metadata remains small and has explicit size and input-count limits.
  • A production request can represent at least 1,000 secure-8192 inputs without embedding their bytes in JSON.
  • The support server obtains every input in canonical on-chain order.
  • Each retrieved ciphertext is checked against its published commitment before proving.
  • Slot and parent metadata remain paired with the correct input.
  • Missing, duplicate, reordered, oversized, or commitment-mismatched inputs fail before a Boundless order is submitted.
  • The proving guest still derives the input root and output from the exact bytes it consumes.
  • Tests cover 3 inputs, a large simulated round, partial retrieval, reordering, and commitment mismatch.
  • Documentation states the memory, payload, retry, and availability limits of the selected transport.

Why this matters

The current endpoint can pass single-vote tests while failing immediately in a real secure round. It also makes retrying a compute request expensive and gives an untrusted caller a large-memory allocation surface.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions