envio 3.3.0-alpha.7 → 3.3.0-alpha.8

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.
Files changed (89) hide show
  1. package/index.d.ts +23 -5
  2. package/package.json +6 -6
  3. package/src/Api.res +1 -1
  4. package/src/Api.res.mjs +1 -1
  5. package/src/ChainFetching.res +21 -10
  6. package/src/ChainFetching.res.mjs +11 -10
  7. package/src/ChainState.res +328 -165
  8. package/src/ChainState.res.mjs +205 -100
  9. package/src/ChainState.resi +16 -7
  10. package/src/Config.res +11 -27
  11. package/src/Config.res.mjs +8 -7
  12. package/src/Core.res +7 -0
  13. package/src/CrossChainState.res +53 -80
  14. package/src/CrossChainState.res.mjs +43 -59
  15. package/src/CrossChainState.resi +1 -1
  16. package/src/Ecosystem.res +3 -3
  17. package/src/Ecosystem.res.mjs +3 -3
  18. package/src/Envio.res +14 -9
  19. package/src/EventConfigBuilder.res +105 -56
  20. package/src/EventConfigBuilder.res.mjs +69 -33
  21. package/src/EventProcessing.res +19 -15
  22. package/src/EventProcessing.res.mjs +13 -12
  23. package/src/FetchState.res +375 -171
  24. package/src/FetchState.res.mjs +249 -251
  25. package/src/HandlerLoader.res +7 -112
  26. package/src/HandlerLoader.res.mjs +1 -87
  27. package/src/HandlerRegister.res +209 -6
  28. package/src/HandlerRegister.res.mjs +90 -5
  29. package/src/HandlerRegister.resi +13 -2
  30. package/src/IndexerState.res +6 -3
  31. package/src/IndexerState.res.mjs +3 -3
  32. package/src/IndexerState.resi +1 -1
  33. package/src/IndexingAddresses.res +10 -7
  34. package/src/IndexingAddresses.res.mjs +8 -7
  35. package/src/IndexingAddresses.resi +3 -1
  36. package/src/Internal.res +82 -36
  37. package/src/Internal.res.mjs +11 -1
  38. package/src/Main.res +22 -23
  39. package/src/Main.res.mjs +15 -17
  40. package/src/Metrics.res +43 -2
  41. package/src/Metrics.res.mjs +39 -3
  42. package/src/Prometheus.res +0 -35
  43. package/src/Prometheus.res.mjs +33 -68
  44. package/src/RawEvent.res +7 -2
  45. package/src/RawEvent.res.mjs +4 -4
  46. package/src/SimulateItems.res +20 -7
  47. package/src/SimulateItems.res.mjs +7 -11
  48. package/src/TestIndexer.res +1 -1
  49. package/src/TestIndexer.res.mjs +1 -1
  50. package/src/sources/BlockStore.res +46 -0
  51. package/src/sources/BlockStore.res.mjs +24 -0
  52. package/src/sources/EventRouter.res +19 -12
  53. package/src/sources/EventRouter.res.mjs +7 -5
  54. package/src/sources/Evm.res +54 -4
  55. package/src/sources/Evm.res.mjs +43 -4
  56. package/src/sources/EvmChain.res +14 -18
  57. package/src/sources/EvmChain.res.mjs +12 -13
  58. package/src/sources/FieldMask.res +39 -0
  59. package/src/sources/FieldMask.res.mjs +42 -0
  60. package/src/sources/Fuel.res +5 -2
  61. package/src/sources/Fuel.res.mjs +4 -3
  62. package/src/sources/HyperFuelSource.res +31 -40
  63. package/src/sources/HyperFuelSource.res.mjs +52 -44
  64. package/src/sources/HyperSync.res +31 -9
  65. package/src/sources/HyperSync.res.mjs +47 -31
  66. package/src/sources/HyperSync.resi +10 -3
  67. package/src/sources/HyperSyncClient.res +15 -4
  68. package/src/sources/HyperSyncHeightStream.res +1 -8
  69. package/src/sources/HyperSyncHeightStream.res.mjs +0 -2
  70. package/src/sources/HyperSyncSource.res +37 -58
  71. package/src/sources/HyperSyncSource.res.mjs +42 -42
  72. package/src/sources/RpcSource.res +91 -82
  73. package/src/sources/RpcSource.res.mjs +76 -45
  74. package/src/sources/RpcWebSocketHeightStream.res +0 -5
  75. package/src/sources/RpcWebSocketHeightStream.res.mjs +0 -2
  76. package/src/sources/SimulateSource.res +5 -3
  77. package/src/sources/SimulateSource.res.mjs +12 -4
  78. package/src/sources/Source.res +19 -5
  79. package/src/sources/SourceManager.res +62 -6
  80. package/src/sources/SourceManager.res.mjs +55 -8
  81. package/src/sources/SourceManager.resi +10 -0
  82. package/src/sources/Svm.res +14 -10
  83. package/src/sources/Svm.res.mjs +23 -6
  84. package/src/sources/SvmHyperSyncClient.res +5 -6
  85. package/src/sources/SvmHyperSyncSource.res +82 -41
  86. package/src/sources/SvmHyperSyncSource.res.mjs +86 -41
  87. package/src/sources/TransactionStore.res +6 -107
  88. package/src/sources/TransactionStore.res.mjs +5 -86
  89. package/svm.schema.json +19 -0
