diff --git a/Cargo.lock b/Cargo.lock index b6a26e3c..015b8beb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2612,7 +2612,6 @@ dependencies = [ "keccak-hash", "lazy_static", "log", - "regex", "reqwest", "secp256k1", "serde", @@ -4629,7 +4628,6 @@ dependencies = [ "hex-literal", "hyper", "indexer-common", - "lazy_static", "log", "once_cell", "prometheus", diff --git a/common/Cargo.toml b/common/Cargo.toml index 354ac151..aa159a67 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -15,7 +15,6 @@ faux = { version = "0.1.10", optional = true } keccak-hash = "0.10.0" lazy_static = "1.4.0" log = "0.4.20" -regex = "1.7.1" reqwest = "0.11.20" secp256k1 = { version = "0.27.0", features = ["recovery"] } serde = { version = "1.0.188", features = ["derive"] } diff --git a/common/src/graphql.rs b/common/src/graphql.rs deleted file mode 100644 index 4a767b13..00000000 --- a/common/src/graphql.rs +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2023-, GraphOps and Semiotic Labs. -// SPDX-License-Identifier: Apache-2.0 - -use std::collections::HashSet; - -use regex::Regex; - -/// There is no convenient function for filtering GraphQL executable documents -/// For sake of simplicity, use regex to filter graphql query string -/// Return original string if the query is okay, otherwise error out with -/// unsupported fields -pub fn filter_supported_fields( - query: &str, - supported_root_fields: &HashSet<&str>, -) -> Result> { - // Create a regex pattern to match the fields not in the supported fields - let re = Regex::new(r"\b(\w+)\s*\{").unwrap(); - let mut unsupported_fields = Vec::new(); - - for cap in re.captures_iter(query) { - if let Some(match_) = cap.get(1) { - let field = match_.as_str(); - if !supported_root_fields.contains(field) { - unsupported_fields.push(field.to_string()); - } - } - } - - if !unsupported_fields.is_empty() { - return Err(unsupported_fields); - } - - Ok(query.to_string()) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_filter_supported_fields_with_valid_fields() { - let supported_fields = vec![ - "indexingStatuses", - "publicProofsOfIndexing", - "entityChangesInBlock", - ] - .into_iter() - .collect::>(); - - let query_string = "{ - indexingStatuses { - subgraph - health - } - publicProofsOfIndexing { - number - } - }"; - - assert_eq!( - filter_supported_fields(query_string, &supported_fields).unwrap(), - query_string.to_string() - ); - } - - #[test] - fn test_filter_supported_fields_with_unsupported_fields() { - let supported_fields = vec![ - "indexingStatuses", - "publicProofsOfIndexing", - "entityChangesInBlock", - ] - .into_iter() - .collect::>(); - - let query_string = "{ - someField { - subfield1 - subfield2 - } - indexingStatuses { - subgraph - health - } - }"; - - let filtered = filter_supported_fields(query_string, &supported_fields); - assert!(filtered.is_err(),); - let errors = filtered.err().unwrap(); - assert_eq!(errors.len(), 1); - assert_eq!(errors.first().unwrap(), &String::from("someField")); - } -} diff --git a/common/src/lib.rs b/common/src/lib.rs index b8e06310..33908443 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -3,7 +3,6 @@ pub mod allocations; pub mod attestations; -pub mod graphql; pub mod network_subgraph; pub mod signature_verification; pub mod types; diff --git a/service/Cargo.toml b/service/Cargo.toml index 8b9e2e17..84c3eaaa 100644 --- a/service/Cargo.toml +++ b/service/Cargo.toml @@ -46,7 +46,6 @@ ethereum-types = "0.14.1" sqlx = { version = "0.7.1", features = ["postgres", "runtime-tokio", "bigdecimal", "rust_decimal", "time"] } alloy-primitives = { version = "0.3.3", features = ["serde"] } alloy-sol-types = "0.3.2" -lazy_static = "1.4.0" [dev-dependencies] faux = "0.1.10" diff --git a/service/src/query_processor.rs b/service/src/query_processor.rs index ae0b683c..19f66141 100644 --- a/service/src/query_processor.rs +++ b/service/src/query_processor.rs @@ -55,10 +55,6 @@ pub enum QueryError { IndexingError, #[error("Bad or invalid entity data found in the subgraph: {}", .0.to_string())] BadData(anyhow::Error), - #[error("Invalid GraphQL query string: {0}")] - InvalidFormat(String), - #[error("Cannot query field: {:#?}", .0)] - UnsupportedFields(Vec), #[error("Unknown error: {0}")] Other(anyhow::Error), } diff --git a/service/src/server/routes/status.rs b/service/src/server/routes/status.rs index 2b2d5d7c..66320dff 100644 --- a/service/src/server/routes/status.rs +++ b/service/src/server/routes/status.rs @@ -1,64 +1,30 @@ // Copyright 2023-, GraphOps and Semiotic Labs. // SPDX-License-Identifier: Apache-2.0 -use std::collections::HashSet; - use axum::{ http::{Request, StatusCode}, response::IntoResponse, Extension, Json, }; -use hyper::body::Bytes; - use reqwest::{header, Client}; use crate::server::ServerOptions; -use indexer_common::graphql::filter_supported_fields; use super::bad_request_response; -lazy_static::lazy_static! { - static ref SUPPORTED_ROOT_FIELDS: HashSet<&'static str> = - vec![ - "indexingStatuses", - "publicProofsOfIndexing", - "entityChangesInBlock", - "blockData", - "cachedEthereumCalls", - "subgraphFeatures", - "apiVersions", - ].into_iter().collect(); -} - // Custom middleware function to process the request before reaching the main handler pub async fn status_queries( Extension(server): Extension, req: Request, ) -> impl IntoResponse { - let body_bytes = hyper::body::to_bytes(req.into_body()).await.unwrap(); - // Read the requested query string - let query_string = match String::from_utf8(body_bytes.to_vec()) { - Ok(s) => s, - Err(e) => return bad_request_response(&e.to_string()), - }; - - // filter supported root fields - let query_string = match filter_supported_fields(&query_string, &SUPPORTED_ROOT_FIELDS) { - Ok(query) => query, - Err(unsupported_fields) => { - return ( - StatusCode::BAD_REQUEST, - format!("Cannot query field: {:#?}", unsupported_fields), - ) - .into_response(); - } - }; - + let req_body = req.into_body(); + // TODO: Extract the incoming GraphQL operation and filter root fields // Pass the modified operation to the actual endpoint + let request = Client::new() .post(&server.graph_node_status_endpoint) - .body(Bytes::from(query_string)) + .body(req_body) .header(header::CONTENT_TYPE, "application/json"); let response: reqwest::Response = match request.send().await {