@sentio/sdk 1.32.0 → 1.32.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/service.ts CHANGED
@@ -12,6 +12,7 @@ import {
12
12
  EventTrackingConfig,
13
13
  ExportConfig,
14
14
  HandlerType,
15
+ Instruction,
15
16
  LogFilter,
16
17
  LogHandlerConfig,
17
18
  MetricConfig,
@@ -32,7 +33,7 @@ import { Empty } from './gen/google/protobuf/empty'
32
33
  import Long from 'long'
33
34
  import { TextDecoder } from 'util'
34
35
  import { Trace } from './core'
35
- import { Instruction } from '@project-serum/anchor'
36
+ import { Instruction as SolInstruction } from '@project-serum/anchor'
36
37
  import { MetricState } from './core/meter'
37
38
  import { ExporterState } from './core/exporter'
38
39
  import { EventTrackerState } from './core/event-tracker'
@@ -45,6 +46,7 @@ import { AccountProcessorState } from './core/account-processor'
45
46
  import { SuiProcessorState } from './core/sui-processor'
46
47
  import { SolanaProcessorState } from './core/solana-processor'
47
48
  import { ProcessorState } from './binds'
49
+
48
50
  ;(BigInt.prototype as any).toJSON = function () {
49
51
  return this.toString()
50
52
  }
@@ -54,9 +56,12 @@ const DEFAULT_MAX_BLOCK = Long.ZERO
54
56
  const USER_PROCESSOR = 'user_processor'
55
57
 
56
58
  export class ProcessorServiceImpl implements ProcessorServiceImplementation {
59
+ // eth handlers
57
60
  private eventHandlers: ((event: Log) => Promise<ProcessResult>)[] = []
58
61
  private traceHandlers: ((trace: Trace) => Promise<ProcessResult>)[] = []
59
62
  private blockHandlers: ((block: Block) => Promise<ProcessResult>)[] = []
63
+
64
+ // aptos handlers
60
65
  private aptosEventHandlers: ((event: any) => Promise<ProcessResult>)[] = []
61
66
  private aptosCallHandlers: ((func: any) => Promise<ProcessResult>)[] = []
62
67
  private aptosResourceHandlers: ((resourceWithVersion: MoveResourcesWithVersionPayload) => Promise<ProcessResult>)[] =
@@ -468,18 +473,37 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
468
473
  }
469
474
 
470
475
  async processBinding(request: DataBinding, options?: CallContext): Promise<ProcessResult> {
471
- switch (request.handlerType) {
472
- case HandlerType.APT_CALL:
473
- return this.processAptosFunctionCall(request)
474
- case HandlerType.APT_EVENT:
475
- return this.processAptosEvent(request)
476
- case HandlerType.APT_RESOURCE:
477
- return this.processAptosResource(request)
478
- case HandlerType.ETH_LOG:
479
- return this.processLog(request)
480
- default:
481
- throw new ServerError(Status.INVALID_ARGUMENT, 'No handle type registered ' + request.handlerType)
476
+ if (request.handlerIds.length == 0) {
477
+ request.handlerIds = [request.handlerId]
478
+ }
479
+
480
+ const processBindingInternal = (request: DataBinding) => {
481
+ switch (request.handlerType) {
482
+ case HandlerType.APT_CALL:
483
+ return this.processAptosFunctionCall(request)
484
+ case HandlerType.APT_EVENT:
485
+ return this.processAptosEvent(request)
486
+ case HandlerType.APT_RESOURCE:
487
+ return this.processAptosResource(request)
488
+ case HandlerType.ETH_LOG:
489
+ return this.processLog(request)
490
+ case HandlerType.ETH_TRACE:
491
+ return this.processTrace(request)
492
+ case HandlerType.ETH_BLOCK:
493
+ return this.processBlockNew(request)
494
+ case HandlerType.SOL_INSTRUCTIONS:
495
+ return this.processInstructionsNew(request)
496
+ // TODO migrate SOLANA SUI cases
497
+ // case HandlerType.INSTRUCTION:
498
+ // return this.processInstruction(request)
499
+ default:
500
+ throw new ServerError(Status.INVALID_ARGUMENT, 'No handle type registered ' + request.handlerType)
501
+ }
482
502
  }
503
+
504
+ const result = await processBindingInternal(request)
505
+ recordRuntimeInfo(result, request.handlerType)
506
+ return result
483
507
  }
484
508
 
485
509
  async processLogs(request: ProcessBindingsRequest, context: CallContext): Promise<ProcessBindingResponse> {
@@ -514,17 +538,23 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
514
538
  if (!l.data) {
515
539
  throw new ServerError(Status.INVALID_ARGUMENT, "Log can't be null")
516
540
  }
541
+ if (l.handlerIds.length == 0) {
542
+ l.handlerIds = [l.handlerId]
543
+ }
517
544
 
518
- try {
519
- const jsonString = Utf8ArrayToStr(l.data.raw)
520
- const log: Log = JSON.parse(jsonString)
521
- const handler = this.eventHandlers[l.handlerId]
522
- return handler(log).catch((e) => {
523
- throw new ServerError(Status.INTERNAL, 'error processing log: ' + jsonString + '\n' + errorString(e))
524
- })
525
- } catch (e) {
526
- throw new ServerError(Status.INTERNAL, 'error parse log: ' + l)
545
+ const promises: Promise<ProcessResult>[] = []
546
+ const jsonString = Utf8ArrayToStr(l.data.raw)
547
+ const log: Log = JSON.parse(jsonString)
548
+
549
+ for (const handlerId of l.handlerIds) {
550
+ const handler = this.eventHandlers[handlerId]
551
+ promises.push(
552
+ handler(log).catch((e) => {
553
+ throw new ServerError(Status.INTERNAL, 'error processing log: ' + jsonString + '\n' + errorString(e))
554
+ })
555
+ )
527
556
  }
557
+ return mergeProcessResults(await Promise.all(promises))
528
558
  }
529
559
 
530
560
  async processTransactions(
@@ -560,7 +590,7 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
560
590
  await Promise.all(processorPromises)
561
591
  }
562
592
 
563
- recordRuntimeInfo(result, HandlerType.TRANSACTION)
593
+ recordRuntimeInfo(result, HandlerType.SUI_TRANSACTION)
564
594
  return {
565
595
  result,
566
596
  configUpdated: false,
@@ -589,7 +619,7 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
589
619
  new Promise((resolve, _) => {
590
620
  for (const processor of SolanaProcessorState.INSTANCE.getValues()) {
591
621
  if (processor.address === instruction.programAccountId) {
592
- let parsedInstruction: Instruction | null = null
622
+ let parsedInstruction: SolInstruction | null = null
593
623
  if (instruction.parsed) {
594
624
  parsedInstruction = processor.getParsedInstruction(
595
625
  JSON.parse(new TextDecoder().decode(instruction.parsed))
@@ -623,13 +653,64 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
623
653
  await Promise.all(processorPromises)
624
654
  }
625
655
 
626
- recordRuntimeInfo(result, HandlerType.INSTRUCTION)
656
+ recordRuntimeInfo(result, HandlerType.SOL_INSTRUCTIONS)
627
657
  return {
628
658
  result,
629
659
  configUpdated: false,
630
660
  }
631
661
  }
632
662
 
663
+ async processInstructionsNew(request: DataBinding): Promise<ProcessResult> {
664
+ if (!this.started) {
665
+ throw new ServerError(Status.UNAVAILABLE, 'Service not started.')
666
+ }
667
+ if (!request.data) {
668
+ throw new ServerError(Status.INVALID_ARGUMENT, 'instruction data cannot be empty')
669
+ }
670
+
671
+ const jsonString = Utf8ArrayToStr(request.data.raw)
672
+ const instructions: Instruction[] = JSON.parse(jsonString)
673
+ const promises: Promise<ProcessResult>[] = []
674
+
675
+ // Only have instruction handlers for solana processors
676
+ if (SolanaProcessorState.INSTANCE.getValues()) {
677
+ for (const instruction of instructions) {
678
+ if (!instruction) {
679
+ throw new ServerError(Status.INVALID_ARGUMENT, 'instruction cannot be null')
680
+ }
681
+
682
+ for (const processor of SolanaProcessorState.INSTANCE.getValues()) {
683
+ if (processor.address === instruction.programAccountId) {
684
+ let parsedInstruction: SolInstruction | null = null
685
+ if (instruction.parsed) {
686
+ parsedInstruction = processor.getParsedInstruction(
687
+ JSON.parse(new TextDecoder().decode(instruction.parsed))
688
+ )
689
+ } else if (instruction.instructionData) {
690
+ parsedInstruction = processor.getParsedInstruction(instruction.instructionData)
691
+ }
692
+ if (parsedInstruction == null) {
693
+ continue
694
+ }
695
+ const insHandler = processor.getInstructionHandler(parsedInstruction)
696
+ if (insHandler == null) {
697
+ continue
698
+ }
699
+ const res = await processor.handleInstruction(
700
+ parsedInstruction,
701
+ instruction.accounts,
702
+ insHandler,
703
+ instruction.slot
704
+ )
705
+
706
+ promises.push(Promise.resolve(res))
707
+ }
708
+ }
709
+ }
710
+ }
711
+ return mergeProcessResults(await Promise.all(promises))
712
+ }
713
+
633
714
  async processBlocks(request: ProcessBlocksRequest, context: CallContext): Promise<ProcessBindingResponse> {
634
715
  if (!this.started) {
635
716
  throw new ServerError(Status.UNAVAILABLE, 'Service Not started.')
@@ -638,7 +719,7 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
638
719
  const promises = request.blockBindings.map((binding) => this.processBlock(binding))
639
720
  const result = mergeProcessResults(await Promise.all(promises))
640
721
 
641
- recordRuntimeInfo(result, HandlerType.BLOCK)
722
+ recordRuntimeInfo(result, HandlerType.ETH_BLOCK)
642
723
  return {
643
724
  result,
644
725
  configUpdated: false,
@@ -663,6 +744,30 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
663
744
  return mergeProcessResults(await Promise.all(promises))
664
745
  }
665
746
 
747
+ // TODO remove above old processBlock logic
748
+ async processBlockNew(binding: DataBinding): Promise<ProcessResult> {
749
+ if (!binding.data) {
750
+ throw new ServerError(Status.INVALID_ARGUMENT, "Block can't be empty")
751
+ }
752
+ if (binding.handlerIds.length == 0) {
753
+ binding.handlerIds = [binding.handlerId]
754
+ }
755
+
756
+ const jsonString = Utf8ArrayToStr(binding.data.raw)
757
+
758
+ const block: Block = JSON.parse(jsonString)
759
+
760
+ const promises: Promise<ProcessResult>[] = []
761
+ for (const handlerId of binding.handlerIds) {
762
+ promises.push(
763
+ this.blockHandlers[handlerId](block).catch((e) => {
764
+ throw new ServerError(Status.INTERNAL, 'error processing block: ' + block.number + '\n' + errorString(e))
765
+ })
766
+ )
767
+ }
768
+ return mergeProcessResults(await Promise.all(promises))
769
+ }
770
+
666
771
  async processTraces(request: ProcessBindingsRequest, context: CallContext): Promise<ProcessBindingResponse> {
667
772
  if (!this.started) {
668
773
  throw new ServerError(Status.UNAVAILABLE, 'Service Not started.')
@@ -682,26 +787,41 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
682
787
  if (!binding.data) {
683
788
  throw new ServerError(Status.INVALID_ARGUMENT, "Trace can't be empty")
684
789
  }
790
+ if (binding.handlerIds.length == 0) {
791
+ binding.handlerIds = [binding.handlerId]
792
+ }
685
793
  const jsonString = Utf8ArrayToStr(binding.data.raw)
686
794
  const trace: Trace = JSON.parse(jsonString)
687
795
 
688
- return this.traceHandlers[binding.handlerId](trace).catch((e) => {
689
- throw new ServerError(Status.INTERNAL, 'error processing trace: ' + jsonString + '\n' + errorString(e))
690
- })
796
+ const promises: Promise<ProcessResult>[] = []
797
+
798
+ for (const handlerId of binding.handlerIds) {
799
+ promises.push(
800
+ this.traceHandlers[handlerId](trace).catch((e) => {
801
+ throw new ServerError(Status.INTERNAL, 'error processing trace: ' + jsonString + '\n' + errorString(e))
802
+ })
803
+ )
804
+ }
805
+ return mergeProcessResults(await Promise.all(promises))
691
806
  }
692
807
 
693
808
  async processAptosEvent(binding: DataBinding): Promise<ProcessResult> {
694
809
  if (!binding.data) {
695
810
  throw new ServerError(Status.INVALID_ARGUMENT, "Event can't be empty")
696
811
  }
812
+ const promises: Promise<ProcessResult>[] = []
697
813
  const jsonString = Utf8ArrayToStr(binding.data.raw)
698
814
  const event = JSON.parse(jsonString)
699
- // only support aptos event for now
700
- const result = await this.aptosEventHandlers[binding.handlerId](event).catch((e) => {
701
- throw new ServerError(Status.INTERNAL, 'error processing event: ' + jsonString + '\n' + errorString(e))
702
- })
703
- recordRuntimeInfo(result, HandlerType.APT_EVENT)
704
- return result
815
+
816
+ for (const handlerId of binding.handlerIds) {
817
+ // only support aptos event for now
818
+ promises.push(
819
+ this.aptosEventHandlers[handlerId](event).catch((e) => {
820
+ throw new ServerError(Status.INTERNAL, 'error processing event: ' + jsonString + '\n' + errorString(e))
821
+ })
822
+ )
823
+ }
824
+ return mergeProcessResults(await Promise.all(promises))
705
825
  }
706
826
 
707
827
  async processAptosResource(binding: DataBinding): Promise<ProcessResult> {
@@ -710,11 +830,15 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
710
830
  }
711
831
  const jsonString = Utf8ArrayToStr(binding.data.raw)
712
832
  const json = JSON.parse(jsonString) as MoveResourcesWithVersionPayload
713
- const result = await this.aptosResourceHandlers[binding.handlerId](json).catch((e) => {
714
- throw new ServerError(Status.INTERNAL, 'error processing event: ' + jsonString + '\n' + errorString(e))
715
- })
716
- recordRuntimeInfo(result, HandlerType.APT_RESOURCE)
717
- return result
833
+ const promises: Promise<ProcessResult>[] = []
834
+ for (const handlerId of binding.handlerIds) {
835
+ promises.push(
836
+ this.aptosResourceHandlers[handlerId](json).catch((e) => {
837
+ throw new ServerError(Status.INTERNAL, 'error processing event: ' + jsonString + '\n' + errorString(e))
838
+ })
839
+ )
840
+ }
841
+ return mergeProcessResults(await Promise.all(promises))
718
842
  }
719
843
 
720
844
  async processAptosFunctionCall(binding: DataBinding): Promise<ProcessResult> {
@@ -723,12 +847,16 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
723
847
  }
724
848
  const jsonString = Utf8ArrayToStr(binding.data.raw)
725
849
  const call = JSON.parse(jsonString)
726
- // only support aptos call for now
727
- const result = await this.aptosCallHandlers[binding.handlerId](call).catch((e) => {
728
- throw new ServerError(Status.INTERNAL, 'error processing call: ' + jsonString + '\n' + errorString(e))
729
- })
730
- recordRuntimeInfo(result, HandlerType.APT_CALL)
731
- return result
850
+
851
+ const promises: Promise<ProcessResult>[] = []
852
+ for (const handlerId of binding.handlerIds) {
853
+ // only support aptos call for now
854
+ const promise = this.aptosCallHandlers[handlerId](call).catch((e) => {
855
+ throw new ServerError(Status.INTERNAL, 'error processing call: ' + jsonString + '\n' + errorString(e))
856
+ })
857
+ promises.push(promise)
858
+ }
859
+ return mergeProcessResults(await Promise.all(promises))
732
860
  }
733
861
  }
734
862
 
@@ -132,7 +132,8 @@ export class TestProcessorServer implements ProcessorServiceImplementation {
132
132
  data: {
133
133
  raw: toBytes(trace),
134
134
  },
135
- handlerId: config.handlerId,
135
+ handlerId: 0,
136
+ handlerIds: [config.handlerId],
136
137
  handlerType: HandlerType.ETH_TRACE,
137
138
  }
138
139
  }
@@ -193,7 +194,8 @@ export class TestProcessorServer implements ProcessorServiceImplementation {
193
194
  data: {
194
195
  raw: toBytes(log),
195
196
  },
196
- handlerId: config.handlerId,
197
+ handlerId: 0,
198
+ handlerIds: [config.handlerId],
197
199
  handlerType: HandlerType.ETH_LOG,
198
200
  }
199
201
  }
@@ -254,7 +256,8 @@ export class TestProcessorServer implements ProcessorServiceImplementation {
254
256
  data: {
255
257
  raw: toBytes(log),
256
258
  },
257
- handlerId: config.handlerId,
259
+ handlerIds: [config.handlerId],
260
+ handlerId: 0,
258
261
  handlerType: HandlerType.ETH_LOG,
259
262
  }
260
263
  }