envio 2.29.0-alpha.1 → 2.29.0-alpha.2
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/package.json +5 -5
- package/src/Envio.gen.ts +7 -3
- package/src/Envio.res +5 -8
- package/src/EventRegister.res +37 -14
- package/src/EventRegister.res.js +23 -5
- package/src/EventRegister.resi +1 -1
- package/src/FetchState.res +26 -5
- package/src/FetchState.res.js +28 -13
- package/src/Internal.res +3 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "envio",
|
|
3
|
-
"version": "v2.29.0-alpha.
|
|
3
|
+
"version": "v2.29.0-alpha.2",
|
|
4
4
|
"description": "A latency and sync speed optimized, developer friendly blockchain data indexer.",
|
|
5
5
|
"bin": "./bin.js",
|
|
6
6
|
"main": "./index.js",
|
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
},
|
|
26
26
|
"homepage": "https://envio.dev",
|
|
27
27
|
"optionalDependencies": {
|
|
28
|
-
"envio-linux-x64": "v2.29.0-alpha.
|
|
29
|
-
"envio-linux-arm64": "v2.29.0-alpha.
|
|
30
|
-
"envio-darwin-x64": "v2.29.0-alpha.
|
|
31
|
-
"envio-darwin-arm64": "v2.29.0-alpha.
|
|
28
|
+
"envio-linux-x64": "v2.29.0-alpha.2",
|
|
29
|
+
"envio-linux-arm64": "v2.29.0-alpha.2",
|
|
30
|
+
"envio-darwin-x64": "v2.29.0-alpha.2",
|
|
31
|
+
"envio-darwin-arm64": "v2.29.0-alpha.2"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@envio-dev/hypersync-client": "0.6.6",
|
package/src/Envio.gen.ts
CHANGED
|
@@ -17,9 +17,13 @@ export type blockEvent = Internal_blockEvent;
|
|
|
17
17
|
|
|
18
18
|
export type onBlockArgs<context> = { readonly block: blockEvent; readonly context: context };
|
|
19
19
|
|
|
20
|
-
export type
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
export type onBlockOptions<chain> = {
|
|
21
|
+
readonly name: string;
|
|
22
|
+
readonly chain: chain;
|
|
23
|
+
readonly interval?: number;
|
|
24
|
+
readonly startBlock?: number;
|
|
25
|
+
readonly endBlock?: number
|
|
26
|
+
};
|
|
23
27
|
|
|
24
28
|
export type logger = $$logger;
|
|
25
29
|
|
package/src/Envio.res
CHANGED
|
@@ -11,16 +11,13 @@ type onBlockArgs<'context> = {
|
|
|
11
11
|
context: 'context,
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
@unboxed
|
|
15
|
-
type chainReference = Id(int) // | Name(string)
|
|
16
|
-
|
|
17
14
|
@genType
|
|
18
|
-
type onBlockOptions = {
|
|
15
|
+
type onBlockOptions<'chain> = {
|
|
19
16
|
name: string,
|
|
20
|
-
chain:
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
17
|
+
chain: 'chain,
|
|
18
|
+
interval?: int,
|
|
19
|
+
startBlock?: int,
|
|
20
|
+
endBlock?: int,
|
|
24
21
|
}
|
|
25
22
|
|
|
26
23
|
@genType.import(("./Types.ts", "Logger"))
|
package/src/EventRegister.res
CHANGED
|
@@ -10,11 +10,18 @@ type activeRegistration = {
|
|
|
10
10
|
|
|
11
11
|
let activeRegistration = ref(None)
|
|
12
12
|
|
|
13
|
+
// Might happen for tests when the handler file
|
|
14
|
+
// is imported by a non-envio process (eg mocha)
|
|
15
|
+
// and initialized before we started registration.
|
|
16
|
+
// So we track them here to register when the startRegistration is called.
|
|
17
|
+
// Theoretically we could keep preRegistration without an explicit start
|
|
18
|
+
// but I want it to be this way, so for the actual indexer run
|
|
19
|
+
// an error is thrown with the exact stack trace where the handler was registered.
|
|
20
|
+
let preRegistered = []
|
|
21
|
+
|
|
13
22
|
let withRegistration = (fn: activeRegistration => unit) => {
|
|
14
23
|
switch activeRegistration.contents {
|
|
15
|
-
| None =>
|
|
16
|
-
// So we just ignore handlers in this case
|
|
17
|
-
()
|
|
24
|
+
| None => preRegistered->Belt.Array.push(fn)
|
|
18
25
|
| Some(r) =>
|
|
19
26
|
if r.finished {
|
|
20
27
|
Js.Exn.raiseError(
|
|
@@ -27,7 +34,7 @@ let withRegistration = (fn: activeRegistration => unit) => {
|
|
|
27
34
|
}
|
|
28
35
|
|
|
29
36
|
let startRegistration = (~ecosystem, ~multichain, ~preloadHandlers) => {
|
|
30
|
-
|
|
37
|
+
let r = {
|
|
31
38
|
ecosystem,
|
|
32
39
|
multichain,
|
|
33
40
|
preloadHandlers,
|
|
@@ -35,7 +42,15 @@ let startRegistration = (~ecosystem, ~multichain, ~preloadHandlers) => {
|
|
|
35
42
|
onBlockByChainId: Js.Dict.empty(),
|
|
36
43
|
},
|
|
37
44
|
finished: false,
|
|
38
|
-
}
|
|
45
|
+
}
|
|
46
|
+
activeRegistration.contents = Some(r)
|
|
47
|
+
while preRegistered->Js.Array2.length > 0 {
|
|
48
|
+
// Loop + cleanup in one go
|
|
49
|
+
switch preRegistered->Js.Array2.pop {
|
|
50
|
+
| Some(fn) => fn(r)
|
|
51
|
+
| None => ()
|
|
52
|
+
}
|
|
53
|
+
}
|
|
39
54
|
}
|
|
40
55
|
|
|
41
56
|
let finishRegistration = () => {
|
|
@@ -49,12 +64,17 @@ let finishRegistration = () => {
|
|
|
49
64
|
}
|
|
50
65
|
}
|
|
51
66
|
|
|
52
|
-
let onBlockOptionsSchema = S.schema(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
67
|
+
let onBlockOptionsSchema = S.schema(s =>
|
|
68
|
+
{
|
|
69
|
+
"name": s.matches(S.string),
|
|
70
|
+
"chain": s.matches(S.int),
|
|
71
|
+
"interval": s.matches(S.option(S.int->S.intMin(1))->S.Option.getOr(1)),
|
|
72
|
+
"startBlock": s.matches(S.option(S.int)),
|
|
73
|
+
"endBlock": s.matches(S.option(S.int)),
|
|
74
|
+
}
|
|
75
|
+
)
|
|
56
76
|
|
|
57
|
-
let onBlock = (
|
|
77
|
+
let onBlock = (rawOptions: unknown, handler: Internal.onBlockArgs => promise<unit>) => {
|
|
58
78
|
withRegistration(registration => {
|
|
59
79
|
// There's no big reason for this. It's just more work
|
|
60
80
|
switch registration.ecosystem {
|
|
@@ -82,9 +102,9 @@ let onBlock = (options: Envio.onBlockOptions, handler: Internal.onBlockArgs => p
|
|
|
82
102
|
)
|
|
83
103
|
}
|
|
84
104
|
|
|
85
|
-
options->S.
|
|
86
|
-
let chainId = switch options
|
|
87
|
-
|
|
|
105
|
+
let options = rawOptions->S.parseOrThrow(onBlockOptionsSchema)
|
|
106
|
+
let chainId = switch options["chain"] {
|
|
107
|
+
| chainId => chainId
|
|
88
108
|
// Dmitry: I want to add names for chains in the future
|
|
89
109
|
// and to be able to use them as a lookup.
|
|
90
110
|
// To do so, we'll need to pass a config during reigstration
|
|
@@ -101,7 +121,10 @@ let onBlock = (options: Envio.onBlockOptions, handler: Internal.onBlockArgs => p
|
|
|
101
121
|
(
|
|
102
122
|
{
|
|
103
123
|
index: 0,
|
|
104
|
-
name: options
|
|
124
|
+
name: options["name"],
|
|
125
|
+
startBlock: options["startBlock"],
|
|
126
|
+
endBlock: options["endBlock"],
|
|
127
|
+
interval: options["interval"],
|
|
105
128
|
chainId,
|
|
106
129
|
handler,
|
|
107
130
|
}: Internal.onBlockConfig
|
package/src/EventRegister.res.js
CHANGED
|
@@ -12,6 +12,8 @@ var activeRegistration = {
|
|
|
12
12
|
contents: undefined
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
+
var preRegistered = [];
|
|
16
|
+
|
|
15
17
|
function withRegistration(fn) {
|
|
16
18
|
var r = activeRegistration.contents;
|
|
17
19
|
if (r !== undefined) {
|
|
@@ -20,12 +22,14 @@ function withRegistration(fn) {
|
|
|
20
22
|
} else {
|
|
21
23
|
return fn(r);
|
|
22
24
|
}
|
|
25
|
+
} else {
|
|
26
|
+
preRegistered.push(fn);
|
|
27
|
+
return ;
|
|
23
28
|
}
|
|
24
|
-
|
|
25
29
|
}
|
|
26
30
|
|
|
27
31
|
function startRegistration(ecosystem, multichain, preloadHandlers) {
|
|
28
|
-
|
|
32
|
+
var r = {
|
|
29
33
|
ecosystem: ecosystem,
|
|
30
34
|
multichain: multichain,
|
|
31
35
|
preloadHandlers: preloadHandlers,
|
|
@@ -34,6 +38,14 @@ function startRegistration(ecosystem, multichain, preloadHandlers) {
|
|
|
34
38
|
},
|
|
35
39
|
finished: false
|
|
36
40
|
};
|
|
41
|
+
activeRegistration.contents = r;
|
|
42
|
+
while(preRegistered.length > 0) {
|
|
43
|
+
var fn = preRegistered.pop();
|
|
44
|
+
if (fn !== undefined) {
|
|
45
|
+
fn(r);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
};
|
|
37
49
|
}
|
|
38
50
|
|
|
39
51
|
function finishRegistration() {
|
|
@@ -49,11 +61,14 @@ function finishRegistration() {
|
|
|
49
61
|
var onBlockOptionsSchema = S$RescriptSchema.schema(function (s) {
|
|
50
62
|
return {
|
|
51
63
|
name: s.m(S$RescriptSchema.string),
|
|
52
|
-
chain: s.m(S$RescriptSchema.$$int)
|
|
64
|
+
chain: s.m(S$RescriptSchema.$$int),
|
|
65
|
+
interval: s.m(S$RescriptSchema.$$Option.getOr(S$RescriptSchema.option(S$RescriptSchema.intMin(S$RescriptSchema.$$int, 1, undefined)), 1)),
|
|
66
|
+
startBlock: s.m(S$RescriptSchema.option(S$RescriptSchema.$$int)),
|
|
67
|
+
endBlock: s.m(S$RescriptSchema.option(S$RescriptSchema.$$int))
|
|
53
68
|
};
|
|
54
69
|
});
|
|
55
70
|
|
|
56
|
-
function onBlock(
|
|
71
|
+
function onBlock(rawOptions, handler) {
|
|
57
72
|
withRegistration(function (registration) {
|
|
58
73
|
var match = registration.ecosystem;
|
|
59
74
|
if (match !== "evm") {
|
|
@@ -68,7 +83,7 @@ function onBlock(options, handler) {
|
|
|
68
83
|
} else {
|
|
69
84
|
Js_exn.raiseError("Block Handlers require the Preload Optimization feature. Enable it by setting the `preload_handlers` option to `true` in your config.");
|
|
70
85
|
}
|
|
71
|
-
S$RescriptSchema.
|
|
86
|
+
var options = S$RescriptSchema.parseOrThrow(rawOptions, onBlockOptionsSchema);
|
|
72
87
|
var chainId = options.chain;
|
|
73
88
|
var onBlockByChainId = registration.registrations.onBlockByChainId;
|
|
74
89
|
var match$2 = onBlockByChainId[String(chainId)];
|
|
@@ -79,6 +94,9 @@ function onBlock(options, handler) {
|
|
|
79
94
|
index: 0,
|
|
80
95
|
name: options.name,
|
|
81
96
|
chainId: chainId,
|
|
97
|
+
startBlock: options.startBlock,
|
|
98
|
+
endBlock: options.endBlock,
|
|
99
|
+
interval: options.interval,
|
|
82
100
|
handler: handler
|
|
83
101
|
}];
|
|
84
102
|
return ;
|
package/src/EventRegister.resi
CHANGED
package/src/FetchState.res
CHANGED
|
@@ -52,6 +52,7 @@ type t = {
|
|
|
52
52
|
// since partitions might be deleted on merge or cleaned up
|
|
53
53
|
nextPartitionIndex: int,
|
|
54
54
|
isFetchingAtHead: bool,
|
|
55
|
+
startBlock: int,
|
|
55
56
|
endBlock: option<int>,
|
|
56
57
|
maxAddrInPartition: int,
|
|
57
58
|
normalSelection: selection,
|
|
@@ -78,6 +79,7 @@ let copy = (fetchState: t) => {
|
|
|
78
79
|
{
|
|
79
80
|
maxAddrInPartition: fetchState.maxAddrInPartition,
|
|
80
81
|
partitions: fetchState.partitions,
|
|
82
|
+
startBlock: fetchState.startBlock,
|
|
81
83
|
endBlock: fetchState.endBlock,
|
|
82
84
|
nextPartitionIndex: fetchState.nextPartitionIndex,
|
|
83
85
|
isFetchingAtHead: fetchState.isFetchingAtHead,
|
|
@@ -252,6 +254,7 @@ let updateInternal = (
|
|
|
252
254
|
|
|
253
255
|
{
|
|
254
256
|
maxAddrInPartition: fetchState.maxAddrInPartition,
|
|
257
|
+
startBlock: fetchState.startBlock,
|
|
255
258
|
endBlock: fetchState.endBlock,
|
|
256
259
|
contractConfigs: fetchState.contractConfigs,
|
|
257
260
|
normalSelection: fetchState.normalSelection,
|
|
@@ -640,10 +643,26 @@ let handleQueryResult = (
|
|
|
640
643
|
}
|
|
641
644
|
|
|
642
645
|
if nextLatestFullyFetchedBlockNumber > prevLatestFetchedBlockNumber {
|
|
643
|
-
for
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
646
|
+
for configIdx in 0 to onBlockConfigs->Array.length - 1 {
|
|
647
|
+
let onBlockConfig = onBlockConfigs->Js.Array2.unsafe_get(configIdx)
|
|
648
|
+
|
|
649
|
+
let handlerStartBlock = switch onBlockConfig.startBlock {
|
|
650
|
+
| Some(startBlock) => startBlock
|
|
651
|
+
| None => fetchState.startBlock
|
|
652
|
+
}
|
|
653
|
+
let rangeStart = Pervasives.max(handlerStartBlock, prevLatestFetchedBlockNumber + 1)
|
|
654
|
+
let rangeEnd = switch onBlockConfig.endBlock {
|
|
655
|
+
| Some(endBlock) => Pervasives.min(endBlock, nextLatestFullyFetchedBlockNumber)
|
|
656
|
+
| None => nextLatestFullyFetchedBlockNumber
|
|
657
|
+
}
|
|
658
|
+
if rangeStart <= rangeEnd {
|
|
659
|
+
for blockNumber in rangeStart to rangeEnd {
|
|
660
|
+
if (blockNumber - handlerStartBlock)->Pervasives.mod(onBlockConfig.interval) === 0 {
|
|
661
|
+
newQueue->Array.push(
|
|
662
|
+
Block({onBlockConfig, blockNumber, logIndex: blockItemLogIndex}),
|
|
663
|
+
)
|
|
664
|
+
}
|
|
665
|
+
}
|
|
647
666
|
}
|
|
648
667
|
}
|
|
649
668
|
}
|
|
@@ -959,12 +978,13 @@ let make = (
|
|
|
959
978
|
~contracts: array<indexingContract>,
|
|
960
979
|
~maxAddrInPartition,
|
|
961
980
|
~chainId,
|
|
981
|
+
~progressBlockNumber=startBlock - 1,
|
|
962
982
|
~onBlockConfigs=?,
|
|
963
983
|
~blockLag=0,
|
|
964
984
|
): t => {
|
|
965
985
|
let latestFetchedBlock = {
|
|
966
986
|
blockTimestamp: 0,
|
|
967
|
-
blockNumber:
|
|
987
|
+
blockNumber: progressBlockNumber,
|
|
968
988
|
}
|
|
969
989
|
|
|
970
990
|
let notDependingOnAddresses = []
|
|
@@ -1078,6 +1098,7 @@ let make = (
|
|
|
1078
1098
|
isFetchingAtHead: false,
|
|
1079
1099
|
maxAddrInPartition,
|
|
1080
1100
|
chainId,
|
|
1101
|
+
startBlock,
|
|
1081
1102
|
endBlock,
|
|
1082
1103
|
latestFullyFetchedBlock: latestFetchedBlock,
|
|
1083
1104
|
normalSelection,
|
package/src/FetchState.res.js
CHANGED
|
@@ -10,6 +10,7 @@ var Logging = require("./Logging.res.js");
|
|
|
10
10
|
var Belt_Int = require("rescript/lib/js/belt_Int.js");
|
|
11
11
|
var Caml_obj = require("rescript/lib/js/caml_obj.js");
|
|
12
12
|
var Belt_Array = require("rescript/lib/js/belt_Array.js");
|
|
13
|
+
var Caml_int32 = require("rescript/lib/js/caml_int32.js");
|
|
13
14
|
var Prometheus = require("./Prometheus.res.js");
|
|
14
15
|
var Belt_Option = require("rescript/lib/js/belt_Option.js");
|
|
15
16
|
var Belt_Result = require("rescript/lib/js/belt_Result.js");
|
|
@@ -21,6 +22,7 @@ function copy(fetchState) {
|
|
|
21
22
|
partitions: fetchState.partitions,
|
|
22
23
|
nextPartitionIndex: fetchState.nextPartitionIndex,
|
|
23
24
|
isFetchingAtHead: fetchState.isFetchingAtHead,
|
|
25
|
+
startBlock: fetchState.startBlock,
|
|
24
26
|
endBlock: fetchState.endBlock,
|
|
25
27
|
maxAddrInPartition: fetchState.maxAddrInPartition,
|
|
26
28
|
normalSelection: fetchState.normalSelection,
|
|
@@ -142,6 +144,7 @@ function updateInternal(fetchState, partitionsOpt, nextPartitionIndexOpt, indexi
|
|
|
142
144
|
partitions: partitions,
|
|
143
145
|
nextPartitionIndex: nextPartitionIndex,
|
|
144
146
|
isFetchingAtHead: isFetchingAtHead,
|
|
147
|
+
startBlock: fetchState.startBlock,
|
|
145
148
|
endBlock: fetchState.endBlock,
|
|
146
149
|
maxAddrInPartition: fetchState.maxAddrInPartition,
|
|
147
150
|
normalSelection: fetchState.normalSelection,
|
|
@@ -423,16 +426,27 @@ function handleQueryResult(fetchState, query, latestFetchedBlock, newItems, curr
|
|
|
423
426
|
}
|
|
424
427
|
var nextLatestFullyFetchedBlockNumber$1 = nextLatestFullyFetchedBlockNumber;
|
|
425
428
|
if (nextLatestFullyFetchedBlockNumber$1 > prevLatestFetchedBlockNumber) {
|
|
426
|
-
for(var
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
429
|
+
for(var configIdx = 0 ,configIdx_finish = onBlockConfigs.length; configIdx < configIdx_finish; ++configIdx){
|
|
430
|
+
var onBlockConfig = onBlockConfigs[configIdx];
|
|
431
|
+
var startBlock = onBlockConfig.startBlock;
|
|
432
|
+
var handlerStartBlock = startBlock !== undefined ? startBlock : fetchState.startBlock;
|
|
433
|
+
var rangeStart = Caml.int_max(handlerStartBlock, prevLatestFetchedBlockNumber + 1 | 0);
|
|
434
|
+
var endBlock = onBlockConfig.endBlock;
|
|
435
|
+
var rangeEnd = endBlock !== undefined && endBlock < nextLatestFullyFetchedBlockNumber$1 ? endBlock : nextLatestFullyFetchedBlockNumber$1;
|
|
436
|
+
if (rangeStart <= rangeEnd) {
|
|
437
|
+
for(var blockNumber = rangeStart; blockNumber <= rangeEnd; ++blockNumber){
|
|
438
|
+
if (Caml_int32.mod_(blockNumber - handlerStartBlock | 0, onBlockConfig.interval) === 0) {
|
|
439
|
+
newQueue.push({
|
|
440
|
+
kind: 1,
|
|
441
|
+
onBlockConfig: onBlockConfig,
|
|
442
|
+
blockNumber: blockNumber,
|
|
443
|
+
logIndex: 16777216
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
}
|
|
435
448
|
}
|
|
449
|
+
|
|
436
450
|
}
|
|
437
451
|
}
|
|
438
452
|
|
|
@@ -689,11 +703,11 @@ function getEarliestEvent(param) {
|
|
|
689
703
|
}
|
|
690
704
|
}
|
|
691
705
|
|
|
692
|
-
function make(startBlock, endBlock, eventConfigs, contracts, maxAddrInPartition, chainId, onBlockConfigs, blockLagOpt) {
|
|
706
|
+
function make(startBlock, endBlock, eventConfigs, contracts, maxAddrInPartition, chainId, progressBlockNumberOpt, onBlockConfigs, blockLagOpt) {
|
|
707
|
+
var progressBlockNumber = progressBlockNumberOpt !== undefined ? progressBlockNumberOpt : startBlock - 1 | 0;
|
|
693
708
|
var blockLag = blockLagOpt !== undefined ? blockLagOpt : 0;
|
|
694
|
-
var latestFetchedBlock_blockNumber = startBlock - 1 | 0;
|
|
695
709
|
var latestFetchedBlock = {
|
|
696
|
-
blockNumber:
|
|
710
|
+
blockNumber: progressBlockNumber,
|
|
697
711
|
blockTimestamp: 0
|
|
698
712
|
};
|
|
699
713
|
var notDependingOnAddresses = [];
|
|
@@ -780,7 +794,7 @@ function make(startBlock, endBlock, eventConfigs, contracts, maxAddrInPartition,
|
|
|
780
794
|
Prometheus.IndexingAddresses.set(numAddresses, chainId);
|
|
781
795
|
Prometheus.IndexingPartitions.set(partitions.length, chainId);
|
|
782
796
|
Prometheus.IndexingBufferSize.set(0, chainId);
|
|
783
|
-
Prometheus.IndexingBufferBlockNumber.set(
|
|
797
|
+
Prometheus.IndexingBufferBlockNumber.set(progressBlockNumber, chainId);
|
|
784
798
|
if (endBlock !== undefined) {
|
|
785
799
|
Prometheus.IndexingEndBlock.set(endBlock, chainId);
|
|
786
800
|
}
|
|
@@ -788,6 +802,7 @@ function make(startBlock, endBlock, eventConfigs, contracts, maxAddrInPartition,
|
|
|
788
802
|
partitions: partitions,
|
|
789
803
|
nextPartitionIndex: partitions.length,
|
|
790
804
|
isFetchingAtHead: false,
|
|
805
|
+
startBlock: startBlock,
|
|
791
806
|
endBlock: endBlock,
|
|
792
807
|
maxAddrInPartition: maxAddrInPartition,
|
|
793
808
|
normalSelection: normalSelection,
|