envio 3.3.0-alpha.1 → 3.3.0-alpha.3

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 (84) hide show
  1. package/index.d.ts +23 -21
  2. package/package.json +6 -6
  3. package/src/Batch.res +0 -6
  4. package/src/Batch.res.mjs +0 -11
  5. package/src/BatchProcessing.res +2 -12
  6. package/src/BatchProcessing.res.mjs +2 -7
  7. package/src/ChainFetching.res +42 -6
  8. package/src/ChainFetching.res.mjs +30 -11
  9. package/src/ChainMetadata.res +1 -11
  10. package/src/ChainMetadata.res.mjs +1 -10
  11. package/src/ChainState.res +150 -1
  12. package/src/ChainState.res.mjs +138 -9
  13. package/src/ChainState.resi +51 -1
  14. package/src/Config.res +3 -6
  15. package/src/Config.res.mjs +2 -3
  16. package/src/Core.res +7 -0
  17. package/src/CrossChainState.res +24 -26
  18. package/src/CrossChainState.res.mjs +19 -16
  19. package/src/Ecosystem.res +6 -3
  20. package/src/Envio.res +3 -2
  21. package/src/EventConfigBuilder.res +61 -23
  22. package/src/EventConfigBuilder.res.mjs +27 -13
  23. package/src/EventProcessing.res +63 -21
  24. package/src/EventProcessing.res.mjs +47 -22
  25. package/src/FetchState.res +53 -43
  26. package/src/FetchState.res.mjs +71 -54
  27. package/src/HandlerLoader.res +10 -1
  28. package/src/HandlerLoader.res.mjs +15 -8
  29. package/src/Internal.res +46 -7
  30. package/src/Internal.res.mjs +19 -1
  31. package/src/LoadLayer.res +5 -5
  32. package/src/LoadLayer.res.mjs +6 -6
  33. package/src/Main.res +3 -50
  34. package/src/Main.res.mjs +2 -23
  35. package/src/PgStorage.res +4 -4
  36. package/src/PgStorage.res.mjs +5 -5
  37. package/src/Prometheus.res +10 -10
  38. package/src/Prometheus.res.mjs +9 -9
  39. package/src/PruneStaleHistory.res +2 -2
  40. package/src/PruneStaleHistory.res.mjs +3 -3
  41. package/src/Rollback.res +3 -3
  42. package/src/Rollback.res.mjs +4 -4
  43. package/src/SimulateItems.res +80 -15
  44. package/src/SimulateItems.res.mjs +65 -21
  45. package/src/TestIndexer.res +48 -36
  46. package/src/TestIndexer.res.mjs +35 -28
  47. package/src/bindings/Performance.res +7 -0
  48. package/src/bindings/Performance.res.mjs +21 -0
  49. package/src/bindings/Performance.resi +7 -0
  50. package/src/sources/EventRouter.res +17 -21
  51. package/src/sources/EventRouter.res.mjs +6 -9
  52. package/src/sources/Evm.res +47 -67
  53. package/src/sources/Evm.res.mjs +42 -65
  54. package/src/sources/Fuel.res +3 -3
  55. package/src/sources/Fuel.res.mjs +1 -6
  56. package/src/sources/HyperFuelSource.res +15 -11
  57. package/src/sources/HyperFuelSource.res.mjs +13 -11
  58. package/src/sources/HyperSync.res +7 -1
  59. package/src/sources/HyperSync.res.mjs +6 -3
  60. package/src/sources/HyperSync.resi +2 -0
  61. package/src/sources/HyperSyncClient.res +14 -79
  62. package/src/sources/HyperSyncClient.res.mjs +1 -22
  63. package/src/sources/HyperSyncSource.res +44 -27
  64. package/src/sources/HyperSyncSource.res.mjs +32 -27
  65. package/src/sources/RpcSource.res +14 -10
  66. package/src/sources/RpcSource.res.mjs +11 -9
  67. package/src/sources/SimulateSource.res +4 -2
  68. package/src/sources/SimulateSource.res.mjs +1 -0
  69. package/src/sources/Source.res +5 -1
  70. package/src/sources/SourceManager.res +17 -16
  71. package/src/sources/SourceManager.res.mjs +10 -15
  72. package/src/sources/Svm.res +23 -6
  73. package/src/sources/Svm.res.mjs +24 -6
  74. package/src/sources/SvmHyperSyncClient.res +3 -29
  75. package/src/sources/SvmHyperSyncSource.res +78 -96
  76. package/src/sources/SvmHyperSyncSource.res.mjs +79 -91
  77. package/src/sources/TransactionStore.res +128 -0
  78. package/src/sources/TransactionStore.res.mjs +97 -0
  79. package/src/tui/Tui.res +13 -16
  80. package/src/tui/Tui.res.mjs +12 -14
  81. package/svm.schema.json +30 -37
  82. package/src/bindings/Hrtime.res +0 -58
  83. package/src/bindings/Hrtime.res.mjs +0 -90
  84. package/src/bindings/Hrtime.resi +0 -30
package/src/LoadLayer.res CHANGED
@@ -85,7 +85,7 @@ let callEffect = (
85
85
  )
86
86
 
