Skip to content

Commit f81df1e

Browse files
committed
starknet_transaction_prover: unify HTTP middleware stack via macro
1 parent 9155cef commit f81df1e

2 files changed

Lines changed: 36 additions & 40 deletions

File tree

crates/starknet_transaction_prover/src/server.rs

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,38 @@ pub type OhttpJsonrpseeLayer = OhttpLayer<fn(Full<Bytes>) -> HttpBody>;
2626
/// Pass this to `OhttpLayer::new` when constructing the layer.
2727
pub const OHTTP_JSONRPSEE_BODY_BUILDER: fn(Full<Bytes>) -> HttpBody = HttpBody::new;
2828

29+
/// The production HTTP middleware stack, applied verbatim by both transports:
30+
/// the HTTP path (`start_server`) and the HTTPS path (`tls::start_tls_server`).
31+
///
32+
/// This is a macro rather than a helper function because the value is a deeply
33+
/// nested `ServiceBuilder<Stack<Stack<...>>>` whose type cannot be spelled in a
34+
/// signature. Defining the chain once keeps the two transports from drifting.
35+
///
36+
/// Defined above `pub mod tls;` on purpose: `macro_rules!` scoping is textual, so moving the
37+
/// definition below the module would make it invisible to `tls.rs`. The macro also resolves
38+
/// `ServiceBuilder`, the layer types, and `HttpBody` at each call site (not at the definition),
39+
/// so every caller must have them in scope — adding a layer here adds an import obligation at
40+
/// each call site.
41+
///
42+
/// Layer order (tower makes the last-added layer innermost):
43+
/// - `HealthLayer` sits outermost so `GET /health` is answered before any other middleware runs.
44+
/// - `OhttpLayer` must sit OUTSIDE `CompressionLayer` so compression applies to the inner JSON-RPC
45+
/// response (the client's inner `Accept-Encoding` travels through BHTTP into jsonrpsee) rather
46+
/// than to the OHTTP ciphertext envelope. `MapRequestBodyLayer`/`MapResponseBodyLayer` keep
47+
/// `HttpBody` on both sides of OHTTP to satisfy its symmetric-body bound; `HttpBody::new` is a
48+
/// zero-cost wrapper, so non-OHTTP requests still stream through unbuffered.
49+
macro_rules! prover_http_middleware {
50+
($cors_layer:expr, $ohttp_layer:expr $(,)?) => {
51+
ServiceBuilder::new()
52+
.layer(HealthLayer)
53+
.option_layer($cors_layer)
54+
.layer(MapRequestBodyLayer::new(HttpBody::new))
55+
.option_layer($ohttp_layer)
56+
.layer(MapResponseBodyLayer::new(HttpBody::new))
57+
.layer(CompressionLayer::new())
58+
};
59+
}
60+
2961
pub mod config;
3062
pub mod cors;
3163
pub mod errors;
@@ -64,31 +96,8 @@ pub async fn start_server(
6496
.build();
6597
let server = ServerBuilder::default()
6698
.set_config(server_config)
67-
// `OhttpLayer` must sit OUTSIDE `CompressionLayer` so compression
68-
// applies to the inner JSON-RPC response (the client's inner
69-
// `Accept-Encoding` travels through BHTTP into jsonrpsee) rather than
70-
// to the OHTTP ciphertext envelope. Because tower's `ServiceBuilder`
71-
// makes the last-added layer innermost, `CompressionLayer` is added
72-
// last here.
73-
//
74-
// `MapRequestBodyLayer` wraps hyper's `Request<Incoming>` into
75-
// `Request<HttpBody>` before `OhttpLayer` sees it — `OhttpLayer`'s
76-
// symmetric-body bound requires `B = HttpBody` on both sides.
77-
// `MapResponseBodyLayer` converts `CompressionBody<HttpBody>` back to
78-
// `HttpBody` on the response path so `OhttpLayer` receives the body
79-
// type it expects. `HttpBody::new` is a zero-cost wrapper, so
80-
// non-OHTTP requests still stream through unbuffered.
81-
.set_http_middleware(
82-
// `HealthLayer` sits outermost so `GET /health` is answered
83-
// before any other middleware runs.
84-
ServiceBuilder::new()
85-
.layer(HealthLayer)
86-
.option_layer(cors_layer)
87-
.layer(MapRequestBodyLayer::new(HttpBody::new))
88-
.option_layer(ohttp_layer)
89-
.layer(MapResponseBodyLayer::new(HttpBody::new))
90-
.layer(CompressionLayer::new()),
91-
)
99+
// See `prover_http_middleware!` for the full layer-order rationale.
100+
.set_http_middleware(prover_http_middleware!(cors_layer, ohttp_layer))
92101
.build(&addr)
93102
.await
94103
.context(format!("Failed to bind JSON-RPC server to {addr}"))?;

crates/starknet_transaction_prover/src/server/tls.rs

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -52,23 +52,10 @@ pub async fn start_tls_server(
5252
.max_connections(max_connections)
5353
.max_request_body_size(max_request_body_size)
5454
.build();
55-
// See `server.rs` for the rationale — `OhttpLayer` sits outside `CompressionLayer`
56-
// so compression acts on the inner JSON-RPC response, not on the OHTTP envelope.
57-
// `MapRequestBodyLayer`/`MapResponseBodyLayer` keep `HttpBody` on both sides of
58-
// OHTTP to satisfy its symmetric-body bound.
55+
// See `prover_http_middleware!` for the full layer-order rationale.
5956
let svc_builder = ServerBuilder::default()
6057
.set_config(server_config)
61-
.set_http_middleware(
62-
// `HealthLayer` sits outermost so `GET /health` is answered before
63-
// any other middleware runs.
64-
ServiceBuilder::new()
65-
.layer(HealthLayer)
66-
.option_layer(cors_layer)
67-
.layer(MapRequestBodyLayer::new(HttpBody::new))
68-
.option_layer(ohttp_layer)
69-
.layer(MapResponseBodyLayer::new(HttpBody::new))
70-
.layer(CompressionLayer::new()),
71-
)
58+
.set_http_middleware(prover_http_middleware!(cors_layer, ohttp_layer))
7259
.to_service_builder();
7360

7461
let listener = TcpListener::bind(addr)

0 commit comments

Comments
 (0)