@@ -10,13 +10,12 @@ pub mod status;
1010
1111pub use features:: { SubgraphFeature , SubgraphFeatureValidationError } ;
1212
13- use anyhow:: ensure;
1413use anyhow:: { anyhow, Error } ;
1514use futures03:: { future:: try_join3, stream:: FuturesOrdered , TryStreamExt as _} ;
1615use semver:: Version ;
1716use serde:: { de, ser} ;
1817use serde_yaml;
19- use slog:: { debug , info, Logger } ;
18+ use slog:: { info, Logger } ;
2019use stable_hash:: { FieldAddress , StableHash } ;
2120use stable_hash_legacy:: SequenceNumber ;
2221use std:: { collections:: BTreeSet , marker:: PhantomData } ;
@@ -25,6 +24,7 @@ use wasmparser;
2524use web3:: types:: Address ;
2625
2726use crate :: {
27+ bail,
2828 blockchain:: { BlockPtr , Blockchain , DataSource as _} ,
2929 components:: {
3030 link_resolver:: LinkResolver ,
@@ -41,6 +41,7 @@ use crate::{
4141 offchain:: OFFCHAIN_KINDS , DataSource , DataSourceTemplate , UnresolvedDataSource ,
4242 UnresolvedDataSourceTemplate ,
4343 } ,
44+ ensure,
4445 prelude:: { r, CheapClone , ENV_VARS } ,
4546} ;
4647
@@ -356,7 +357,7 @@ pub enum SubgraphManifestResolveError {
356357 #[ error( "subgraph is not valid YAML" ) ]
357358 InvalidFormat ,
358359 #[ error( "resolve error: {0}" ) ]
359- ResolveError ( anyhow:: Error ) ,
360+ ResolveError ( # [ from ] anyhow:: Error ) ,
360361}
361362
362363/// Data source contexts are conveniently represented as entities.
@@ -496,7 +497,7 @@ pub struct BaseSubgraphManifest<C, S, D, T> {
496497}
497498
498499/// SubgraphManifest with IPFS links unresolved
499- type UnresolvedSubgraphManifest < C > = BaseSubgraphManifest <
500+ pub type UnresolvedSubgraphManifest < C > = BaseSubgraphManifest <
500501 C ,
501502 UnresolvedSchema ,
502503 UnresolvedDataSource < C > ,
@@ -614,35 +615,16 @@ impl<C: Blockchain> SubgraphManifest<C> {
614615 /// Entry point for resolving a subgraph definition.
615616 pub async fn resolve_from_raw (
616617 id : DeploymentHash ,
617- mut raw : serde_yaml:: Mapping ,
618+ raw : serde_yaml:: Mapping ,
618619 resolver : & Arc < dyn LinkResolver > ,
619620 logger : & Logger ,
620621 max_spec_version : semver:: Version ,
621622 ) -> Result < Self , SubgraphManifestResolveError > {
622- // Inject the IPFS hash as the ID of the subgraph into the definition.
623- raw. insert ( "id" . into ( ) , id. to_string ( ) . into ( ) ) ;
624-
625- // Parse the YAML data into an UnresolvedSubgraphManifest
626- let unresolved: UnresolvedSubgraphManifest < C > = serde_yaml:: from_value ( raw. into ( ) ) ?;
627-
628- debug ! ( logger, "Features {:?}" , unresolved. features) ;
623+ let unresolved = UnresolvedSubgraphManifest :: parse ( id, raw) ?;
629624
630625 let resolved = unresolved
631626 . resolve ( resolver, logger, max_spec_version)
632- . await
633- . map_err ( SubgraphManifestResolveError :: ResolveError ) ?;
634-
635- if ( resolved. spec_version < SPEC_VERSION_0_0_7 )
636- && resolved
637- . data_sources
638- . iter ( )
639- . any ( |ds| OFFCHAIN_KINDS . contains ( & ds. kind ( ) ) )
640- {
641- return Err ( SubgraphManifestResolveError :: ResolveError ( anyhow ! (
642- "Offchain data sources not supported prior to {}" ,
643- SPEC_VERSION_0_0_7
644- ) ) ) ;
645- }
627+ . await ?;
646628
647629 Ok ( resolved)
648630 }
@@ -685,15 +667,37 @@ impl<C: Blockchain> SubgraphManifest<C> {
685667 ) -> Result < UnifiedMappingApiVersion , DifferentMappingApiVersions > {
686668 UnifiedMappingApiVersion :: try_from_versions ( self . api_versions ( ) )
687669 }
670+
671+ pub fn template_idx_and_name ( & self ) -> impl Iterator < Item = ( u32 , String ) > + ' _ {
672+ // We cannot include static data sources in the map because a static data source and a
673+ // template may have the same name in the manifest. Duplicated with
674+ // `UnresolvedSubgraphManifest::template_idx_and_name`.
675+ let ds_len = self . data_sources . len ( ) as u32 ;
676+ self . templates
677+ . iter ( )
678+ . map ( |t| t. name ( ) . to_owned ( ) )
679+ . enumerate ( )
680+ . map ( move |( idx, name) | ( ds_len + idx as u32 , name) )
681+ }
688682}
689683
690684impl < C : Blockchain > UnresolvedSubgraphManifest < C > {
685+ pub fn parse (
686+ id : DeploymentHash ,
687+ mut raw : serde_yaml:: Mapping ,
688+ ) -> Result < Self , SubgraphManifestResolveError > {
689+ // Inject the IPFS hash as the ID of the subgraph into the definition.
690+ raw. insert ( "id" . into ( ) , id. to_string ( ) . into ( ) ) ;
691+
692+ serde_yaml:: from_value ( raw. into ( ) ) . map_err ( Into :: into)
693+ }
694+
691695 pub async fn resolve (
692696 self ,
693697 resolver : & Arc < dyn LinkResolver > ,
694698 logger : & Logger ,
695699 max_spec_version : semver:: Version ,
696- ) -> Result < SubgraphManifest < C > , anyhow :: Error > {
700+ ) -> Result < SubgraphManifest < C > , SubgraphManifestResolveError > {
697701 let UnresolvedSubgraphManifest {
698702 id,
699703 spec_version,
@@ -714,14 +718,14 @@ impl<C: Blockchain> UnresolvedSubgraphManifest<C> {
714718 max_spec_version,
715719 id,
716720 spec_version
717- ) ) ;
721+ ) . into ( ) ) ;
718722 }
719723
720724 let ds_count = data_sources. len ( ) ;
721725 if ds_count as u64 + templates. len ( ) as u64 > u32:: MAX as u64 {
722- return Err ( anyhow ! (
723- "Subgraph has too many declared data sources and templates" ,
724- ) ) ;
726+ return Err (
727+ anyhow ! ( "Subgraph has too many declared data sources and templates" , ) . into ( ) ,
728+ ) ;
725729 }
726730
727731 let ( schema, data_sources, templates) = try_join3 (
@@ -754,6 +758,17 @@ impl<C: Blockchain> UnresolvedSubgraphManifest<C> {
754758 ) ;
755759 }
756760
761+ if spec_version < SPEC_VERSION_0_0_7
762+ && data_sources
763+ . iter ( )
764+ . any ( |ds| OFFCHAIN_KINDS . contains ( & ds. kind ( ) ) )
765+ {
766+ bail ! (
767+ "Offchain data sources not supported prior to {}" ,
768+ SPEC_VERSION_0_0_7
769+ ) ;
770+ }
771+
757772 Ok ( SubgraphManifest {
758773 id,
759774 spec_version,
0 commit comments