Skip to content

Commit

Permalink
Reject requests for blocks before subgraph minimum
Browse files Browse the repository at this point in the history
  • Loading branch information
Theodus committed Feb 10, 2022
1 parent e9e6f1a commit 94b30d3
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 2 deletions.
3 changes: 3 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,9 @@ async fn handle_subgraph_query_inner(
QueryEngineError::FeesTooHigh(count) => {
format!("No suitable indexer found, {} indexers requesting higher fees for this query", count)
}
QueryEngineError::BlockBeforeMin => {
"Requested block before minimum `startBlock` of subgraph manifest".into()
}
QueryEngineError::MissingBlock(_) => {
"Gateway failed to resolve required blocks".into()
}
Expand Down
23 changes: 21 additions & 2 deletions src/manifest_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub struct SubgraphInfo {
pub deployment: SubgraphDeploymentID,
pub network: String,
pub features: Vec<String>,
pub min_block: u64,
}

pub type SubgraphInfoMap =
Expand Down Expand Up @@ -74,21 +75,31 @@ pub async fn fetch_manifest(
.map_err(|err| (deployment, err.to_string()))?;
let manifest = serde_yaml::from_str::<SubgraphManifest>(&payload)
.map_err(|err| (deployment, err.to_string()))?;
let min_block = manifest
.data_sources
.iter()
.map(|data_source| data_source.source.start_block.unwrap_or(0))
.min()
.unwrap_or(0);
// We are assuming that all `dataSource.network` fields are identical.
// This is guaranteed for now.
let network = manifest
.data_sources
.into_iter()
.filter_map(|data_source| data_source.network)
.map(|data_source| data_source.network)
.next()
.ok_or_else(|| (deployment, "Network not found".to_string()))?;
Ok(SubgraphInfo {
deployment,
network,
min_block,
features: manifest.features,
})
}

// Subgraph manifest schema:
// https://github.com/graphprotocol/graph-node/blob/master/docs/subgraph-manifest.md

#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SubgraphManifest {
Expand All @@ -98,6 +109,14 @@ pub struct SubgraphManifest {
}

#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DataSource {
pub network: Option<String>,
pub network: String,
pub source: EthereumContractSource,
}

#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct EthereumContractSource {
pub start_block: Option<u64>,
}
7 changes: 7 additions & 0 deletions src/query_engine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ pub enum QueryEngineError {
NoIndexerSelected,
FeesTooHigh(usize),
MalformedQuery,
BlockBeforeMin,
MissingBlock(UnresolvedBlock),
}

Expand Down Expand Up @@ -276,6 +277,12 @@ where
let freshness_requirements =
Indexers::freshness_requirements(&mut context, block_resolver).await?;

// Reject queries for blocks before minimum start block of subgraph manifest.
match freshness_requirements.minimum_block {
Some(min_block) if min_block < subgraph.min_block => return Err(BlockBeforeMin),
_ => (),
};

for retry_count in 0..self.config.indexer_selection_retry_limit {
let selection_timer = with_metric(
&METRICS.indexer_selection_duration,
Expand Down
1 change: 1 addition & 0 deletions src/query_engine/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ impl Topology {
query.subgraph = Some(Ptr::new(SubgraphInfo {
deployment: deployment.id,
network: deployment.network,
min_block: 0,
features: vec![],
}));
query
Expand Down

0 comments on commit 94b30d3

Please sign in to comment.