Skip to content

Commit 02d611a

Browse files
committed
server/index-node : lazy load features from manifest when a subgraph is not deployed
1 parent 87c802a commit 02d611a

File tree

4 files changed

+153
-3
lines changed

4 files changed

+153
-3
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

chain/substreams/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ mod trigger;
77
pub mod block_ingestor;
88
pub mod mapper;
99

10+
pub use crate::chain::Chain;
1011
pub use block_stream::BlockStreamBuilder;
1112
pub use chain::*;
1213
pub use codec::EntityChanges;

server/index-node/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ graph-chain-ethereum = { path = "../../chain/ethereum" }
1414
graph-chain-near = { path = "../../chain/near" }
1515
graph-chain-cosmos = { path = "../../chain/cosmos" }
1616
graph-chain-starknet = { path = "../../chain/starknet" }
17+
graph-chain-substreams = { path = "../../chain/substreams" }
1718
graphql-parser = "0.4.0"
1819
http = "0.2"
1920
hyper = "0.14"

server/index-node/src/resolver.rs

Lines changed: 150 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use graph::blockchain::{Blockchain, BlockchainKind, BlockchainMap};
1111
use graph::components::store::{BlockPtrForNumber, BlockStore, Store};
1212
use graph::components::versions::VERSIONS;
1313
use graph::data::graphql::{object, IntoValue, ObjectOrInterface, ValueMap};
14-
use graph::data::subgraph::status;
14+
use graph::data::subgraph::{status, DeploymentFeatures};
1515
use graph::data::value::Object;
1616
use graph::prelude::*;
1717
use graph_graphql::prelude::{a, ExecutionContext, Resolver};
@@ -468,6 +468,150 @@ impl<S: Store> IndexNodeResolver<S> {
468468
.unwrap_or(r::Value::Null))
469469
}
470470

471+
async fn validate_and_extract_features<C, SgStore>(
472+
subgraph_store: &Arc<SgStore>,
473+
unvalidated_subgraph_manifest: UnvalidatedSubgraphManifest<C>,
474+
) -> Result<DeploymentFeatures, QueryExecutionError>
475+
where
476+
C: Blockchain,
477+
SgStore: SubgraphStore,
478+
{
479+
match unvalidated_subgraph_manifest
480+
.validate(subgraph_store.clone(), false)
481+
.await
482+
{
483+
Ok(subgraph_manifest) => Ok(subgraph_manifest.deployment_features()),
484+
Err(_) => Err(QueryExecutionError::InvalidSubgraphManifest),
485+
}
486+
}
487+
488+
async fn get_features_from_ipfs(
489+
&self,
490+
deployment_hash: &DeploymentHash,
491+
) -> Result<DeploymentFeatures, QueryExecutionError> {
492+
let raw_yaml: serde_yaml::Mapping = {
493+
let file_bytes = self
494+
.link_resolver
495+
.cat(&self.logger, &deployment_hash.to_ipfs_link())
496+
.await
497+
.map_err(SubgraphManifestResolveError::ResolveError)?;
498+
499+
serde_yaml::from_slice(&file_bytes).map_err(SubgraphManifestResolveError::ParseError)?
500+
};
501+
502+
let kind = BlockchainKind::from_manifest(&raw_yaml)
503+
.map_err(SubgraphManifestResolveError::ResolveError)?;
504+
505+
let max_spec_version = ENV_VARS.max_spec_version.clone();
506+
507+
let result = match kind {
508+
BlockchainKind::Ethereum => {
509+
let unvalidated_subgraph_manifest =
510+
UnvalidatedSubgraphManifest::<graph_chain_ethereum::Chain>::resolve(
511+
deployment_hash.clone(),
512+
raw_yaml,
513+
&self.link_resolver,
514+
&self.logger,
515+
max_spec_version,
516+
)
517+
.await?;
518+
519+
Self::validate_and_extract_features(
520+
&self.store.subgraph_store(),
521+
unvalidated_subgraph_manifest,
522+
)
523+
.await?
524+
}
525+
BlockchainKind::Cosmos => {
526+
let unvalidated_subgraph_manifest =
527+
UnvalidatedSubgraphManifest::<graph_chain_cosmos::Chain>::resolve(
528+
deployment_hash.clone(),
529+
raw_yaml,
530+
&self.link_resolver,
531+
&self.logger,
532+
max_spec_version,
533+
)
534+
.await?;
535+
536+
Self::validate_and_extract_features(
537+
&self.store.subgraph_store(),
538+
unvalidated_subgraph_manifest,
539+
)
540+
.await?
541+
}
542+
BlockchainKind::Near => {
543+
let unvalidated_subgraph_manifest =
544+
UnvalidatedSubgraphManifest::<graph_chain_near::Chain>::resolve(
545+
deployment_hash.clone(),
546+
raw_yaml,
547+
&self.link_resolver,
548+
&self.logger,
549+
max_spec_version,
550+
)
551+
.await?;
552+
553+
Self::validate_and_extract_features(
554+
&self.store.subgraph_store(),
555+
unvalidated_subgraph_manifest,
556+
)
557+
.await?
558+
}
559+
BlockchainKind::Arweave => {
560+
let unvalidated_subgraph_manifest =
561+
UnvalidatedSubgraphManifest::<graph_chain_arweave::Chain>::resolve(
562+
deployment_hash.clone(),
563+
raw_yaml,
564+
&self.link_resolver,
565+
&self.logger,
566+
max_spec_version,
567+
)
568+
.await?;
569+
570+
Self::validate_and_extract_features(
571+
&self.store.subgraph_store(),
572+
unvalidated_subgraph_manifest,
573+
)
574+
.await?
575+
}
576+
BlockchainKind::Substreams => {
577+
let unvalidated_subgraph_manifest =
578+
UnvalidatedSubgraphManifest::<graph_chain_substreams::Chain>::resolve(
579+
deployment_hash.clone(),
580+
raw_yaml,
581+
&self.link_resolver,
582+
&self.logger,
583+
max_spec_version,
584+
)
585+
.await?;
586+
587+
Self::validate_and_extract_features(
588+
&self.store.subgraph_store(),
589+
unvalidated_subgraph_manifest,
590+
)
591+
.await?
592+
}
593+
BlockchainKind::Starknet => {
594+
let unvalidated_subgraph_manifest =
595+
UnvalidatedSubgraphManifest::<graph_chain_substreams::Chain>::resolve(
596+
deployment_hash.clone(),
597+
raw_yaml,
598+
&self.link_resolver,
599+
&self.logger,
600+
max_spec_version,
601+
)
602+
.await?;
603+
604+
Self::validate_and_extract_features(
605+
&self.store.subgraph_store(),
606+
unvalidated_subgraph_manifest,
607+
)
608+
.await?
609+
}
610+
};
611+
612+
Ok(result)
613+
}
614+
471615
async fn resolve_subgraph_features(
472616
&self,
473617
field: &a::Field,
@@ -481,9 +625,12 @@ impl<S: Store> IndexNodeResolver<S> {
481625
})?;
482626

483627
let subgraph_store = self.store.subgraph_store();
484-
let deployment_features = subgraph_store.subgraph_features(&deployment_hash).await?;
628+
let features = match subgraph_store.subgraph_features(&deployment_hash).await? {
629+
Some(features) => features,
630+
None => self.get_features_from_ipfs(&deployment_hash).await?,
631+
};
485632

486-
Ok(deployment_features.into_value())
633+
Ok(features.into_value())
487634
}
488635

489636
fn resolve_api_versions(&self, _field: &a::Field) -> Result<r::Value, QueryExecutionError> {

0 commit comments

Comments
 (0)