Skip to content

Commit

Permalink
refactor: consolidate cost model handling
Browse files Browse the repository at this point in the history
  • Loading branch information
Theodus committed Dec 6, 2024
1 parent c5850cc commit 99edfbc
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 228 deletions.
1 change: 0 additions & 1 deletion src/indexers.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
pub use urls::*;

pub mod cost_models;
pub mod indexing_progress;
pub mod public_poi;
mod urls;
112 changes: 0 additions & 112 deletions src/indexers/cost_models.rs

This file was deleted.

19 changes: 1 addition & 18 deletions src/indexers/urls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,6 @@ pub fn status_url<U: Borrow<Url>>(url: U) -> StatusUrl {
StatusUrl(url)
}

/// Builds the URL to the cost model endpoint of the indexer.
///
/// # Panics
/// The function panics if the URL cannot be built.
pub fn cost_url<U: Borrow<Url>>(url: U) -> CostUrl {
let url = url
.borrow()
.join("cost/")
.expect("failed to build indexer cost URL");
CostUrl(url)
}

/// Newtype wrapper around `Url` to provide type safety.
macro_rules! url_new_type {
($name:ident) => {
Expand Down Expand Up @@ -69,13 +57,12 @@ macro_rules! url_new_type {
}

url_new_type!(StatusUrl);
url_new_type!(CostUrl);

#[cfg(test)]
mod tests {
use url::Url;

use super::{cost_url, status_url};
use super::status_url;

/// Ensure the different URL builder functions accept owned and borrowed URL parameters.
#[test]
Expand All @@ -85,9 +72,5 @@ mod tests {
// Status URL
let _ = status_url(&url);
let _ = status_url(url.clone());

// Cost URL
let _ = cost_url(&url);
let _ = cost_url(url.clone());
}
}
2 changes: 1 addition & 1 deletion src/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ pub use errors::{DeploymentError, SubgraphError};
pub use internal::{Indexing, IndexingId};
pub use service::{NetworkService, ResolvedSubgraphInfo};

pub mod cost_model;
mod errors;
pub mod host_filter;
pub mod indexer_indexing_cost_model_resolver;
pub mod indexer_indexing_poi_blocklist;
pub mod indexer_indexing_poi_resolver;
pub mod indexer_indexing_progress_resolver;
Expand Down
121 changes: 121 additions & 0 deletions src/network/cost_model.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
use std::collections::HashMap;

use anyhow::anyhow;
use thegraph_core::DeploymentId;
use thegraph_graphql_http::{
graphql::{Document, IntoDocument, IntoDocumentWithVariables},
http_client::ReqwestExt,
};
use url::Url;

pub struct CostModelResolver {
http: reqwest::Client,
cache: parking_lot::Mutex<HashMap<DeploymentId, u128>>,
}

impl CostModelResolver {
pub fn new(http: reqwest::Client) -> Self {
Self {
http,
cache: Default::default(),
}
}

pub async fn resolve(
&self,
url: &Url,
indexings: &[DeploymentId],
) -> HashMap<DeploymentId, u128> {
let sources = match self.fetch_cost_model_sources(url, indexings).await {
Ok(sources) => sources,
Err(cost_model_err) => {
tracing::debug!(%url, %cost_model_err);
return self.cache.lock().clone();
}
};

// Only support cost models of the form `default => x;`.
let cost_models: HashMap<DeploymentId, u128> = sources
.into_iter()
.filter_map(|(deployment, src)| Some((deployment, parse_simple_cost_model(&src)?)))
.collect();

*self.cache.lock() = cost_models.clone();
cost_models
}

async fn fetch_cost_model_sources(
&self,
url: &Url,
deployments: &[DeploymentId],
) -> anyhow::Result<HashMap<DeploymentId, String>> {
let url = url.join("cost").map_err(|_| anyhow!("invalid URL"))?;

const QUERY: &str = r#"
query costModels($deployments: [String!]!) {
costModels(deployments: $deployments) {
deployment
model
}
}
"#;
let deployments = deployments.iter().map(|item| item.to_string()).collect();
#[derive(serde::Deserialize)]
#[serde(rename_all = "camelCase")]
struct Response {
cost_models: Vec<CostModelSource>,
}
#[derive(serde::Deserialize)]
pub struct CostModelSource {
pub deployment: DeploymentId,
pub model: String,
}
struct Request {
deployments: Vec<String>,
}
impl IntoDocumentWithVariables for Request {
type Variables = serde_json::Value;
fn into_document_with_variables(self) -> (Document, Self::Variables) {
(
QUERY.into_document(),
serde_json::json!({ "deployments": self.deployments }),
)
}
}
let resp = self
.http
.post(url)
.send_graphql::<Response>(Request { deployments })
.await??;
Ok(resp
.cost_models
.into_iter()
.map(|CostModelSource { deployment, model }| (deployment, model))
.collect())
}
}

fn parse_simple_cost_model(src: &str) -> Option<u128> {
let (_, rest) = src.split_once("default")?;
let (_, rest) = rest.split_once("=>")?;
let (consumed, _) = rest.split_once(";")?;
let token = consumed.trim();
let fee: f64 = token.parse().ok()?;
Some((fee * 1e18) as u128)
}

#[cfg(test)]
mod test {
#[test]
fn parse_simple_cost_model() {
let tests = [
("default => 0;", 0),
("default => 1;", 1000000000000000000),
("default => 0.00001;", 10000000000000),
(" default => 0.004100 ; ", 4100000000000000),
];
for (src, expected) in tests {
assert_eq!(super::parse_simple_cost_model(src), Some(expected));
}
}
}
93 changes: 0 additions & 93 deletions src/network/indexer_indexing_cost_model_resolver.rs

This file was deleted.

2 changes: 1 addition & 1 deletion src/network/internal/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use thegraph_core::alloy::primitives::Address;
use crate::{
config::BlockedIndexer,
network::{
host_filter::HostFilter, indexer_indexing_cost_model_resolver::CostModelResolver,
cost_model::CostModelResolver, host_filter::HostFilter,
indexer_indexing_poi_blocklist::PoiBlocklist, indexer_indexing_poi_resolver::PoiResolver,
indexer_indexing_progress_resolver::IndexingProgressResolver,
version_filter::VersionFilter,
Expand Down
Loading

0 comments on commit 99edfbc

Please sign in to comment.