envio 3.0.0-alpha.1 → 3.0.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.
- package/evm.schema.json +63 -48
- package/fuel.schema.json +35 -31
- package/index.d.ts +1 -0
- package/package.json +15 -11
- package/rescript.json +1 -1
- 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 +18 -7
- package/src/Config.res.mjs +28 -7
- package/src/Ecosystem.res +25 -0
- package/src/Ecosystem.res.mjs +29 -0
- package/src/Env.res +243 -0
- package/src/Env.res.mjs +270 -0
- 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/EventRegister.res +4 -15
- package/src/EventRegister.res.mjs +3 -9
- package/src/EventRegister.resi +2 -8
- 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.gen.ts +3 -14
- package/src/Internal.res +4 -12
- 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/UserContext.res +356 -0
- package/src/UserContext.res.mjs +238 -0
- package/src/bindings/DateFns.res +71 -0
- package/src/bindings/DateFns.res.mjs +22 -0
- package/src/bindings/EventSource.res +13 -0
- package/src/bindings/EventSource.res.mjs +2 -0
- 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 +179 -0
- package/src/sources/HyperSyncHeightStream.res.mjs +127 -0
- package/src/sources/HyperSyncSource.res +7 -65
- package/src/sources/HyperSyncSource.res.mjs +10 -66
- package/src/sources/RpcSource.res +4 -4
- package/src/sources/RpcSource.res.mjs +3 -3
- package/src/sources/Solana.res +59 -0
- package/src/sources/Solana.res.mjs +79 -0
- package/src/sources/Source.res +2 -2
- package/src/sources/SourceManager.res +24 -32
- package/src/sources/SourceManager.res.mjs +20 -20
- package/src/sources/SourceManager.resi +4 -5
- package/src/Platform.res +0 -140
- package/src/Platform.res.mjs +0 -170
|
@@ -186,7 +186,7 @@ function make(param) {
|
|
|
186
186
|
var endpointUrl = param.endpointUrl;
|
|
187
187
|
var chain = param.chain;
|
|
188
188
|
var getSelectionConfig = memoGetSelectionConfig(chain);
|
|
189
|
-
var getItemsOrThrow = async function (fromBlock, toBlock, addressesByContractName, indexingContracts,
|
|
189
|
+
var getItemsOrThrow = async function (fromBlock, toBlock, addressesByContractName, indexingContracts, knownHeight, param, selection, retry, logger) {
|
|
190
190
|
var mkLogAndRaise = function (extra, extra$1) {
|
|
191
191
|
return ErrorHandling.mkLogAndRaise(logger, extra, extra$1);
|
|
192
192
|
};
|
|
@@ -221,7 +221,7 @@ function make(param) {
|
|
|
221
221
|
_1: {
|
|
222
222
|
TAG: "FailedGettingItems",
|
|
223
223
|
exn: null,
|
|
224
|
-
attemptedToBlock: Belt_Option.getWithDefault(toBlock,
|
|
224
|
+
attemptedToBlock: Belt_Option.getWithDefault(toBlock, knownHeight),
|
|
225
225
|
retry: tmp
|
|
226
226
|
},
|
|
227
227
|
Error: new Error()
|
|
@@ -232,7 +232,7 @@ function make(param) {
|
|
|
232
232
|
_1: {
|
|
233
233
|
TAG: "FailedGettingItems",
|
|
234
234
|
exn: error,
|
|
235
|
-
attemptedToBlock: Belt_Option.getWithDefault(toBlock,
|
|
235
|
+
attemptedToBlock: Belt_Option.getWithDefault(toBlock, knownHeight),
|
|
236
236
|
retry: {
|
|
237
237
|
TAG: "WithBackoff",
|
|
238
238
|
message: "Unexpected issue while fetching events from HyperFuel client. Attempt a retry.",
|
|
@@ -243,7 +243,7 @@ function make(param) {
|
|
|
243
243
|
};
|
|
244
244
|
}
|
|
245
245
|
var pageFetchTime = Hrtime.intFromMillis(Hrtime.toMillis(Hrtime.timeSince(startFetchingBatchTimeRef)));
|
|
246
|
-
var
|
|
246
|
+
var knownHeight$1 = pageUnsafe.archiveHeight;
|
|
247
247
|
var heighestBlockQueried = pageUnsafe.nextBlock - 1 | 0;
|
|
248
248
|
var match = Belt_Array.get(pageUnsafe.items, pageUnsafe.items.length - 1 | 0);
|
|
249
249
|
var lastBlockQueriedPromise;
|
|
@@ -407,7 +407,7 @@ function make(param) {
|
|
|
407
407
|
"page fetch time (ms)": stats_page$unknownfetch$unknowntime$unknown$lparms$rpar
|
|
408
408
|
};
|
|
409
409
|
return {
|
|
410
|
-
|
|
410
|
+
knownHeight: knownHeight$1,
|
|
411
411
|
reorgGuard: reorgGuard,
|
|
412
412
|
parsedQueueItems: parsedQueueItems,
|
|
413
413
|
fromBlockQueried: fromBlock,
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Pure js implementation of the HyperSync height stream.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
type t = {
|
|
6
|
+
heightRef: ref<int>,
|
|
7
|
+
errorRef: ref<option<string>>,
|
|
8
|
+
timeoutIdRef: ref<Js.Global.timeoutId>,
|
|
9
|
+
eventsourceRef: ref<option<EventSource.t>>,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let make = (~hyperSyncUrl, ~apiToken) => {
|
|
13
|
+
/**
|
|
14
|
+
On every successful ping or height event, clear the timeout and set a new one.
|
|
15
|
+
|
|
16
|
+
if the timeout lapses, close and reconnect the EventSource.
|
|
17
|
+
*/
|
|
18
|
+
let rec updateTimeoutId = (
|
|
19
|
+
~eventsourceRef: ref<option<EventSource.t>>,
|
|
20
|
+
~timeoutIdRef: ref<Js.Global.timeoutId>,
|
|
21
|
+
~hyperSyncUrl,
|
|
22
|
+
~apiToken,
|
|
23
|
+
~heightRef: ref<int>,
|
|
24
|
+
~errorRef: ref<option<string>>,
|
|
25
|
+
) => {
|
|
26
|
+
timeoutIdRef.contents->Js.Global.clearTimeout
|
|
27
|
+
|
|
28
|
+
// Should receive a ping at least every 5s, so 15s is a safe margin
|
|
29
|
+
// for staleness to restart the EventSource connection
|
|
30
|
+
let staleTimeMillis = 15_000
|
|
31
|
+
let newTimeoutId = Js.Global.setTimeout(() => {
|
|
32
|
+
Logging.trace({
|
|
33
|
+
"msg": "Timeout fired for height stream",
|
|
34
|
+
"url": hyperSyncUrl,
|
|
35
|
+
"staleTimeMillis": staleTimeMillis,
|
|
36
|
+
})
|
|
37
|
+
refreshEventSource(
|
|
38
|
+
~eventsourceRef,
|
|
39
|
+
~hyperSyncUrl,
|
|
40
|
+
~apiToken,
|
|
41
|
+
~heightRef,
|
|
42
|
+
~errorRef,
|
|
43
|
+
~timeoutIdRef,
|
|
44
|
+
)
|
|
45
|
+
}, staleTimeMillis)
|
|
46
|
+
|
|
47
|
+
timeoutIdRef := newTimeoutId
|
|
48
|
+
}
|
|
49
|
+
and /**
|
|
50
|
+
Instantiate a new EventSource and set it to the shared refs.
|
|
51
|
+
Add the necessary event listeners, handle errors
|
|
52
|
+
and update the timeout.
|
|
53
|
+
*/
|
|
54
|
+
refreshEventSource = (
|
|
55
|
+
~eventsourceRef: ref<option<EventSource.t>>,
|
|
56
|
+
~hyperSyncUrl,
|
|
57
|
+
~apiToken,
|
|
58
|
+
~heightRef: ref<int>,
|
|
59
|
+
~errorRef: ref<option<string>>,
|
|
60
|
+
~timeoutIdRef: ref<Js.Global.timeoutId>,
|
|
61
|
+
) => {
|
|
62
|
+
// Close the old EventSource if it exists (on a new connection after timeout)
|
|
63
|
+
switch eventsourceRef.contents {
|
|
64
|
+
| Some(es) => es->EventSource.close
|
|
65
|
+
| None => ()
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
let userAgent = `hyperindex/${Utils.EnvioPackage.value.version}`
|
|
69
|
+
let es = EventSource.create(
|
|
70
|
+
~url=`${hyperSyncUrl}/height/sse`,
|
|
71
|
+
~options={
|
|
72
|
+
headers: Js.Dict.fromArray([
|
|
73
|
+
("Authorization", `Bearer ${apiToken}`),
|
|
74
|
+
("User-Agent", userAgent),
|
|
75
|
+
]),
|
|
76
|
+
},
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
// Set the new EventSource to the shared ref
|
|
80
|
+
eventsourceRef := Some(es)
|
|
81
|
+
// Update the timeout in case connection goes stale
|
|
82
|
+
updateTimeoutId(~eventsourceRef, ~timeoutIdRef, ~hyperSyncUrl, ~apiToken, ~heightRef, ~errorRef)
|
|
83
|
+
|
|
84
|
+
es->EventSource.onopen(_ => {
|
|
85
|
+
Logging.trace({"msg": "SSE connection opened for height stream", "url": hyperSyncUrl})
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
es->EventSource.onerror(error => {
|
|
89
|
+
Logging.trace({
|
|
90
|
+
"msg": "EventSource error",
|
|
91
|
+
"error": error->Js.Exn.message,
|
|
92
|
+
})
|
|
93
|
+
// On errors, set the error ref
|
|
94
|
+
// so that getHeight can raise an error
|
|
95
|
+
errorRef :=
|
|
96
|
+
Some(error->Js.Exn.message->Belt.Option.getWithDefault("Unexpected no error.message"))
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
es->EventSource.addEventListener("ping", _event => {
|
|
100
|
+
// ping lets us know from the server that the connection is still alive
|
|
101
|
+
// and that the height hasn't updated for 5seconds
|
|
102
|
+
// update the timeout on each successful ping received
|
|
103
|
+
updateTimeoutId(
|
|
104
|
+
~eventsourceRef,
|
|
105
|
+
~timeoutIdRef,
|
|
106
|
+
~hyperSyncUrl,
|
|
107
|
+
~apiToken,
|
|
108
|
+
~heightRef,
|
|
109
|
+
~errorRef,
|
|
110
|
+
)
|
|
111
|
+
// reset the error ref, since we had a successful ping
|
|
112
|
+
errorRef := None
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
es->EventSource.addEventListener("height", event => {
|
|
116
|
+
switch event.data->Belt.Int.fromString {
|
|
117
|
+
| Some(height) =>
|
|
118
|
+
// On a successful height event, update the timeout
|
|
119
|
+
// and reset the error ref
|
|
120
|
+
updateTimeoutId(
|
|
121
|
+
~eventsourceRef,
|
|
122
|
+
~timeoutIdRef,
|
|
123
|
+
~hyperSyncUrl,
|
|
124
|
+
~apiToken,
|
|
125
|
+
~heightRef,
|
|
126
|
+
~errorRef,
|
|
127
|
+
)
|
|
128
|
+
errorRef := None
|
|
129
|
+
// Set the actual height ref
|
|
130
|
+
heightRef := height
|
|
131
|
+
| None =>
|
|
132
|
+
Logging.trace({"msg": "Height was not a number in event.data", "data": event.data})
|
|
133
|
+
errorRef := Some("Height was not a number in event.data")
|
|
134
|
+
}
|
|
135
|
+
})
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Refs used between the functions
|
|
139
|
+
|
|
140
|
+
let heightRef = ref(0)
|
|
141
|
+
let errorRef = ref(None)
|
|
142
|
+
let eventsourceRef = ref(None)
|
|
143
|
+
// Timeout doesn't do anything for initalization
|
|
144
|
+
let timeoutIdRef = ref(Js.Global.setTimeout(() => (), 0))
|
|
145
|
+
refreshEventSource(
|
|
146
|
+
~eventsourceRef,
|
|
147
|
+
~hyperSyncUrl,
|
|
148
|
+
~apiToken,
|
|
149
|
+
~heightRef,
|
|
150
|
+
~errorRef,
|
|
151
|
+
~timeoutIdRef,
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
{
|
|
155
|
+
heightRef,
|
|
156
|
+
errorRef,
|
|
157
|
+
timeoutIdRef,
|
|
158
|
+
eventsourceRef,
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
let getHeight = async (t: t) => {
|
|
163
|
+
while t.heightRef.contents == 0 && t.errorRef.contents == None {
|
|
164
|
+
// Poll internally until height is over 0
|
|
165
|
+
await Utils.delay(200)
|
|
166
|
+
}
|
|
167
|
+
switch t.errorRef.contents {
|
|
168
|
+
| None => t.heightRef.contents
|
|
169
|
+
| Some(error) => Js.Exn.raiseError(error)
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
let close = t => {
|
|
174
|
+
t.timeoutIdRef.contents->Js.Global.clearTimeout
|
|
175
|
+
switch t.eventsourceRef.contents {
|
|
176
|
+
| Some(es) => es->EventSource.close
|
|
177
|
+
| None => ()
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Utils from "../Utils.res.mjs";
|
|
4
|
+
import * as Js_exn from "rescript/lib/es6/js_exn.js";
|
|
5
|
+
import * as Js_dict from "rescript/lib/es6/js_dict.js";
|
|
6
|
+
import * as Logging from "../Logging.res.mjs";
|
|
7
|
+
import * as Belt_Int from "rescript/lib/es6/belt_Int.js";
|
|
8
|
+
import * as Belt_Option from "rescript/lib/es6/belt_Option.js";
|
|
9
|
+
import * as Caml_option from "rescript/lib/es6/caml_option.js";
|
|
10
|
+
import * as Eventsource from "eventsource";
|
|
11
|
+
|
|
12
|
+
function make(hyperSyncUrl, apiToken) {
|
|
13
|
+
var updateTimeoutId = function (eventsourceRef, timeoutIdRef, hyperSyncUrl, apiToken, heightRef, errorRef) {
|
|
14
|
+
clearTimeout(timeoutIdRef.contents);
|
|
15
|
+
var newTimeoutId = setTimeout((function () {
|
|
16
|
+
Logging.trace({
|
|
17
|
+
msg: "Timeout fired for height stream",
|
|
18
|
+
url: hyperSyncUrl,
|
|
19
|
+
staleTimeMillis: 15000
|
|
20
|
+
});
|
|
21
|
+
refreshEventSource(eventsourceRef, hyperSyncUrl, apiToken, heightRef, errorRef, timeoutIdRef);
|
|
22
|
+
}), 15000);
|
|
23
|
+
timeoutIdRef.contents = newTimeoutId;
|
|
24
|
+
};
|
|
25
|
+
var refreshEventSource = function (eventsourceRef, hyperSyncUrl, apiToken, heightRef, errorRef, timeoutIdRef) {
|
|
26
|
+
var es = eventsourceRef.contents;
|
|
27
|
+
if (es !== undefined) {
|
|
28
|
+
Caml_option.valFromOption(es).close();
|
|
29
|
+
}
|
|
30
|
+
var userAgent = "hyperindex/" + Utils.EnvioPackage.value.version;
|
|
31
|
+
var es$1 = new Eventsource.EventSource(hyperSyncUrl + "/height/sse", {
|
|
32
|
+
headers: Js_dict.fromArray([
|
|
33
|
+
[
|
|
34
|
+
"Authorization",
|
|
35
|
+
"Bearer " + apiToken
|
|
36
|
+
],
|
|
37
|
+
[
|
|
38
|
+
"User-Agent",
|
|
39
|
+
userAgent
|
|
40
|
+
]
|
|
41
|
+
])
|
|
42
|
+
});
|
|
43
|
+
eventsourceRef.contents = Caml_option.some(es$1);
|
|
44
|
+
updateTimeoutId(eventsourceRef, timeoutIdRef, hyperSyncUrl, apiToken, heightRef, errorRef);
|
|
45
|
+
es$1.onopen = (function () {
|
|
46
|
+
Logging.trace({
|
|
47
|
+
msg: "SSE connection opened for height stream",
|
|
48
|
+
url: hyperSyncUrl
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
es$1.onerror = (function (error) {
|
|
52
|
+
Logging.trace({
|
|
53
|
+
msg: "EventSource error",
|
|
54
|
+
error: error.message
|
|
55
|
+
});
|
|
56
|
+
errorRef.contents = Belt_Option.getWithDefault(error.message, "Unexpected no error.message");
|
|
57
|
+
});
|
|
58
|
+
es$1.addEventListener("ping", (function (_event) {
|
|
59
|
+
updateTimeoutId(eventsourceRef, timeoutIdRef, hyperSyncUrl, apiToken, heightRef, errorRef);
|
|
60
|
+
errorRef.contents = undefined;
|
|
61
|
+
}));
|
|
62
|
+
es$1.addEventListener("height", (function ($$event) {
|
|
63
|
+
var height = Belt_Int.fromString($$event.data);
|
|
64
|
+
if (height !== undefined) {
|
|
65
|
+
updateTimeoutId(eventsourceRef, timeoutIdRef, hyperSyncUrl, apiToken, heightRef, errorRef);
|
|
66
|
+
errorRef.contents = undefined;
|
|
67
|
+
heightRef.contents = height;
|
|
68
|
+
} else {
|
|
69
|
+
Logging.trace({
|
|
70
|
+
msg: "Height was not a number in event.data",
|
|
71
|
+
data: $$event.data
|
|
72
|
+
});
|
|
73
|
+
errorRef.contents = "Height was not a number in event.data";
|
|
74
|
+
}
|
|
75
|
+
}));
|
|
76
|
+
};
|
|
77
|
+
var heightRef = {
|
|
78
|
+
contents: 0
|
|
79
|
+
};
|
|
80
|
+
var errorRef = {
|
|
81
|
+
contents: undefined
|
|
82
|
+
};
|
|
83
|
+
var eventsourceRef = {
|
|
84
|
+
contents: undefined
|
|
85
|
+
};
|
|
86
|
+
var timeoutIdRef = {
|
|
87
|
+
contents: setTimeout((function () {
|
|
88
|
+
|
|
89
|
+
}), 0)
|
|
90
|
+
};
|
|
91
|
+
refreshEventSource(eventsourceRef, hyperSyncUrl, apiToken, heightRef, errorRef, timeoutIdRef);
|
|
92
|
+
return {
|
|
93
|
+
heightRef: heightRef,
|
|
94
|
+
errorRef: errorRef,
|
|
95
|
+
timeoutIdRef: timeoutIdRef,
|
|
96
|
+
eventsourceRef: eventsourceRef
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async function getHeight(t) {
|
|
101
|
+
while(t.heightRef.contents === 0 && t.errorRef.contents === undefined) {
|
|
102
|
+
await Utils.delay(200);
|
|
103
|
+
};
|
|
104
|
+
var error = t.errorRef.contents;
|
|
105
|
+
if (error !== undefined) {
|
|
106
|
+
return Js_exn.raiseError(error);
|
|
107
|
+
} else {
|
|
108
|
+
return t.heightRef.contents;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function close(t) {
|
|
113
|
+
clearTimeout(t.timeoutIdRef.contents);
|
|
114
|
+
var es = t.eventsourceRef.contents;
|
|
115
|
+
if (es !== undefined) {
|
|
116
|
+
Caml_option.valFromOption(es).close();
|
|
117
|
+
return ;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export {
|
|
123
|
+
make ,
|
|
124
|
+
getHeight ,
|
|
125
|
+
close ,
|
|
126
|
+
}
|
|
127
|
+
/* Utils Not a pure module */
|
|
@@ -159,63 +159,6 @@ type options = {
|
|
|
159
159
|
enableQueryCaching: bool,
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
-
module HeightState: {
|
|
163
|
-
type t
|
|
164
|
-
let make: (HyperSyncClient.t, ~chainId: int) => Promise.t<t>
|
|
165
|
-
let getHeight: t => Promise.t<int>
|
|
166
|
-
} = {
|
|
167
|
-
open HyperSyncClient
|
|
168
|
-
type t = {
|
|
169
|
-
heightStream: HeightStream.t,
|
|
170
|
-
mutable currentHeight: int,
|
|
171
|
-
mutable errMessage: option<string>,
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
let makeInternal = async (client: HyperSyncClient.t) => {
|
|
175
|
-
currentHeight: 0,
|
|
176
|
-
heightStream: await client.streamHeight(),
|
|
177
|
-
errMessage: None,
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
let start = async (state: t, ~chainId) => {
|
|
181
|
-
while true {
|
|
182
|
-
let height = await state.heightStream.recv()
|
|
183
|
-
switch height {
|
|
184
|
-
| Height({height}) => state.currentHeight = height
|
|
185
|
-
| Connected =>
|
|
186
|
-
Logging.trace({"msg": "HyperSync height stream is connected", "chainId": chainId})
|
|
187
|
-
state.errMessage = None
|
|
188
|
-
| Reconnecting({delayMillis, errorMsg}) =>
|
|
189
|
-
Logging.trace({
|
|
190
|
-
"msg": "HyperSync height stream is reconnecting",
|
|
191
|
-
"err": errorMsg,
|
|
192
|
-
"delayMillis": delayMillis,
|
|
193
|
-
"chainId": chainId,
|
|
194
|
-
})
|
|
195
|
-
state.errMessage = Some(errorMsg)
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
let make = async (client: HyperSyncClient.t, ~chainId) => {
|
|
201
|
-
let state = await makeInternal(client)
|
|
202
|
-
let _async = state->start(~chainId)
|
|
203
|
-
state
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
let getHeight = async (state: t) => {
|
|
207
|
-
while state.currentHeight == 0 && state.errMessage->Belt.Option.isNone {
|
|
208
|
-
// Just poll internally until its no longer 0
|
|
209
|
-
await Utils.delay(200)
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
switch state.errMessage {
|
|
213
|
-
| Some(errMessage) => Js.Exn.raiseError(errMessage)
|
|
214
|
-
| None => state.currentHeight
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
162
|
let make = (
|
|
220
163
|
{
|
|
221
164
|
contracts,
|
|
@@ -306,7 +249,7 @@ let make = (
|
|
|
306
249
|
~toBlock,
|
|
307
250
|
~addressesByContractName,
|
|
308
251
|
~indexingContracts,
|
|
309
|
-
~
|
|
252
|
+
~knownHeight,
|
|
310
253
|
~partitionId as _,
|
|
311
254
|
~selection,
|
|
312
255
|
~retry,
|
|
@@ -339,7 +282,7 @@ let make = (
|
|
|
339
282
|
Source.GetItemsError(
|
|
340
283
|
Source.FailedGettingItems({
|
|
341
284
|
exn: %raw(`null`),
|
|
342
|
-
attemptedToBlock: toBlock->Option.getWithDefault(
|
|
285
|
+
attemptedToBlock: toBlock->Option.getWithDefault(knownHeight),
|
|
343
286
|
retry: switch error {
|
|
344
287
|
| WrongInstance =>
|
|
345
288
|
let backoffMillis = switch retry {
|
|
@@ -365,7 +308,7 @@ let make = (
|
|
|
365
308
|
Source.GetItemsError(
|
|
366
309
|
Source.FailedGettingItems({
|
|
367
310
|
exn,
|
|
368
|
-
attemptedToBlock: toBlock->Option.getWithDefault(
|
|
311
|
+
attemptedToBlock: toBlock->Option.getWithDefault(knownHeight),
|
|
369
312
|
retry: WithBackoff({
|
|
370
313
|
message: `Unexpected issue while fetching events from HyperSync client. Attempt a retry.`,
|
|
371
314
|
backoffMillis: switch retry {
|
|
@@ -382,7 +325,7 @@ let make = (
|
|
|
382
325
|
startFetchingBatchTimeRef->Hrtime.timeSince->Hrtime.toMillis->Hrtime.intFromMillis
|
|
383
326
|
|
|
384
327
|
//set height and next from block
|
|
385
|
-
let
|
|
328
|
+
let knownHeight = pageUnsafe.archiveHeight
|
|
386
329
|
|
|
387
330
|
//The heighest (biggest) blocknumber that was accounted for in
|
|
388
331
|
//Our query. Not necessarily the blocknumber of the last log returned
|
|
@@ -594,7 +537,7 @@ let make = (
|
|
|
594
537
|
parsedQueueItems,
|
|
595
538
|
latestFetchedBlockNumber: rangeLastBlock.blockNumber,
|
|
596
539
|
stats,
|
|
597
|
-
|
|
540
|
+
knownHeight,
|
|
598
541
|
reorgGuard,
|
|
599
542
|
fromBlockQueried: fromBlock,
|
|
600
543
|
}
|
|
@@ -610,7 +553,7 @@ let make = (
|
|
|
610
553
|
|
|
611
554
|
let malformedTokenMessage = `Your token is malformed. For more info: https://docs.envio.dev/docs/HyperSync/api-tokens.`
|
|
612
555
|
|
|
613
|
-
let
|
|
556
|
+
let heightStream = HyperSyncHeightStream.make(~hyperSyncUrl=endpointUrl, ~apiToken)
|
|
614
557
|
|
|
615
558
|
{
|
|
616
559
|
name,
|
|
@@ -620,8 +563,7 @@ let make = (
|
|
|
620
563
|
poweredByHyperSync: true,
|
|
621
564
|
getBlockHashes,
|
|
622
565
|
getHeightOrThrow: async () => {
|
|
623
|
-
|
|
624
|
-
try await heightState->HeightState.getHeight catch {
|
|
566
|
+
try await heightStream->HyperSyncHeightStream.getHeight catch {
|
|
625
567
|
| Js.Exn.Error(exn)
|
|
626
568
|
if exn
|
|
627
569
|
->Js.Exn.message
|
|
@@ -16,6 +16,7 @@ import * as Caml_exceptions from "rescript/lib/es6/caml_exceptions.js";
|
|
|
16
16
|
import * as HyperSyncClient from "./HyperSyncClient.res.mjs";
|
|
17
17
|
import * as Caml_splice_call from "rescript/lib/es6/caml_splice_call.js";
|
|
18
18
|
import * as Caml_js_exceptions from "rescript/lib/es6/caml_js_exceptions.js";
|
|
19
|
+
import * as HyperSyncHeightStream from "./HyperSyncHeightStream.res.mjs";
|
|
19
20
|
|
|
20
21
|
function getSelectionConfig(selection, chain) {
|
|
21
22
|
var nonOptionalBlockFieldNames = new Set();
|
|
@@ -120,62 +121,7 @@ function memoGetSelectionConfig(chain) {
|
|
|
120
121
|
};
|
|
121
122
|
}
|
|
122
123
|
|
|
123
|
-
|
|
124
|
-
return {
|
|
125
|
-
heightStream: await client.streamHeight(),
|
|
126
|
-
currentHeight: 0,
|
|
127
|
-
errMessage: undefined
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
async function start(state, chainId) {
|
|
132
|
-
while(true) {
|
|
133
|
-
var height = await state.heightStream.recv();
|
|
134
|
-
if (typeof height !== "object") {
|
|
135
|
-
Logging.trace({
|
|
136
|
-
msg: "HyperSync height stream is connected",
|
|
137
|
-
chainId: chainId
|
|
138
|
-
});
|
|
139
|
-
state.errMessage = undefined;
|
|
140
|
-
} else if (height.type === "Height") {
|
|
141
|
-
state.currentHeight = height.height;
|
|
142
|
-
} else {
|
|
143
|
-
var errorMsg = height.errorMsg;
|
|
144
|
-
Logging.trace({
|
|
145
|
-
msg: "HyperSync height stream is reconnecting",
|
|
146
|
-
err: errorMsg,
|
|
147
|
-
delayMillis: height.delayMillis,
|
|
148
|
-
chainId: chainId
|
|
149
|
-
});
|
|
150
|
-
state.errMessage = errorMsg;
|
|
151
|
-
}
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
async function make(client, chainId) {
|
|
156
|
-
var state = await makeInternal(client);
|
|
157
|
-
start(state, chainId);
|
|
158
|
-
return state;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
async function getHeight(state) {
|
|
162
|
-
while(state.currentHeight === 0 && Belt_Option.isNone(state.errMessage)) {
|
|
163
|
-
await Utils.delay(200);
|
|
164
|
-
};
|
|
165
|
-
var errMessage = state.errMessage;
|
|
166
|
-
if (errMessage !== undefined) {
|
|
167
|
-
return Js_exn.raiseError(errMessage);
|
|
168
|
-
} else {
|
|
169
|
-
return state.currentHeight;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
var HeightState = {
|
|
174
|
-
make: make,
|
|
175
|
-
getHeight: getHeight
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
function make$1(param) {
|
|
124
|
+
function make(param) {
|
|
179
125
|
var lowercaseAddresses = param.lowercaseAddresses;
|
|
180
126
|
var eventRouter = param.eventRouter;
|
|
181
127
|
var shouldUseHypersyncClientDecoder = param.shouldUseHypersyncClientDecoder;
|
|
@@ -233,7 +179,7 @@ function make$1(param) {
|
|
|
233
179
|
Belt_Array.forEach(param.contracts, (function (contract) {
|
|
234
180
|
contractNameAbiMapping[contract.name] = contract.abi;
|
|
235
181
|
}));
|
|
236
|
-
var getItemsOrThrow = async function (fromBlock, toBlock, addressesByContractName, indexingContracts,
|
|
182
|
+
var getItemsOrThrow = async function (fromBlock, toBlock, addressesByContractName, indexingContracts, knownHeight, param, selection, retry, logger) {
|
|
237
183
|
var mkLogAndRaise = function (extra, extra$1) {
|
|
238
184
|
return ErrorHandling.mkLogAndRaise(logger, extra, extra$1);
|
|
239
185
|
};
|
|
@@ -275,7 +221,7 @@ function make$1(param) {
|
|
|
275
221
|
_1: {
|
|
276
222
|
TAG: "FailedGettingItems",
|
|
277
223
|
exn: null,
|
|
278
|
-
attemptedToBlock: Belt_Option.getWithDefault(toBlock,
|
|
224
|
+
attemptedToBlock: Belt_Option.getWithDefault(toBlock, knownHeight),
|
|
279
225
|
retry: tmp
|
|
280
226
|
},
|
|
281
227
|
Error: new Error()
|
|
@@ -286,7 +232,7 @@ function make$1(param) {
|
|
|
286
232
|
_1: {
|
|
287
233
|
TAG: "FailedGettingItems",
|
|
288
234
|
exn: error,
|
|
289
|
-
attemptedToBlock: Belt_Option.getWithDefault(toBlock,
|
|
235
|
+
attemptedToBlock: Belt_Option.getWithDefault(toBlock, knownHeight),
|
|
290
236
|
retry: {
|
|
291
237
|
TAG: "WithBackoff",
|
|
292
238
|
message: "Unexpected issue while fetching events from HyperSync client. Attempt a retry.",
|
|
@@ -297,7 +243,7 @@ function make$1(param) {
|
|
|
297
243
|
};
|
|
298
244
|
}
|
|
299
245
|
var pageFetchTime = Hrtime.intFromMillis(Hrtime.toMillis(Hrtime.timeSince(startFetchingBatchTimeRef)));
|
|
300
|
-
var
|
|
246
|
+
var knownHeight$1 = pageUnsafe.archiveHeight;
|
|
301
247
|
var heighestBlockQueried = pageUnsafe.nextBlock - 1 | 0;
|
|
302
248
|
var match = pageUnsafe.rollbackGuard;
|
|
303
249
|
var lastBlockQueriedPromise;
|
|
@@ -425,7 +371,7 @@ function make$1(param) {
|
|
|
425
371
|
"page fetch time (ms)": stats_page$unknownfetch$unknowntime$unknown$lparms$rpar
|
|
426
372
|
};
|
|
427
373
|
return {
|
|
428
|
-
|
|
374
|
+
knownHeight: knownHeight$1,
|
|
429
375
|
reorgGuard: reorgGuard,
|
|
430
376
|
parsedQueueItems: parsedQueueItems,
|
|
431
377
|
fromBlockQueried: fromBlock,
|
|
@@ -437,7 +383,7 @@ function make$1(param) {
|
|
|
437
383
|
var getBlockHashes = function (blockNumbers, logger) {
|
|
438
384
|
return HyperSync.queryBlockDataMulti(endpointUrl, apiToken, blockNumbers, logger).then(HyperSync.mapExn);
|
|
439
385
|
};
|
|
440
|
-
var
|
|
386
|
+
var heightStream = HyperSyncHeightStream.make(endpointUrl, apiToken);
|
|
441
387
|
return {
|
|
442
388
|
name: "HyperSync",
|
|
443
389
|
sourceFor: "Sync",
|
|
@@ -446,9 +392,8 @@ function make$1(param) {
|
|
|
446
392
|
pollingInterval: 32,
|
|
447
393
|
getBlockHashes: getBlockHashes,
|
|
448
394
|
getHeightOrThrow: (async function () {
|
|
449
|
-
var heightState = await heightStatePromise;
|
|
450
395
|
try {
|
|
451
|
-
return await getHeight(
|
|
396
|
+
return await HyperSyncHeightStream.getHeight(heightStream);
|
|
452
397
|
}
|
|
453
398
|
catch (raw_exn){
|
|
454
399
|
var exn = Caml_js_exceptions.internalToOCamlException(raw_exn);
|
|
@@ -472,7 +417,6 @@ function make$1(param) {
|
|
|
472
417
|
export {
|
|
473
418
|
getSelectionConfig ,
|
|
474
419
|
memoGetSelectionConfig ,
|
|
475
|
-
|
|
476
|
-
make$1 as make,
|
|
420
|
+
make ,
|
|
477
421
|
}
|
|
478
422
|
/* Viem Not a pure module */
|
|
@@ -601,7 +601,7 @@ let make = (
|
|
|
601
601
|
~toBlock,
|
|
602
602
|
~addressesByContractName,
|
|
603
603
|
~indexingContracts,
|
|
604
|
-
~
|
|
604
|
+
~knownHeight,
|
|
605
605
|
~partitionId,
|
|
606
606
|
~selection: FetchState.selection,
|
|
607
607
|
~retry as _,
|
|
@@ -621,8 +621,8 @@ let make = (
|
|
|
621
621
|
|
|
622
622
|
// Always have a toBlock for an RPC worker
|
|
623
623
|
let toBlock = switch toBlock {
|
|
624
|
-
| Some(toBlock) => Pervasives.min(toBlock,
|
|
625
|
-
| None =>
|
|
624
|
+
| Some(toBlock) => Pervasives.min(toBlock, knownHeight)
|
|
625
|
+
| None => knownHeight
|
|
626
626
|
}
|
|
627
627
|
|
|
628
628
|
let suggestedToBlock = Pervasives.min(fromBlock + suggestedBlockInterval - 1, toBlock)
|
|
@@ -874,7 +874,7 @@ let make = (
|
|
|
874
874
|
stats: {
|
|
875
875
|
totalTimeElapsed: totalTimeElapsed,
|
|
876
876
|
},
|
|
877
|
-
|
|
877
|
+
knownHeight,
|
|
878
878
|
reorgGuard,
|
|
879
879
|
fromBlockQueried: fromBlock,
|
|
880
880
|
}
|
|
@@ -604,11 +604,11 @@ function make(param) {
|
|
|
604
604
|
return HyperSyncClient.Decoder.fromSignatures(allEventSignatures);
|
|
605
605
|
}
|
|
606
606
|
};
|
|
607
|
-
var getItemsOrThrow = async function (fromBlock, toBlock, addressesByContractName, indexingContracts,
|
|
607
|
+
var getItemsOrThrow = async function (fromBlock, toBlock, addressesByContractName, indexingContracts, knownHeight, partitionId, selection, param, param$1) {
|
|
608
608
|
var startFetchingBatchTimeRef = Hrtime.makeTimer();
|
|
609
609
|
var maxSuggestedBlockInterval = mutSuggestedBlockIntervals[maxSuggestedBlockIntervalKey];
|
|
610
610
|
var suggestedBlockInterval = maxSuggestedBlockInterval !== undefined ? maxSuggestedBlockInterval : Belt_Option.getWithDefault(mutSuggestedBlockIntervals[partitionId], syncConfig.initialBlockInterval);
|
|
611
|
-
var toBlock$1 = toBlock !== undefined && toBlock <
|
|
611
|
+
var toBlock$1 = toBlock !== undefined && toBlock < knownHeight ? toBlock : knownHeight;
|
|
612
612
|
var suggestedToBlock = Caml.int_max(Caml.int_min((fromBlock + suggestedBlockInterval | 0) - 1 | 0, toBlock$1), fromBlock);
|
|
613
613
|
var firstBlockParentPromise = fromBlock > 0 ? LazyLoader.get(blockLoader.contents, fromBlock - 1 | 0).then(function (res) {
|
|
614
614
|
return res;
|
|
@@ -785,7 +785,7 @@ function make(param) {
|
|
|
785
785
|
prevRangeLastBlock: reorgGuard_prevRangeLastBlock
|
|
786
786
|
};
|
|
787
787
|
return {
|
|
788
|
-
|
|
788
|
+
knownHeight: knownHeight,
|
|
789
789
|
reorgGuard: reorgGuard,
|
|
790
790
|
parsedQueueItems: parsedQueueItems,
|
|
791
791
|
fromBlockQueried: fromBlock,
|