Skip to content

Commit

Permalink
graphql: Make StoreResolver::at_block only return indexing_error if n…
Browse files Browse the repository at this point in the history
…on-fatal-errors is enabled
  • Loading branch information
evaporei committed Jun 13, 2022
1 parent 367a440 commit 8010fa8
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 12 deletions.
18 changes: 18 additions & 0 deletions store/postgres/src/deployment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,24 @@ pub(crate) fn has_deterministic_errors(
.map_err(|e| e.into())
}

/// Looks for deterministic errors if the subgraph has the non-fatal errors
/// feature enabled.
pub(crate) fn has_non_fatal_errors(
conn: &PgConnection,
site: &Site,
id: &DeploymentHash,
block: Option<BlockNumber>,
) -> Result<bool, StoreError> {
let has_non_fatal_errors_feature =
features(conn, site)?.contains(&SubgraphFeature::NonFatalErrors);

if has_non_fatal_errors_feature {
has_deterministic_errors(conn, id, block)
} else {
Ok(false)
}
}

pub fn update_deployment_status(
conn: &PgConnection,
deployment_id: &DeploymentHash,
Expand Down
7 changes: 5 additions & 2 deletions store/postgres/src/query_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,13 @@ impl QueryStoreTrait for QueryStore {
}

async fn has_non_fatal_errors(&self, block: Option<BlockNumber>) -> Result<bool, StoreError> {
let id = self.site.deployment.clone();
let site = self.site.clone();
let id = site.deployment.clone();

self.store
.with_conn(move |conn, _| {
crate::deployment::has_deterministic_errors(conn, &id, block).map_err(|e| e.into())
crate::deployment::has_non_fatal_errors(conn, &site, &id, block)
.map_err(|e| e.into())
})
.await
}
Expand Down
2 changes: 1 addition & 1 deletion store/postgres/tests/graft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ async fn create_grafted_subgraph(
base_block: BlockPtr,
) -> Result<DeploymentLocator, StoreError> {
let base = Some((DeploymentHash::new(base_id).unwrap(), base_block));
test_store::create_subgraph(subgraph_id, schema, base).await
test_store::create_subgraph(subgraph_id, schema, base, None).await
}

fn find_entities(
Expand Down
69 changes: 65 additions & 4 deletions store/postgres/tests/subgraph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use graph::{
server::index_node::VersionInfo,
store::{DeploymentLocator, StatusStore},
},
data::subgraph::schema::SubgraphHealth,
data::subgraph::schema::{DeploymentCreate, SubgraphError},
data::subgraph::{schema::SubgraphHealth, SubgraphFeature},
prelude::EntityChange,
prelude::EntityChangeOperation,
prelude::QueryStoreManager,
Expand All @@ -20,7 +20,11 @@ use graph::{
use graph_store_postgres::layout_for_tests::Connection as Primary;
use graph_store_postgres::SubgraphStore;

use std::{collections::HashSet, marker::PhantomData, sync::Arc};
use std::{
collections::{BTreeSet, HashSet},
marker::PhantomData,
sync::Arc,
};
use test_store::*;

const SUBGRAPH_GQL: &str = "
Expand Down Expand Up @@ -51,6 +55,17 @@ fn get_version_info(store: &Store, subgraph_name: &str) -> VersionInfo {
store.version_info(&current).unwrap()
}

async fn create_subgraph_with_non_fatal_feature(
subgraph_id: &DeploymentHash,
schema: &str,
) -> DeploymentLocator {
let mut features = BTreeSet::new();
features.insert(SubgraphFeature::NonFatalErrors);
test_store::create_subgraph(subgraph_id, schema, None, Some(features))
.await
.unwrap()
}

#[test]
fn reassign_subgraph() {
async fn setup() -> DeploymentLocator {
Expand Down Expand Up @@ -533,7 +548,7 @@ fn fatal_vs_non_fatal() {
async fn setup() -> DeploymentLocator {
let id = DeploymentHash::new("failUnfail").unwrap();
remove_subgraphs();
create_test_subgraph(&id, SUBGRAPH_GQL).await
create_subgraph_with_non_fatal_feature(&id, SUBGRAPH_GQL).await
}

run_test_sequentially(|store| async move {
Expand Down Expand Up @@ -570,14 +585,60 @@ fn fatal_vs_non_fatal() {
})
}

#[test]
fn has_non_fatal_errors_without_feature() {
async fn setup() -> DeploymentLocator {
let id = DeploymentHash::new("failUnfail").unwrap();
remove_subgraphs();
// Doesn't have any subgraph features.
create_test_subgraph(&id, SUBGRAPH_GQL).await
}

run_test_sequentially(|store| async move {
let deployment = setup().await;
let query_store = store
.query_store(deployment.hash.clone().into(), false)
.await
.unwrap();

let error = || SubgraphError {
subgraph_id: deployment.hash.clone(),
message: "test".to_string(),
block_ptr: Some(BLOCKS[1].clone()),
handler: None,
deterministic: true,
};

store
.subgraph_store()
.writable(LOGGER.clone(), deployment.id)
.await
.expect("can get writable")
.fail_subgraph(error())
.await
.unwrap();

// Returns false because there are no errors.
assert!(!query_store.has_non_fatal_errors(None).await.unwrap());

transact_errors(&store, &deployment, BLOCKS[1].clone(), vec![error()])
.await
.unwrap();

// Still returns false because the subgraph doesn't have
// the NonFatalErrors feature.
assert!(!query_store.has_non_fatal_errors(None).await.unwrap());
})
}

#[test]
fn fail_unfail_deterministic_error() {
const NAME: &str = "failUnfailDeterministic";

async fn setup() -> DeploymentLocator {
let id = DeploymentHash::new(NAME).unwrap();
remove_subgraphs();
create_test_subgraph(&id, SUBGRAPH_GQL).await
create_subgraph_with_non_fatal_feature(&id, SUBGRAPH_GQL).await
}

run_test_sequentially(|store| async move {
Expand Down
17 changes: 12 additions & 5 deletions store/test-store/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@ use graph::log;
use graph::prelude::{QueryStoreManager as _, SubgraphStore as _, *};
use graph::semver::Version;
use graph::{
blockchain::ChainIdentifier, components::store::DeploymentLocator,
components::store::EntityType, components::store::StatusStore,
components::store::StoredDynamicDataSource, data::subgraph::status, prelude::NodeId,
blockchain::ChainIdentifier,
components::store::DeploymentLocator,
components::store::EntityType,
components::store::StatusStore,
components::store::StoredDynamicDataSource,
data::subgraph::{status, SubgraphFeature},
prelude::NodeId,
};
use graph_graphql::prelude::{
execute_query, Query as PreparedQuery, QueryExecutionOptions, StoreResolver,
Expand Down Expand Up @@ -150,13 +154,14 @@ pub async fn create_subgraph(
subgraph_id: &DeploymentHash,
schema: &str,
base: Option<(DeploymentHash, BlockPtr)>,
features: Option<BTreeSet<SubgraphFeature>>,
) -> Result<DeploymentLocator, StoreError> {
let schema = Schema::parse(schema, subgraph_id.clone()).unwrap();

let manifest = SubgraphManifest::<graph_chain_ethereum::Chain> {
id: subgraph_id.clone(),
spec_version: Version::new(1, 0, 0),
features: BTreeSet::new(),
features: features.unwrap_or_default(),
description: Some(format!("manifest for {}", subgraph_id)),
repository: Some(format!("repo for {}", subgraph_id)),
schema: schema.clone(),
Expand Down Expand Up @@ -191,7 +196,9 @@ pub async fn create_subgraph(
}

pub async fn create_test_subgraph(subgraph_id: &DeploymentHash, schema: &str) -> DeploymentLocator {
create_subgraph(subgraph_id, schema, None).await.unwrap()
create_subgraph(subgraph_id, schema, None, None)
.await
.unwrap()
}

pub fn remove_subgraph(id: &DeploymentHash) {
Expand Down

0 comments on commit 8010fa8

Please sign in to comment.