@@ -13,10 +13,16 @@ function make(items, endBlock, chain) {
13
13
  poweredByHyperSync: false,
14
14
  pollingInterval: 0,
15
15
  getBlockHashes: (param, param$1) => Promise.resolve({
16
- TAG: "Ok",
17
- _0: []
16
+ result: {
17
+ TAG: "Ok",
18
+ _0: []
19
+ },
20
+ requestStats: []
21
+ }),
22
+ getHeightOrThrow: () => Promise.resolve({
23
+ height: Primitive_int.max(endBlock, 1),
24
+ requestStats: []
18
25
  }),
19
- getHeightOrThrow: () => Promise.resolve(Primitive_int.max(endBlock, 1)),
20
26
  getItemsOrThrow: (param, param$1, param$2, param$3, param$4, param$5, param$6, param$7, param$8, param$9) => {
21
27
  let result = delivered.contents ? [] : (delivered.contents = true, items);
22
28
  let reportedHeight = Primitive_int.max(endBlock, 1);
@@ -25,12 +31,14 @@ function make(items, endBlock, chain) {
25
31
  blockHashes: [],
26
32
  parsedQueueItems: result,
27
33
  transactionStore: undefined,
34
+ blockStore: undefined,
28
35
  fromBlockQueried: 0,
29
36
  latestFetchedBlockNumber: reportedHeight,
30
37
  latestFetchedBlockTimestamp: 0,
31
38
  stats: {
32
39
  "total time elapsed (s)": 0
33
- }
40
+ },
41
+ requestStats: []
34
42
  });
35
43
  },
36
44
  simulateItems: items
@@ -7,6 +7,11 @@ type blockRangeFetchStats = {
7
7
  @as("page fetch time (s)") pageFetchTime?: float,
8
8
  }
9
9
 
10
+ // A single backend request a source method actually made (cache/dedup hits
11
+ // aren't requests), with the time it took. SourceManager aggregates these
12
+ // per (source, method) into the envio_source_request_* metrics.
13
+ type requestStat = {method: string, seconds: float}
14
+
10
15
  /**
11
16
  Thes response returned from a block range fetch
12
17
  */
@@ -22,10 +27,22 @@ type blockRangeFetchResponse = {
22
27
  // transactionIndex); merged into the chain's store on apply. `None` for
23
28
  // sources that keep the transaction inline on the payload (RPC/Fuel/Simulate).
24
29
  transactionStore: option<TransactionStore.t>,
30
+ // Page of blocks for this response's items, keyed by block number; merged into
31
+ // the chain's store on apply. `None` for sources that keep the block fully
32
+ // inline on the payload (RPC/Fuel/Simulate).
33
+ blockStore: option<BlockStore.t>,
25
34
  fromBlockQueried: int,
26
35
  latestFetchedBlockNumber: int,
27
36
  latestFetchedBlockTimestamp: int,
28
37
  stats: blockRangeFetchStats,
38
+ requestStats: array<requestStat>,
39
+ }
40
+
41
+ type getHeightResponse = {height: int, requestStats: array<requestStat>}
42
+
43
+ type getBlockHashesResponse = {
44
+ result: result<array<ReorgDetection.blockDataWithTimestamp>, exn>,
45
+ requestStats: array<requestStat>,
29
46
  }
