envio 3.0.0-alpha.2 → 3.0.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/evm.schema.json +44 -34
- package/fuel.schema.json +32 -21
- package/index.d.ts +4 -1
- package/index.js +1 -0
- package/package.json +7 -6
- package/src/Batch.res.mjs +1 -1
- package/src/Benchmark.res +394 -0
- package/src/Benchmark.res.mjs +398 -0
- package/src/ChainFetcher.res +459 -0
- package/src/ChainFetcher.res.mjs +281 -0
- package/src/ChainManager.res +179 -0
- package/src/ChainManager.res.mjs +139 -0
- package/src/Config.res +15 -1
- package/src/Config.res.mjs +28 -5
- package/src/Ecosystem.res +9 -124
- package/src/Ecosystem.res.mjs +19 -160
- package/src/Env.res +0 -1
- package/src/Env.res.mjs +0 -3
- package/src/Envio.gen.ts +9 -1
- package/src/Envio.res +12 -9
- package/src/EventProcessing.res +476 -0
- package/src/EventProcessing.res.mjs +341 -0
- package/src/FetchState.res +54 -29
- package/src/FetchState.res.mjs +62 -35
- package/src/GlobalState.res +1169 -0
- package/src/GlobalState.res.mjs +1196 -0
- package/src/Internal.res +43 -1
- package/src/LoadLayer.res +444 -0
- package/src/LoadLayer.res.mjs +296 -0
- package/src/LoadLayer.resi +32 -0
- package/src/Prometheus.res +8 -8
- package/src/Prometheus.res.mjs +10 -10
- package/src/ReorgDetection.res +6 -10
- package/src/ReorgDetection.res.mjs +6 -6
- package/src/Types.ts +1 -1
- package/src/UserContext.res +356 -0
- package/src/UserContext.res.mjs +238 -0
- package/src/Utils.res +15 -0
- package/src/Utils.res.mjs +18 -0
- package/src/bindings/ClickHouse.res +31 -1
- package/src/bindings/ClickHouse.res.mjs +27 -1
- package/src/bindings/DateFns.res +71 -0
- package/src/bindings/DateFns.res.mjs +22 -0
- package/src/bindings/Ethers.res +27 -63
- package/src/bindings/Ethers.res.mjs +18 -65
- package/src/sources/Evm.res +87 -0
- package/src/sources/Evm.res.mjs +105 -0
- package/src/sources/EvmChain.res +95 -0
- package/src/sources/EvmChain.res.mjs +61 -0
- package/src/sources/Fuel.res +19 -34
- package/src/sources/Fuel.res.mjs +34 -16
- package/src/sources/FuelSDK.res +37 -0
- package/src/sources/FuelSDK.res.mjs +29 -0
- package/src/sources/HyperFuel.res +2 -2
- package/src/sources/HyperFuel.resi +1 -1
- package/src/sources/HyperFuelClient.res +2 -2
- package/src/sources/HyperFuelSource.res +8 -8
- package/src/sources/HyperFuelSource.res.mjs +5 -5
- package/src/sources/HyperSyncHeightStream.res +28 -110
- package/src/sources/HyperSyncHeightStream.res.mjs +30 -63
- package/src/sources/HyperSyncSource.res +16 -18
- package/src/sources/HyperSyncSource.res.mjs +25 -25
- package/src/sources/Rpc.res +43 -0
- package/src/sources/Rpc.res.mjs +31 -0
- package/src/sources/RpcSource.res +13 -8
- package/src/sources/RpcSource.res.mjs +12 -7
- package/src/sources/Source.res +3 -2
- package/src/sources/SourceManager.res +183 -108
- package/src/sources/SourceManager.res.mjs +162 -99
- package/src/sources/SourceManager.resi +4 -5
- package/src/sources/Svm.res +59 -0
- package/src/sources/Svm.res.mjs +79 -0
- package/src/bindings/Ethers.gen.ts +0 -14
|
@@ -10,6 +10,7 @@ import * as Belt_Array from "rescript/lib/es6/belt_Array.js";
|
|
|
10
10
|
import * as FetchState from "../FetchState.res.mjs";
|
|
11
11
|
import * as Prometheus from "../Prometheus.res.mjs";
|
|
12
12
|
import * as Belt_Option from "rescript/lib/es6/belt_Option.js";
|
|
13
|
+
import * as Caml_option from "rescript/lib/es6/caml_option.js";
|
|
13
14
|
import * as ErrorHandling from "../ErrorHandling.res.mjs";
|
|
14
15
|
import * as Caml_js_exceptions from "rescript/lib/es6/caml_js_exceptions.js";
|
|
15
16
|
|
|
@@ -35,7 +36,15 @@ function make(sources, maxPartitionConcurrency, newBlockFallbackStallTimeoutOpt,
|
|
|
35
36
|
Prometheus.IndexingMaxConcurrency.set(maxPartitionConcurrency, initialActiveSource.chain);
|
|
36
37
|
Prometheus.IndexingConcurrency.set(0, initialActiveSource.chain);
|
|
37
38
|
return {
|
|
38
|
-
|
|
39
|
+
sourcesState: Belt_Array.map(sources, (function (source) {
|
|
40
|
+
return {
|
|
41
|
+
source: source,
|
|
42
|
+
knownHeight: 0,
|
|
43
|
+
unsubscribe: undefined,
|
|
44
|
+
pendingHeightResolvers: [],
|
|
45
|
+
disabled: false
|
|
46
|
+
};
|
|
47
|
+
})),
|
|
39
48
|
statusStart: Hrtime.makeTimer(),
|
|
40
49
|
status: "Idle",
|
|
41
50
|
maxPartitionConcurrency: maxPartitionConcurrency,
|
|
@@ -68,10 +77,10 @@ function trackNewStatus(sourceManager, newStatus) {
|
|
|
68
77
|
sourceManager.status = newStatus;
|
|
69
78
|
}
|
|
70
79
|
|
|
71
|
-
async function fetchNext(sourceManager, fetchState,
|
|
72
|
-
var
|
|
73
|
-
if (typeof
|
|
74
|
-
switch (
|
|
80
|
+
async function fetchNext(sourceManager, fetchState, executeQuery, waitForNewBlock, onNewBlock, stateId) {
|
|
81
|
+
var nextQuery = FetchState.getNextQuery(fetchState, sourceManager.maxPartitionConcurrency - sourceManager.fetchingPartitionsCount | 0, stateId);
|
|
82
|
+
if (typeof nextQuery !== "object") {
|
|
83
|
+
switch (nextQuery) {
|
|
75
84
|
case "WaitingForNewBlock" :
|
|
76
85
|
var waitingStateId = sourceManager.waitingForNewBlockStateId;
|
|
77
86
|
if (waitingStateId !== undefined && waitingStateId >= stateId) {
|
|
@@ -79,12 +88,12 @@ async function fetchNext(sourceManager, fetchState, currentBlockHeight, executeQ
|
|
|
79
88
|
}
|
|
80
89
|
trackNewStatus(sourceManager, "WaitingForNewBlock");
|
|
81
90
|
sourceManager.waitingForNewBlockStateId = stateId;
|
|
82
|
-
var
|
|
91
|
+
var knownHeight = await waitForNewBlock(fetchState.knownHeight);
|
|
83
92
|
var waitingStateId$1 = sourceManager.waitingForNewBlockStateId;
|
|
84
93
|
if (waitingStateId$1 !== undefined && waitingStateId$1 === stateId) {
|
|
85
94
|
trackNewStatus(sourceManager, "Idle");
|
|
86
95
|
sourceManager.waitingForNewBlockStateId = undefined;
|
|
87
|
-
return onNewBlock(
|
|
96
|
+
return onNewBlock(knownHeight);
|
|
88
97
|
} else {
|
|
89
98
|
return ;
|
|
90
99
|
}
|
|
@@ -94,12 +103,12 @@ async function fetchNext(sourceManager, fetchState, currentBlockHeight, executeQ
|
|
|
94
103
|
|
|
95
104
|
}
|
|
96
105
|
} else {
|
|
97
|
-
var queries
|
|
98
|
-
FetchState.startFetchingQueries(fetchState, queries
|
|
99
|
-
sourceManager.fetchingPartitionsCount = sourceManager.fetchingPartitionsCount + queries
|
|
106
|
+
var queries = nextQuery._0;
|
|
107
|
+
FetchState.startFetchingQueries(fetchState, queries, stateId);
|
|
108
|
+
sourceManager.fetchingPartitionsCount = sourceManager.fetchingPartitionsCount + queries.length | 0;
|
|
100
109
|
Prometheus.IndexingConcurrency.set(sourceManager.fetchingPartitionsCount, sourceManager.activeSource.chain);
|
|
101
110
|
trackNewStatus(sourceManager, "Querieng");
|
|
102
|
-
await Promise.all(Belt_Array.map(queries
|
|
111
|
+
await Promise.all(Belt_Array.map(queries, (function (q) {
|
|
103
112
|
var promise = executeQuery(q);
|
|
104
113
|
promise.then(function (param) {
|
|
105
114
|
sourceManager.fetchingPartitionsCount = sourceManager.fetchingPartitionsCount - 1 | 0;
|
|
@@ -115,64 +124,110 @@ async function fetchNext(sourceManager, fetchState, currentBlockHeight, executeQ
|
|
|
115
124
|
}
|
|
116
125
|
}
|
|
117
126
|
|
|
118
|
-
|
|
119
|
-
|
|
127
|
+
function disableSource(sourceState) {
|
|
128
|
+
if (sourceState.disabled) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
sourceState.disabled = true;
|
|
132
|
+
var unsubscribe = sourceState.unsubscribe;
|
|
133
|
+
if (unsubscribe !== undefined) {
|
|
134
|
+
unsubscribe();
|
|
135
|
+
}
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async function getSourceNewHeight(sourceManager, sourceState, knownHeight, status, logger) {
|
|
140
|
+
var source = sourceState.source;
|
|
141
|
+
var initialHeight = sourceState.knownHeight;
|
|
142
|
+
var newHeight = initialHeight;
|
|
120
143
|
var retry = 0;
|
|
121
|
-
while(newHeight <=
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
newHeight = height;
|
|
130
|
-
if (height <= currentBlockHeight) {
|
|
131
|
-
retry = 0;
|
|
132
|
-
var pollingInterval = status.contents === "Stalled" ? sourceManager.stalledPollingInterval : source.pollingInterval;
|
|
133
|
-
await Utils.delay(pollingInterval);
|
|
144
|
+
while(newHeight <= knownHeight && status.contents !== "Done") {
|
|
145
|
+
var match = sourceState.unsubscribe;
|
|
146
|
+
if (match !== undefined) {
|
|
147
|
+
var height = await new Promise((function (resolve, _reject) {
|
|
148
|
+
sourceState.pendingHeightResolvers.push(resolve);
|
|
149
|
+
}));
|
|
150
|
+
if (height > initialHeight) {
|
|
151
|
+
newHeight = height;
|
|
134
152
|
}
|
|
135
153
|
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
154
|
+
} else {
|
|
155
|
+
try {
|
|
156
|
+
var endTimer = Prometheus.SourceGetHeightDuration.startTimer({
|
|
157
|
+
source: source.name,
|
|
158
|
+
chainId: source.chain
|
|
159
|
+
});
|
|
160
|
+
var height$1 = await source.getHeightOrThrow();
|
|
161
|
+
endTimer();
|
|
162
|
+
newHeight = height$1;
|
|
163
|
+
if (height$1 <= knownHeight) {
|
|
164
|
+
retry = 0;
|
|
165
|
+
var createSubscription = source.createHeightSubscription;
|
|
166
|
+
if (createSubscription !== undefined) {
|
|
167
|
+
var unsubscribe = createSubscription(function (newHeight) {
|
|
168
|
+
sourceState.knownHeight = newHeight;
|
|
169
|
+
var resolvers = sourceState.pendingHeightResolvers;
|
|
170
|
+
sourceState.pendingHeightResolvers = [];
|
|
171
|
+
Belt_Array.forEach(resolvers, (function (resolve) {
|
|
172
|
+
resolve(newHeight);
|
|
173
|
+
}));
|
|
174
|
+
});
|
|
175
|
+
sourceState.unsubscribe = unsubscribe;
|
|
176
|
+
} else {
|
|
177
|
+
var pollingInterval = status.contents === "Stalled" ? sourceManager.stalledPollingInterval : source.pollingInterval;
|
|
178
|
+
await Utils.delay(pollingInterval);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
}
|
|
183
|
+
catch (raw_exn){
|
|
184
|
+
var exn = Caml_js_exceptions.internalToOCamlException(raw_exn);
|
|
185
|
+
var retryInterval = sourceManager.getHeightRetryInterval(retry);
|
|
186
|
+
Logging.childTrace(logger, {
|
|
187
|
+
msg: "Height retrieval from " + source.name + " source failed. Retrying in " + String(retryInterval) + "ms.",
|
|
188
|
+
source: source.name,
|
|
189
|
+
err: Utils.prettifyExn(exn)
|
|
190
|
+
});
|
|
191
|
+
retry = retry + 1 | 0;
|
|
192
|
+
await Utils.delay(retryInterval);
|
|
193
|
+
}
|
|
147
194
|
}
|
|
148
195
|
};
|
|
149
|
-
|
|
196
|
+
if (newHeight > initialHeight) {
|
|
197
|
+
Prometheus.SourceHeight.set(source.name, source.chain, newHeight);
|
|
198
|
+
}
|
|
150
199
|
return newHeight;
|
|
151
200
|
}
|
|
152
201
|
|
|
153
|
-
async function waitForNewBlock(sourceManager,
|
|
202
|
+
async function waitForNewBlock(sourceManager, knownHeight) {
|
|
154
203
|
var logger = Logging.createChild({
|
|
155
204
|
chainId: sourceManager.activeSource.chain,
|
|
156
|
-
|
|
205
|
+
knownHeight: knownHeight
|
|
157
206
|
});
|
|
158
207
|
Logging.childTrace(logger, "Initiating check for new blocks.");
|
|
159
|
-
var isInitialHeightFetch =
|
|
208
|
+
var isInitialHeightFetch = knownHeight === 0;
|
|
160
209
|
var syncSources = [];
|
|
161
210
|
var fallbackSources = [];
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
211
|
+
Belt_Array.forEach(sourceManager.sourcesState, (function (sourceState) {
|
|
212
|
+
var source = sourceState.source;
|
|
213
|
+
if (sourceState.disabled) {
|
|
214
|
+
return ;
|
|
215
|
+
} else {
|
|
216
|
+
if (source.sourceFor === "Sync" || source.sourceFor === "Live" && !isInitialHeightFetch || source === sourceManager.activeSource) {
|
|
217
|
+
syncSources.push(sourceState);
|
|
218
|
+
} else {
|
|
219
|
+
fallbackSources.push(sourceState);
|
|
220
|
+
}
|
|
221
|
+
return ;
|
|
222
|
+
}
|
|
223
|
+
}));
|
|
169
224
|
var status = {
|
|
170
225
|
contents: "Active"
|
|
171
226
|
};
|
|
172
|
-
var match = await Promise.race(Belt_Array.concat(Belt_Array.map(syncSources, (async function (
|
|
227
|
+
var match = await Promise.race(Belt_Array.concat(Belt_Array.map(syncSources, (async function (sourceState) {
|
|
173
228
|
return [
|
|
174
|
-
source,
|
|
175
|
-
await getSourceNewHeight(sourceManager,
|
|
229
|
+
sourceState.source,
|
|
230
|
+
await getSourceNewHeight(sourceManager, sourceState, knownHeight, status, logger)
|
|
176
231
|
];
|
|
177
232
|
})), [Utils.delay(sourceManager.newBlockFallbackStallTimeout).then(function () {
|
|
178
233
|
if (status.contents !== "Done") {
|
|
@@ -183,10 +238,10 @@ async function waitForNewBlock(sourceManager, currentBlockHeight) {
|
|
|
183
238
|
Logging.childWarn(logger, "No new blocks detected within " + String(sourceManager.newBlockFallbackStallTimeout / 1000 | 0) + "s. Polling will continue at a reduced rate. For better reliability, refer to our RPC fallback guide: https://docs.envio.dev/docs/HyperIndex/rpc-sync");
|
|
184
239
|
}
|
|
185
240
|
}
|
|
186
|
-
return Promise.race(Belt_Array.map(fallbackSources, (async function (
|
|
241
|
+
return Promise.race(Belt_Array.map(fallbackSources, (async function (sourceState) {
|
|
187
242
|
return [
|
|
188
|
-
source,
|
|
189
|
-
await getSourceNewHeight(sourceManager,
|
|
243
|
+
sourceState.source,
|
|
244
|
+
await getSourceNewHeight(sourceManager, sourceState, knownHeight, status, logger)
|
|
190
245
|
];
|
|
191
246
|
})));
|
|
192
247
|
})]));
|
|
@@ -203,38 +258,42 @@ async function waitForNewBlock(sourceManager, currentBlockHeight) {
|
|
|
203
258
|
return newBlockHeight;
|
|
204
259
|
}
|
|
205
260
|
|
|
206
|
-
function
|
|
261
|
+
function getNextSyncSourceState(sourceManager, initialSourceState, currentSourceState, attemptFallbacksOpt) {
|
|
207
262
|
var attemptFallbacks = attemptFallbacksOpt !== undefined ? attemptFallbacksOpt : false;
|
|
208
263
|
var before = [];
|
|
209
264
|
var after = [];
|
|
210
265
|
var hasActive = {
|
|
211
266
|
contents: false
|
|
212
267
|
};
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
268
|
+
Belt_Array.forEach(sourceManager.sourcesState, (function (sourceState) {
|
|
269
|
+
var source = sourceState.source;
|
|
270
|
+
if (sourceState.disabled) {
|
|
271
|
+
return ;
|
|
272
|
+
}
|
|
273
|
+
if (sourceState === currentSourceState) {
|
|
274
|
+
hasActive.contents = true;
|
|
275
|
+
return ;
|
|
276
|
+
}
|
|
277
|
+
var match = source.sourceFor;
|
|
278
|
+
var tmp;
|
|
279
|
+
switch (match) {
|
|
280
|
+
case "Sync" :
|
|
281
|
+
tmp = true;
|
|
282
|
+
break;
|
|
283
|
+
case "Fallback" :
|
|
284
|
+
case "Live" :
|
|
285
|
+
tmp = attemptFallbacks || sourceState === initialSourceState;
|
|
286
|
+
break;
|
|
287
|
+
|
|
288
|
+
}
|
|
289
|
+
if (tmp) {
|
|
290
|
+
(
|
|
291
|
+
hasActive.contents ? after : before
|
|
292
|
+
).push(sourceState);
|
|
293
|
+
return ;
|
|
294
|
+
}
|
|
228
295
|
|
|
229
|
-
}
|
|
230
|
-
if (tmp) {
|
|
231
|
-
(
|
|
232
|
-
hasActive.contents ? after : before
|
|
233
|
-
).push(source);
|
|
234
|
-
return ;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
});
|
|
296
|
+
}));
|
|
238
297
|
var s = Belt_Array.get(after, 0);
|
|
239
298
|
if (s !== undefined) {
|
|
240
299
|
return s;
|
|
@@ -243,11 +302,11 @@ function getNextSyncSource(sourceManager, initialSource, currentSource, attemptF
|
|
|
243
302
|
if (s$1 !== undefined) {
|
|
244
303
|
return s$1;
|
|
245
304
|
} else {
|
|
246
|
-
return
|
|
305
|
+
return currentSourceState;
|
|
247
306
|
}
|
|
248
307
|
}
|
|
249
308
|
|
|
250
|
-
async function executeQuery(sourceManager, query,
|
|
309
|
+
async function executeQuery(sourceManager, query, knownHeight) {
|
|
251
310
|
var match = query.target;
|
|
252
311
|
var toBlockRef;
|
|
253
312
|
toBlockRef = typeof match !== "object" ? undefined : (
|
|
@@ -255,11 +314,15 @@ async function executeQuery(sourceManager, query, currentBlockHeight) {
|
|
|
255
314
|
);
|
|
256
315
|
var responseRef;
|
|
257
316
|
var retryRef = 0;
|
|
258
|
-
var
|
|
259
|
-
|
|
317
|
+
var initialSourceState = sourceManager.sourcesState.find(function (s) {
|
|
318
|
+
return s.source === sourceManager.activeSource;
|
|
319
|
+
});
|
|
320
|
+
var initialSourceState$1 = initialSourceState === undefined ? undefined : Caml_option.some(initialSourceState);
|
|
321
|
+
var sourceStateRef = initialSourceState$1;
|
|
260
322
|
var shouldUpdateActiveSource = false;
|
|
261
323
|
while(Belt_Option.isNone(responseRef)) {
|
|
262
|
-
var
|
|
324
|
+
var sourceState = sourceStateRef;
|
|
325
|
+
var source = sourceState.source;
|
|
263
326
|
var toBlock = toBlockRef;
|
|
264
327
|
var retry = retryRef;
|
|
265
328
|
var logger = Logging.createChild({
|
|
@@ -273,7 +336,7 @@ async function executeQuery(sourceManager, query, currentBlockHeight) {
|
|
|
273
336
|
retry: retry
|
|
274
337
|
});
|
|
275
338
|
try {
|
|
276
|
-
var response = await source.getItemsOrThrow(query.fromBlock, toBlock, query.addressesByContractName, query.indexingContracts,
|
|
339
|
+
var response = await source.getItemsOrThrow(query.fromBlock, toBlock, query.addressesByContractName, query.indexingContracts, knownHeight, query.partitionId, query.selection, retry, logger);
|
|
277
340
|
Logging.childTrace(logger, {
|
|
278
341
|
msg: "Fetched block range from server",
|
|
279
342
|
toBlock: response.latestFetchedBlockNumber,
|
|
@@ -310,7 +373,7 @@ async function executeQuery(sourceManager, query, currentBlockHeight) {
|
|
|
310
373
|
case "WithBackoff" :
|
|
311
374
|
var backoffMillis = match$1.backoffMillis;
|
|
312
375
|
var attemptFallbacks = retry >= 10;
|
|
313
|
-
var
|
|
376
|
+
var nextSourceState = !(retry === 0 || retry === 1) && retry % 2 === 0 ? getNextSyncSourceState(sourceManager, initialSourceState$1, sourceState, attemptFallbacks) : sourceState;
|
|
314
377
|
var log = retry >= 4 ? Logging.childWarn : Logging.childTrace;
|
|
315
378
|
log(logger, {
|
|
316
379
|
msg: match$1.message,
|
|
@@ -319,13 +382,13 @@ async function executeQuery(sourceManager, query, currentBlockHeight) {
|
|
|
319
382
|
retry: retry,
|
|
320
383
|
err: Utils.prettifyExn(exn)
|
|
321
384
|
});
|
|
322
|
-
var shouldSwitch =
|
|
385
|
+
var shouldSwitch = nextSourceState !== sourceState;
|
|
323
386
|
if (shouldSwitch) {
|
|
324
387
|
Logging.childInfo(logger, {
|
|
325
388
|
msg: "Switching to another data-source",
|
|
326
|
-
source:
|
|
389
|
+
source: nextSourceState.source.name
|
|
327
390
|
});
|
|
328
|
-
|
|
391
|
+
sourceStateRef = nextSourceState;
|
|
329
392
|
shouldUpdateActiveSource = true;
|
|
330
393
|
} else {
|
|
331
394
|
await Utils.delay(backoffMillis < 60000 ? backoffMillis : 60000);
|
|
@@ -333,8 +396,8 @@ async function executeQuery(sourceManager, query, currentBlockHeight) {
|
|
|
333
396
|
retryRef = retryRef + 1 | 0;
|
|
334
397
|
break;
|
|
335
398
|
case "ImpossibleForTheQuery" :
|
|
336
|
-
var
|
|
337
|
-
var hasAnotherSource =
|
|
399
|
+
var nextSourceState$1 = getNextSyncSourceState(sourceManager, initialSourceState$1, sourceState, true);
|
|
400
|
+
var hasAnotherSource = nextSourceState$1 !== initialSourceState$1;
|
|
338
401
|
Logging.childWarn(logger, {
|
|
339
402
|
msg: match$1.message + (
|
|
340
403
|
hasAnotherSource ? " - Attempting to another source" : ""
|
|
@@ -343,7 +406,7 @@ async function executeQuery(sourceManager, query, currentBlockHeight) {
|
|
|
343
406
|
err: Utils.prettifyExn(exn)
|
|
344
407
|
});
|
|
345
408
|
if (hasAnotherSource) {
|
|
346
|
-
|
|
409
|
+
sourceStateRef = nextSourceState$1;
|
|
347
410
|
shouldUpdateActiveSource = false;
|
|
348
411
|
retryRef = 0;
|
|
349
412
|
} else {
|
|
@@ -356,9 +419,9 @@ async function executeQuery(sourceManager, query, currentBlockHeight) {
|
|
|
356
419
|
|
|
357
420
|
}
|
|
358
421
|
if (exit === 1) {
|
|
359
|
-
var
|
|
360
|
-
var
|
|
361
|
-
if (
|
|
422
|
+
var nextSourceState$2 = getNextSyncSourceState(sourceManager, initialSourceState$1, sourceState, undefined);
|
|
423
|
+
var notAlreadyDisabled = disableSource(sourceState);
|
|
424
|
+
if (notAlreadyDisabled) {
|
|
362
425
|
switch (error$1.TAG) {
|
|
363
426
|
case "UnsupportedSelection" :
|
|
364
427
|
Logging.childError(logger, error$1.message);
|
|
@@ -376,14 +439,14 @@ async function executeQuery(sourceManager, query, currentBlockHeight) {
|
|
|
376
439
|
|
|
377
440
|
}
|
|
378
441
|
}
|
|
379
|
-
if (
|
|
442
|
+
if (nextSourceState$2 === sourceState) {
|
|
380
443
|
ErrorHandling.mkLogAndRaise(logger, "The indexer doesn't have data-sources which can continue fetching. Please, check the error logs or reach out to the Envio team.", null);
|
|
381
444
|
} else {
|
|
382
445
|
Logging.childInfo(logger, {
|
|
383
446
|
msg: "Switching to another data-source",
|
|
384
|
-
source:
|
|
447
|
+
source: nextSourceState$2.source.name
|
|
385
448
|
});
|
|
386
|
-
|
|
449
|
+
sourceStateRef = nextSourceState$2;
|
|
387
450
|
shouldUpdateActiveSource = true;
|
|
388
451
|
retryRef = 0;
|
|
389
452
|
}
|
|
@@ -395,7 +458,7 @@ async function executeQuery(sourceManager, query, currentBlockHeight) {
|
|
|
395
458
|
}
|
|
396
459
|
};
|
|
397
460
|
if (shouldUpdateActiveSource) {
|
|
398
|
-
sourceManager.activeSource =
|
|
461
|
+
sourceManager.activeSource = sourceStateRef.source;
|
|
399
462
|
}
|
|
400
463
|
return responseRef;
|
|
401
464
|
}
|
|
@@ -13,19 +13,18 @@ let getActiveSource: t => Source.t
|
|
|
13
13
|
let fetchNext: (
|
|
14
14
|
t,
|
|
15
15
|
~fetchState: FetchState.t,
|
|
16
|
-
~currentBlockHeight: int,
|
|
17
16
|
~executeQuery: FetchState.query => promise<unit>,
|
|
18
|
-
~waitForNewBlock: (~
|
|
19
|
-
~onNewBlock: (~
|
|
17
|
+
~waitForNewBlock: (~knownHeight: int) => promise<int>,
|
|
18
|
+
~onNewBlock: (~knownHeight: int) => unit,
|
|
20
19
|
~stateId: int,
|
|
21
20
|
) => promise<unit>
|
|
22
21
|
|
|
23
|
-
let waitForNewBlock: (t, ~
|
|
22
|
+
let waitForNewBlock: (t, ~knownHeight: int) => promise<int>
|
|
24
23
|
|
|
25
24
|
let executeQuery: (
|
|
26
25
|
t,
|
|
27
26
|
~query: FetchState.query,
|
|
28
|
-
~
|
|
27
|
+
~knownHeight: int,
|
|
29
28
|
) => promise<Source.blockRangeFetchResponse>
|
|
30
29
|
|
|
31
30
|
let makeGetHeightRetryInterval: (
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
@get external getNumber: Internal.eventBlock => int = "height"
|
|
2
|
+
@get external getTimestamp: Internal.eventBlock => int = "time"
|
|
3
|
+
@get external getId: Internal.eventBlock => string = "hash"
|
|
4
|
+
|
|
5
|
+
let cleanUpRawEventFieldsInPlace: Js.Json.t => unit = %raw(`fields => {
|
|
6
|
+
delete fields.hash
|
|
7
|
+
delete fields.height
|
|
8
|
+
delete fields.time
|
|
9
|
+
}`)
|
|
10
|
+
|
|
11
|
+
let ecosystem: Ecosystem.t = {
|
|
12
|
+
name: Svm,
|
|
13
|
+
blockFields: ["slot"],
|
|
14
|
+
transactionFields: [],
|
|
15
|
+
blockNumberName: "height",
|
|
16
|
+
blockTimestampName: "time",
|
|
17
|
+
blockHashName: "hash",
|
|
18
|
+
getNumber,
|
|
19
|
+
getTimestamp,
|
|
20
|
+
getId,
|
|
21
|
+
cleanUpRawEventFieldsInPlace,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
module GetFinalizedSlot = {
|
|
25
|
+
let route = Rpc.makeRpcRoute(
|
|
26
|
+
"getSlot",
|
|
27
|
+
S.tuple(s => {
|
|
28
|
+
s.tag(0, {"commitment": "finalized"})
|
|
29
|
+
()
|
|
30
|
+
}),
|
|
31
|
+
S.int,
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let makeRPCSource = (~chain, ~rpc: string): Source.t => {
|
|
36
|
+
let client = Rest.client(rpc)
|
|
37
|
+
|
|
38
|
+
{
|
|
39
|
+
name: "Svm",
|
|
40
|
+
sourceFor: Sync,
|
|
41
|
+
chain,
|
|
42
|
+
poweredByHyperSync: false,
|
|
43
|
+
pollingInterval: 10_000,
|
|
44
|
+
getBlockHashes: (~blockNumbers as _, ~logger as _) =>
|
|
45
|
+
Js.Exn.raiseError("Svm does not support getting block hashes"),
|
|
46
|
+
getHeightOrThrow: () => GetFinalizedSlot.route->Rest.fetch((), ~client),
|
|
47
|
+
getItemsOrThrow: (
|
|
48
|
+
~fromBlock as _,
|
|
49
|
+
~toBlock as _,
|
|
50
|
+
~addressesByContractName as _,
|
|
51
|
+
~indexingContracts as _,
|
|
52
|
+
~knownHeight as _,
|
|
53
|
+
~partitionId as _,
|
|
54
|
+
~selection as _,
|
|
55
|
+
~retry as _,
|
|
56
|
+
~logger as _,
|
|
57
|
+
) => Js.Exn.raiseError("Svm does not support getting items"),
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Rpc from "./Rpc.res.mjs";
|
|
4
|
+
import * as Rest from "../vendored/Rest.res.mjs";
|
|
5
|
+
import * as Js_exn from "rescript/lib/es6/js_exn.js";
|
|
6
|
+
import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
|
|
7
|
+
|
|
8
|
+
var cleanUpRawEventFieldsInPlace = (fields => {
|
|
9
|
+
delete fields.hash
|
|
10
|
+
delete fields.height
|
|
11
|
+
delete fields.time
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
var ecosystem_blockFields = ["slot"];
|
|
15
|
+
|
|
16
|
+
var ecosystem_transactionFields = [];
|
|
17
|
+
|
|
18
|
+
function ecosystem_getNumber(prim) {
|
|
19
|
+
return prim.height;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function ecosystem_getTimestamp(prim) {
|
|
23
|
+
return prim.time;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function ecosystem_getId(prim) {
|
|
27
|
+
return prim.hash;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
var ecosystem = {
|
|
31
|
+
name: "svm",
|
|
32
|
+
blockFields: ecosystem_blockFields,
|
|
33
|
+
transactionFields: ecosystem_transactionFields,
|
|
34
|
+
blockNumberName: "height",
|
|
35
|
+
blockTimestampName: "time",
|
|
36
|
+
blockHashName: "hash",
|
|
37
|
+
getNumber: ecosystem_getNumber,
|
|
38
|
+
getTimestamp: ecosystem_getTimestamp,
|
|
39
|
+
getId: ecosystem_getId,
|
|
40
|
+
cleanUpRawEventFieldsInPlace: cleanUpRawEventFieldsInPlace
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
var route = Rpc.makeRpcRoute("getSlot", S$RescriptSchema.tuple(function (s) {
|
|
44
|
+
s.tag(0, {
|
|
45
|
+
commitment: "finalized"
|
|
46
|
+
});
|
|
47
|
+
}), S$RescriptSchema.$$int);
|
|
48
|
+
|
|
49
|
+
var GetFinalizedSlot = {
|
|
50
|
+
route: route
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
function makeRPCSource(chain, rpc) {
|
|
54
|
+
var client = Rest.client(rpc, undefined);
|
|
55
|
+
return {
|
|
56
|
+
name: "Svm",
|
|
57
|
+
sourceFor: "Sync",
|
|
58
|
+
chain: chain,
|
|
59
|
+
poweredByHyperSync: false,
|
|
60
|
+
pollingInterval: 10000,
|
|
61
|
+
getBlockHashes: (function (param, param$1) {
|
|
62
|
+
return Js_exn.raiseError("Svm does not support getting block hashes");
|
|
63
|
+
}),
|
|
64
|
+
getHeightOrThrow: (function () {
|
|
65
|
+
return Rest.$$fetch(route, undefined, client);
|
|
66
|
+
}),
|
|
67
|
+
getItemsOrThrow: (function (param, param$1, param$2, param$3, param$4, param$5, param$6, param$7, param$8) {
|
|
68
|
+
return Js_exn.raiseError("Svm does not support getting items");
|
|
69
|
+
})
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export {
|
|
74
|
+
cleanUpRawEventFieldsInPlace ,
|
|
75
|
+
ecosystem ,
|
|
76
|
+
GetFinalizedSlot ,
|
|
77
|
+
makeRPCSource ,
|
|
78
|
+
}
|
|
79
|
+
/* route Not a pure module */
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/* TypeScript file generated from Ethers.res by genType. */
|
|
2
|
-
|
|
3
|
-
/* eslint-disable */
|
|
4
|
-
/* tslint:disable */
|
|
5
|
-
|
|
6
|
-
import * as EthersJS from './Ethers.res.mjs';
|
|
7
|
-
|
|
8
|
-
import type {t as Address_t} from '../../src/Address.gen.js';
|
|
9
|
-
|
|
10
|
-
export const Addresses_mockAddresses: Address_t[] = EthersJS.Addresses.mockAddresses as any;
|
|
11
|
-
|
|
12
|
-
export const Addresses_defaultAddress: Address_t = EthersJS.Addresses.defaultAddress as any;
|
|
13
|
-
|
|
14
|
-
export const Addresses: { mockAddresses: Address_t[]; defaultAddress: Address_t } = EthersJS.Addresses as any;
|