@@ -11,7 +11,7 @@ use graph::blockchain::{Blockchain, BlockchainKind, BlockchainMap};
11
11
use graph:: components:: store:: { BlockPtrForNumber , BlockStore , Store } ;
12
12
use graph:: components:: versions:: VERSIONS ;
13
13
use graph:: data:: graphql:: { object, IntoValue , ObjectOrInterface , ValueMap } ;
14
- use graph:: data:: subgraph:: status;
14
+ use graph:: data:: subgraph:: { status, DeploymentFeatures } ;
15
15
use graph:: data:: value:: Object ;
16
16
use graph:: prelude:: * ;
17
17
use graph_graphql:: prelude:: { a, ExecutionContext , Resolver } ;
@@ -468,6 +468,150 @@ impl<S: Store> IndexNodeResolver<S> {
468
468
. unwrap_or ( r:: Value :: Null ) )
469
469
}
470
470
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
+
471
615
async fn resolve_subgraph_features (
472
616
& self ,
473
617
field : & a:: Field ,
@@ -481,9 +625,12 @@ impl<S: Store> IndexNodeResolver<S> {
481
625
} ) ?;
482
626
483
627
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
+ } ;
485
632
486
- Ok ( deployment_features . into_value ( ) )
633
+ Ok ( features . into_value ( ) )
487
634
}
488
635
489
636
fn resolve_api_versions ( & self , _field : & a:: Field ) -> Result < r:: Value , QueryExecutionError > {
0 commit comments