Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughThis PR removes the REST HTTP API, retaining only JSON-RPC endpoints plus a simple /is_alive route. HTTP endpoint wrappers in accounts and dump_load are deleted; their internal impl functions remain. The server is simplified to serve only JSON-RPC, with related routing, middleware checks, and HTTP handlers removed. Restrictive mode now validates only JSON-RPC methods, dropping URI-based restrictions. CLI restricted-methods validation is updated accordingly. JSON-RPC get_devnet_config now returns StrictRpcResult. Main startup switches to serve_http_json_rpc. Tests are updated to drop HTTP GET flows and use JSON-RPC equivalents; helper traits and HTTP-focused utilities are removed. Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Pre-merge checks (4 passed, 1 warning)❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
crates/starknet-devnet/src/cli.rs (1)
712-729: Update tests to JSON-RPC-only expectations.Tests still assert mixed “JSON-RPC methods or HTTP routes” and accept “/mint”. With HTTP routes removed, these will fail. Adjust assertions and inputs to JSON-RPC names only.
- assert!(err.to_string().contains( - "Restricted methods contain unsupported JSON-RPC methods or HTTP routes: \ - devnet_loadd, xyz" - )); + assert!(err.to_string().contains( + "Restricted methods contain unsupported JSON-RPC methods: devnet_loadd, xyz" + )); @@ - Args::parse_from(["--", "--restrictive-mode", "devnet_dump", "/mint"]).to_config().unwrap(); + Args::parse_from([ + "--", "--restrictive-mode", + "devnet_dump", + "devnet_getPredeployedAccounts" + ]).to_config().unwrap();If preferred, replace devnet_dump/devnet_getPredeployedAccounts with any guaranteed-present JSON-RPC methods.
crates/starknet-devnet-server/src/api/http/endpoints/accounts.rs (1)
22-34: Drop unnecessary async to avoid awaiting while holding the Starknet lockget_balance_unit is synchronous; making it async forces awaiting inside get_predeployed_accounts_impl while the mutex is held. Prefer a plain function to reduce overhead and future deadlock risk if awaits are added later.
-pub(crate) async fn get_balance_unit( +pub(crate) fn get_balance_unit( starknet: &mut Starknet, address: ContractAddress, unit: FeeUnit, ) -> HttpApiResult<AccountBalanceResponse> { @@ - let eth = get_balance_unit(&mut starknet, account.address, FeeUnit::WEI).await?; - let strk = get_balance_unit(&mut starknet, account.address, FeeUnit::FRI).await?; + let eth = get_balance_unit(&mut starknet, account.address, FeeUnit::WEI)?; + let strk = get_balance_unit(&mut starknet, account.address, FeeUnit::FRI)?;Also applies to: 54-58
crates/starknet-devnet-server/src/server.rs (1)
45-55: Re-enable a sane body limit and allow OPTIONS for CORS preflightDisabling the default body limit plus logging can amplify memory risk on large payloads. Set a reasonable cap (e.g., 10 MiB) and explicitly allow OPTIONS for browser preflight.
- .layer(TimeoutLayer::new(Duration::from_secs(server_config.timeout.into()))) - .layer(DefaultBodyLimit::disable()) + .layer(TimeoutLayer::new(Duration::from_secs(server_config.timeout.into()))) + .layer(DefaultBodyLimit::max(10 * 1024 * 1024)) // 10 MiB .layer( // More details: https://docs.rs/tower-http/latest/tower_http/cors/index.html CorsLayer::new() .allow_origin(HeaderValue::from_static("*")) .allow_headers(vec![header::CONTENT_TYPE]) - .allow_methods(vec![Method::GET, Method::POST]), + .allow_methods(vec![Method::GET, Method::POST, Method::OPTIONS]), );
🧹 Nitpick comments (15)
crates/starknet-devnet-server/src/restrictive_mode.rs (4)
25-30: Prefer &str (and optionally a Set) for membership checksAccepting &String needlessly constrains callers and causes extra allocations at call sites. Use &str and iterate, or switch to a HashSet for O(1) lookups.
-pub(crate) fn is_json_rpc_method_restricted( - json_rpc_method: &String, - restricted_methods: &[String], -) -> bool { - restricted_methods.contains(json_rpc_method) -} +pub(crate) fn is_json_rpc_method_restricted( + json_rpc_method: &str, + restricted_methods: &[String], +) -> bool { + restricted_methods.iter().any(|m| m == json_rpc_method) +}Optional follow-up: keep DEFAULT_RESTRICTED_JSON_RPC_METHODS as a HashSet<&'static str> (once_cell::sync::Lazy) for faster membership tests.
41-47: Fix method name typo in the ad-hoc list"devnet_CreateBlocks" likely meant "devnet_createBlock". Avoid subtle test confusion from near-miss names.
- &(["devnet_abortBlocks", "devnet_CreateBlocks", "devnet_mint"] + &(["devnet_abortBlocks", "devnet_createBlock", "devnet_mint"]
52-54: Non-restricted sample: consider a known valid methodUsing a method that might not exist (e.g., devnet_getAccountBalance) can mislead future readers. Prefer a known, allowed RPC such as "starknet_chainId".
- assert_is_not_restricted("devnet_getAccountBalance", &DEFAULT_RESTRICTED_JSON_RPC_METHODS); + assert_is_not_restricted("starknet_chainId", &DEFAULT_RESTRICTED_JSON_RPC_METHODS);
64-69: Remove gratuitous allocations in test helpersWith the fn signature change to &str, you can avoid to_string() in tests.
- assert!(is_json_rpc_method_restricted(&method.to_string(), restricted_methods)); + assert!(is_json_rpc_method_restricted(method, restricted_methods)); @@ - assert!(!is_json_rpc_method_restricted(&method.to_string(), restricted_methods)); + assert!(!is_json_rpc_method_restricted(method, restricted_methods));crates/starknet-devnet-server/src/api/http/endpoints/dump_load.rs (1)
2-2: HTTP-typed result in a post-HTTP worldThis impl still returns HttpApiResult/HttpApiError from a module under api/http, but REST wrappers are gone. Consider moving dump_impl to a transport-agnostic module (e.g., api/ops or api/internal) and return a common ApiError/Result so JSON-RPC can use it without HTTP coupling.
tests/integration/test_restrictive_mode.rs (1)
12-12: Strengthen the positive-case assertion (optional)You can assert a known field from devnet_getConfig to prove functionality beyond mere success, e.g., check presence of "chainId" or configured flags. If not needed, current check is fine.
crates/starknet-devnet/src/main.rs (3)
333-349: Server startup flow LGTM, but minor ergonomics nit.Spawning the server with with_graceful_shutdown is correct. Consider logging “JSON-RPC only” to make the breaking change explicit to users when Devnet starts.
- info!("Starknet Devnet listening on {}", address); + info!("Starknet Devnet listening on {} (JSON-RPC only)", address);
370-399: Unify signal handling to a portable form.The per-OS signal branching works, but you can simplify and avoid subtle platform quirks by using the cross-platform tokio::signal::ctrl_c() directly in select.
- #[cfg(unix)] - let mut sigint = { signal(SignalKind::interrupt()).expect("Failed to setup SIGINT handler") }; - - #[cfg(windows)] - let mut sigint = { - let ctrl_c_signal = ctrl_c().expect("Failed to setup Ctrl+C handler"); - Box::pin(ctrl_c_signal) - }; + // Cross-platform ctrl-c listener (works on Unix and Windows) + let mut ctrlc = tokio::signal::ctrl_c(); @@ - _ = sigint.recv() => { + _ = &mut ctrlc => { return Ok(()) }
379-393: Add a request timeout to the internal reqwest client.Without a timeout, the periodic POST to self could hang indefinitely under transient issues. Use a small timeout (e.g., server_config.timeout) to fail fast.
- let devnet_client = reqwest::Client::new(); + let devnet_client = reqwest::Client::builder() + .timeout(std::time::Duration::from_secs(10)) + .build() + .expect("Failed to build reqwest client");If you prefer wiring the CLI timeout, pass it via ServerConfig and reuse here.
crates/starknet-devnet-server/src/api/json_rpc/endpoints.rs (1)
20-21: Decouple JSON-RPC from the http module type.get_devnet_config constructs DevnetConfig from crate::api::http::endpoints::DevnetConfig. Since HTTP surface is being removed, consider relocating DevnetConfig to a transport-agnostic module (e.g., crate::api::models) to avoid coupling JSON-RPC to http::*.
-use crate::api::http::endpoints::DevnetConfig; +use crate::api::models::DevnetConfig; // move the type to a shared/models modulecrates/starknet-devnet/src/cli.rs (1)
303-327: Validation logic simplified to JSON-RPC only — good; small perf/readability nit.For large lists, converting json_rpc_methods to a HashSet avoids O(n²) contains checks and clarifies intent.
- let json_rpc_methods = JsonRpcRequest::all_variants_serde_renames(); + let json_rpc_methods: std::collections::HashSet<_> = + JsonRpcRequest::all_variants_serde_renames().into_iter().collect(); @@ - if !json_rpc_methods.contains(method) { + if !json_rpc_methods.contains(method.as_str()) { wrong_restricted_methods.push(method.clone()); }crates/starknet-devnet-server/src/api/http/endpoints/accounts.rs (1)
10-12: Consider decoupling result/error types from “http” now that REST endpoints are goneThese impls return HttpApiResult/HttpApiError despite no remaining HTTP surface. Suggest introducing a crate-level ApiResult (and From conversions to RPC errors) to avoid leaking HTTP semantics into internal logic.
Also applies to: 74-95
crates/starknet-devnet-server/src/server.rs (2)
31-39: Harden /is_alive and support HEADReturn an explicit status and add HEAD for common load balancers and k8s probes. Keeps GET body simple and content-type implicit via status.
-use axum::routing::{IntoMakeService, get, post}; +use axum::routing::{IntoMakeService, get, head, post}; @@ - let mut routes = Router::new() - .route("/is_alive", get(|| async { "Alive!!!" }))// Only REST endpoint to simplify liveness probe + let mut routes = Router::new() + .route( + "/is_alive", + get(|| async { StatusCode::OK }).head(|| async { StatusCode::OK }), + ) // Only REST endpoint to simplify liveness probe .merge(json_rpc_routes(json_rpc_handler.clone())) .layer(TraceLayer::new_for_http());
101-113: Response/request body logging collects entire bodies; consider samplingCollecting full bodies can be expensive and can break streaming in other contexts. Consider capping logged bytes, redacting large payloads, or making logging opt-in per request header.
crates/starknet-devnet-server/src/api/http/endpoints/mod.rs (1)
6-12: Module naming still implies HTTP; consider relocating helpersWith REST removed, keeping helper modules under api::http is misleading. Consider moving accounts/mint_token helpers to a shared/internal module (e.g., api::helpers or domain::accounts).
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
crates/starknet-devnet-server/src/api/http/endpoints/accounts.rs(1 hunks)crates/starknet-devnet-server/src/api/http/endpoints/dump_load.rs(1 hunks)crates/starknet-devnet-server/src/api/http/endpoints/mod.rs(1 hunks)crates/starknet-devnet-server/src/api/json_rpc/endpoints.rs(2 hunks)crates/starknet-devnet-server/src/restrictive_mode.rs(1 hunks)crates/starknet-devnet-server/src/server.rs(2 hunks)crates/starknet-devnet/src/cli.rs(2 hunks)crates/starknet-devnet/src/main.rs(2 hunks)tests/integration/common/errors.rs(0 hunks)tests/integration/common/reqwest_client.rs(0 hunks)tests/integration/test_account_selection.rs(0 hunks)tests/integration/test_minting.rs(0 hunks)tests/integration/test_restrictive_mode.rs(1 hunks)
💤 Files with no reviewable changes (4)
- tests/integration/common/errors.rs
- tests/integration/test_minting.rs
- tests/integration/test_account_selection.rs
- tests/integration/common/reqwest_client.rs
🔇 Additional comments (9)
crates/starknet-devnet-server/src/restrictive_mode.rs (1)
56-61: Nice: runtime guard that restricted methods actually existThis protects against drift between constants and serde renames. LGTM.
crates/starknet-devnet-server/src/api/http/endpoints/dump_load.rs (1)
7-35: Lock scoping looks good; error surface is clearReleasing starknet lock before acquiring dumpable_events avoids lock contention; error mapping is straightforward. LGTM.
crates/starknet-devnet/src/main.rs (1)
14-14: Good switch to JSON-RPC-only server entrypoint.Main now depends solely on serve_http_json_rpc, aligning with the PR goal to remove non-RPC logic.
crates/starknet-devnet-server/src/api/json_rpc/endpoints.rs (2)
664-671: Return type change to StrictRpcResult is correct.The endpoint now matches the rest of the JSON-RPC handlers that return StrictRpcResult, simplifying error handling.
509-513: Verify MSRV for Option::is_none_or usage.is_none_or is relatively new. If the project enforces an MSRV older than its stabilization, replace with map_or for compatibility.
- .is_none_or(|token| token.starts_with(CONTINUATION_TOKEN_ORIGIN_PREFIX)) + .as_ref().map_or(true, |token| token.starts_with(CONTINUATION_TOKEN_ORIGIN_PREFIX))Would you like me to sweep the repo for other recent-stdlib usages against your MSRV?
crates/starknet-devnet/src/cli.rs (1)
198-202: Docstring update to devnet_createBlock is spot-on.Accurately reflects the removal of the POST /create_block route.
crates/starknet-devnet-server/src/api/http/endpoints/accounts.rs (2)
22-34: Confirm use of BlockTag::PreConfirmed for balancesget_balance_unit uses PreConfirmed while get_account_balance_impl defaults to Latest. If intentional (e.g., stable balances for predeployed accounts), document it; otherwise align tags for consistency.
41-51: Double-check exposure of private_key in SerializableAccountWith HTTP removed, ensure any RPC that consumes this still intends to expose private_key. If no longer needed externally, omit it from the response type.
crates/starknet-devnet-server/src/api/http/endpoints/mod.rs (1)
6-12: Public module items inaccountsandmint_tokenare all referenced by HTTP and JSON-RPC endpoints. No dead code removal needed.
cb816e1 to
329517a
Compare
Co-authored-by: FabijanC <fc@spaceshard.io>
|
Applied all review suggestions! |
Usage related changes
Resolves #837.
This is a breaking change, all non-RPC calls (except liveness check) are removed and users MUST use JSON RPC equivalents from
devnetnamespace.Development related changes
None
Checklist:
./scripts/format.sh./scripts/clippy_check.sh./scripts/check_unused_deps.sh./scripts/check_spelling.sh./website/README.mdAfter this is merged, small refactor of starknet-devnet-server crate would be nice, as there isn't two separate APIs anymore, but code is still split between the two.
Summary by CodeRabbit
Breaking Changes
New Features
Documentation
Tests