30
47
 
31
48
  type getItemsRetry =
@@ -51,11 +68,8 @@ type t = {
51
68
  poweredByHyperSync: bool,
52
69
  /* Frequency (in ms) used when polling for new events on this network. */
53
70
  pollingInterval: int,
54
- getBlockHashes: (
55
- ~blockNumbers: array<int>,
56
- ~logger: Pino.t,
57
- ) => promise<result<array<ReorgDetection.blockDataWithTimestamp>, exn>>,
58
- getHeightOrThrow: unit => promise<int>,
71
+ getBlockHashes: (~blockNumbers: array<int>, ~logger: Pino.t) => promise<getBlockHashesResponse>,
72
+ getHeightOrThrow: unit => promise<getHeightResponse>,
59
73
  getItemsOrThrow: (
60
74
  ~fromBlock: int,
61
75
  ~toBlock: option<int>,
@@ -1,5 +1,10 @@
1
1
  type sourceManagerStatus = Idle | WaitingForNewBlock | Querieng
2
2
 
3
+ // Cumulative per-method request count/time for a source, aggregated from the
4
+ // requestStat arrays returned by its methods. Rendered into
5
+ // envio_source_request_* by Metrics.renderSourceRequests.
6
+ type requestStatAgg = {mutable count: int, mutable seconds: float}
7
+
3
8
  type sourceState = {
4
9
  source: Source.t,
5
10
  mutable knownHeight: int,
@@ -9,6 +14,28 @@ type sourceState = {
9
14
  // Timestamp (ms) when this source last failed during executeQuery.
10
15
  // Used to decide when to attempt recovery to this source.
11
16
  mutable lastFailedAt: option<float>,
17
+ requestStats: dict<requestStatAgg>,
18
+ }
19
+
20
+ let recordRequestStats = (sourceState: sourceState, requestStats: array<Source.requestStat>) => {
21
+ requestStats->Array.forEach(({method, seconds}) => {
22
+ switch sourceState.requestStats->Utils.Dict.dangerouslyGetNonOption(method) {
23
+ | Some(agg) =>
24
+ agg.count = agg.count + 1
25
+ agg.seconds = agg.seconds +. seconds
26
+ | None => sourceState.requestStats->Dict.set(method, {count: 1, seconds})
27
+ }
28
+ })
29
+ }
30
+
31
+ // Flattened (source, method) aggregates for Metrics.renderSourceRequests to
32
+ // inline into the /metrics response.
33
+ type requestStatSample = {
34
+ sourceName: string,
35
+ chainId: int,
36
+ method: string,
37
+ count: int,
38
+ seconds: float,
12
39
  }
13
40
 
14
41
  // Encapsulates the fetching logic for a chain's sources.
@@ -46,6 +73,25 @@ type t = {
46
73
 
47
74
  let getActiveSource = sourceManager => sourceManager.activeSource
48
75
 
76
+ let getRequestStatSamples = (sourceManager: t): array<requestStatSample> => {
77
+ let samples = []
78
+ sourceManager.sourcesState->Array.forEach(sourceState => {
79
+ let chainId = sourceState.source.chain->ChainMap.Chain.toChainId
80
+ sourceState.requestStats->Utils.Dict.forEachWithKey((agg, method) => {
81
+ samples
82
+ ->Array.push({
83
+ sourceName: sourceState.source.name,
84
+ chainId,
85
+ method,
86
+ count: agg.count,
87
+ seconds: agg.seconds,
88
+ })
89
+ ->ignore
90
+ })
91
+ })
92
+ samples
93
+ }
94
+
49
95
  // Partition queries currently in flight on this chain's sources. Summed across
50
96
  // chains by CrossChainState to enforce the indexer-wide concurrency budget.
51
97
  let inFlightCount = sourceManager => sourceManager.fetchingPartitionsCount
@@ -187,6 +233,7 @@ let make = (
187
233
  pendingHeightResolvers: [],
188
234
  disabled: false,
189
235
  lastFailedAt: None,
236
+ requestStats: Dict.make(),
190
237
  }),
191
238
  activeSource: initialActiveSource,
192
239
  waitingForNewBlockStateId: None,
@@ -344,7 +391,9 @@ let getSourceNewHeight = async (
344
391
  let h = ref(initialHeight)
345
392
  while h.contents <= knownHeight && !(newHeight.contents > initialHeight) {
346
393
  try {
347
- h := (await source.getHeightOrThrow())
394
+ let res = await source.getHeightOrThrow()
395
+ sourceState->recordRequestStats(res.requestStats)
396
+ h := res.height
348
397
  } catch {
349
398
  | _ => ()
350
399
  }
@@ -363,7 +412,9 @@ let getSourceNewHeight = async (
363
412
  | None =>
364
413
  // No subscription, use REST polling
365
414
  try {
366
- let height = await source.getHeightOrThrow()
415
+ let res = await source.getHeightOrThrow()
416
+ sourceState->recordRequestStats(res.requestStats)
417
+ let height = res.height
367
418
 
368
419
  newHeight := height
369
420
  if height <= knownHeight {
@@ -385,6 +436,9 @@ let getSourceNewHeight = async (
385
436
  }
386
437
  })
387
438
  sourceState.unsubscribe = Some(unsubscribe)
439
+ // Count a subscription (re)start rather than every pushed height —
440
+ // there's no request/response to time here.
441
+ sourceState->recordRequestStats([{Source.method: "heightSubscription", seconds: 0.}])
388
442
  | _ =>
389
443
  // Slowdown polling when the chain isn't progressing
390
444
  let pollingInterval = if reducedPolling {
@@ -680,16 +734,17 @@ let executeQuery = async (
680
734
  ~partitionId=query.partitionId,
681
735
  ~knownHeight,
682
736
  ~selection=query.selection,
683
- // Ceil (not truncate) so a sub-1 estimate from a sparse partition over a
737
+ // Ceil (not truncate) so a sub-1 target from a sparse partition over a
684
738
  // small range doesn't round down to 0 and ask the backend to cap the
685
739
  // response at nothing — 0 items is indistinguishable from "no signal".
686
740
  ~itemsTarget={
687
- let est = query.estResponseSize->Math.ceil->Float.toInt
688
- est > 0 ? est : FetchState.minEstResponseSize->Float.toInt
741
+ let target = query.itemsTarget->Math.ceil->Float.toInt
742
+ target > 0 ? target : FetchState.minItemsTarget->Float.toInt
689
743
  },
690
744
  ~retry,
691
745
  ~logger,
692
746
  )
747
+ sourceState->recordRequestStats(response.requestStats)
693
748
  sourceState.lastFailedAt = None
694
749
  responseRef := Some(response)
695
750
  } catch {
@@ -829,7 +884,8 @@ let getBlockHashes = async (sourceManager: t, ~blockNumbers: array<int>, ~isReal
829
884
 
830
885
  try {
831
886
  let res = await source.getBlockHashes(~blockNumbers, ~logger)
832
- switch res {
887
+ sourceState->recordRequestStats(res.requestStats)
888
+ switch res.result {
833
889
  | Ok(data) =>
834
890
  sourceState.lastFailedAt = None
835
891
  responseRef := Some(data)
@@ -14,10 +14,44 @@ import * as Primitive_float from "@rescript/runtime/lib/es6/Primitive_float.js";
14
14
  import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
15
15
  import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
16
16
 
17
+ function recordRequestStats(sourceState, requestStats) {
18
+ requestStats.forEach(param => {
19
+ let seconds = param.seconds;
20
+ let method = param.method;
21
+ let agg = sourceState.requestStats[method];
22
+ if (agg !== undefined) {
23
+ agg.count = agg.count + 1 | 0;
24
+ agg.seconds = agg.seconds + seconds;
25
+ } else {
26
+ sourceState.requestStats[method] = {
27
+ count: 1,
28
+ seconds: seconds
29
+ };
30
+ }
31
+ });
32
+ }
33
+
17
34
  function getActiveSource(sourceManager) {
18
35
  return sourceManager.activeSource;
19
36
  }
20
37
 
38
+ function getRequestStatSamples(sourceManager) {
39
+ let samples = [];
40
+ sourceManager.sourcesState.forEach(sourceState => {
41
+ let chainId = sourceState.source.chain;
42
+ Utils.Dict.forEachWithKey(sourceState.requestStats, (agg, method) => {
43
+ samples.push({
44
+ sourceName: sourceState.source.name,
45
+ chainId: chainId,
46
+ method: method,
47
+ count: agg.count,
48
+ seconds: agg.seconds
49
+ });
50
+ });
51
+ });
52
+ return samples;
53
+ }
54
+
21
55
  function inFlightCount(sourceManager) {
22
56
  return sourceManager.fetchingPartitionsCount;
23
57
  }
@@ -137,7 +171,8 @@ function make(sources, isRealtime, newBlockStallTimeoutOpt, newBlockStallTimeout
137
171
  unsubscribe: undefined,
138
172
  pendingHeightResolvers: [],
139
173
  disabled: false,
140
- lastFailedAt: undefined
174
+ lastFailedAt: undefined,
175
+ requestStats: {}
141
176
  })),
142
177
  statusStart: Performance.now(),
143
178
  status: "Idle",
@@ -263,7 +298,9 @@ async function getSourceNewHeight(sourceManager, sourceState, knownHeight, stall
263
298
  let h = initialHeight;
264
299
  while (h <= knownHeight && newHeight.contents <= initialHeight) {
265
300
  try {
266
- h = await source.getHeightOrThrow();
301
+ let res = await source.getHeightOrThrow();
302
+ recordRequestStats(sourceState, res.requestStats);
303
+ h = res.height;
267
304
  } catch (exn) {
268
305
 
269
306
  }
@@ -282,7 +319,9 @@ async function getSourceNewHeight(sourceManager, sourceState, knownHeight, stall
282
319
  }
283
320
  } else {
284
321
  try {
285
- let height$1 = await source.getHeightOrThrow();
322
+ let res = await source.getHeightOrThrow();
323
+ recordRequestStats(sourceState, res.requestStats);
324
+ let height$1 = res.height;
286
325
  newHeight.contents = height$1;
287
326
  if (height$1 <= knownHeight) {
288
327
  retry = 0;
@@ -299,6 +338,10 @@ async function getSourceNewHeight(sourceManager, sourceState, knownHeight, stall
299
338
  resolvers.forEach(resolve => resolve(newHeight));
300
339
  });
301
340
  sourceState.unsubscribe = unsubscribe;
341
+ recordRequestStats(sourceState, [{
342
+ method: "heightSubscription",
343
+ seconds: 0
344
+ }]);
302
345
  } else {
303
346
  exit = 1;
304
347
  }
@@ -500,8 +543,9 @@ async function executeQuery(sourceManager, query, knownHeight, isRealtime) {
500
543
  retry: retry
501
544
  });
502
545
  try {
503
- let est = Math.ceil(query.estResponseSize) | 0;
504
- let response = await source.getItemsOrThrow(query.fromBlock, toBlock, query.addressesByContractName, FetchState.deriveContractNameByAddress(query.addressesByContractName), knownHeight, query.partitionId, query.selection, est > 0 ? est : FetchState.minEstResponseSize | 0, retry, logger$2);
546
+ let target = Math.ceil(query.itemsTarget) | 0;
547
+ let response = await source.getItemsOrThrow(query.fromBlock, toBlock, query.addressesByContractName, FetchState.deriveContractNameByAddress(query.addressesByContractName), knownHeight, query.partitionId, query.selection, target > 0 ? target : FetchState.minItemsTarget | 0, retry, logger$2);
548
+ recordRequestStats(sourceState, response.requestStats);
505
549
  sourceState.lastFailedAt = undefined;
506
550
  responseRef = response;
507
551
  } catch (raw_error) {
@@ -637,11 +681,13 @@ async function getBlockHashes(sourceManager, blockNumbers, isRealtime) {
637
681
  });
638
682
  try {
639
683
  let res = await source.getBlockHashes(blockNumbers, logger$1);
640
- if (res.TAG === "Ok") {
684
+ recordRequestStats(sourceState, res.requestStats);
685
+ let data = res.result;
686
+ if (data.TAG === "Ok") {
641
687
  sourceState.lastFailedAt = undefined;
642
- responseRef = res._0;
688
+ responseRef = data._0;
643
689
  } else {
644
- throw res._0;
690
+ throw data._0;
645
691
  }
646
692
  } catch (raw_exn) {
647
693
  let exn = Primitive_exceptions.internalToException(raw_exn);
@@ -673,6 +719,7 @@ export {
673
719
  getSourceRole,
674
720
  make,
675
721
  getActiveSource,
722
+ getRequestStatSamples,
676
723
  inFlightCount,
677
724
  onReorg,
678
725
  dispatch,
@@ -21,6 +21,16 @@ let make: (
21
21
 
22
22
  let getActiveSource: t => Source.t
23
23
 
24
+ type requestStatSample = {
25
+ sourceName: string,
26
+ chainId: int,
27
+ method: string,
28
+ count: int,
29
+ seconds: float,
30
+ }
31
+
32
+ let getRequestStatSamples: t => array<requestStatSample>
33
+
24
34
  let inFlightCount: t => int
25
35
 
26
36
  let onReorg: (t, ~rollbackTargetBlock: int) => unit
@@ -16,6 +16,17 @@ let transactionFields =
16
16
  // Computed per event at config build and cached on the event config.
17
17
  let eventTransactionFieldMask = TransactionStore.makeMaskFn(transactionFields)
18
18
 
19
+ // Ordered block field names. The index of each is the field code shared with the
20
+ // Rust store (`SvmBlockField`) — keep this order in sync.
21
+ let blockFields = ["slot", "time", "hash", "height", "parentSlot", "parentHash"]
22
+
23
+ // `slot`/`time`/`hash` are always included; every other block field is opt-in
24
+ // via `field_selection.block_fields`. All are materialised from the store.
25
+ //
26
+ // One instruction's selected block fields → store selection bitmask. Computed per
27
+ // event at config build and cached on the event config.
28
+ let eventBlockFieldMask = BlockStore.makeMaskFn(blockFields)
29
+
19
30
  let make = (~logger: Pino.t): Ecosystem.t => {
20
31
  name: Svm,
21
32
  blockNumberName: "height",
@@ -37,8 +48,8 @@ let make = (~logger: Pino.t): Ecosystem.t => {
37
48
  Logging.createChildFrom(
38
49
  ~logger,
39
50
  ~params={
40
- "program": eventItem.eventConfig.contractName,
41
- "instruction": eventItem.eventConfig.name,
51
+ "program": eventItem.onEventRegistration.eventConfig.contractName,
52
+ "instruction": eventItem.onEventRegistration.eventConfig.name,
42
53
  "chainId": eventItem.chain->ChainMap.Chain.toChainId,
43
54
  "slot": eventItem.blockNumber,
44
55
  "programId": instruction.programId,
@@ -84,14 +95,7 @@ let makeRPCSource = (~chain, ~rpc: string, ~sourceFor: Source.sourceFor=Sync): S
84
95
  let timerRef = Performance.now()
85
96
  let height = await GetFinalizedSlot.route->Rest.fetch((), ~client)
86
97
  let seconds = timerRef->Performance.secondsSince
87
- Prometheus.SourceRequestCount.increment(~sourceName=name, ~chainId, ~method="getSlot")
88
- Prometheus.SourceRequestCount.addSeconds(
89
- ~sourceName=name,
90
- ~chainId,
91
- ~method="getSlot",
92
- ~seconds,
93
- )
94
- height
98
+ {Source.height, requestStats: [{Source.method: "getSlot", seconds}]}
95
99
  },
96
100
  getItemsOrThrow: (
97
101
  ~fromBlock as _,
@@ -5,7 +5,7 @@ import * as Rest from "../vendored/Rest.res.mjs";
5
5
  import * as Utils from "../Utils.res.mjs";
6
6
  import * as Logging from "../Logging.res.mjs";
7
7
  import * as Internal from "../Internal.res.mjs";
8
- import * as Prometheus from "../Prometheus.res.mjs";
8
+ import * as BlockStore from "./BlockStore.res.mjs";
9
9
  import * as Performance from "../bindings/Performance.res.mjs";
10
10
  import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
11
11
  import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
@@ -19,6 +19,17 @@ let cleanUpRawEventFieldsInPlace = (fields => {
19
19
 
20
20
  let eventTransactionFieldMask = TransactionStore.makeMaskFn(Internal.allSvmTransactionFields);
21
21
 
22
+ let blockFields = [
23
+ "slot",
24
+ "time",
25
+ "hash",
26
+ "height",
27
+ "parentSlot",
28
+ "parentHash"
29
+ ];
30
+
31
+ let eventBlockFieldMask = BlockStore.makeMaskFn(blockFields);
32
+
22
33
  function make(logger) {
23
34
  return {
24
35
  name: "svm",
@@ -34,8 +45,8 @@ function make(logger) {
34
45
  toEventLogger: eventItem => {
35
46
  let instruction = eventItem.payload;
36
47
  return Logging.createChildFrom(logger, {
37
- program: eventItem.eventConfig.contractName,
38
- instruction: eventItem.eventConfig.name,
48
+ program: eventItem.onEventRegistration.eventConfig.contractName,
49
+ instruction: eventItem.onEventRegistration.eventConfig.name,
39
50
  chainId: eventItem.chain,
40
51
  slot: eventItem.blockNumber,
41
52
  programId: instruction.programId
@@ -72,9 +83,13 @@ function makeRPCSource(chain, rpc, sourceForOpt) {
72
83
  let timerRef = Performance.now();
73
84
  let height = await Rest.fetch(route, undefined, client);
74
85
  let seconds = Performance.secondsSince(timerRef);
75
- Prometheus.SourceRequestCount.increment(name, chain, "getSlot");
76
- Prometheus.SourceRequestCount.addSeconds(name, chain, "getSlot", seconds);
77
- return height;
86
+ return {
87
+ height: height,
88
+ requestStats: [{
89
+ method: "getSlot",
90
+ seconds: seconds
91
+ }]
92
+ };
78
93
  },
79
94
  getItemsOrThrow: (param, param$1, param$2, param$3, param$4, param$5, param$6, param$7, param$8, param$9) => Stdlib_JsError.throwWithMessage("Svm does not support getting items")
80
95
  };
@@ -86,6 +101,8 @@ export {
86
101
  cleanUpRawEventFieldsInPlace,
87
102
  transactionFields,
88
103
  eventTransactionFieldMask,
104
+ blockFields,
105
+ eventBlockFieldMask,
89
106
  make,
90
107
  GetFinalizedSlot,
91
108
  makeRPCSource,
@@ -138,13 +138,12 @@ module QueryTypes = {
138
138
  }
139
139
 
140
140
  module ResponseTypes = {
141
+ // Lean per-slot header for reorg detection and each item's slot/time; the
142
+ // selectable fields live in the block store and are materialised on demand.
141
143
  type block = {
142
144
  slot: int,
143
145
  blockhash: string,
144
- parentSlot?: int,
145
- parentBlockhash?: string,
146
146
  blockTime?: int,
147
- blockHeight?: int,
148
147
  }
149
148
 
150
149
  /// Borsh-decoded view attached by the Rust client. `argsJson`/`accountsJson`
@@ -206,9 +205,9 @@ type queryResponse = ResponseTypes.queryResponse
206
205
 
207
206
  type t = {
208
207
  getHeight: unit => promise<int>,
209
- // Returns the response plus a page of raw transactions (kept in Rust),
210
- // keyed by (slot, transactionIndex), materialised at batch prep.
211
- get: (~query: query) => promise<(queryResponse, TransactionStore.t)>,
208
+ // Returns the response plus pages of raw transactions and blocks (kept in
209
+ // Rust), keyed by (slot, transactionIndex) / slot, materialised at batch prep.
210
+ get: (~query: query) => promise<(queryResponse, TransactionStore.t, BlockStore.t)>,
212
211
  }
213
212
 
214
213
  @send