Skip to content

starknet_transaction_prover: avoid redundant request-id re-parse in RequestSpanLayer - #14743

Merged
avi-starkware merged 1 commit into
main-v0.14.3from
claude/perf/starknet-transaction-prover-request-id-reuse-48213
Jul 12, 2026
Merged

starknet_transaction_prover: avoid redundant request-id re-parse in RequestSpanLayer#14743
avi-starkware merged 1 commit into
main-v0.14.3from
claude/perf/starknet-transaction-prover-request-id-reuse-48213

Conversation

@gkaempfer

Copy link
Copy Markdown
Contributor

What

Follow-up perf cleanup to #14222, which added RequestSpanLayer (crates/starknet_transaction_prover/src/server/request_span.rs) below the OHTTP layer to bind a tracing span with a request-id over every HTTP request handled by the transaction-prover server.

For plaintext (non-OHTTP) requests, RequestSpanLayer called extract_or_generate_request_id(&request), which re-parses and re-validates the x-request-id header (UTF-8 conversion, length check, byte-by-byte ASCII-safety scan, String allocation) on every single request — even though the upstream RequestLogLayer (request_log.rs), earlier in the same middleware chain (prover_http_middleware! in server.rs), already computed and validated that exact id moments earlier.

Fix

RequestLogLayer::call now stashes the already-validated id in a new RequestId(String) request extension right after computing it. RequestSpanLayer::call reads that extension first, and only falls back to extract_or_generate_request_id when the extension is absent — e.g. when RequestSpanLayer is exercised standalone in unit tests without RequestLogLayer upstream. The OHTTP-decapsulated branch (fresh envelope-unlinkable id) is untouched — it never reads this extension.

This is safe because request extensions survive MapRequestBodyLayer (http::Request::map preserves them) and the OHTTP layer's non-OHTTP passthrough route (inner.oneshot(request) with the request unchanged), so the extension set by the outer RequestLogLayer reaches the inner RequestSpanLayer unmodified in the production chain.

Tests

  • Added plaintext_prefers_request_id_extension_over_header, which sets the RequestId extension and the x-request-id header to two different values (a state RequestLogLayer never produces in practice) and asserts, via a traced log line emitted inside the span, that the extension's value — not the header's — is what the span carries. This locks in the fast path so a future refactor can't silently regress back to header re-parsing.
  • All pre-existing starknet_transaction_prover / tower_ohttp tests pass (122 passed, 0 regressions; the only failure, test_compiled_class_v1_to_casm_round_trip, is a pre-existing, network-dependent Cairo-compiler-download failure unrelated to this change and reproduces identically on the unmodified base branch).
  • cargo clippy -p starknet_transaction_prover -p tower_ohttp --all-targets is clean.
  • scripts/rust_fmt.sh applied, no outstanding diffs.

An independent Opus review confirmed correctness (no cross-request leak — the extension lives in per-request http::Extensions, not shared service state; OHTTP unlinkability is fully preserved) and flagged two style/coverage suggestions, both addressed in this PR (map_or_else instead of map().unwrap_or_else(), and the extension-vs-header divergence test above).


Generated by Claude Code

…equestSpanLayer

RequestSpanLayer re-parsed and re-validated the x-request-id header on
every plaintext request via extract_or_generate_request_id, even though
RequestLogLayer (upstream in the same chain) already computed and
validated that exact id moments earlier. RequestLogLayer now stashes the
validated id in a RequestId request extension; RequestSpanLayer reads it
directly, falling back to re-deriving it only when used standalone
(e.g. without RequestLogLayer upstream, as in some unit tests).

Follow-up to #14222.
@cursor

cursor Bot commented Jul 9, 2026

Copy link
Copy Markdown

PR Summary

Low Risk
Small middleware optimization with preserved OHTTP unlinkability behavior and a targeted regression test; no auth or data-model changes.

Overview
Plaintext HTTP requests no longer pay a second x-request-id parse/validate in RequestSpanLayer when RequestLogLayer ran first.

RequestLogLayer now inserts a RequestId request extension with the id it already computed. On the non-OHTTP path, RequestSpanLayer clones that extension for the tracing span and only falls back to extract_or_generate_request_id when the extension is missing (e.g. standalone tests). The OHTTP decapsulated branch is unchanged—it still mints a fresh envelope-unlinkable id and does not read this extension.

Adds plaintext_prefers_request_id_extension_over_header, which forces a header/extension mismatch and asserts the span uses the extension value via traced logs.

Reviewed by Cursor Bugbot for commit 981c4c8. Bugbot is set up for automated code reviews on this repo. Configure here.

@reviewable-StarkWare

Copy link
Copy Markdown

This change is Reviewable

@avi-starkware avi-starkware left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm:

@avi-starkware reviewed 3 files and all commit messages, and made 1 comment.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on gkaempfer).

@avi-starkware
avi-starkware added this pull request to the merge queue Jul 12, 2026
Merged via the queue into main-v0.14.3 with commit 8d3a740 Jul 12, 2026
19 checks passed

Copy link
Copy Markdown
Contributor Author

Security scan complete — no issues detected.


Generated by Claude Code

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.

4 participants