envio 3.3.0-alpha.1 → 3.3.0-alpha.10

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 (136) hide show
  1. package/evm.schema.json +10 -0
  2. package/index.d.ts +45 -25
  3. package/package.json +7 -7
  4. package/src/Address.res +5 -2
  5. package/src/Address.res.mjs +3 -1
  6. package/src/Api.res +1 -1
  7. package/src/Api.res.mjs +1 -1
  8. package/src/Batch.res +0 -6
  9. package/src/Batch.res.mjs +1 -12
  10. package/src/BatchProcessing.res +7 -12
  11. package/src/BatchProcessing.res.mjs +8 -7
  12. package/src/Bin.res +3 -0
  13. package/src/Bin.res.mjs +4 -0
  14. package/src/ChainFetching.res +43 -9
  15. package/src/ChainFetching.res.mjs +34 -15
  16. package/src/ChainMetadata.res +1 -11
  17. package/src/ChainMetadata.res.mjs +1 -10
  18. package/src/ChainState.res +605 -151
  19. package/src/ChainState.res.mjs +427 -104
  20. package/src/ChainState.resi +72 -4
  21. package/src/Config.res +61 -33
  22. package/src/Config.res.mjs +50 -10
  23. package/src/ContractRegisterContext.res +2 -12
  24. package/src/ContractRegisterContext.res.mjs +3 -5
  25. package/src/Core.res +14 -3
  26. package/src/CrossChainState.res +113 -89
  27. package/src/CrossChainState.res.mjs +64 -60
  28. package/src/CrossChainState.resi +1 -1
  29. package/src/Ecosystem.res +5 -6
  30. package/src/Ecosystem.res.mjs +3 -3
  31. package/src/Envio.res +17 -11
  32. package/src/EnvioGlobal.res +53 -0
  33. package/src/EnvioGlobal.res.mjs +31 -0
  34. package/src/EventConfigBuilder.res +177 -88
  35. package/src/EventConfigBuilder.res.mjs +99 -42
  36. package/src/EventProcessing.res +74 -28
  37. package/src/EventProcessing.res.mjs +55 -29
  38. package/src/ExitOnCaughtUp.res +10 -2
  39. package/src/ExitOnCaughtUp.res.mjs +10 -1
  40. package/src/FetchState.res +544 -356
  41. package/src/FetchState.res.mjs +412 -471
  42. package/src/HandlerLoader.res +8 -104
  43. package/src/HandlerLoader.res.mjs +2 -81
  44. package/src/HandlerRegister.res +518 -144
  45. package/src/HandlerRegister.res.mjs +285 -133
  46. package/src/HandlerRegister.resi +24 -8
  47. package/src/IndexerState.res +10 -3
  48. package/src/IndexerState.res.mjs +11 -4
  49. package/src/IndexerState.resi +2 -1
  50. package/src/IndexingAddresses.res +108 -0
  51. package/src/IndexingAddresses.res.mjs +101 -0
  52. package/src/IndexingAddresses.resi +34 -0
  53. package/src/Internal.res +155 -46
  54. package/src/Internal.res.mjs +30 -2
  55. package/src/LoadLayer.res +5 -5
  56. package/src/LoadLayer.res.mjs +6 -6
  57. package/src/LogSelection.res +102 -165
  58. package/src/LogSelection.res.mjs +101 -116
  59. package/src/Main.res +71 -236
  60. package/src/Main.res.mjs +60 -145
  61. package/src/Metrics.res +74 -0
  62. package/src/Metrics.res.mjs +75 -0
  63. package/src/PgStorage.res +4 -4
  64. package/src/PgStorage.res.mjs +5 -5
  65. package/src/Prometheus.res +10 -63
  66. package/src/Prometheus.res.mjs +124 -171
  67. package/src/PruneStaleHistory.res +2 -2
  68. package/src/PruneStaleHistory.res.mjs +3 -3
  69. package/src/RawEvent.res +7 -2
  70. package/src/RawEvent.res.mjs +4 -4
  71. package/src/Rollback.res +3 -3
  72. package/src/Rollback.res.mjs +4 -4
  73. package/src/RollbackCommit.res +4 -1
  74. package/src/RollbackCommit.res.mjs +3 -2
  75. package/src/SimulateDeadInputTracker.res +85 -0
  76. package/src/SimulateDeadInputTracker.res.mjs +73 -0
  77. package/src/SimulateDeadInputTracker.resi +12 -0
  78. package/src/SimulateItems.res +91 -23
  79. package/src/SimulateItems.res.mjs +55 -32
  80. package/src/TestIndexer.res +54 -40
  81. package/src/TestIndexer.res.mjs +37 -30
  82. package/src/bindings/Performance.res +7 -0
  83. package/src/bindings/Performance.res.mjs +21 -0
  84. package/src/bindings/Performance.resi +7 -0
  85. package/src/bindings/Viem.res +0 -41
  86. package/src/bindings/Viem.res.mjs +1 -43
  87. package/src/sources/BlockStore.res +46 -0
  88. package/src/sources/BlockStore.res.mjs +24 -0
  89. package/src/sources/EventRouter.res +36 -33
  90. package/src/sources/EventRouter.res.mjs +13 -14
  91. package/src/sources/Evm.res +83 -72
  92. package/src/sources/Evm.res.mjs +53 -69
  93. package/src/sources/EvmChain.res +18 -20
  94. package/src/sources/EvmChain.res.mjs +15 -15
  95. package/src/sources/EvmRpcClient.res +74 -5
  96. package/src/sources/EvmRpcClient.res.mjs +13 -4
  97. package/src/sources/FieldMask.res +39 -0
  98. package/src/sources/FieldMask.res.mjs +42 -0
  99. package/src/sources/Fuel.res +9 -6
  100. package/src/sources/Fuel.res.mjs +5 -10
  101. package/src/sources/HyperFuelSource.res +46 -50
  102. package/src/sources/HyperFuelSource.res.mjs +64 -54
  103. package/src/sources/HyperSync.res +39 -7
  104. package/src/sources/HyperSync.res.mjs +57 -37
  105. package/src/sources/HyperSync.resi +12 -2
  106. package/src/sources/HyperSyncClient.res +22 -111
  107. package/src/sources/HyperSyncClient.res.mjs +2 -30
  108. package/src/sources/HyperSyncHeightStream.res +1 -8
  109. package/src/sources/HyperSyncHeightStream.res.mjs +0 -2
  110. package/src/sources/HyperSyncSource.res +94 -107
  111. package/src/sources/HyperSyncSource.res.mjs +82 -86
  112. package/src/sources/Rpc.res +15 -47
  113. package/src/sources/Rpc.res.mjs +25 -56
  114. package/src/sources/RpcSource.res +320 -467
  115. package/src/sources/RpcSource.res.mjs +268 -385
  116. package/src/sources/RpcWebSocketHeightStream.res +0 -5
  117. package/src/sources/RpcWebSocketHeightStream.res.mjs +0 -2
  118. package/src/sources/SimulateSource.res +10 -4
  119. package/src/sources/SimulateSource.res.mjs +16 -6
  120. package/src/sources/Source.res +34 -6
  121. package/src/sources/SourceManager.res +77 -19
  122. package/src/sources/SourceManager.res.mjs +63 -21
  123. package/src/sources/SourceManager.resi +10 -0
  124. package/src/sources/Svm.res +31 -16
  125. package/src/sources/Svm.res.mjs +36 -13
  126. package/src/sources/SvmHyperSyncClient.res +5 -32
  127. package/src/sources/SvmHyperSyncSource.res +159 -134
  128. package/src/sources/SvmHyperSyncSource.res.mjs +164 -129
  129. package/src/sources/TransactionStore.res +49 -0
  130. package/src/sources/TransactionStore.res.mjs +30 -0
  131. package/src/tui/Tui.res +13 -16
  132. package/src/tui/Tui.res.mjs +12 -14
  133. package/svm.schema.json +49 -37
  134. package/src/bindings/Hrtime.res +0 -58
  135. package/src/bindings/Hrtime.res.mjs +0 -90
  136. package/src/bindings/Hrtime.resi +0 -30
