@@ -5,7 +5,7 @@ use graph::data::query::Trace;
5
5
use web3:: types:: Address ;
6
6
7
7
use graph:: blockchain:: { Blockchain , BlockchainKind , BlockchainMap } ;
8
- use graph:: components:: store:: { BlockStore , EntityType , Store } ;
8
+ use graph:: components:: store:: { BlockPtrForNumber , BlockStore , EntityType , Store } ;
9
9
use graph:: components:: versions:: VERSIONS ;
10
10
use graph:: data:: graphql:: { object, IntoValue , ObjectOrInterface , ValueMap } ;
11
11
use graph:: data:: subgraph:: status;
@@ -15,6 +15,9 @@ use graph_graphql::prelude::{a, ExecutionContext, Resolver};
15
15
16
16
use crate :: auth:: PoiProtection ;
17
17
18
+ /// Timeout for calls to fetch the block from JSON-RPC or Firehose.
19
+ const BLOCK_HASH_FROM_NUMBER_TIMEOUT : Duration = Duration :: from_secs ( 10 ) ;
20
+
18
21
#[ derive( Clone , Debug ) ]
19
22
struct PublicProofOfIndexingRequest {
20
23
pub deployment : DeploymentHash ,
@@ -212,62 +215,10 @@ impl<S: Store> IndexNodeResolver<S> {
212
215
. get_required :: < BlockNumber > ( "blockNumber" )
213
216
. expect ( "Valid blockNumber required" ) ;
214
217
215
- macro_rules! try_resolve_for_chain {
216
- ( $typ: path ) => {
217
- let blockchain = self . blockchain_map. get:: <$typ>( network. to_string( ) ) . ok( ) ;
218
-
219
- if let Some ( blockchain) = blockchain {
220
- debug!(
221
- self . logger,
222
- "Fetching block hash from number" ;
223
- "network" => & network,
224
- "block_number" => block_number,
225
- ) ;
226
-
227
- let block_ptr_res = blockchain
228
- . block_pointer_from_number( & self . logger, block_number)
229
- . await ;
230
-
231
- if let Err ( e) = block_ptr_res {
232
- warn!(
233
- self . logger,
234
- "Failed to fetch block hash from number" ;
235
- "network" => & network,
236
- "chain" => <$typ as Blockchain >:: KIND . to_string( ) ,
237
- "block_number" => block_number,
238
- "error" => e. to_string( ) ,
239
- ) ;
240
- return Ok ( r:: Value :: Null ) ;
241
- }
242
-
243
- let block_ptr = block_ptr_res. unwrap( ) ;
244
- return Ok ( r:: Value :: String ( block_ptr. hash_hex( ) ) ) ;
245
- }
246
- } ;
218
+ match self . block_ptr_for_number ( network, block_number) . await ? {
219
+ Some ( block_ptr) => Ok ( r:: Value :: String ( block_ptr. hash_hex ( ) ) ) ,
220
+ None => Ok ( r:: Value :: Null ) ,
247
221
}
248
-
249
- // Ugly, but we can't get back an object trait from the `BlockchainMap`,
250
- // so this seems like the next best thing.
251
- try_resolve_for_chain ! ( graph_chain_ethereum:: Chain ) ;
252
- try_resolve_for_chain ! ( graph_chain_arweave:: Chain ) ;
253
- try_resolve_for_chain ! ( graph_chain_cosmos:: Chain ) ;
254
- try_resolve_for_chain ! ( graph_chain_near:: Chain ) ;
255
-
256
- // If you're adding support for a new chain and this `match` clause just
257
- // gave you a compiler error, then this message is for you! You need to
258
- // add a new `try_resolve!` macro invocation above for your new chain
259
- // type.
260
- match BlockchainKind :: Ethereum {
261
- // Note: we don't actually care about substreams here.
262
- BlockchainKind :: Substreams
263
- | BlockchainKind :: Arweave
264
- | BlockchainKind :: Ethereum
265
- | BlockchainKind :: Cosmos
266
- | BlockchainKind :: Near => ( ) ,
267
- }
268
-
269
- // The given network does not exist.
270
- Ok ( r:: Value :: Null )
271
222
}
272
223
273
224
async fn resolve_cached_ethereum_calls (
@@ -405,7 +356,7 @@ impl<S: Store> IndexNodeResolver<S> {
405
356
Ok ( poi)
406
357
}
407
358
408
- fn resolve_public_proofs_of_indexing (
359
+ async fn resolve_public_proofs_of_indexing (
409
360
& self ,
410
361
field : & a:: Field ,
411
362
) -> Result < r:: Value , QueryExecutionError > {
@@ -420,41 +371,41 @@ impl<S: Store> IndexNodeResolver<S> {
420
371
return Err ( QueryExecutionError :: TooExpensive ) ;
421
372
}
422
373
423
- Ok ( r:: Value :: List (
424
- requests
425
- . into_iter ( )
426
- . map ( |request| {
427
- match futures:: executor:: block_on (
428
- self . store . get_public_proof_of_indexing (
429
- & request. deployment ,
430
- request. block_number ,
431
- ) ,
432
- ) {
433
- Ok ( Some ( poi) ) => ( Some ( poi) , request) ,
434
- Ok ( None ) => ( None , request) ,
435
- Err ( e) => {
436
- error ! (
437
- self . logger,
438
- "Failed to query public proof of indexing" ;
439
- "subgraph" => & request. deployment,
440
- "block" => format!( "{}" , request. block_number) ,
441
- "error" => format!( "{:?}" , e)
442
- ) ;
443
- ( None , request)
444
- }
445
- }
446
- } )
447
- . map ( |( poi_result, request) | PublicProofOfIndexingResult {
374
+ let mut public_poi_results = vec ! [ ] ;
375
+ for request in requests {
376
+ let ( poi_result, request) = match self
377
+ . store
378
+ . get_public_proof_of_indexing ( & request. deployment , request. block_number , self )
379
+ . await
380
+ {
381
+ Ok ( Some ( poi) ) => ( Some ( poi) , request) ,
382
+ Ok ( None ) => ( None , request) ,
383
+ Err ( e) => {
384
+ error ! (
385
+ self . logger,
386
+ "Failed to query public proof of indexing" ;
387
+ "subgraph" => & request. deployment,
388
+ "block" => format!( "{}" , request. block_number) ,
389
+ "error" => format!( "{:?}" , e)
390
+ ) ;
391
+ ( None , request)
392
+ }
393
+ } ;
394
+
395
+ public_poi_results. push (
396
+ PublicProofOfIndexingResult {
448
397
deployment : request. deployment ,
449
398
block : match poi_result {
450
399
Some ( ( ref block, _) ) => block. clone ( ) ,
451
400
None => PartialBlockPtr :: from ( request. block_number ) ,
452
401
} ,
453
402
proof_of_indexing : poi_result. map ( |( _, poi) | poi) ,
454
- } )
455
- . map ( IntoValue :: into_value)
456
- . collect ( ) ,
457
- ) )
403
+ }
404
+ . into_value ( ) ,
405
+ )
406
+ }
407
+
408
+ Ok ( r:: Value :: List ( public_poi_results) )
458
409
}
459
410
460
411
fn resolve_indexing_status_for_version (
@@ -517,6 +468,85 @@ impl<S: Store> IndexNodeResolver<S> {
517
468
. collect ( ) ,
518
469
) )
519
470
}
471
+
472
+ async fn block_ptr_for_number (
473
+ & self ,
474
+ network : String ,
475
+ block_number : BlockNumber ,
476
+ ) -> Result < Option < BlockPtr > , QueryExecutionError > {
477
+ macro_rules! try_resolve_for_chain {
478
+ ( $typ: path ) => {
479
+ let blockchain = self . blockchain_map. get:: <$typ>( network. to_string( ) ) . ok( ) ;
480
+
481
+ if let Some ( blockchain) = blockchain {
482
+ debug!(
483
+ self . logger,
484
+ "Fetching block hash from number" ;
485
+ "network" => & network,
486
+ "block_number" => block_number,
487
+ ) ;
488
+
489
+ let block_ptr_res = tokio:: time:: timeout( BLOCK_HASH_FROM_NUMBER_TIMEOUT , blockchain
490
+ . block_pointer_from_number( & self . logger, block_number)
491
+ . map_err( Error :: from) )
492
+ . await
493
+ . map_err( Error :: from)
494
+ . and_then( |x| x) ;
495
+
496
+ if let Err ( e) = block_ptr_res {
497
+ warn!(
498
+ self . logger,
499
+ "Failed to fetch block hash from number" ;
500
+ "network" => & network,
501
+ "chain" => <$typ as Blockchain >:: KIND . to_string( ) ,
502
+ "block_number" => block_number,
503
+ "error" => e. to_string( ) ,
504
+ ) ;
505
+ return Ok ( None ) ;
506
+ }
507
+
508
+ let block_ptr = block_ptr_res. unwrap( ) ;
509
+ return Ok ( Some ( block_ptr) ) ;
510
+ }
511
+ } ;
512
+ }
513
+
514
+ // Ugly, but we can't get back an object trait from the `BlockchainMap`,
515
+ // so this seems like the next best thing.
516
+ try_resolve_for_chain ! ( graph_chain_ethereum:: Chain ) ;
517
+ try_resolve_for_chain ! ( graph_chain_arweave:: Chain ) ;
518
+ try_resolve_for_chain ! ( graph_chain_cosmos:: Chain ) ;
519
+ try_resolve_for_chain ! ( graph_chain_near:: Chain ) ;
520
+
521
+ // If you're adding support for a new chain and this `match` clause just
522
+ // gave you a compiler error, then this message is for you! You need to
523
+ // add a new `try_resolve!` macro invocation above for your new chain
524
+ // type.
525
+ match BlockchainKind :: Ethereum {
526
+ // Note: we don't actually care about substreams here.
527
+ BlockchainKind :: Substreams
528
+ | BlockchainKind :: Arweave
529
+ | BlockchainKind :: Ethereum
530
+ | BlockchainKind :: Cosmos
531
+ | BlockchainKind :: Near => ( ) ,
532
+ }
533
+
534
+ // The given network does not exist.
535
+ Ok ( None )
536
+ }
537
+ }
538
+
539
+ #[ async_trait]
540
+ impl < S : Store > BlockPtrForNumber for IndexNodeResolver < S > {
541
+ async fn block_ptr_for_number (
542
+ & self ,
543
+ network : String ,
544
+ block_number : BlockNumber ,
545
+ ) -> Result < Option < BlockPtr > , Error > {
546
+ self . block_ptr_for_number ( network, block_number)
547
+ . map_err ( Error :: from)
548
+ . await
549
+ }
520
550
}
521
551
522
552
fn entity_changes_to_graphql ( entity_changes : Vec < EntityOperation > ) -> r:: Value {
@@ -643,7 +673,7 @@ impl<S: Store> Resolver for IndexNodeResolver<S> {
643
673
644
674
// The top-level `publicProofsOfIndexing` field
645
675
( None , "PublicProofOfIndexingResult" , "publicProofsOfIndexing" ) => {
646
- self . resolve_public_proofs_of_indexing ( field)
676
+ self . resolve_public_proofs_of_indexing ( field) . await
647
677
}
648
678
649
679
// Resolve fields of `Object` values (e.g. the `chains` field of `ChainIndexingStatus`)
0 commit comments