Skip to content

Promote frontend and harden browser, onion, FFI, and lint checks#661

Merged
RyanKung merged 24 commits into
masterfrom
codex/frontend-extension-typescript
Jul 19, 2026
Merged

Promote frontend and harden browser, onion, FFI, and lint checks#661
RyanKung merged 24 commits into
masterfrom
codex/frontend-extension-typescript

Conversation

@RyanKung

@RyanKung RyanKung commented Jul 8, 2026

Copy link
Copy Markdown
Member

Summary

  • Promote the browser Workbench from examples/frontend into the top-level frontend app, adding Home/Node surfaces, extension-aware navigation, landing assets, and modular Rust-generated theme/style code.
  • Replace checked-in extension JavaScript with strict TypeScript sources for the MV3 service worker, node bridge, wallet bridge, package script, and wallet fixture test harness; wire Biome/TypeScript checks into QACI.
  • Align browser and native onion proxy behavior: TCP-backed HTTPS exits, native/browser exit descriptor compatibility, direct-first-hop route selection with remote relay candidates, HTTP proxy workbench controls, and Docker cluster defaults for proxy testing.
  • Harden Rust runtime surfaces touched by this branch, including SNARK witness/circuit validation, Rust 1.97 toolchain/release build compatibility, removal of the unused LLVM backend, and stricter workspace lint policy.
  • Harden the FFI Python wrapper against null request/provider pointers and cover those failure paths with tests.
  • Enforce missing documentation as a Rust lint across workspace crates, while keeping the protobuf DTO compatibility module as the only documented local exception.

Why

The browser frontend is no longer only an example: it now carries the project landing page, node workbench, and extension UX. That makes the browser/native proxy abstraction, extension packaging path, and repo lint policy part of the main product surface. This PR brings those paths under stricter checks while keeping the native node, browser node, and FFI wrappers aligned around the same runtime behavior.

Validation

  • git diff --check
  • npm run build:frontend-extension-scripts
  • uv run --with web3 --with cffi --with pytest pytest examples/ffi/tests -q
  • cargo check -p rings-core --all-targets
  • cargo check -p rings-core --target wasm32-unknown-unknown --no-default-features --features wasm
  • cargo check -p rings-core --no-default-features --features dummy
  • cargo check -p rings-transport --all-targets
  • cargo check -p rings-transport --target wasm32-unknown-unknown --no-default-features --features web-sys-webrtc
  • cargo check -p rings-transport --no-default-features --features dummy
  • cargo check -p rings-derive -p rings-rpc -p rings-snark -p rings-node
  • cargo check -p rings-node --all-targets

@RyanKung RyanKung changed the title Add strict TypeScript for frontend extension scripts Promote frontend and harden browser onion proxy Jul 15, 2026
@RyanKung RyanKung changed the title Promote frontend and harden browser onion proxy Promote frontend and harden browser, onion, FFI, and lint checks Jul 18, 2026
@RyanKung
RyanKung force-pushed the codex/frontend-extension-typescript branch from dcecc39 to d0b6ffb Compare July 18, 2026 19:29
Comment thread crates/node/src/onion/https/mod.rs Outdated
}
let url = format!("https://{}{}", authority, normalize_path(&request.path)?);
let response = browser_fetch(&url, request, body_limit).await?;
let response = execute_https_request(&url, request, body_limit).await?;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[P1] Bound the exit-side HTTPS fetch lifetime

execute_exit_fetch awaits execute_https_request without an exit-side deadline or abort. The caller's 30-second timeout only removes the client-side pending request; it cannot cancel this task after the frame reaches an exit. In browser mode, fetch can remain pending indefinitely (and the native client has no explicit request timeout), so the _lease at line 564 is retained indefinitely. Repeated stalled targets can therefore exhaust the advertised max_circuits/max_streams limits, or grow without bound when those limits are 0. Please add a bounded timeout with cancellation/AbortController at the exit and cover the timeout path with a regression test.

@rings-auto-reviewer rings-auto-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Request changes: the exit-side HTTPS fetch needs a bounded lifetime and cancellation so stalled targets cannot retain exit leases indefinitely.

}

/// Create a new instance after validating the R1CS and witness shape.
pub fn try_new(r1cs: Arc<R1CS<F>>, witness: Vec<F>) -> Result<Self> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[P2] Do not leave an unchecked public Circuit constructor

try_new now validates the R1CS and witness shape, but the public Circuit::new still constructs the same type without validation. That lets callers create an invalid state and reach StepCircuit::arity, which performs self.r1cs.num_inputs - 1 without a fallible check; malformed public R1CS data can therefore panic in debug builds or produce a bogus arity in release builds. Make the unchecked constructor private/remove it, or make every public construction path return the validation error, and add a regression test for malformed R1CS input.

Comment thread crates/node/src/onion/https/mod.rs Outdated
}
let url = format!("https://{}{}", authority, normalize_path(&request.path)?);
let response = browser_fetch(&url, request, body_limit).await?;
let response = execute_https_request(&url, request, body_limit).await?;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[P2] Reserve the response budget before reading the target body

The remaining byte budget is sampled at line 566, but the response is charged only after execute_https_request has read the complete body at line 572. With a chunked response, every concurrent request can observe the same remaining budget and download that many bytes into its own Vec; only after the target-side work is complete does record_exit_bytes reject all but the first successful charge. This makes max_bytes_per_minute ineffective as a bound on exit-side work and differs from the TCP path, which charges each chunk before forwarding it. Reserve the response budget atomically or charge chunks through the shared accounting gate, and add a concurrent streaming-response regression test.

@rings-auto-reviewer
rings-auto-reviewer Bot dismissed their stale review July 18, 2026 21:10

Fixed in a2fcd44. Native and browser HTTPS exits now have bounded cancellation, response bytes are accounted per chunk, and the strict Rustacean validation suite passes.

@rings-auto-reviewer rings-auto-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Re-review of a2fcd44: no new actionable findings. The previous blockers are closed: native HTTPS exits have a bounded reqwest request timeout, browser exits pass an AbortController signal and abort on timeout, response bytes are charged per chunk through the shared accounting gate, and Circuit construction/deserialization validates the R1CS and witness shape before StepCircuit access. The current QACI and CodeQL checks are green.

@RyanKung
RyanKung marked this pull request as ready for review July 19, 2026 11:07
@cursor

cursor Bot commented Jul 19, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@RyanKung
RyanKung merged commit 017f635 into master Jul 19, 2026
10 checks passed
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.

1 participant