@@ -4,31 +4,27 @@ import * as Rpc from "./Rpc.res.mjs";
4
4
  import * as Rest from "../vendored/Rest.res.mjs";
5
5
  import * as Time from "../Time.res.mjs";
6
6
  import * as Utils from "../Utils.res.mjs";
7
- import * as Hrtime from "../bindings/Hrtime.res.mjs";
8
7
  import * as Source from "./Source.res.mjs";
9
8
  import * as Address from "../Address.res.mjs";
10
9
  import * as Logging from "../Logging.res.mjs";
11
10
  import * as Internal from "../Internal.res.mjs";
12
- import * as FetchState from "../FetchState.res.mjs";
13
11
  import * as LazyLoader from "../LazyLoader.res.mjs";
14
- import * as Prometheus from "../Prometheus.res.mjs";
15
- import * as Stdlib_Int from "@rescript/runtime/lib/es6/Stdlib_Int.js";
16
12
  import * as EventRouter from "./EventRouter.res.mjs";
13
+ import * as Performance from "../bindings/Performance.res.mjs";
14
+ import * as Stdlib_JSON from "@rescript/runtime/lib/es6/Stdlib_JSON.js";
17
15
  import * as EvmRpcClient from "./EvmRpcClient.res.mjs";
18
16
  import * as LogSelection from "../LogSelection.res.mjs";
19
17
  import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
18
+ import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";
20
19
  import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
21
20
  import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
22
21
  import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
23
22
  import * as Stdlib_Promise from "@rescript/runtime/lib/es6/Stdlib_Promise.js";
24
- import * as HyperSyncClient from "./HyperSyncClient.res.mjs";
25
23
  import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
26
24
  import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
27
25
  import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
28
26
  import * as RpcWebSocketHeightStream from "./RpcWebSocketHeightStream.res.mjs";
29
27
 
30
- let QueryTimout = /* @__PURE__ */Primitive_exceptions.create("RpcSource.QueryTimout");
31
-
32
28
  let TransactionDataNotFound = /* @__PURE__ */Primitive_exceptions.create("RpcSource.TransactionDataNotFound");
33
29
 
34
30
  async function getKnownRawBlock(client, blockNumber) {
@@ -49,11 +45,11 @@ function parseBlockInfo(json) {
49
45
  };
50
46
  }
51
47
 