87
87
  if hadActiveCalls {
88
- let elapsed = Hrtime.secondsBetween(~from=effect.prevCallStartTimerRef, ~to=timerRef)
88
+ let elapsed = Performance.secondsBetween(~from=effect.prevCallStartTimerRef, ~to=timerRef)
89
89
  if elapsed > 0. {
90
90
  Prometheus.EffectCalls.timeCounter->Prometheus.SafeCounter.handleFloat(
91
91
  ~labels=effectName,
@@ -113,17 +113,17 @@ let callEffect = (
113
113
  ~labels=effectName,
114
114
  ~value=effect.activeCallsCount,
115
115
  )
116
- let newTimer = Hrtime.makeTimer()
116
+ let newTimer = Performance.now()
117
117
  Prometheus.EffectCalls.timeCounter->Prometheus.SafeCounter.handleFloat(
118
118
  ~labels=effectName,
119
- ~value=Hrtime.secondsBetween(~from=effect.prevCallStartTimerRef, ~to=newTimer),
119
+ ~value=Performance.secondsBetween(~from=effect.prevCallStartTimerRef, ~to=newTimer),
120
120
  )
121
121
  effect.prevCallStartTimerRef = newTimer
122
122
 
123
123
  Prometheus.EffectCalls.totalCallsCount->Prometheus.SafeCounter.increment(~labels=effectName)
124
124
  Prometheus.EffectCalls.sumTimeCounter->Prometheus.SafeCounter.handleFloat(
125
125
  ~labels=effectName,
126
- ~value=timerRef->Hrtime.timeSince->Hrtime.toSecondsFloat,
126
+ ~value=timerRef->Performance.secondsSince,
127
127
  )
128
128
  })
129
129
  }
