From 92846351a82c9f9fd6cda6107d24dc1f7de8b071 Mon Sep 17 00:00:00 2001 From: Theo Butler Date: Mon, 2 Dec 2024 10:59:39 -0500 Subject: [PATCH] feat: remove support for API key max_budget (#983) --- src/auth.rs | 13 ++----------- src/client_query.rs | 19 +++---------------- src/config.rs | 4 ++-- src/middleware/require_auth.rs | 6 ++---- src/subgraph_studio.rs | 12 +++++------- 5 files changed, 14 insertions(+), 40 deletions(-) diff --git a/src/auth.rs b/src/auth.rs index 785a7b969..6718c9449 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -4,9 +4,7 @@ use std::{ }; use anyhow::{anyhow, bail, ensure}; -use ordered_float::NotNan; use serde::Deserialize; -use serde_with::serde_as; use thegraph_core::SubgraphId; use tokio::sync::watch; @@ -15,7 +13,6 @@ pub struct AuthSettings { pub key: String, pub user: String, pub authorized_subgraphs: Vec, - pub budget_usd: Option>, } impl AuthSettings { @@ -32,15 +29,11 @@ impl AuthSettings { } } -#[serde_as] #[derive(Clone, Debug, Default, Deserialize)] -pub struct APIKey { +pub struct ApiKey { pub key: String, pub user_address: String, pub query_status: QueryStatus, - #[serde_as(as = "Option>")] - #[serde(rename = "max_budget")] - pub max_budget_usd: Option>, #[serde(default)] pub subgraphs: Vec, #[serde(default)] @@ -61,7 +54,7 @@ pub struct AuthContext { /// This is used to disable the payment requirement on testnets. If `true`, all queries will be /// checked for the `query_status` of their API key. pub payment_required: bool, - pub api_keys: watch::Receiver>, + pub api_keys: watch::Receiver>, pub special_api_keys: Arc>, } @@ -77,7 +70,6 @@ impl AuthContext { key: token.to_string(), user: String::new(), authorized_subgraphs: vec![], - budget_usd: None, }); } @@ -109,7 +101,6 @@ impl AuthContext { key: api_key.key.clone(), user: api_key.user_address.clone(), authorized_subgraphs: api_key.subgraphs.clone(), - budget_usd: api_key.max_budget_usd, }) } } diff --git a/src/client_query.rs b/src/client_query.rs index b08c0e3f9..eea2f441b 100644 --- a/src/client_query.rs +++ b/src/client_query.rs @@ -68,22 +68,9 @@ pub async fn handle_query( let client_request: QueryBody = serde_json::from_reader(payload.reader()).map_err(|err| Error::BadQuery(err.into()))?; - // Calculate the budget for the query let grt_per_usd = *ctx.grt_per_usd.borrow(); let one_grt = NotNan::new(1e18).unwrap(); - let budget = { - let mut budget = *(ctx.budgeter.query_fees_target.0 * grt_per_usd * one_grt) as u128; - if let Some(user_budget_usd) = auth.budget_usd { - // Security: Consumers can and will set their budget to unreasonably high values. - // This `.min` prevents the budget from being set far beyond what it would be - // automatically. The reason this is important is that sometimes queries are - // subsidized, and we would be at-risk to allow arbitrarily high values. - let max_budget = budget * 10; - - budget = (*(user_budget_usd * grt_per_usd * one_grt) as u128).min(max_budget); - } - budget - }; + let budget = *(ctx.budgeter.query_fees_target.0 * grt_per_usd * one_grt) as u128; let (tx, mut rx) = mpsc::channel(1); tokio::spawn( @@ -838,7 +825,7 @@ mod tests { use tower::ServiceExt; use crate::{ - auth::{APIKey, AuthContext, AuthSettings}, + auth::{ApiKey, AuthContext, AuthSettings}, middleware::{legacy_auth_adapter, RequireAuthorizationLayer}, }; @@ -852,7 +839,7 @@ mod tests { if let Some(key) = key { ctx.api_keys = watch::channel(HashMap::from([( key.into(), - APIKey { + ApiKey { key: key.into(), ..Default::default() }, diff --git a/src/config.rs b/src/config.rs index 960373b39..c2ad61e1d 100644 --- a/src/config.rs +++ b/src/config.rs @@ -17,7 +17,7 @@ use thegraph_core::{ }; use url::Url; -use crate::{auth::APIKey, network::subgraph_client::TrustedIndexer}; +use crate::{auth::ApiKey, network::subgraph_client::TrustedIndexer}; /// The Graph Gateway configuration. #[serde_as] @@ -93,7 +93,7 @@ pub enum ApiKeys { special: Vec, }, /// Fixed set of API keys - Fixed(Vec), + Fixed(Vec), } #[derive(Deserialize)] diff --git a/src/middleware/require_auth.rs b/src/middleware/require_auth.rs index a7b9edd96..18d4aa6b4 100644 --- a/src/middleware/require_auth.rs +++ b/src/middleware/require_auth.rs @@ -174,12 +174,11 @@ mod tests { use headers::{Authorization, ContentType, HeaderMapExt}; use http_body_util::BodyExt; use hyper::http; - use ordered_float::NotNan; use tokio::sync::watch; use tokio_test::assert_ready_ok; use super::{AuthContext, AuthSettings, RequireAuthorizationLayer}; - use crate::auth::APIKey; + use crate::auth::ApiKey; fn test_auth_ctx(key: Option<&str>) -> AuthContext { let mut ctx = AuthContext { @@ -190,9 +189,8 @@ mod tests { if let Some(key) = key { ctx.api_keys = watch::channel(HashMap::from([( key.into(), - APIKey { + ApiKey { key: key.into(), - max_budget_usd: Some(NotNan::new(1e3).unwrap()), ..Default::default() }, )])) diff --git a/src/subgraph_studio.rs b/src/subgraph_studio.rs index 572782241..beaa07a8d 100644 --- a/src/subgraph_studio.rs +++ b/src/subgraph_studio.rs @@ -7,13 +7,13 @@ use tokio::{ }; use url::Url; -use crate::auth::{APIKey, QueryStatus}; +use crate::auth::{ApiKey, QueryStatus}; pub async fn api_keys( client: reqwest::Client, url: Url, auth: String, -) -> watch::Receiver> { +) -> watch::Receiver> { let (tx, mut rx) = watch::channel(Default::default()); let mut client = Client { client, url, auth }; tokio::spawn(async move { @@ -44,7 +44,7 @@ struct Client { } impl Client { - async fn fetch_api_keys(&mut self) -> anyhow::Result> { + async fn fetch_api_keys(&mut self) -> anyhow::Result> { #[derive(Deserialize, Debug)] struct _ApiKeys { api_keys: Vec<_ApiKey>, @@ -54,7 +54,6 @@ impl Client { key: String, user_address: String, query_status: QueryStatus, - max_budget: Option, #[serde(default)] subgraphs: Vec, #[serde(default)] @@ -73,12 +72,11 @@ impl Client { .api_keys .into_iter() .map(|api_key| { - let api_key = APIKey { + let api_key = ApiKey { key: api_key.key, user_address: api_key.user_address, query_status: api_key.query_status, domains: api_key.domains, - max_budget_usd: api_key.max_budget.and_then(|b| b.try_into().ok()), subgraphs: api_key .subgraphs .into_iter() @@ -87,7 +85,7 @@ impl Client { }; (api_key.key.clone(), api_key) }) - .collect::>(); + .collect::>(); tracing::info!(api_keys = api_keys.len()); Ok(api_keys)