52
- async function getKnownRawBlockWithBackoff(client, sourceName, chain, blockNumber, backoffMsOnFailure) {
48
+ async function getKnownRawBlockWithBackoff(client, sourceName, chain, blockNumber, backoffMsOnFailure, recordRequest) {
53
49
  let currentBackoff = backoffMsOnFailure;
54
50
  let result;
55
51
  while (Stdlib_Option.isNone(result)) {
56
- Prometheus.SourceRequestCount.increment(sourceName, chain, "eth_getBlockByNumber");
52
+ let timerRef = Performance.now();
57
53
  let exit = 0;
58
54
  let json;
59
55
  try {
@@ -61,6 +57,7 @@ async function getKnownRawBlockWithBackoff(client, sourceName, chain, blockNumbe
61
57
  exit = 1;
62
58
  } catch (raw_err) {
63
59
  let err = Primitive_exceptions.internalToException(raw_err);
60
+ recordRequest("eth_getBlockByNumber", Performance.secondsSince(timerRef));
64
61
  Logging.warn({
65
62
  err: Utils.prettifyExn(err),
66
63
  msg: `Issue while running fetching batch of events from the RPC. Will wait ` + currentBackoff.toString() + `ms and try again.`,
@@ -72,318 +69,191 @@ async function getKnownRawBlockWithBackoff(client, sourceName, chain, blockNumbe
72
69
  currentBackoff = (currentBackoff << 1);
73
70
  }
74
71
  if (exit === 1) {
72
+ recordRequest("eth_getBlockByNumber", Performance.secondsSince(timerRef));
75
73
  result = json;
76
74
  }
77
75
  };
78
76
  return Stdlib_Option.getOrThrow(result, undefined);
79
77
  }
80
78
 
81
- let suggestedRangeRegExp = /retry with the range (\d+)-(\d+)/;
82
-
83
- let blockRangeLimitRegExp = /limited to a (\d+) blocks range/;
84
-
85
- let alchemyRangeRegExp = /up to a (\d+) block range/;
86
-
87
- let cloudflareRangeRegExp = /Max range: (\d+)/;
88
-
89
- let thirdwebRangeRegExp = /Maximum allowed number of requested blocks is (\d+)/;
90
-
91
- let blockpiRangeRegExp = /limited to (\d+) block/;
92
-
93
- let baseRangeRegExp = /block range too large/;
94
-
95
- let maxAllowedBlocksRegExp = /maximum allowed is (\d+) blocks/;
96
-
97
- let blastPaidRegExp = /exceeds the range allowed for your plan \(\d+ > (\d+)\)/;
98
-
99
- let chainstackRegExp = /Block range limit exceeded./;
100
-
101
- let coinbaseRegExp = /please limit the query to at most (\d+) blocks/;
102
-
103
- let publicNodeRegExp = /maximum block range: (\d+)/;
104
-
105
- let hyperliquidRegExp = /query exceeds max block range (\d+)/;
106
-
107
- function parseMessageForBlockRange(message) {
108
- let extractBlockRange = (execResult, isMaxRange) => {
109
- let match = execResult.slice(1);
110
- if (match.length !== 1) {
111
- return;
112
- }
113
- let blockRangeLimit = match[0];
114
- if (blockRangeLimit === undefined) {
115
- return;
116
- }
117
- let blockRangeLimit$1 = Stdlib_Int.fromString(blockRangeLimit, undefined);
118
- if (blockRangeLimit$1 !== undefined && blockRangeLimit$1 > 0) {
119
- return [
120
- blockRangeLimit$1,
121
- isMaxRange
122
- ];
123
- }
124
- };
125
- let execResult = suggestedRangeRegExp.exec(message);
126
- if (execResult == null) {
127
- let execResult$1 = blockRangeLimitRegExp.exec(message);
128
- if (!(execResult$1 == null)) {
129
- return extractBlockRange(execResult$1, true);
130
- }
131
- let execResult$2 = alchemyRangeRegExp.exec(message);
132
- if (!(execResult$2 == null)) {
133
- return extractBlockRange(execResult$2, true);
134
- }
135
- let execResult$3 = cloudflareRangeRegExp.exec(message);
136
- if (!(execResult$3 == null)) {
137
- return extractBlockRange(execResult$3, true);
138
- }
139
- let execResult$4 = thirdwebRangeRegExp.exec(message);
140
- if (!(execResult$4 == null)) {
141
- return extractBlockRange(execResult$4, true);
142
- }
143
- let execResult$5 = blockpiRangeRegExp.exec(message);
144
- if (!(execResult$5 == null)) {
145
- return extractBlockRange(execResult$5, true);
146
- }
147
- let execResult$6 = maxAllowedBlocksRegExp.exec(message);
148
- if (!(execResult$6 == null)) {
149
- return extractBlockRange(execResult$6, true);
150
- }
151
- let match = baseRangeRegExp.exec(message);
152
- if (!(match == null)) {
153
- return [
154
- 2000,
155
- true
156
- ];
157
- }
158
- let execResult$7 = blastPaidRegExp.exec(message);
159
- if (!(execResult$7 == null)) {
160
- return extractBlockRange(execResult$7, true);
161
- }
162
- let match$1 = chainstackRegExp.exec(message);
163
- if (!(match$1 == null)) {
164
- return [
165
- 10000,
166
- true
167
- ];
168
- }
169
- let execResult$8 = coinbaseRegExp.exec(message);
170
- if (!(execResult$8 == null)) {
171
- return extractBlockRange(execResult$8, true);
172
- }
173
- let execResult$9 = publicNodeRegExp.exec(message);
174
- if (!(execResult$9 == null)) {
175
- return extractBlockRange(execResult$9, true);
176
- }
177
- let execResult$10 = hyperliquidRegExp.exec(message);
178
- if (!(execResult$10 == null)) {
179
- return extractBlockRange(execResult$10, true);
180
- } else {
181
- return;
182
- }
79
+ function getErrorMessage(exn) {
80
+ if (exn.RE_EXN_ID === Rpc.JsonRpcError) {
81
+ return exn._1.message;
82
+ }
83
+ if (exn.RE_EXN_ID !== "JsExn") {
84
+ return;
183
85
  }
184
- let match$2 = execResult.slice(1);
185
- if (match$2.length !== 2) {
86
+ let msg = Stdlib_JsExn.message(exn._1);
87
+ if (msg === undefined) {
186
88
  return;
187
89
  }
188
- let fromBlock = match$2[0];
189
- if (fromBlock === undefined) {
90
+ let obj;
91
+ try {
92
+ obj = Stdlib_JSON.Decode.object(JSON.parse(msg));
93
+ } catch (exn$1) {
190
94
  return;
191
95
  }
192
- let toBlock = match$2[1];
193
- if (toBlock === undefined) {
96
+ if (obj === undefined) {
194
97
  return;
195
98
  }
196
- let match$3 = Stdlib_Int.fromString(fromBlock, undefined);
197
- let match$4 = Stdlib_Int.fromString(toBlock, undefined);
198
- if (match$3 !== undefined && match$4 !== undefined && match$4 >= match$3) {
199
- return [
200
- (match$4 - match$3 | 0) + 1 | 0,
201
- false
202
- ];
99
+ let match = obj["errorMessage"];
100
+ if (typeof match === "string") {
101
+ return match;
203
102
  }
204
103
  }
205
104
 
206
- function getSuggestedBlockIntervalFromExn(exn) {
207
- if (exn.RE_EXN_ID === Rpc.JsonRpcError) {
208
- return parseMessageForBlockRange(exn._1.message);
209
- }
105
+ function parseGetNextPageRetryError(exn) {
210
106
  if (exn.RE_EXN_ID !== "JsExn") {
211
107
  return;
212
108
  }
109
+ let msg = Stdlib_JsExn.message(exn._1);
110
+ if (msg === undefined) {
111
+ return;
112
+ }
113
+ let obj;
213
114
  try {
214
- let message = exn._1.error.message;
215
- S$RescriptSchema.assertOrThrow(message, S$RescriptSchema.string);
216
- return parseMessageForBlockRange(message);
115
+ obj = Stdlib_JSON.Decode.object(JSON.parse(msg));
217
116
  } catch (exn$1) {
218
117
  return;
219
118
  }
220
- }
221
-
222
- let maxSuggestedBlockIntervalKey = "max";
223
-
224
- function getNextPage(fromBlock, toBlock, addresses, topicQuery, loadBlock, sc, client, mutSuggestedBlockIntervals, partitionId, sourceName, chainId) {
225
- let queryTimoutPromise = Time.resolvePromiseAfterDelay(sc.queryTimeoutMillis).then(() => Promise.reject({
226
- RE_EXN_ID: QueryTimout,
227
- _1: `Query took longer than ` + (sc.queryTimeoutMillis / 1000 | 0).toString() + ` seconds`
228
- }));
229
- let latestFetchedBlockPromise = loadBlock(toBlock);
230
- Prometheus.SourceRequestCount.increment(sourceName, chainId, "eth_getLogs");
231
- let logsPromise = Rpc.getLogs(client, {
232
- fromBlock: fromBlock,
233
- toBlock: toBlock,
234
- address: addresses,
235
- topics: topicQuery
236
- }).then(async logs => ({
237
- logs: logs,
238
- latestFetchedBlockInfo: await latestFetchedBlockPromise
239
- }));
240
- return Stdlib_Promise.$$catch(Promise.race([
241
- queryTimoutPromise,
242
- logsPromise
243
- ]), err => {
244
- let match = getSuggestedBlockIntervalFromExn(err);
245
- if (match !== undefined) {
246
- let nextBlockIntervalTry = match[0];
247
- mutSuggestedBlockIntervals[match[1] ? maxSuggestedBlockIntervalKey : partitionId] = nextBlockIntervalTry;
248
- throw {
249
- RE_EXN_ID: Source.GetItemsError,
250
- _1: {
251
- TAG: "FailedGettingItems",
252
- exn: err,
253
- attemptedToBlock: toBlock,
254
- retry: {
255
- TAG: "WithSuggestedToBlock",
256
- toBlock: (fromBlock + nextBlockIntervalTry | 0) - 1 | 0
119
+ if (obj === undefined) {
120
+ return;
121
+ }
122
+ let match = obj["kind"];
123
+ let match$1 = obj["attemptedToBlock"];
124
+ let match$2 = obj["retry"];
125
+ if (match === undefined) {
126
+ return;
127
+ }
128
+ if (typeof match !== "string") {
129
+ return;
130
+ }
131
+ if (match !== "Retry") {
132
+ return;
133
+ }
134
+ if (match$1 === undefined) {
135
+ return;
136
+ }
137
+ if (typeof match$1 !== "number") {
138
+ return;
139
+ }
140
+ if (match$2 === undefined) {
141
+ return;
142
+ }
143
+ if (typeof match$2 !== "object" || match$2 === null || Array.isArray(match$2)) {
144
+ return;
145
+ }
146
+ let match$3 = obj["requestStats"];
147
+ let requestStats = match$3 !== undefined ? (
148
+ Array.isArray(match$3) ? Stdlib_Array.filterMap(match$3, s => {
149
+ let o = Stdlib_JSON.Decode.object(s);
150
+ if (o === undefined) {
151
+ return;
257
152
  }
258
- },
259
- Error: new Error()
260
- };
153
+ let match = o["method"];
154
+ let match$1 = o["seconds"];
155
+ if (typeof match === "string" && typeof match$1 === "number") {
156
+ return {
157
+ method: match,
158
+ seconds: match$1
159
+ };
160
+ }
161
+ }) : []
162
+ ) : [];
163
+ let match$4 = match$2["tag"];
164
+ let retry;
165
+ if (typeof match$4 === "string") {
166
+ switch (match$4) {
167
+ case "WithBackoff" :
168
+ let match$5 = match$2["message"];
169
+ let match$6 = match$2["backoffMillis"];
170
+ retry = typeof match$5 === "string" && typeof match$6 === "number" ? ({
171
+ TAG: "WithBackoff",
172
+ message: match$5,
173
+ backoffMillis: match$6 | 0
174
+ }) : undefined;
175
+ break;
176
+ case "WithSuggestedToBlock" :
177
+ let match$7 = match$2["toBlock"];
178
+ retry = typeof match$7 === "number" ? ({
179
+ TAG: "WithSuggestedToBlock",
180
+ toBlock: match$7 | 0
181
+ }) : undefined;
182
+ break;
183
+ default:
184
+ retry = undefined;
261
185
  }
262
- let executedBlockInterval = (toBlock - fromBlock | 0) + 1 | 0;
263
- let nextBlockIntervalTry$1 = executedBlockInterval * sc.backoffMultiplicative | 0;
264
- mutSuggestedBlockIntervals[partitionId] = nextBlockIntervalTry$1;
186
+ } else {
187
+ retry = undefined;
188
+ }
189
+ return Stdlib_Option.map(retry, retry => [
190
+ match$1 | 0,
191
+ retry,
192
+ requestStats
193
+ ]);
194
+ }
195
+
196
+ function getSelectionConfig(selection) {
197
+ let evmOnEventRegistrations = selection.onEventRegistrations;
198
+ if (Utils.$$Array.isEmpty(evmOnEventRegistrations)) {
265
199
  throw {
266
200
  RE_EXN_ID: Source.GetItemsError,
267
201
  _1: {
268
- TAG: "FailedGettingItems",
269
- exn: err,
270
- attemptedToBlock: toBlock,
271
- retry: {
272
- TAG: "WithBackoff",
273
- message: `Failed getting data for the block range. Will try smaller block range for the next attempt.`,
274
- backoffMillis: sc.backoffMillis
275
- }
202
+ TAG: "UnsupportedSelection",
203
+ message: "Invalid events configuration for the partition. Nothing to fetch. Please, report to the Envio team."
276
204
  },
277
205
  Error: new Error()
278
206
  };
279
- });
280
- }
281
-
282
- function getSelectionConfig(selection, chain) {
283
- let staticTopicSelections = [];
284
- let dynamicEventFilters = [];
285
- selection.eventConfigs.forEach(param => {
286
- let s = param.getEventFiltersOrThrow(chain);
287
- if (s.TAG === "Static") {
288
- staticTopicSelections.push(...s._0);
207
+ }
208
+ let noAddressTopicSelections = [];
209
+ let byContract = {};
210
+ let wildcardByContract = {};
211
+ let contractNames = new Set();
212
+ evmOnEventRegistrations.forEach(reg => {
213
+ let contractName = reg.eventConfig.contractName;
214
+ let resolvedWhere = reg.resolvedWhere;
215
+ if (reg.dependsOnAddresses) {
216
+ contractNames.add(contractName);
217
+ return Utils.Dict.pushMany(reg.isWildcard ? wildcardByContract : byContract, contractName, resolvedWhere.topicSelections);
218
+ } else {
219
+ noAddressTopicSelections.push(...LogSelection.materializeTopicSelections(resolvedWhere.topicSelections, []));
289
220
  return;
290
221
  }
291
- dynamicEventFilters.push(s._0);
292
222
  });
293
- let match = LogSelection.compressTopicSelections(staticTopicSelections);
294
- let len = match.length;
295
- let getLogSelectionOrThrow;
296
- if (len !== 1) {
297
- if (len !== 0) {
298
- throw {
299
- RE_EXN_ID: Source.GetItemsError,
300
- _1: {
301
- TAG: "UnsupportedSelection",
302
- message: "RPC data-source currently supports event filters only when there's a single wildcard event. Please, create a GitHub issue if it's a blocker for you."
303
- },
304
- Error: new Error()
305
- };
306
- }
307
- let len$1 = dynamicEventFilters.length;
308
- if (len$1 !== 1) {
309
- if (len$1 !== 0) {
310
- throw {
311
- RE_EXN_ID: Source.GetItemsError,
312
- _1: {
313
- TAG: "UnsupportedSelection",
314
- message: "RPC data-source currently supports event filters only when there's a single wildcard event. Please, create a GitHub issue if it's a blocker for you."
315
- },
316
- Error: new Error()
317
- };
318
- }
319
- throw {
320
- RE_EXN_ID: Source.GetItemsError,
321
- _1: {
322
- TAG: "UnsupportedSelection",
323
- message: "Invalid events configuration for the partition. Nothing to fetch. Please, report to the Envio team."
324
- },
325
- Error: new Error()
326
- };
327
- }
328
- let dynamicEventFilter = dynamicEventFilters[0];
329
- if (selection.eventConfigs.length === 1) {
330
- let eventConfig = Utils.$$Array.firstUnsafe(selection.eventConfigs);
331
- getLogSelectionOrThrow = addressesByContractName => {
332
- let addresses = FetchState.addressesByContractNameGetAll(addressesByContractName);
333
- let match = dynamicEventFilter(addresses);
334
- if (match.length !== 1) {
335
- throw {
336
- RE_EXN_ID: Source.GetItemsError,
337
- _1: {
338
- TAG: "UnsupportedSelection",
339
- message: "RPC data-source currently doesn't support an array of event filters. Please, create a GitHub issue if it's a blocker for you."
340
- },
341
- Error: new Error()
342
- };
223
+ let toLogSelections = (addresses, topicSelections) => LogSelection.compressTopicSelections(topicSelections).map(topicSelection => ({
224
+ addresses: addresses,
225
+ topicQuery: Rpc.GetLogs.mapTopicQuery(topicSelection)
226
+ }));
227
+ let noAddressLogSelections = toLogSelections(undefined, noAddressTopicSelections);
228
+ let getLogSelectionsOrThrow = contractNames.size === 0 ? param => noAddressLogSelections : addressesByContractName => {
229
+ let logSelections = noAddressLogSelections.slice();
230
+ contractNames.forEach(contractName => {
231
+ let addresses = addressesByContractName[contractName];
232
+ if (addresses === undefined) {
233
+ return;
343
234
  }
344
- return {
345
- addresses: eventConfig.isWildcard ? undefined : addresses,
346
- topicQuery: Rpc.GetLogs.mapTopicQuery(match[0])
347
- };
348
- };
349
- } else {
350
- throw {
351
- RE_EXN_ID: Source.GetItemsError,
352
- _1: {
353
- TAG: "UnsupportedSelection",
354
- message: "RPC data-source currently supports event filters only when there's a single wildcard event. Please, create a GitHub issue if it's a blocker for you."
355
- },
356
- Error: new Error()
357
- };
358
- }
359
- } else {
360
- let topicSelection = match[0];
361
- if (dynamicEventFilters.length !== 0) {
362
- throw {
363
- RE_EXN_ID: Source.GetItemsError,
364
- _1: {
365
- TAG: "UnsupportedSelection",
366
- message: "RPC data-source currently supports event filters only when there's a single wildcard event. Please, create a GitHub issue if it's a blocker for you."
367
- },
368
- Error: new Error()
369
- };
370
- }
371
- let topicQuery = Rpc.GetLogs.mapTopicQuery(topicSelection);
372
- getLogSelectionOrThrow = addressesByContractName => {
373
- let addresses = FetchState.addressesByContractNameGetAll(addressesByContractName);
374
- return {
375
- addresses: addresses.length !== 0 ? addresses : undefined,
376
- topicQuery: topicQuery
377
- };
235
+ if (addresses.length === 0) {
236
+ return;
237
+ }
238
+ let topicSelections = byContract[contractName];
239
+ if (topicSelections !== undefined) {
240
+ logSelections.push(...toLogSelections(addresses, LogSelection.materializeTopicSelections(topicSelections, addresses)));
241
+ }
242
+ let topicSelections$1 = wildcardByContract[contractName];
243
+ if (topicSelections$1 !== undefined) {
244
+ logSelections.push(...toLogSelections(undefined, LogSelection.materializeTopicSelections(topicSelections$1, addresses)));
245
+ return;
246
+ }
247
+ });
248
+ return logSelections;
378
249
  };
379
- }
380
250
  return {
381
- getLogSelectionOrThrow: getLogSelectionOrThrow
251
+ getLogSelectionsOrThrow: getLogSelectionsOrThrow
382
252
  };
383
253
  }
384
254
 
385
- function memoGetSelectionConfig(chain) {
386
- return Utils.$$WeakMap.memoize(selection => getSelectionConfig(selection, chain));
255
+ function memoGetSelectionConfig() {
256
+ return Utils.$$WeakMap.memoize(getSelectionConfig);
387
257
  }
388
258
 
389
259
  let lowercaseAddressSchema = S$RescriptSchema.transform(S$RescriptSchema.string, param => ({
@@ -918,8 +788,8 @@ function makeThrowingGetEventTransaction(getTransactionJson, getReceiptJson, low
918
788
  }
919
789
 
920
790
  function make(param) {
791
+ let headers = param.headers;
921
792
  let lowercaseAddresses = param.lowercaseAddresses;
922
- let allEventParams = param.allEventParams;
923
793
  let eventRouter = param.eventRouter;
924
794
  let chain = param.chain;
925
795
  let url = param.url;
@@ -927,13 +797,27 @@ function make(param) {
927
797
  let host = Utils.Url.getHostFromUrl(url);
928
798
  let urlHost = host !== undefined ? host : Stdlib_JsError.throwWithMessage(`The RPC url for chain ` + chain.toString() + ` is in incorrect format. The RPC url needs to start with either http:// or https://`);
929
799
  let name = `RPC (` + urlHost + `)`;
930
- let getSelectionConfig = memoGetSelectionConfig(chain);
931
- let mutSuggestedBlockIntervals = {};
932
- let client = Rpc.makeClient(url);
933
- let rpcClient = EvmRpcClient.make(url, undefined);
800
+ let getSelectionConfig$1 = Utils.$$WeakMap.memoize(getSelectionConfig);
801
+ let client = Rpc.makeClient(url, headers);
802
+ let rpcClient = EvmRpcClient.make(url, !lowercaseAddresses, syncConfig, undefined, headers, param.allEventParams);
803
+ let pendingRequestStats = [];
804
+ let recordRequest = (method, seconds) => {
805
+ pendingRequestStats.push({
806
+ method: method,
807
+ seconds: seconds
808
+ });
809
+ };
810
+ let drainRequestStats = () => {
811
+ let stats = pendingRequestStats.slice();
812
+ Utils.$$Array.clearInPlace(pendingRequestStats);
813
+ return stats;
814
+ };
934
815
  let makeTransactionLoader = () => LazyLoader.make(transactionHash => {
935
- Prometheus.SourceRequestCount.increment(name, chain, "eth_getTransactionByHash");
936
- return Rest.fetch(Rpc.GetTransactionByHash.rawRoute, transactionHash, client);
816
+ let timerRef = Performance.now();
817
+ return Rest.fetch(Rpc.GetTransactionByHash.rawRoute, transactionHash, client).then(res => {
818
+ recordRequest("eth_getTransactionByHash", Performance.secondsSince(timerRef));
819
+ return res;
820
+ });
937
821
  }, (am, exn) => Logging.error({
938
822
  err: Utils.prettifyExn(exn),
939
823
  msg: `Top level promise timeout reached. Please review other errors or warnings in the code. This function will retry in ` + (am._retryDelayMillis / 1000 | 0).toString() + ` seconds. It is highly likely that your indexer isn't syncing on one or more chains currently. Also take a look at the "suggestedFix" in the metadata of this command`,
@@ -944,7 +828,7 @@ function make(param) {
944
828
  suggestedFix: "This likely means the RPC url you are using is not responding correctly. Please try another RPC endipoint."
945
829
  }
946
830
  }), undefined, undefined, undefined, undefined);
947
- let makeBlockLoader = () => LazyLoader.make(blockNumber => getKnownRawBlockWithBackoff(client, name, chain, blockNumber, 1000), (am, exn) => Logging.error({
831
+ let makeBlockLoader = () => LazyLoader.make(blockNumber => getKnownRawBlockWithBackoff(client, name, chain, blockNumber, 1000, recordRequest), (am, exn) => Logging.error({
948
832
  err: Utils.prettifyExn(exn),
949
833
  msg: `Top level promise timeout reached. Please review other errors or warnings in the code. This function will retry in ` + (am._retryDelayMillis / 1000 | 0).toString() + ` seconds. It is highly likely that your indexer isn't syncing on one or more chains currently. Also take a look at the "suggestedFix" in the metadata of this command`,
950
834
  source: name,
@@ -955,8 +839,11 @@ function make(param) {
955
839
  }
956
840
  }), undefined, undefined, undefined, undefined);
957
841
  let makeReceiptLoader = () => LazyLoader.make(transactionHash => {
958
- Prometheus.SourceRequestCount.increment(name, chain, "eth_getTransactionReceipt");
959
- return Rest.fetch(Rpc.GetTransactionReceipt.rawRoute, transactionHash, client);
842
+ let timerRef = Performance.now();
843
+ return Rest.fetch(Rpc.GetTransactionReceipt.rawRoute, transactionHash, client).then(res => {
844
+ recordRequest("eth_getTransactionReceipt", Performance.secondsSince(timerRef));
845
+ return res;
846
+ });
960
847
  }, (am, exn) => Logging.error({
961
848
  err: Utils.prettifyExn(exn),
962
849
  msg: `Top level promise timeout reached. Please review other errors or warnings in the code. This function will retry in ` + (am._retryDelayMillis / 1000 | 0).toString() + ` seconds. It is highly likely that your indexer isn't syncing on one or more chains currently. Also take a look at the "suggestedFix" in the metadata of this command`,
@@ -998,65 +885,47 @@ function make(param) {
998
885
  Error: new Error()
999
886
  };
1000
887
  }, lowercaseAddresses);
1001
- let convertLogToHyperSyncEvent = log => {
1002
- let hyperSyncLog_removed = log.removed;
1003
- let hyperSyncLog_logIndex = log.logIndex;
1004
- let hyperSyncLog_transactionIndex = log.transactionIndex;
1005
- let hyperSyncLog_transactionHash = log.transactionHash;
1006
- let hyperSyncLog_blockHash = log.blockHash;
1007
- let hyperSyncLog_blockNumber = log.blockNumber;
1008
- let hyperSyncLog_address = Primitive_option.some(log.address);
1009
- let hyperSyncLog_data = log.data;
1010
- let hyperSyncLog_topics = log.topics;
1011
- let hyperSyncLog = {
1012
- removed: hyperSyncLog_removed,
1013
- logIndex: hyperSyncLog_logIndex,
1014
- transactionIndex: hyperSyncLog_transactionIndex,
1015
- transactionHash: hyperSyncLog_transactionHash,
1016
- blockHash: hyperSyncLog_blockHash,
1017
- blockNumber: hyperSyncLog_blockNumber,
1018
- address: hyperSyncLog_address,
1019
- data: hyperSyncLog_data,
1020
- topics: hyperSyncLog_topics
1021
- };
1022
- return {
1023
- log: hyperSyncLog
1024
- };
1025
- };
1026
- let hscDecoder = {
1027
- contents: undefined
1028
- };
1029
- let getHscDecoder = () => {
1030
- let decoder = hscDecoder.contents;
1031
- if (decoder !== undefined) {
1032
- return decoder;
1033
- }
1034
- let decoder$1 = HyperSyncClient.Decoder.fromParams(allEventParams, !lowercaseAddresses);
1035
- hscDecoder.contents = decoder$1;
1036
- return decoder$1;
1037
- };
1038
- let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, indexingAddresses, knownHeight, partitionId, selection, retry, param) => {
1039
- let startFetchingBatchTimeRef = Hrtime.makeTimer();
1040
- let maxSuggestedBlockInterval = mutSuggestedBlockIntervals[maxSuggestedBlockIntervalKey];
1041
- let suggestedBlockInterval = maxSuggestedBlockInterval !== undefined ? maxSuggestedBlockInterval : Stdlib_Option.getOr(mutSuggestedBlockIntervals[partitionId], syncConfig.initialBlockInterval);
888
+ let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, contractNameByAddress, knownHeight, partitionId, selection, param, retry, param$1) => {
889
+ let startFetchingBatchTimeRef = Performance.now();
1042
890
  let toBlock$1 = toBlock !== undefined ? Primitive_int.min(toBlock, knownHeight) : knownHeight;
1043
- let suggestedToBlock = Primitive_int.max(Primitive_int.min((fromBlock + suggestedBlockInterval | 0) - 1 | 0, toBlock$1), fromBlock);
1044
891
  let firstBlockParentPromise = fromBlock > 0 ? LazyLoader.get(blockLoader.contents, fromBlock - 1 | 0).then(json => parseBlockInfo(json)) : Promise.resolve(undefined);
1045
- let match = getSelectionConfig(selection);
1046
- let match$1 = match.getLogSelectionOrThrow(addressesByContractName);
1047
- let match$2 = await getNextPage(fromBlock, suggestedToBlock, match$1.addresses, match$1.topicQuery, blockNumber => LazyLoader.get(blockLoader.contents, blockNumber).then(parseBlockInfo), syncConfig, client, mutSuggestedBlockIntervals, partitionId, name, chain);
1048
- let latestFetchedBlockInfo = match$2.latestFetchedBlockInfo;
1049
- let logs = match$2.logs;
1050
- let executedBlockInterval = (suggestedToBlock - fromBlock | 0) + 1 | 0;
1051
- if (executedBlockInterval >= suggestedBlockInterval && !(maxSuggestedBlockIntervalKey in mutSuggestedBlockIntervals)) {
1052
- mutSuggestedBlockIntervals[partitionId] = Primitive_int.min(executedBlockInterval + syncConfig.accelerationAdditive | 0, syncConfig.intervalCeiling);
1053
- }
1054
- let hyperSyncEvents = logs.map(convertLogToHyperSyncEvent);
1055
- let parsedEvents;
892
+ let match = getSelectionConfig$1(selection);
893
+ let logSelections = match.getLogSelectionsOrThrow(addressesByContractName);
894
+ let match$1;
1056
895
  try {
1057
- parsedEvents = await getHscDecoder().decodeLogs(hyperSyncEvents);
896
+ match$1 = await rpcClient.getNextPage({
897
+ fromBlock: fromBlock,
898
+ toBlockCeiling: toBlock$1,
899
+ logSelections: logSelections.map(param => ({
900
+ addresses: param.addresses,
901
+ topics: param.topicQuery.map(filter => {
902
+ if (filter === null) {
903
+ return null;
904
+ } else if (typeof filter === "string") {
905
+ return [filter];
906
+ } else {
907
+ return filter;
908
+ }
909
+ })
910
+ })),
911
+ partitionId: partitionId
912
+ });
1058
913
  } catch (raw_exn) {
1059
914
  let exn = Primitive_exceptions.internalToException(raw_exn);
915
+ let match$2 = parseGetNextPageRetryError(exn);
916
+ if (match$2 !== undefined) {
917
+ match$2[2].forEach(stat => recordRequest(stat.method, stat.seconds));
918
+ throw {
919
+ RE_EXN_ID: Source.GetItemsError,
920
+ _1: {
921
+ TAG: "FailedGettingItems",
922
+ exn: exn,
923
+ attemptedToBlock: match$2[0],
924
+ retry: match$2[1]
925
+ },
926
+ Error: new Error()
927
+ };
928
+ }
1060
929
  throw {
1061
930
  RE_EXN_ID: Source.GetItemsError,
1062
931
  _1: {
@@ -1064,22 +933,27 @@ function make(param) {
1064
933
  exn: exn,
1065
934
  attemptedToBlock: toBlock$1,
1066
935
  retry: {
1067
- TAG: "ImpossibleForTheQuery",
1068
- message: "Failed to parse events using hypersync client decoder. Please double-check your ABI."
936
+ TAG: "WithBackoff",
937
+ message: "Unexpected issue while fetching events from the RPC client. Attempt a retry.",
938
+ backoffMillis: retry !== 0 ? 1000 * retry | 0 : 500
1069
939
  }
1070
940
  },
1071
941
  Error: new Error()
1072
942
  };
1073
943
  }
1074
- let parsedQueueItems = await Promise.all(Stdlib_Array.filterMap(Stdlib_Array.zip(logs, parsedEvents), param => {
1075
- let log = param[0];
944
+ let items = match$1.items;
945
+ match$1.requestStats.forEach(stat => recordRequest(stat.method, stat.seconds));
946
+ let latestFetchedBlockInfo = await LazyLoader.get(blockLoader.contents, match$1.toBlock).then(parseBlockInfo);
947
+ let parsedQueueItems = await Promise.all(Stdlib_Array.filterMap(items, param => {
948
+ let log = param.log;
1076
949
  let topic0 = Stdlib_Option.getOr(log.topics[0], "0x0");
1077
950
  let routedAddress = lowercaseAddresses ? Address.Evm.fromAddressLowercaseOrThrow(log.address) : Address.Evm.fromAddressOrThrow(log.address);
1078
- let eventConfig = EventRouter.get(eventRouter, EventRouter.getEvmEventId(topic0, log.topics.length), routedAddress, log.blockNumber, indexingAddresses);
1079
- if (eventConfig === undefined) {
951
+ let onEventRegistration = EventRouter.get(eventRouter, EventRouter.getEvmEventId(topic0, log.topics.length), routedAddress, contractNameByAddress);
952
+ if (onEventRegistration === undefined) {
1080
953
  return;
1081
954
  }
1082
- let decoded = Stdlib_Option.flatMap(Primitive_option.fromNullable(param[1]), __x => __x[eventConfig.contractName]);
955
+ let eventConfig = onEventRegistration.eventConfig;
956
+ let decoded = Stdlib_Option.flatMap(Primitive_option.fromNullable(param.params), __x => __x[eventConfig.contractName]);
1083
957
  if (decoded === undefined) {
1084
958
  return;
1085
959
  }
@@ -1125,12 +999,11 @@ function make(param) {
1125
999
  let block = match[0];
1126
1000
  return {
1127
1001
  kind: 0,
1128
- eventConfig: eventConfig,
1129
- timestamp: block.timestamp,
1002
+ onEventRegistration: onEventRegistration,
1130
1003
  chain: chain,
1131
1004
  blockNumber: block.number,
1132
- blockHash: block.hash,
1133
1005
  logIndex: log.logIndex,
1006
+ transactionIndex: log.transactionIndex,
1134
1007
  payload: {
1135
1008
  contractName: eventConfig.contractName,
1136
1009
  eventName: eventConfig.name,
@@ -1138,14 +1011,14 @@ function make(param) {
1138
1011
  chainId: chain,
1139
1012
  srcAddress: routedAddress,
1140
1013
  logIndex: log.logIndex,
1141
- transaction: match[1],
1142
- block: block
1014
+ transaction: Primitive_option.some(match[1]),
1015
+ block: Primitive_option.some(block)
1143
1016
  }
1144
1017
  };
1145
1018
  })();
1146
1019
  }));
1147
1020
  let optFirstBlockParent = await firstBlockParentPromise;
1148
- let totalTimeElapsed = Hrtime.toSecondsFloat(Hrtime.timeSince(startFetchingBatchTimeRef));
1021
+ let totalTimeElapsed = Performance.secondsSince(startFetchingBatchTimeRef);
1149
1022
  let blockHashes = [];
1150
1023
  let pushBlockInfo = b => {
1151
1024
  blockHashes.push({
@@ -1164,7 +1037,8 @@ function make(param) {
1164
1037
  if (optFirstBlockParent !== undefined) {
1165
1038
  pushBlockInfo(optFirstBlockParent);
1166
1039
  }
1167
- logs.forEach(log => {
1040
+ items.forEach(param => {
1041
+ let log = param.log;
1168
1042
  blockHashes.push({
1169
1043
  blockHash: log.blockHash,
1170
1044
  blockNumber: log.blockNumber
@@ -1174,12 +1048,15 @@ function make(param) {
1174
1048
  knownHeight: knownHeight,
1175
1049
  blockHashes: blockHashes,
1176
1050
  parsedQueueItems: parsedQueueItems,
1051
+ transactionStore: undefined,
1052
+ blockStore: undefined,
1177
1053
  fromBlockQueried: fromBlock,
1178
1054
  latestFetchedBlockNumber: latestFetchedBlockInfo.number,
1179
1055
  latestFetchedBlockTimestamp: latestFetchedBlockInfo.timestamp,
1180
1056
  stats: {
1181
1057
  "total time elapsed (s)": totalTimeElapsed
1182
- }
1058
+ },
1059
+ requestStats: drainRequestStats()
1183
1060
  };
1184
1061
  };
1185
1062
  let onReorg = param => {
@@ -1187,19 +1064,28 @@ function make(param) {
1187
1064
  transactionLoader.contents = makeTransactionLoader();
1188
1065
  receiptLoader.contents = makeReceiptLoader();
1189
1066
  };
1190
- let getBlockHashes = (blockNumbers, _currentlyUnusedLogger) => Stdlib_Promise.$$catch(Promise.all(blockNumbers.map(blockNum => LazyLoader.get(blockLoader.contents, blockNum))).then(rawBlocks => ({
1191
- TAG: "Ok",
1192
- _0: rawBlocks.map(json => {
1193
- let b = parseBlockInfo(json);
1194
- return {
1195
- blockHash: b.hash,
1196
- blockNumber: b.number,
1197
- blockTimestamp: b.timestamp
1198
- };
1199
- })
1200
- })), exn => Promise.resolve({
1201
- TAG: "Error",
1202
- _0: exn
1067
+ let getBlockHashes = (blockNumbers, _currentlyUnusedLogger) => Stdlib_Promise.$$catch(Promise.all(blockNumbers.map(blockNum => LazyLoader.get(blockLoader.contents, blockNum))).then(rawBlocks => {
1068
+ let result = {
1069
+ TAG: "Ok",
1070
+ _0: rawBlocks.map(json => {
1071
+ let b = parseBlockInfo(json);
1072
+ return {
1073
+ blockHash: b.hash,
1074
+ blockNumber: b.number,
1075
+ blockTimestamp: b.timestamp
1076
+ };
1077
+ })
1078
+ };
1079
+ return {
1080
+ result: result,
1081
+ requestStats: drainRequestStats()
1082
+ };
1083
+ }), exn => Promise.resolve({
1084
+ result: {
1085
+ TAG: "Error",
1086
+ _0: exn
1087
+ },
1088
+ requestStats: drainRequestStats()
1203
1089
  }));
1204
1090
  let createHeightSubscription = Stdlib_Option.map(param.ws, wsUrl => (onHeight => RpcWebSocketHeightStream.subscribe(wsUrl, chain, onHeight)));
1205
1091
  return {
@@ -1210,20 +1096,19 @@ function make(param) {
1210
1096
  pollingInterval: syncConfig.pollingInterval,
1211
1097
  getBlockHashes: getBlockHashes,
1212
1098
  getHeightOrThrow: async () => {
1213
- let timerRef = Hrtime.makeTimer();
1099
+ let timerRef = Performance.now();
1214
1100
  let height;
1215
1101
  try {
1216
1102
  height = await rpcClient.getHeight();
1217
1103
  } catch (exn) {
1218
- let seconds = Hrtime.toSecondsFloat(Hrtime.timeSince(timerRef));
1219
- Prometheus.SourceRequestCount.increment(name, chain, "eth_blockNumber");
1220
- Prometheus.SourceRequestCount.addSeconds(name, chain, "eth_blockNumber", seconds);
1104
+ recordRequest("eth_blockNumber", Performance.secondsSince(timerRef));
1221
1105
  throw exn;
1222
1106
  }
1223
- let seconds$1 = Hrtime.toSecondsFloat(Hrtime.timeSince(timerRef));
1224
- Prometheus.SourceRequestCount.increment(name, chain, "eth_blockNumber");
1225
- Prometheus.SourceRequestCount.addSeconds(name, chain, "eth_blockNumber", seconds$1);
1226
- return height;
1107
+ recordRequest("eth_blockNumber", Performance.secondsSince(timerRef));
1108
+ return {
1109
+ height: height,
1110
+ requestStats: drainRequestStats()
1111
+ };
1227
1112
  },
1228
1113
  getItemsOrThrow: getItemsOrThrow,
1229
1114
  createHeightSubscription: createHeightSubscription,
@@ -1232,14 +1117,12 @@ function make(param) {
1232
1117
  }
1233
1118
 
1234
1119
  export {
1235
- QueryTimout,
1236
1120
  TransactionDataNotFound,
1237
1121
  getKnownRawBlock,
1238
1122
  parseBlockInfo,
1239
1123
  getKnownRawBlockWithBackoff,
1240
- getSuggestedBlockIntervalFromExn,
1241
- maxSuggestedBlockIntervalKey,
1242
- getNextPage,
1124
+ getErrorMessage,
1125
+ parseGetNextPageRetryError,
1243
1126
  getSelectionConfig,
1244
1127
  memoGetSelectionConfig,
1245
1128
  lowercaseAddressSchema,