@@ -7,7 +7,7 @@ use anyhow::Error;
7
7
use async_stream:: stream;
8
8
use futures03:: Stream ;
9
9
use prost_types:: Any ;
10
- use std:: collections:: { BTreeMap , HashMap , HashSet } ;
10
+ use std:: collections:: { BTreeMap , BTreeSet , HashMap } ;
11
11
use std:: fmt;
12
12
use std:: sync:: Arc ;
13
13
use std:: time:: Instant ;
@@ -339,53 +339,127 @@ impl<C: Blockchain> TriggersAdapterWrapper<C> {
339
339
pub async fn blocks_with_subgraph_triggers (
340
340
& self ,
341
341
logger : & Logger ,
342
- subgraph_filter : & SubgraphFilter ,
342
+ filters : & [ SubgraphFilter ] ,
343
343
range : SubgraphTriggerScanRange < C > ,
344
344
) -> Result < Vec < BlockWithTriggers < C > > , Error > {
345
- let store = self
346
- . source_subgraph_stores
347
- . get ( & subgraph_filter. subgraph )
348
- . ok_or_else ( || anyhow ! ( "Store not found for subgraph: {}" , subgraph_filter. subgraph) ) ?;
345
+ if filters. is_empty ( ) {
346
+ return Err ( anyhow ! ( "No subgraph filters provided" ) ) ;
347
+ }
348
+
349
+ let ( blocks, hash_to_entities) = match range {
350
+ SubgraphTriggerScanRange :: Single ( block) => {
351
+ let hash_to_entities = self
352
+ . fetch_entities_for_filters ( filters, block. number ( ) , block. number ( ) )
353
+ . await ?;
354
+
355
+ ( vec ! [ block] , hash_to_entities)
356
+ }
357
+ SubgraphTriggerScanRange :: Range ( from, to) => {
358
+ let hash_to_entities = self . fetch_entities_for_filters ( filters, from, to) . await ?;
359
+
360
+ // Get block numbers that have entities
361
+ let mut block_numbers: BTreeSet < _ > = hash_to_entities
362
+ . iter ( )
363
+ . flat_map ( |( _, entities, _) | entities. keys ( ) . copied ( ) )
364
+ . collect ( ) ;
365
+
366
+ // Always include the last block in the range
367
+ block_numbers. insert ( to) ;
368
+
369
+ let blocks = self
370
+ . adapter
371
+ . load_block_ptrs_by_numbers ( logger. clone ( ) , block_numbers)
372
+ . await ?;
349
373
350
- let schema = <dyn crate :: components:: store:: SourceableStore >:: input_schema ( store) ;
374
+ ( blocks, hash_to_entities)
375
+ }
376
+ } ;
351
377
352
- let adapter = self . adapter . clone ( ) ;
378
+ create_subgraph_triggers :: < C > ( logger. clone ( ) , blocks, hash_to_entities) . await
379
+ }
380
+
381
+ async fn fetch_entities_for_filters (
382
+ & self ,
383
+ filters : & [ SubgraphFilter ] ,
384
+ from : BlockNumber ,
385
+ to : BlockNumber ,
386
+ ) -> Result <
387
+ Vec < (
388
+ DeploymentHash ,
389
+ BTreeMap < BlockNumber , Vec < EntitySourceOperation > > ,
390
+ u32 ,
391
+ ) > ,
392
+ Error ,
393
+ > {
394
+ let futures = filters
395
+ . iter ( )
396
+ . filter_map ( |filter| {
397
+ self . source_subgraph_stores
398
+ . get ( & filter. subgraph )
399
+ . map ( |store| {
400
+ let store = store. clone ( ) ;
401
+ let schema = store. input_schema ( ) ;
402
+
403
+ async move {
404
+ let entities =
405
+ get_entities_for_range ( & store, filter, & schema, from, to) . await ?;
406
+ Ok :: < _ , Error > ( ( filter. subgraph . clone ( ) , entities, filter. manifest_idx ) )
407
+ }
408
+ } )
409
+ } )
410
+ . collect :: < Vec < _ > > ( ) ;
411
+
412
+ if futures. is_empty ( ) {
413
+ return Ok ( Vec :: new ( ) ) ;
414
+ }
353
415
354
- scan_subgraph_triggers :: < C > ( logger , store , & adapter , & schema , & subgraph_filter , range ) . await
416
+ futures03 :: future :: try_join_all ( futures ) . await
355
417
}
356
418
}
357
419
358
420
fn create_subgraph_trigger_from_entities (
359
- filter : & SubgraphFilter ,
421
+ subgraph : & DeploymentHash ,
360
422
entities : Vec < EntitySourceOperation > ,
423
+ manifest_idx : u32 ,
361
424
) -> Vec < subgraph:: TriggerData > {
362
425
entities
363
426
. into_iter ( )
364
427
. map ( |entity| subgraph:: TriggerData {
365
- source : filter . subgraph . clone ( ) ,
428
+ source : subgraph. clone ( ) ,
366
429
entity,
430
+ source_idx : manifest_idx,
367
431
} )
368
432
. collect ( )
369
433
}
370
434
371
435
async fn create_subgraph_triggers < C : Blockchain > (
372
436
logger : Logger ,
373
437
blocks : Vec < C :: Block > ,
374
- filter : & SubgraphFilter ,
375
- mut entities : BTreeMap < BlockNumber , Vec < EntitySourceOperation > > ,
438
+ subgraph_data : Vec < (
439
+ DeploymentHash ,
440
+ BTreeMap < BlockNumber , Vec < EntitySourceOperation > > ,
441
+ u32 ,
442
+ ) > ,
376
443
) -> Result < Vec < BlockWithTriggers < C > > , Error > {
377
444
let logger_clone = logger. cheap_clone ( ) ;
378
-
379
445
let blocks: Vec < BlockWithTriggers < C > > = blocks
380
446
. into_iter ( )
381
447
. map ( |block| {
382
448
let block_number = block. number ( ) ;
383
- let trigger_data = entities
384
- . remove ( & block_number)
385
- . map ( |e| create_subgraph_trigger_from_entities ( filter, e) )
386
- . unwrap_or_else ( Vec :: new) ;
449
+ let mut all_trigger_data = Vec :: new ( ) ;
450
+
451
+ for ( hash, entities, manifest_idx) in subgraph_data. iter ( ) {
452
+ if let Some ( block_entities) = entities. get ( & block_number) {
453
+ let trigger_data = create_subgraph_trigger_from_entities (
454
+ hash,
455
+ block_entities. clone ( ) ,
456
+ * manifest_idx,
457
+ ) ;
458
+ all_trigger_data. extend ( trigger_data) ;
459
+ }
460
+ }
387
461
388
- BlockWithTriggers :: new_with_subgraph_triggers ( block, trigger_data , & logger_clone)
462
+ BlockWithTriggers :: new_with_subgraph_triggers ( block, all_trigger_data , & logger_clone)
389
463
} )
390
464
. collect ( ) ;
391
465
@@ -397,36 +471,6 @@ pub enum SubgraphTriggerScanRange<C: Blockchain> {
397
471
Range ( BlockNumber , BlockNumber ) ,
398
472
}
399
473
400
- async fn scan_subgraph_triggers < C : Blockchain > (
401
- logger : & Logger ,
402
- store : & Arc < dyn SourceableStore > ,
403
- adapter : & Arc < dyn TriggersAdapter < C > > ,
404
- schema : & InputSchema ,
405
- filter : & SubgraphFilter ,
406
- range : SubgraphTriggerScanRange < C > ,
407
- ) -> Result < Vec < BlockWithTriggers < C > > , Error > {
408
- match range {
409
- SubgraphTriggerScanRange :: Single ( block) => {
410
- let entities =
411
- get_entities_for_range ( store, filter, schema, block. number ( ) , block. number ( ) )
412
- . await ?;
413
- create_subgraph_triggers :: < C > ( logger. clone ( ) , vec ! [ block] , filter, entities) . await
414
- }
415
- SubgraphTriggerScanRange :: Range ( from, to) => {
416
- let entities = get_entities_for_range ( store, filter, schema, from, to) . await ?;
417
- let mut block_numbers: HashSet < BlockNumber > = entities. keys ( ) . cloned ( ) . collect ( ) ;
418
- // Ensure the 'to' block is included in the block_numbers
419
- block_numbers. insert ( to) ;
420
-
421
- let blocks = adapter
422
- . load_block_ptrs_by_numbers ( logger. clone ( ) , block_numbers)
423
- . await ?;
424
-
425
- create_subgraph_triggers :: < C > ( logger. clone ( ) , blocks, filter, entities) . await
426
- }
427
- }
428
- }
429
-
430
474
#[ derive( Debug , Clone , Eq , PartialEq ) ]
431
475
pub enum EntityOperationKind {
432
476
Create ,
@@ -474,11 +518,11 @@ impl<C: Blockchain> TriggersAdapterWrapper<C> {
474
518
to : BlockNumber ,
475
519
filter : & Arc < TriggerFilterWrapper < C > > ,
476
520
) -> Result < ( Vec < BlockWithTriggers < C > > , BlockNumber ) , Error > {
477
- if let Some ( subgraph_filter ) = filter. subgraph_filter . first ( ) {
521
+ if ! filter. subgraph_filter . is_empty ( ) {
478
522
let blocks_with_triggers = self
479
523
. blocks_with_subgraph_triggers (
480
524
logger,
481
- subgraph_filter,
525
+ & filter . subgraph_filter ,
482
526
SubgraphTriggerScanRange :: Range ( from, to) ,
483
527
)
484
528
. await ?;
@@ -504,11 +548,11 @@ impl<C: Blockchain> TriggersAdapterWrapper<C> {
504
548
"block_hash" => block. hash( ) . hash_hex( ) ,
505
549
) ;
506
550
507
- if let Some ( subgraph_filter ) = filter. subgraph_filter . first ( ) {
551
+ if ! filter. subgraph_filter . is_empty ( ) {
508
552
let blocks_with_triggers = self
509
553
. blocks_with_subgraph_triggers (
510
554
logger,
511
- subgraph_filter,
555
+ & filter . subgraph_filter ,
512
556
SubgraphTriggerScanRange :: Single ( block) ,
513
557
)
514
558
. await ?;
@@ -594,7 +638,7 @@ pub trait TriggersAdapter<C: Blockchain>: Send + Sync {
594
638
async fn load_block_ptrs_by_numbers (
595
639
& self ,
596
640
logger : Logger ,
597
- block_numbers : HashSet < BlockNumber > ,
641
+ block_numbers : BTreeSet < BlockNumber > ,
598
642
) -> Result < Vec < C :: Block > > ;
599
643
}
600
644
0 commit comments