@sentio/sdk 1.8.1 → 1.8.2

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.
@@ -123,6 +123,7 @@ export interface ContractConfig {
123
123
  contract: ContractInfo | undefined;
124
124
  blockConfigs: BlockHandlerConfig[];
125
125
  logConfigs: LogHandlerConfig[];
126
+ traceConfigs: TraceHandlerConfig[];
126
127
  startBlock: Long;
127
128
  endBlock: Long;
128
129
  instructionConfig: InstructionHandlerConfig | undefined;
@@ -151,6 +152,11 @@ export interface BlockHandlerConfig {
151
152
  handlerId: number;
152
153
  }
153
154
 
155
+ export interface TraceHandlerConfig {
156
+ signature: string;
157
+ handlerId: number;
158
+ }
159
+
154
160
  export interface LogHandlerConfig {
155
161
  filters: LogFilter[];
156
162
  handlerId: number;
@@ -180,7 +186,7 @@ export interface ProcessLogsResponse {
180
186
  }
181
187
 
182
188
  export interface ProcessTracesRequest {
183
- logBindings: LogBinding[];
189
+ traceBindings: TraceBinding[];
184
190
  }
185
191
 
186
192
  export interface ProcessTracesResponse {
@@ -524,6 +530,7 @@ function createBaseContractConfig(): ContractConfig {
524
530
  contract: undefined,
525
531
  blockConfigs: [],
526
532
  logConfigs: [],
533
+ traceConfigs: [],
527
534
  startBlock: Long.UZERO,
528
535
  endBlock: Long.UZERO,
529
536
  instructionConfig: undefined,
@@ -545,6 +552,9 @@ export const ContractConfig = {
545
552
  for (const v of message.logConfigs) {
546
553
  LogHandlerConfig.encode(v!, writer.uint32(26).fork()).ldelim();
547
554
  }
555
+ for (const v of message.traceConfigs) {
556
+ TraceHandlerConfig.encode(v!, writer.uint32(18).fork()).ldelim();
557
+ }
548
558
  if (!message.startBlock.isZero()) {
549
559
  writer.uint32(32).uint64(message.startBlock);
550
560
  }
@@ -583,6 +593,11 @@ export const ContractConfig = {
583
593
  LogHandlerConfig.decode(reader, reader.uint32())
584
594
  );
585
595
  break;
596
+ case 2:
597
+ message.traceConfigs.push(
598
+ TraceHandlerConfig.decode(reader, reader.uint32())
599
+ );
600
+ break;
586
601
  case 4:
587
602
  message.startBlock = reader.uint64() as Long;
588
603
  break;
@@ -617,6 +632,9 @@ export const ContractConfig = {
617
632
  logConfigs: Array.isArray(object?.logConfigs)
618
633
  ? object.logConfigs.map((e: any) => LogHandlerConfig.fromJSON(e))
619
634
  : [],
635
+ traceConfigs: Array.isArray(object?.traceConfigs)
636
+ ? object.traceConfigs.map((e: any) => TraceHandlerConfig.fromJSON(e))
637
+ : [],
620
638
  startBlock: isSet(object.startBlock)
621
639
  ? Long.fromValue(object.startBlock)
622
640
  : Long.UZERO,
@@ -652,6 +670,13 @@ export const ContractConfig = {
652
670
  } else {
653
671
  obj.logConfigs = [];
654
672
  }
673
+ if (message.traceConfigs) {
674
+ obj.traceConfigs = message.traceConfigs.map((e) =>
675
+ e ? TraceHandlerConfig.toJSON(e) : undefined
676
+ );
677
+ } else {
678
+ obj.traceConfigs = [];
679
+ }
655
680
  message.startBlock !== undefined &&
656
681
  (obj.startBlock = (message.startBlock || Long.UZERO).toString());
657
682
  message.endBlock !== undefined &&
@@ -675,6 +700,8 @@ export const ContractConfig = {
675
700
  object.blockConfigs?.map((e) => BlockHandlerConfig.fromPartial(e)) || [];
676
701
  message.logConfigs =
677
702
  object.logConfigs?.map((e) => LogHandlerConfig.fromPartial(e)) || [];
703
+ message.traceConfigs =
704
+ object.traceConfigs?.map((e) => TraceHandlerConfig.fromPartial(e)) || [];
678
705
  message.startBlock =
679
706
  object.startBlock !== undefined && object.startBlock !== null
680
707
  ? Long.fromValue(object.startBlock)
@@ -994,6 +1021,68 @@ export const BlockHandlerConfig = {
994
1021
  },
995
1022
  };
996
1023
 
1024
+ function createBaseTraceHandlerConfig(): TraceHandlerConfig {
1025
+ return { signature: "", handlerId: 0 };
1026
+ }
1027
+
1028
+ export const TraceHandlerConfig = {
1029
+ encode(
1030
+ message: TraceHandlerConfig,
1031
+ writer: _m0.Writer = _m0.Writer.create()
1032
+ ): _m0.Writer {
1033
+ if (message.signature !== "") {
1034
+ writer.uint32(10).string(message.signature);
1035
+ }
1036
+ if (message.handlerId !== 0) {
1037
+ writer.uint32(16).int32(message.handlerId);
1038
+ }
1039
+ return writer;
1040
+ },
1041
+
1042
+ decode(input: _m0.Reader | Uint8Array, length?: number): TraceHandlerConfig {
1043
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
1044
+ let end = length === undefined ? reader.len : reader.pos + length;
1045
+ const message = createBaseTraceHandlerConfig();
1046
+ while (reader.pos < end) {
1047
+ const tag = reader.uint32();
1048
+ switch (tag >>> 3) {
1049
+ case 1:
1050
+ message.signature = reader.string();
1051
+ break;
1052
+ case 2:
1053
+ message.handlerId = reader.int32();
1054
+ break;
1055
+ default:
1056
+ reader.skipType(tag & 7);
1057
+ break;
1058
+ }
1059
+ }
1060
+ return message;
1061
+ },
1062
+
1063
+ fromJSON(object: any): TraceHandlerConfig {
1064
+ return {
1065
+ signature: isSet(object.signature) ? String(object.signature) : "",
1066
+ handlerId: isSet(object.handlerId) ? Number(object.handlerId) : 0,
1067
+ };
1068
+ },
1069
+
1070
+ toJSON(message: TraceHandlerConfig): unknown {
1071
+ const obj: any = {};
1072
+ message.signature !== undefined && (obj.signature = message.signature);
1073
+ message.handlerId !== undefined &&
1074
+ (obj.handlerId = Math.round(message.handlerId));
1075
+ return obj;
1076
+ },
1077
+
1078
+ fromPartial(object: DeepPartial<TraceHandlerConfig>): TraceHandlerConfig {
1079
+ const message = createBaseTraceHandlerConfig();
1080
+ message.signature = object.signature ?? "";
1081
+ message.handlerId = object.handlerId ?? 0;
1082
+ return message;
1083
+ },
1084
+ };
1085
+
997
1086
  function createBaseLogHandlerConfig(): LogHandlerConfig {
998
1087
  return { filters: [], handlerId: 0 };
999
1088
  }
@@ -1400,7 +1489,7 @@ export const ProcessLogsResponse = {
1400
1489
  };
1401
1490
 
1402
1491
  function createBaseProcessTracesRequest(): ProcessTracesRequest {
1403
- return { logBindings: [] };
1492
+ return { traceBindings: [] };
1404
1493
  }
1405
1494
 
1406
1495
  export const ProcessTracesRequest = {
@@ -1408,8 +1497,8 @@ export const ProcessTracesRequest = {
1408
1497
  message: ProcessTracesRequest,
1409
1498
  writer: _m0.Writer = _m0.Writer.create()
1410
1499
  ): _m0.Writer {
1411
- for (const v of message.logBindings) {
1412
- LogBinding.encode(v!, writer.uint32(10).fork()).ldelim();
1500
+ for (const v of message.traceBindings) {
1501
+ TraceBinding.encode(v!, writer.uint32(10).fork()).ldelim();
1413
1502
  }
1414
1503
  return writer;
1415
1504
  },
@@ -1425,7 +1514,9 @@ export const ProcessTracesRequest = {
1425
1514
  const tag = reader.uint32();
1426
1515
  switch (tag >>> 3) {
1427
1516
  case 1:
1428
- message.logBindings.push(LogBinding.decode(reader, reader.uint32()));
1517
+ message.traceBindings.push(
1518
+ TraceBinding.decode(reader, reader.uint32())
1519
+ );
1429
1520
  break;
1430
1521
  default:
1431
1522
  reader.skipType(tag & 7);
@@ -1437,28 +1528,28 @@ export const ProcessTracesRequest = {
1437
1528
 
1438
1529
  fromJSON(object: any): ProcessTracesRequest {
1439
1530
  return {
1440
- logBindings: Array.isArray(object?.logBindings)
1441
- ? object.logBindings.map((e: any) => LogBinding.fromJSON(e))
1531
+ traceBindings: Array.isArray(object?.traceBindings)
1532
+ ? object.traceBindings.map((e: any) => TraceBinding.fromJSON(e))
1442
1533
  : [],
1443
1534
  };
1444
1535
  },
1445
1536
 
1446
1537
  toJSON(message: ProcessTracesRequest): unknown {
1447
1538
  const obj: any = {};
1448
- if (message.logBindings) {
1449
- obj.logBindings = message.logBindings.map((e) =>
1450
- e ? LogBinding.toJSON(e) : undefined
1539
+ if (message.traceBindings) {
1540
+ obj.traceBindings = message.traceBindings.map((e) =>
1541
+ e ? TraceBinding.toJSON(e) : undefined
1451
1542
  );
1452
1543
  } else {
1453
- obj.logBindings = [];
1544
+ obj.traceBindings = [];
1454
1545
  }
1455
1546
  return obj;
1456
1547
  },
1457
1548
 
1458
1549
  fromPartial(object: DeepPartial<ProcessTracesRequest>): ProcessTracesRequest {
1459
1550
  const message = createBaseProcessTracesRequest();
1460
- message.logBindings =
1461
- object.logBindings?.map((e) => LogBinding.fromPartial(e)) || [];
1551
+ message.traceBindings =
1552
+ object.traceBindings?.map((e) => TraceBinding.fromPartial(e)) || [];
1462
1553
  return message;
1463
1554
  },
1464
1555
  };
package/src/meter.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { RecordMetaData } from './gen/processor/protos/processor'
2
- import { Context, EthContext, SolanaContext } from './context'
2
+ import { BaseContext, Context, SolanaContext } from './context'
3
3
  import { toMetricValue, Numberish } from './numberish'
4
4
  import Long from 'long'
5
5
 
@@ -8,7 +8,7 @@ export function normalizeName(name: string) {
8
8
  return name.slice(0, 100).replace(regex, '_')
9
9
  }
10
10
 
11
- function GetRecordMetaData(ctx: EthContext | SolanaContext, name: string, labels: Labels): RecordMetaData {
11
+ function GetRecordMetaData(ctx: BaseContext, name: string, labels: Labels): RecordMetaData {
12
12
  name = normalizeName(name)
13
13
 
14
14
  if (ctx instanceof Context) {
@@ -34,6 +34,17 @@ function GetRecordMetaData(ctx: EthContext | SolanaContext, name: string, labels
34
34
  labels: labels,
35
35
  }
36
36
  }
37
+ if (ctx.trace) {
38
+ return {
39
+ contractAddress: ctx.contract.rawContract.address,
40
+ blockNumber: Long.fromNumber(ctx.trace.blockNumber, true),
41
+ transactionIndex: ctx.trace.transactionPosition, // TODO make sure if this is the right value to set
42
+ logIndex: -1,
43
+ chainId: ctx.chainId.toString(),
44
+ name: name,
45
+ labels: labels,
46
+ }
47
+ }
37
48
  } else if (ctx instanceof SolanaContext) {
38
49
  return {
39
50
  contractAddress: ctx.address,
@@ -51,10 +62,10 @@ function GetRecordMetaData(ctx: EthContext | SolanaContext, name: string, labels
51
62
  export type Labels = { [key: string]: string }
52
63
 
53
64
  export class Counter {
54
- private readonly ctx: EthContext | SolanaContext
65
+ private readonly ctx: BaseContext
55
66
  private readonly name: string
56
67
 
57
- constructor(name: string, ctx: EthContext | SolanaContext) {
68
+ constructor(name: string, ctx: BaseContext) {
58
69
  this.name = name
59
70
  this.ctx = ctx
60
71
  }
@@ -79,9 +90,9 @@ export class Counter {
79
90
 
80
91
  export class Gauge {
81
92
  private readonly name: string
82
- private readonly ctx: EthContext | SolanaContext
93
+ private readonly ctx: BaseContext
83
94
 
84
- constructor(name: string, ctx: EthContext | SolanaContext) {
95
+ constructor(name: string, ctx: BaseContext) {
85
96
  this.name = name
86
97
  this.ctx = ctx
87
98
  }
@@ -96,13 +107,13 @@ export class Gauge {
96
107
  }
97
108
 
98
109
  export class Meter {
99
- private readonly ctx: EthContext | SolanaContext
110
+ private readonly ctx: BaseContext
100
111
 
101
112
  // TODO is map necessary since we are sending request remotely?
102
113
  // counterMap = new Map<string, Counter>()
103
114
  // gaugeMap = new Map<string, Gauge>()
104
115
 
105
- constructor(ctx: EthContext | SolanaContext) {
116
+ constructor(ctx: BaseContext) {
106
117
  this.ctx = ctx
107
118
  }
108
119
 
package/src/service.ts CHANGED
@@ -23,16 +23,19 @@ import {
23
23
  ProcessTransactionsResponse,
24
24
  StartRequest,
25
25
  TemplateInstance,
26
+ TraceBinding,
26
27
  } from './gen/processor/protos/processor'
27
28
 
28
29
  import { Empty } from './gen/google/protobuf/empty'
29
30
  import Long from 'long'
30
31
  import { TextDecoder } from 'util'
32
+ import { Trace } from './trace'
31
33
 
32
34
  const DEFAULT_MAX_BLOCK = Long.ZERO
33
35
 
34
36
  export class ProcessorServiceImpl implements ProcessorServiceImplementation {
35
37
  private eventHandlers: ((event: Log) => Promise<ProcessResult>)[] = []
38
+ private traceHandlers: ((trace: Trace) => Promise<ProcessResult>)[] = []
36
39
  private blockHandlers: ((block: Block) => Promise<ProcessResult>)[] = []
37
40
 
38
41
  // map from chain id to list of processors
@@ -88,6 +91,7 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
88
91
  },
89
92
  blockConfigs: [],
90
93
  logConfigs: [],
94
+ traceConfigs: [],
91
95
  startBlock: processor.config.startBlock,
92
96
  endBlock: DEFAULT_MAX_BLOCK,
93
97
  instructionConfig: undefined,
@@ -104,7 +108,16 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
104
108
  })
105
109
  }
106
110
 
107
- // Step 2. Prepare all the event handlers
111
+ // Step 2. Prepare all trace handlers
112
+ for (const traceHandler of processor.traceHandlers) {
113
+ const handlerId = this.traceHandlers.push(traceHandler.handler) - 1
114
+ contractConfig.traceConfigs.push({
115
+ signature: traceHandler.signature,
116
+ handlerId: handlerId,
117
+ })
118
+ }
119
+
120
+ // Step 3. Prepare all the event handlers
108
121
  for (const eventsHandler of processor.eventHandlers) {
109
122
  // associate id with filter
110
123
  const handlerId = this.eventHandlers.push(eventsHandler.handler) - 1
@@ -151,6 +164,7 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
151
164
  },
152
165
  blockConfigs: [],
153
166
  logConfigs: [],
167
+ traceConfigs: [],
154
168
  startBlock: solanaProcessor.config.startSlot,
155
169
  endBlock: DEFAULT_MAX_BLOCK,
156
170
  instructionConfig: {
@@ -388,10 +402,37 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
388
402
  }
389
403
 
390
404
  async processTraces(request: ProcessTracesRequest, context: CallContext): Promise<ProcessTracesResponse> {
405
+ if (!this.started) {
406
+ throw new ServerError(Status.UNAVAILABLE, 'Service Not started.')
407
+ }
408
+
409
+ const promises = request.traceBindings.map((binding) => this.processTrace(binding))
410
+ const results = await Promise.all(promises)
411
+
412
+ const res = ProcessResult.fromPartial({})
413
+
414
+ for (const r of results) {
415
+ res.counters = res.counters.concat(r.counters)
416
+ res.gauges = res.gauges.concat(r.gauges)
417
+ }
418
+
419
+ recordRuntimeInfo(res, HandlerType.TRACE)
391
420
  return {
392
- result: undefined,
421
+ result: res,
393
422
  }
394
423
  }
424
+
425
+ async processTrace(binding: TraceBinding): Promise<ProcessResult> {
426
+ if (!binding.trace) {
427
+ throw new ServerError(Status.INVALID_ARGUMENT, "Trace can't be empty")
428
+ }
429
+ const jsonString = Utf8ArrayToStr(binding.trace.raw)
430
+ const trace: Trace = JSON.parse(jsonString)
431
+
432
+ return this.traceHandlers[binding.handlerId](trace).catch((e) => {
433
+ throw new ServerError(Status.INTERNAL, 'error processing trace: ' + jsonString + '\n' + e.toString())
434
+ })
435
+ }
395
436
  }
396
437
 
397
438
  // https://ourcodeworld.com/articles/read/164/how-to-convert-an-uint8array-to-string-in-javascript
package/src/trace.ts ADDED
@@ -0,0 +1,64 @@
1
+ // https://github.com/openethereum/parity-ethereum/blob/55c90d4016505317034e3e98f699af07f5404b63/rpc/src/v1/types/trace.rs#L482
2
+ import { Result } from '@ethersproject/abi'
3
+
4
+ export interface TypedTrace<TArgsArray extends Array<any> = any, TArgsObject = any> extends Trace {
5
+ args: TArgsArray & TArgsObject
6
+ }
7
+
8
+ export interface Trace {
9
+ args?: Result
10
+
11
+ action: TraceAction
12
+ blockHash: string
13
+ blockNumber: number
14
+ result: TraceResult
15
+ subtraces: number
16
+ traceAddress: number[]
17
+ transactionHash: string
18
+ transactionPosition: number
19
+ type: string
20
+ error?: string
21
+ }
22
+ // export type CallType = "call" | "callcode" | "delegatecall" | "staticcall"
23
+
24
+ export interface TraceAction {
25
+ from: string
26
+ to: string
27
+ value: number
28
+ gas: number
29
+ input: string
30
+ callType: string
31
+
32
+ init?: string
33
+ address?: string
34
+ balance?: string
35
+ refundAddress?: string
36
+ }
37
+
38
+ // TODO are more field missing for FailedCall, FailedCreate
39
+ export interface TraceResult {
40
+ gasUsed: number
41
+ output: string
42
+ address?: string
43
+ code?: string
44
+ }
45
+
46
+ // const TRACE: Trace = {
47
+ // action: {
48
+ // from: '0xd771111cbfa2bbdafbf9f0e58b49b3f827da31f5',
49
+ // callType: 'call',
50
+ // gas: 0x12154,
51
+ // input:
52
+ // '0xb1a417f4000000000000000000000000d771111cbfa2bbdafbf9f0e58b49b3f827da31f5000000000000000000000000d771111cbfa2bbdafbf9f0e58b49b3f827da31f500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000131888b5aaf000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000',
53
+ // to: '0x0baba1ad5be3a5c0a66e7ac838a129bf948f1ea4',
54
+ // value: 0x131888b5aaf0000,
55
+ // },
56
+ // blockHash: '0x5451711bc530a7c04128fedbe149eb359c10eccd44a83909d448c5244c7eea26',
57
+ // blockNumber: 15533908,
58
+ // result: { gasUsed: 0x114c1, output: '0x' },
59
+ // subtraces: 1,
60
+ // traceAddress: [],
61
+ // transactionHash: '0x66dce11d6217042ed709a38e507e7762c93b1bde4a0447ae7a243493bbdffc0e',
62
+ // transactionPosition: 73,
63
+ // type: 'call',
64
+ // }