@@ -137,7 +137,7 @@ let rec executeWithRateLimit = (
137
137
  ) => {
138
138
  let effectName = effect.name
139
139
 
140
- let timerRef = Hrtime.makeTimer()
140
+ let timerRef = Performance.now()
141
141
  let promises = []
142
142
 
143
143
  switch effect.rateLimit {
@@ -2,11 +2,11 @@
2
2
 
3
3
  import * as Table from "./db/Table.res.mjs";
4
4
  import * as Utils from "./Utils.res.mjs";
5
- import * as Hrtime from "./bindings/Hrtime.res.mjs";
6
5
  import * as Logging from "./Logging.res.mjs";
7
6
  import * as Ecosystem from "./Ecosystem.res.mjs";
8
7
  import * as Prometheus from "./Prometheus.res.mjs";
9
8
  import * as LoadManager from "./LoadManager.res.mjs";
9
+ import * as Performance from "./bindings/Performance.res.mjs";
10
10
  import * as Persistence from "./Persistence.res.mjs";
11
11
  import * as EntityFilter from "./db/EntityFilter.res.mjs";
12
12
  import * as IndexerState from "./IndexerState.res.mjs";
@@ -55,7 +55,7 @@ function callEffect(effect, arg, inMemTable, timerRef, onError) {
55
55
  effect.activeCallsCount = effect.activeCallsCount + 1 | 0;
56
56
  Prometheus.SafeGauge.handleInt(Prometheus.EffectCalls.activeCallsCount, effectName, effect.activeCallsCount);
57
57
  if (hadActiveCalls) {
58
- let elapsed = Hrtime.secondsBetween(effect.prevCallStartTimerRef, timerRef);
58
+ let elapsed = Performance.secondsBetween(effect.prevCallStartTimerRef, timerRef);
59
59
  if (elapsed > 0) {
60
60
  Prometheus.SafeCounter.handleFloat(Prometheus.EffectCalls.timeCounter, effectName, elapsed);
61
61
  }
@@ -64,17 +64,17 @@ function callEffect(effect, arg, inMemTable, timerRef, onError) {
64
64
  return effect.handler(arg).then(output => InMemoryStore.setEffectOutput(inMemTable, arg.checkpointId, arg.cacheKey, output, arg.context.cache)).catch(exn => onError(arg.cacheKey, exn)).finally(() => {
65
65
  effect.activeCallsCount = effect.activeCallsCount - 1 | 0;
66
66
  Prometheus.SafeGauge.handleInt(Prometheus.EffectCalls.activeCallsCount, effectName, effect.activeCallsCount);
67
- let newTimer = Hrtime.makeTimer();
68
- Prometheus.SafeCounter.handleFloat(Prometheus.EffectCalls.timeCounter, effectName, Hrtime.secondsBetween(effect.prevCallStartTimerRef, newTimer));
67
+ let newTimer = Performance.now();
68
+ Prometheus.SafeCounter.handleFloat(Prometheus.EffectCalls.timeCounter, effectName, Performance.secondsBetween(effect.prevCallStartTimerRef, newTimer));
69
69
  effect.prevCallStartTimerRef = newTimer;
70
70
  Prometheus.SafeCounter.increment(Prometheus.EffectCalls.totalCallsCount, effectName);
71
- Prometheus.SafeCounter.handleFloat(Prometheus.EffectCalls.sumTimeCounter, effectName, Hrtime.toSecondsFloat(Hrtime.timeSince(timerRef)));
71
+ Prometheus.SafeCounter.handleFloat(Prometheus.EffectCalls.sumTimeCounter, effectName, Performance.secondsSince(timerRef));
72
72
  });
73
73
  }
74
74
 
75
75
  function executeWithRateLimit(effect, effectArgs, inMemTable, onError, isFromQueue) {
76
76
  let effectName = effect.name;
77
- let timerRef = Hrtime.makeTimer();
77
+ let timerRef = Performance.now();
78
78
  let promises = [];
79
79
  let state = effect.rateLimit;
80
80
  if (state !== undefined) {
package/src/Main.res CHANGED
@@ -1,19 +1,4 @@
1
- type chainData = {
2
- chainId: float,
3
- poweredByHyperSync: bool,
4
- firstEventBlockNumber: option<int>,
5
- latestProcessedBlock: option<int>,
6
- timestampCaughtUpToHeadOrEndblock: option<Date.t>,
7
- numEventsProcessed: float,
8
- latestFetchedBlockNumber: int,
9
- // Need this for API backwards compatibility
10
- @as("currentBlockHeight")
11
- knownHeight: int,
12
- numBatchesFetched: int,
13
- startBlock: int,
14
- endBlock: option<int>,
15
- numAddresses: int,
16
- }
1
+ type chainData = ChainState.chainData
17
2
  @tag("status")
18
3
  type state =
19
4
  | @as("disabled") Disabled({})
@@ -183,7 +168,7 @@ let buildChainsObject = (~config: Config.t) => {
183
168
  | Some(state) => {
184
169
  let chain = ChainMap.Chain.makeUnsafe(~chainId=chainConfig.id)
185
170
  let chainState = state->IndexerState.getChainState(~chain)
186
- let indexingAddresses = (chainState->ChainState.fetchState).indexingAddresses
171
+ let indexingAddresses = chainState->ChainState.indexingAddresses
187
172
 
188
173
  // Collect all addresses for this contract name from indexingAddresses
189
174
  let addresses = []
@@ -780,39 +765,7 @@ let start = async (
780
765
  | None => Initializing({})
781
766
  | Some(state) => {
782
767
  let chains =
783
- state
784
- ->IndexerState.chainStates
785
- ->Dict.valuesToArray
786
- ->Array.map(cs => {
787
- let fetchState = cs->ChainState.fetchState
788
- let latestFetchedBlockNumber = Pervasives.max(
789
- FetchState.bufferBlockNumber(fetchState),
790
- 0,
791
- )
792
- let knownHeight =
793
- cs->ChainState.hasProcessedToEndblock
794
- ? fetchState.endBlock->Option.getOr(fetchState.knownHeight)
795
- : fetchState.knownHeight
796
-
797
- {
798
- chainId: (cs->ChainState.chainConfig).id->Int.toFloat,
799
- poweredByHyperSync: (
800
- cs->ChainState.sourceManager->SourceManager.getActiveSource
801
- ).poweredByHyperSync,
802
- latestFetchedBlockNumber,
803
- knownHeight,
804
- numBatchesFetched: 0,
805
- startBlock: fetchState.startBlock,
806
- endBlock: fetchState.endBlock,
807
- firstEventBlockNumber: fetchState.firstEventBlock,
808
- latestProcessedBlock: cs->ChainState.committedProgressBlockNumber === -1
809
- ? None
810
- : Some(cs->ChainState.committedProgressBlockNumber),
811
- timestampCaughtUpToHeadOrEndblock: cs->ChainState.timestampCaughtUpToHeadOrEndblock,
812
- numEventsProcessed: cs->ChainState.numEventsProcessed,
813
- numAddresses: fetchState->FetchState.numAddresses,
814
- }
815
- })
768
+ state->IndexerState.chainStates->Dict.valuesToArray->Array.map(ChainState.toChainData)
816
769
  Active({
817
770
  envioVersion,
818
771
  chains,
package/src/Main.res.mjs CHANGED
@@ -11,7 +11,6 @@ import * as Process from "process";
11
11
  import * as ChainMap from "./ChainMap.res.mjs";
12
12
  import * as PgStorage from "./PgStorage.res.mjs";
13
13
  import * as ChainState from "./ChainState.res.mjs";
14
- import * as FetchState from "./FetchState.res.mjs";
15
14
  import * as Prometheus from "./Prometheus.res.mjs";
16
15
  import * as IndexerLoop from "./IndexerLoop.res.mjs";
17
16
  import * as Persistence from "./Persistence.res.mjs";
@@ -20,8 +19,6 @@ import Yargs from "yargs/yargs";
20
19
  import * as IndexerState from "./IndexerState.res.mjs";
21
20
  import * as ErrorHandling from "./ErrorHandling.res.mjs";
22
21
  import * as HandlerLoader from "./HandlerLoader.res.mjs";
23
- import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
24
- import * as SourceManager from "./sources/SourceManager.res.mjs";
25
22
  import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
26
23
  import * as Helpers from "yargs/helpers";
27
24
  import * as RollbackCommit from "./RollbackCommit.res.mjs";
@@ -168,7 +165,7 @@ function buildChainsObject(config) {
168
165
  if (state !== undefined) {
169
166
  let chain = ChainMap.Chain.makeUnsafe(chainConfig.id);
170
167
  let chainState = IndexerState.getChainState(Primitive_option.valFromOption(state), chain);
171
- let indexingAddresses = ChainState.fetchState(chainState).indexingAddresses;
168
+ let indexingAddresses = ChainState.indexingAddresses(chainState);
172
169
  let addresses = [];
173
170
  let values = Object.values(indexingAddresses);
174
171
  for (let idx = 0, idx_finish = values.length; idx < idx_finish; ++idx) {
@@ -586,25 +583,7 @@ async function start(persistence, resetOpt, isTestOpt, exitAfterFirstEventBlockO
586
583
  };
587
584
  }
588
585
  let state$1 = Primitive_option.valFromOption(state);
589
- let chains = Object.values(IndexerState.chainStates(state$1)).map(cs => {
590
- let fetchState = ChainState.fetchState(cs);
591
- let latestFetchedBlockNumber = Primitive_int.max(FetchState.bufferBlockNumber(fetchState), 0);
592
- let knownHeight = ChainState.hasProcessedToEndblock(cs) ? Stdlib_Option.getOr(fetchState.endBlock, fetchState.knownHeight) : fetchState.knownHeight;
593
- return {
594
- chainId: ChainState.chainConfig(cs).id,
595
- poweredByHyperSync: SourceManager.getActiveSource(ChainState.sourceManager(cs)).poweredByHyperSync,
596
- firstEventBlockNumber: fetchState.firstEventBlock,
597
- latestProcessedBlock: ChainState.committedProgressBlockNumber(cs) === -1 ? undefined : ChainState.committedProgressBlockNumber(cs),
598
- timestampCaughtUpToHeadOrEndblock: ChainState.timestampCaughtUpToHeadOrEndblock(cs),
599
- numEventsProcessed: ChainState.numEventsProcessed(cs),
600
- latestFetchedBlockNumber: latestFetchedBlockNumber,
601
- currentBlockHeight: knownHeight,
602
- numBatchesFetched: 0,
603
- startBlock: fetchState.startBlock,
604
- endBlock: fetchState.endBlock,
605
- numAddresses: FetchState.numAddresses(fetchState)
606
- };
607
- });
586
+ let chains = Object.values(IndexerState.chainStates(state$1)).map(ChainState.toChainData);
608
587
  return {
609
588
  status: "active",
610
589
  envioVersion: envioVersion,
package/src/PgStorage.res CHANGED
@@ -1707,13 +1707,13 @@ SELECT id, chain_id, -1, -1, contract_name FROM unnest($1::text[],$2::int[],$3::
1707
1707
  // Initialize sink if configured
1708
1708
  let sinkPromise = switch sink {
1709
1709
  | Some(sink) => {
1710
- let timerRef = Hrtime.makeTimer()
1710
+ let timerRef = Performance.now()
1711
1711
  Some(
1712
1712
  sink.writeBatch(~batch, ~updatedEntities=chUpdates)
1713
1713
  ->Promise.thenResolve(_ => {
1714
1714
  Prometheus.StorageWrite.increment(
1715
1715
  ~storage=sink.name,
1716
- ~timeSeconds=timerRef->Hrtime.timeSince->Hrtime.toSecondsFloat,
1716
+ ~timeSeconds=timerRef->Performance.secondsSince,
1717
1717
  )
1718
1718
  None
1719
1719
  })
@@ -1724,7 +1724,7 @@ SELECT id, chain_id, -1, -1, contract_name FROM unnest($1::text[],$2::int[],$3::
1724
1724
  | None => None
1725
1725
  }
1726
1726
 
1727
- let primaryTimerRef = Hrtime.makeTimer()
1727
+ let primaryTimerRef = Performance.now()
1728
1728
  await writeBatch(
1729
1729
  sql,
1730
1730
  ~batch,
@@ -1741,7 +1741,7 @@ SELECT id, chain_id, -1, -1, contract_name FROM unnest($1::text[],$2::int[],$3::
1741
1741
  )
1742
1742
  Prometheus.StorageWrite.increment(
1743
1743
  ~storage="postgres",
1744
- ~timeSeconds=primaryTimerRef->Hrtime.timeSince->Hrtime.toSecondsFloat,
1744
+ ~timeSeconds=primaryTimerRef->Performance.secondsSince,
1745
1745
  )
1746
1746
  }
1747
1747
 
@@ -8,13 +8,13 @@ import * as Table from "./db/Table.res.mjs";
8
8
  import * as Utils from "./Utils.res.mjs";
9
9
  import * as Config from "./Config.res.mjs";
10
10
  import * as Hasura from "./Hasura.res.mjs";
11
- import * as Hrtime from "./bindings/Hrtime.res.mjs";
12
11
  import * as Schema from "./db/Schema.res.mjs";
13
12
  import * as Logging from "./Logging.res.mjs";
14
13
  import * as Internal from "./Internal.res.mjs";
15
14
  import Postgres from "postgres";
16
15
  import * as ChainState from "./ChainState.res.mjs";
17
16
  import * as Prometheus from "./Prometheus.res.mjs";
17
+ import * as Performance from "./bindings/Performance.res.mjs";
18
18
  import * as Persistence from "./Persistence.res.mjs";
19
19
  import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
20
20
  import * as EntityHistory from "./db/EntityHistory.res.mjs";
@@ -1116,16 +1116,16 @@ SELECT id, chain_id, -1, -1, contract_name FROM unnest($1::text[],$2::int[],$3::
1116
1116
  }
1117
1117
  let sinkPromise;
1118
1118
  if (sink !== undefined) {
1119
- let timerRef = Hrtime.makeTimer();
1119
+ let timerRef = Performance.now();
1120
1120
  sinkPromise = sink.writeBatch(batch, chUpdates).then(() => {
1121
- Prometheus.StorageWrite.increment(sink.name, Hrtime.toSecondsFloat(Hrtime.timeSince(timerRef)));
1121
+ Prometheus.StorageWrite.increment(sink.name, Performance.secondsSince(timerRef));
1122
1122
  }).catch(exn => exn);
1123
1123
  } else {
1124
1124
  sinkPromise = undefined;
1125
1125
  }
1126
- let primaryTimerRef = Hrtime.makeTimer();
1126
+ let primaryTimerRef = Performance.now();
1127
1127
  await writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, config, allEntities, setEffectCacheOrThrow, updatedEffectsCache, pgUpdates, sinkPromise, chainMetaData, undefined);
1128
- return Prometheus.StorageWrite.increment("postgres", Hrtime.toSecondsFloat(Hrtime.timeSince(primaryTimerRef)));
1128
+ return Prometheus.StorageWrite.increment("postgres", Performance.secondsSince(primaryTimerRef));
1129
1129
  };
1130
1130
  let close = () => sql.end();
1131
1131
  return {
@@ -212,7 +212,7 @@ module PreloadHandler = {
212
212
 
213
213
  type operationRef = {
214
214
  mutable pendingCount: int,
215
- timerRef: Hrtime.timeRef,
215
+ timerRef: Performance.timeRef,
216
216
  }
217
217
  let operations: dict<operationRef> = Dict.make()
218
218
 
@@ -227,11 +227,11 @@ module PreloadHandler = {
227
227
  key,
228
228
  {
229
229
  pendingCount: 1,
230
- timerRef: Hrtime.makeTimer(),
230
+ timerRef: Performance.now(),
231
231
  },
232
232
  )
233
233
  }
234
- Hrtime.makeTimer()
234
+ Performance.now()
235
235
  }
236
236
 
237
237
  let endOperation = (timerRef, ~contract, ~event) => {
@@ -242,13 +242,13 @@ module PreloadHandler = {
242
242
  if operationRef.pendingCount === 0 {
243
243
  timeCounter->SafeCounter.handleFloat(
244
244
  ~labels,
245
- ~value=operationRef.timerRef->Hrtime.timeSince->Hrtime.toSecondsFloat,
245
+ ~value=operationRef.timerRef->Performance.secondsSince,
246
246
  )
247
247
  operations->Utils.Dict.deleteInPlace(key)
248
248
  }
249
249
  sumTimeCounter->SafeCounter.handleFloat(
250
250
  ~labels,
251
- ~value=timerRef->Hrtime.timeSince->Hrtime.toSecondsFloat,
251
+ ~value=timerRef->Performance.secondsSince,
252
252
  )
253
253
  count->SafeCounter.increment(~labels)
254
254
  }
@@ -764,7 +764,7 @@ module StorageLoad = {
764
764
 
765
765
  type operationRef = {
766
766
  mutable pendingCount: int,
767
- timerRef: Hrtime.timeRef,
767
+ timerRef: Performance.timeRef,
768
768
  }
769
769
  let operations = Dict.make()
770
770
 
@@ -780,12 +780,12 @@ module StorageLoad = {
780
780
  (
781
781
  {
782
782
  pendingCount: 1,
783
- timerRef: Hrtime.makeTimer(),
783
+ timerRef: Performance.now(),
784
784
  }: operationRef
785
785
  ),
786
786
  )
787
787
  }
788
- Hrtime.makeTimer()
788
+ Performance.now()
789
789
  }
790
790
 
791
791
  let endOperation = (timerRef, ~storage, ~operation, ~whereSize, ~size) => {
@@ -796,13 +796,13 @@ module StorageLoad = {
796
796
  if operationRef.pendingCount === 0 {
797
797
  timeCounter->SafeCounter.handleFloat(
798
798
  ~labels,
799
- ~value=operationRef.timerRef->Hrtime.timeSince->Hrtime.toSecondsFloat,
799
+ ~value=operationRef.timerRef->Performance.secondsSince,
800
800
  )
801
801
  operations->Utils.Dict.deleteInPlace(key)
802
802
  }
803
803
  sumTimeCounter->SafeCounter.handleFloat(
804
804
  ~labels,
805
- ~value=timerRef->Hrtime.timeSince->Hrtime.toSecondsFloat,
805
+ ~value=timerRef->Performance.secondsSince,
806
806
  )
807
807
  counter->SafeCounter.increment(~labels)
808
808
  whereSizeCounter->SafeCounter.handleInt(~labels, ~value=whereSize)
@@ -1,8 +1,8 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
3
  import * as Utils from "./Utils.res.mjs";
4
- import * as Hrtime from "./bindings/Hrtime.res.mjs";
5
4
  import * as PromClient from "./bindings/PromClient.res.mjs";
5
+ import * as Performance from "./bindings/Performance.res.mjs";
6
6
  import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
7
7
  import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
8
8
  import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
@@ -290,10 +290,10 @@ function startOperation(contract, event) {
290
290
  } else {
291
291
  operations[key] = {
292
292
  pendingCount: 1,
293
- timerRef: Hrtime.makeTimer()
293
+ timerRef: Performance.now()
294
294
  };
295
295
  }
296
- return Hrtime.makeTimer();
296
+ return Performance.now();
297
297
  }
298
298
 
299
299
  function endOperation(timerRef, contract, event) {
@@ -305,10 +305,10 @@ function endOperation(timerRef, contract, event) {
305
305
  let operationRef = operations[key];
306
306
  operationRef.pendingCount = operationRef.pendingCount - 1 | 0;
307
307
  if (operationRef.pendingCount === 0) {
308
- handleFloat(timeCounter$1, labels, Hrtime.toSecondsFloat(Hrtime.timeSince(operationRef.timerRef)));
308
+ handleFloat(timeCounter$1, labels, Performance.secondsSince(operationRef.timerRef));
309
309
  Utils.Dict.deleteInPlace(operations, key);
310
310
  }
311
- handleFloat(sumTimeCounter, labels, Hrtime.toSecondsFloat(Hrtime.timeSince(timerRef)));
311
+ handleFloat(sumTimeCounter, labels, Performance.secondsSince(timerRef));
312
312
  increment(count$1, labels);
313
313
  }
314
314
 
@@ -775,10 +775,10 @@ function startOperation$1(storage, operation) {
775
775
  } else {
776
776
  operations$1[key] = {
777
777
  pendingCount: 1,
778
- timerRef: Hrtime.makeTimer()
778
+ timerRef: Performance.now()
779
779
  };
780
780
  }
781
- return Hrtime.makeTimer();
781
+ return Performance.now();
782
782
  }
783
783
 
784
784
  function endOperation$1(timerRef, storage, operation, whereSize, size) {
@@ -790,10 +790,10 @@ function endOperation$1(timerRef, storage, operation, whereSize, size) {
790
790
  let operationRef = operations$1[key];
791
791
  operationRef.pendingCount = operationRef.pendingCount - 1 | 0;
792
792
  if (operationRef.pendingCount === 0) {
793
- handleFloat(timeCounter$7, labels, Hrtime.toSecondsFloat(Hrtime.timeSince(operationRef.timerRef)));
793
+ handleFloat(timeCounter$7, labels, Performance.secondsSince(operationRef.timerRef));
794
794
  Utils.Dict.deleteInPlace(operations$1, key);
795
795
  }
796
- handleFloat(sumTimeCounter$3, labels, Hrtime.toSecondsFloat(Hrtime.timeSince(timerRef)));
796
+ handleFloat(sumTimeCounter$3, labels, Performance.secondsSince(timerRef));
797
797
  increment(counter$8, labels);
798
798
  handleInt(whereSizeCounter, labels, whereSize);
799
799
  handleInt(sizeCounter$1, labels, size);
@@ -14,7 +14,7 @@ let runPrune = async (state: IndexerState.t) => {
14
14
  await Utils.delay(1000)
15
15
  }
16
16
  let entityConfig = persistence.allEntities->Array.getUnsafe(idx)
17
- let timeRef = Hrtime.makeTimer()
17
+ let timeRef = Performance.now()
18
18
  try {
19
19
  let () = await persistence.storage.pruneStaleEntityHistory(
20
20
  ~entityName=entityConfig.name,
@@ -34,7 +34,7 @@ let runPrune = async (state: IndexerState.t) => {
34
34
  )
35
35
  }
36
36
  Prometheus.RollbackHistoryPrune.increment(
37
- ~timeSeconds=Hrtime.timeSince(timeRef)->Hrtime.toSecondsFloat,
37
+ ~timeSeconds=Performance.secondsSince(timeRef),
38
38
  ~entityName=entityConfig.name,
39
39
  )
40
40
  }
@@ -1,10 +1,10 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
3
  import * as Utils from "./Utils.res.mjs";
4
- import * as Hrtime from "./bindings/Hrtime.res.mjs";
5
4
  import * as Logging from "./Logging.res.mjs";
6
5
  import * as Throttler from "./Throttler.res.mjs";
7
6
  import * as Prometheus from "./Prometheus.res.mjs";
7
+ import * as Performance from "./bindings/Performance.res.mjs";
8
8
  import * as IndexerState from "./IndexerState.res.mjs";
9
9
  import * as ErrorHandling from "./ErrorHandling.res.mjs";
10
10
  import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
@@ -21,7 +21,7 @@ async function runPrune(state) {
21
21
  await Utils.delay(1000);
22
22
  }
23
23
  let entityConfig = persistence.allEntities[idx];
24
- let timeRef = Hrtime.makeTimer();
24
+ let timeRef = Performance.now();
25
25
  try {
26
26
  await persistence.storage.pruneStaleEntityHistory(entityConfig.name, entityConfig.index, safeCheckpointId);
27
27
  } catch (raw_exn) {
@@ -31,7 +31,7 @@ async function runPrune(state) {
31
31
  safeCheckpointId: safeCheckpointId
32
32
  }), `Failed to prune stale entity history`, exn);
33
33
  }
34
- Prometheus.RollbackHistoryPrune.increment(Hrtime.toSecondsFloat(Hrtime.timeSince(timeRef)), entityConfig.name);
34
+ Prometheus.RollbackHistoryPrune.increment(Performance.secondsSince(timeRef), entityConfig.name);
35
35
  }
36
36
  }
37
37
 
package/src/Rollback.res CHANGED
@@ -18,7 +18,7 @@ let getLastKnownValidBlock = async (
18
18
  ->ChainState.reorgDetection
19
19
  ->ReorgDetection.getThresholdBlockNumbersBelowBlock(
20
20
  ~blockNumber=reorgBlockNumber,
21
- ~knownHeight=(chainState->ChainState.fetchState).knownHeight,
21
+ ~knownHeight=chainState->ChainState.knownHeight,
22
22
  )
23
23
 
24
24
  switch scannedBlockNumbers {
@@ -94,7 +94,7 @@ and executeRollback = async (
94
94
  ~scheduleFetch,
95
95
  ~scheduleProcessing,
96
96
  ) => {
97
- let startTime = Hrtime.makeTimer()
97
+ let startTime = Performance.now()
98
98
 
99
99
  let chainState = state->IndexerState.getChainState(~chain=reorgChain)
100
100
 
@@ -194,7 +194,7 @@ and executeRollback = async (
194
194
  "targetCheckpointId": rollbackTargetCheckpointId,
195
195
  })
196
196
  Prometheus.RollbackSuccess.increment(
197
- ~timeSeconds=Hrtime.timeSince(startTime)->Hrtime.toSecondsFloat,
197
+ ~timeSeconds=Performance.secondsSince(startTime),
198
198
  ~rollbackedProcessedEvents=rollbackedProcessedEvents.contents,
199
199
  )
200
200
 
@@ -1,11 +1,11 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
3
  import * as Utils from "./Utils.res.mjs";
4
- import * as Hrtime from "./bindings/Hrtime.res.mjs";
5
4
  import * as Logging from "./Logging.res.mjs";
6
5
  import * as Writing from "./Writing.res.mjs";
7
6
  import * as ChainState from "./ChainState.res.mjs";
8
7
  import * as Prometheus from "./Prometheus.res.mjs";
8
+ import * as Performance from "./bindings/Performance.res.mjs";
9
9
  import * as IndexerState from "./IndexerState.res.mjs";
10
10
  import * as Stdlib_Float from "@rescript/runtime/lib/es6/Stdlib_Float.js";
11
11
  import * as ErrorHandling from "./ErrorHandling.res.mjs";
@@ -18,7 +18,7 @@ import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
18
18
  import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
19
19
 
20
20
  async function getLastKnownValidBlock(chainState, reorgBlockNumber, isRealtime) {
21
- let scannedBlockNumbers = ReorgDetection.getThresholdBlockNumbersBelowBlock(ChainState.reorgDetection(chainState), reorgBlockNumber, ChainState.fetchState(chainState).knownHeight);
21
+ let scannedBlockNumbers = ReorgDetection.getThresholdBlockNumbersBelowBlock(ChainState.reorgDetection(chainState), reorgBlockNumber, ChainState.knownHeight(chainState));
22
22
  if (scannedBlockNumbers.length === 0) {
23
23
  return ChainState.getHighestBlockBelowThreshold(chainState);
24
24
  }
@@ -32,7 +32,7 @@ async function getLastKnownValidBlock(chainState, reorgBlockNumber, isRealtime)
32
32
  }
33
33
 
34
34
  async function executeRollback(state, reorgChain, rollbackTargetBlockNumber, scheduleFetch, scheduleProcessing) {
35
- let startTime = Hrtime.makeTimer();
35
+ let startTime = Performance.now();
36
36
  let chainState = IndexerState.getChainState(state, reorgChain);
37
37
  let logger = Logging.createChildFrom(ChainState.logger(chainState), {
38
38
  action: "Rollback",
@@ -70,7 +70,7 @@ async function executeRollback(state, reorgChain, rollbackTargetBlockNumber, sch
70
70
  beforeCheckpointId: IndexerState.committedCheckpointId(state),
71
71
  targetCheckpointId: rollbackTargetCheckpointId
72
72
  });
73
- Prometheus.RollbackSuccess.increment(Hrtime.toSecondsFloat(Hrtime.timeSince(startTime)), rollbackedProcessedEvents);
73
+ Prometheus.RollbackSuccess.increment(Performance.secondsSince(startTime), rollbackedProcessedEvents);
74
74
  IndexerState.completeRollback(state, eventsProcessedDiffByChain);
75
75
  scheduleFetch();
76
76
  return scheduleProcessing();
@@ -195,6 +195,78 @@ let findEventConfig = (~config: Config.t, ~contractName: string, ~eventName: str
195
195
  found.contents
196
196
  }
197
197
 
198
+ let dummySrcAddress = Address.unsafeFromString("0x0000000000000000000000000000000000000000")
199
+
200
+ // First address configured for `contractName` on the simulated chain. Only the
201
+ // simulated chain is consulted — a contract's address on another chain has no
202
+ // meaning here.
203
+ let firstContractAddress = (~chainConfig: Config.chain, ~contractName: string): option<
204
+ Address.t,
205
+ > => {
206
+ let found = ref(None)
207
+ chainConfig.contracts->Array.forEach(contract => {
208
+ if found.contents->Option.isNone && contract.name === contractName {
209
+ found := contract.addresses->Array.get(0)
210
+ }
211
+ })
212
+ found.contents
213
+ }
214
+
215
+ let deriveSrcAddress = (
216
+ ~providedSrcAddress: option<Address.t>,
217
+ ~eventConfig: Internal.eventConfig,
218
+ ~chainConfig: Config.chain,
219
+ ): Address.t => {
220
+ switch providedSrcAddress {
221
+ | Some(addr) => addr
222
+ | None =>
223
+ if eventConfig.isWildcard {
224
+ dummySrcAddress
225
+ } else {
226
+ switch firstContractAddress(~chainConfig, ~contractName=eventConfig.contractName) {
227
+ | Some(addr) => addr
228
+ | None => dummySrcAddress
229
+ }
230
+ }
231
+ }
232
+ }
233
+
234
+ // A non-wildcard event is gated by `clientAddressFilter` on srcAddress ownership,
235
+ // so a simulate item whose srcAddress isn't indexed on this chain would be
236
+ // silently dropped (handler never runs). Fail loudly instead.
237
+ let validateSrcAddresses = (
238
+ ~simulateItems: array<JSON.t>,
239
+ ~config: Config.t,
240
+ ~chainConfig: Config.chain,
241
+ ~indexingAddresses: array<Internal.indexingAddress>,
242
+ ): unit => {
243
+ let known = Utils.Set.make()
244
+ indexingAddresses->Array.forEach(ia => known->Utils.Set.add(ia.address->Address.toString)->ignore)
245
+ simulateItems->Array.forEach(rawJson => {
246
+ let raw = rawJson->(Utils.magic: JSON.t => rawSimulateItem)
247
+ switch (raw->getContract, raw->getEvent) {
248
+ | (Some(contractName), Some(eventName)) =>
249
+ switch findEventConfig(~config, ~contractName, ~eventName) {
250
+ | Some(eventConfig) if !eventConfig.isWildcard =>
251
+ let item = rawJson->(Utils.magic: JSON.t => Envio.evmSimulateItem)
252
+ let srcAddress = deriveSrcAddress(
253
+ ~providedSrcAddress=item.srcAddress,
254
+ ~eventConfig,
255
+ ~chainConfig,
256
+ )
257
+ if !(known->Utils.Set.has(srcAddress->Address.toString)) {
258
+ JsError.throwWithMessage(
259
+ `simulate: ${contractName}.${eventName} resolved to address ${srcAddress->Address.toString}, which isn't indexed on chain ${chainConfig.id->Int.toString}. ` ++
260
+ `Provide a "srcAddress" configured or registered for ${contractName} on this chain, or use a wildcard event.`,
261
+ )
262
+ }
263
+ | _ => ()
264
+ }
265
+ | _ => ()
266
+ }
267
+ })
268
+ }
269
+
198
270
  let parse = (~simulateItems: array<JSON.t>, ~config: Config.t, ~chainConfig: Config.chain): array<
199
271
  Internal.item,
200
272
  > => {
@@ -238,21 +310,11 @@ let parse = (~simulateItems: array<JSON.t>, ~config: Config.t, ~chainConfig: Con
238
310
  li
239
311
  }
240
312
 
241
- let srcAddress = switch item.srcAddress {
242
- | Some(addr) => addr
243
- | None =>
244
- // Use first address from contract config
245
- let addr = ref(Address.unsafeFromString("0x0000000000000000000000000000000000000000"))
246
- chainConfig.contracts->Array.forEach(contract => {
247
- if contract.name === contractName {
248
- switch contract.addresses->Array.get(0) {
249
- | Some(a) => addr := a
250
- | None => ()
251
- }
252
- }
253
- })
254
- addr.contents
255
- }
313
+ let srcAddress = deriveSrcAddress(
314
+ ~providedSrcAddress=item.srcAddress,
315
+ ~eventConfig,
316
+ ~chainConfig,
317
+ )
256
318
 
257
319
  let rawItem = rawJson->(Utils.magic: JSON.t => {..})
258
320
  let blockJson: option<JSON.t> =
@@ -288,6 +350,9 @@ let parse = (~simulateItems: array<JSON.t>, ~config: Config.t, ~chainConfig: Con
288
350
  blockNumber,
289
351
  blockHash,
290
352
  logIndex,
353
+ // Simulate keeps the transaction inline on the payload, so the store
354
+ // key is unused.
355
+ transactionIndex: 0,
291
356
  payload: (
292
357
  {
293
358
  contractName: eventConfig.contractName,