envio 3.0.0-alpha.2 → 3.0.0-alpha.20
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 +164 -30
- package/bin.mjs +49 -0
- package/evm.schema.json +79 -169
- package/fuel.schema.json +50 -21
- package/index.d.ts +497 -1
- package/index.js +4 -0
- package/package.json +42 -31
- package/rescript.json +4 -1
- package/src/Batch.res +11 -8
- package/src/Batch.res.mjs +11 -9
- package/src/ChainFetcher.res +531 -0
- package/src/ChainFetcher.res.mjs +339 -0
- package/src/ChainManager.res +190 -0
- package/src/ChainManager.res.mjs +166 -0
- package/src/Change.res +3 -3
- package/src/Config.gen.ts +19 -0
- package/src/Config.res +737 -22
- package/src/Config.res.mjs +703 -26
- package/src/{Indexer.res → Ctx.res} +1 -1
- package/src/Ecosystem.res +9 -124
- package/src/Ecosystem.res.mjs +19 -160
- package/src/Env.res +30 -74
- package/src/Env.res.mjs +25 -87
- package/src/Envio.gen.ts +3 -1
- package/src/Envio.res +20 -9
- package/src/EventProcessing.res +469 -0
- package/src/EventProcessing.res.mjs +337 -0
- package/src/EvmTypes.gen.ts +6 -0
- package/src/EvmTypes.res +1 -0
- package/src/FetchState.res +1256 -639
- package/src/FetchState.res.mjs +1135 -612
- package/src/GlobalState.res +1190 -0
- package/src/GlobalState.res.mjs +1183 -0
- package/src/GlobalStateManager.res +68 -0
- package/src/GlobalStateManager.res.mjs +75 -0
- package/src/GlobalStateManager.resi +7 -0
- package/src/HandlerLoader.res +89 -0
- package/src/HandlerLoader.res.mjs +79 -0
- package/src/HandlerRegister.res +357 -0
- package/src/HandlerRegister.res.mjs +299 -0
- package/src/{EventRegister.resi → HandlerRegister.resi} +13 -13
- package/src/Hasura.res +111 -175
- package/src/Hasura.res.mjs +88 -150
- package/src/InMemoryStore.res +1 -1
- package/src/InMemoryStore.res.mjs +3 -3
- package/src/InMemoryTable.res +1 -1
- package/src/InMemoryTable.res.mjs +1 -1
- package/src/Internal.gen.ts +4 -0
- package/src/Internal.res +230 -12
- package/src/Internal.res.mjs +115 -1
- package/src/LoadLayer.res +444 -0
- package/src/LoadLayer.res.mjs +296 -0
- package/src/LoadLayer.resi +32 -0
- package/src/LogSelection.res +33 -27
- package/src/LogSelection.res.mjs +6 -0
- package/src/Logging.res +21 -7
- package/src/Logging.res.mjs +16 -8
- package/src/Main.res +377 -0
- package/src/Main.res.mjs +339 -0
- package/src/Persistence.res +7 -21
- package/src/Persistence.res.mjs +3 -3
- package/src/PgStorage.gen.ts +10 -0
- package/src/PgStorage.res +116 -69
- package/src/PgStorage.res.d.mts +5 -0
- package/src/PgStorage.res.mjs +93 -50
- package/src/Prometheus.res +294 -224
- package/src/Prometheus.res.mjs +353 -340
- package/src/ReorgDetection.res +6 -10
- package/src/ReorgDetection.res.mjs +6 -6
- package/src/SafeCheckpointTracking.res +4 -4
- package/src/SafeCheckpointTracking.res.mjs +2 -2
- package/src/Sink.res +4 -2
- package/src/Sink.res.mjs +2 -1
- package/src/TableIndices.res +0 -1
- package/src/TestIndexer.res +692 -0
- package/src/TestIndexer.res.mjs +527 -0
- package/src/TestIndexerProxyStorage.res +205 -0
- package/src/TestIndexerProxyStorage.res.mjs +151 -0
- package/src/TopicFilter.res +1 -1
- package/src/Types.ts +1 -1
- package/src/UserContext.res +424 -0
- package/src/UserContext.res.mjs +279 -0
- package/src/Utils.res +97 -26
- package/src/Utils.res.mjs +91 -44
- package/src/bindings/BigInt.res +10 -0
- package/src/bindings/BigInt.res.mjs +15 -0
- package/src/bindings/ClickHouse.res +120 -23
- package/src/bindings/ClickHouse.res.mjs +118 -28
- package/src/bindings/DateFns.res +74 -0
- package/src/bindings/DateFns.res.mjs +22 -0
- package/src/bindings/EventSource.res +8 -1
- package/src/bindings/EventSource.res.mjs +8 -1
- package/src/bindings/Express.res +1 -0
- package/src/bindings/Hrtime.res +14 -1
- package/src/bindings/Hrtime.res.mjs +22 -2
- package/src/bindings/Hrtime.resi +4 -0
- package/src/bindings/Lodash.res +0 -1
- package/src/bindings/NodeJs.res +49 -3
- package/src/bindings/NodeJs.res.mjs +11 -3
- package/src/bindings/Pino.res +24 -10
- package/src/bindings/Pino.res.mjs +14 -8
- package/src/bindings/Postgres.gen.ts +8 -0
- package/src/bindings/Postgres.res +5 -1
- package/src/bindings/Postgres.res.d.mts +5 -0
- package/src/bindings/PromClient.res +0 -10
- package/src/bindings/PromClient.res.mjs +0 -3
- package/src/bindings/Vitest.res +142 -0
- package/src/bindings/Vitest.res.mjs +9 -0
- package/src/bindings/WebSocket.res +27 -0
- package/src/bindings/WebSocket.res.mjs +2 -0
- package/src/bindings/Yargs.res +8 -0
- package/src/bindings/Yargs.res.mjs +2 -0
- package/src/db/EntityHistory.res +7 -7
- package/src/db/EntityHistory.res.mjs +9 -9
- package/src/db/InternalTable.res +59 -111
- package/src/db/InternalTable.res.mjs +73 -104
- package/src/db/Table.res +27 -8
- package/src/db/Table.res.mjs +25 -14
- package/src/sources/Evm.res +84 -0
- package/src/sources/Evm.res.mjs +105 -0
- package/src/sources/EvmChain.res +94 -0
- package/src/sources/EvmChain.res.mjs +60 -0
- package/src/sources/Fuel.res +19 -34
- package/src/sources/Fuel.res.mjs +34 -16
- package/src/sources/FuelSDK.res +38 -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 +33 -13
- package/src/sources/HyperFuelSource.res.mjs +24 -16
- package/src/sources/HyperSync.res +36 -6
- package/src/sources/HyperSync.res.mjs +9 -7
- package/src/sources/HyperSync.resi +4 -0
- package/src/sources/HyperSyncClient.res +1 -1
- package/src/sources/HyperSyncHeightStream.res +47 -116
- package/src/sources/HyperSyncHeightStream.res.mjs +46 -73
- package/src/sources/HyperSyncSource.res +118 -139
- package/src/sources/HyperSyncSource.res.mjs +104 -121
- package/src/sources/Rpc.res +86 -14
- package/src/sources/Rpc.res.mjs +101 -9
- package/src/sources/RpcSource.res +621 -364
- package/src/sources/RpcSource.res.mjs +843 -410
- package/src/sources/RpcWebSocketHeightStream.res +181 -0
- package/src/sources/RpcWebSocketHeightStream.res.mjs +196 -0
- package/src/sources/Source.res +7 -5
- package/src/sources/SourceManager.res +325 -225
- package/src/sources/SourceManager.res.mjs +314 -171
- package/src/sources/SourceManager.resi +17 -6
- package/src/sources/Svm.res +81 -0
- package/src/sources/Svm.res.mjs +90 -0
- package/src/tui/Tui.res +247 -0
- package/src/tui/Tui.res.mjs +337 -0
- package/src/tui/bindings/Ink.res +371 -0
- package/src/tui/bindings/Ink.res.mjs +72 -0
- package/src/tui/bindings/Style.res +123 -0
- package/src/tui/bindings/Style.res.mjs +2 -0
- package/src/tui/components/BufferedProgressBar.res +40 -0
- package/src/tui/components/BufferedProgressBar.res.mjs +57 -0
- package/src/tui/components/CustomHooks.res +122 -0
- package/src/tui/components/CustomHooks.res.mjs +179 -0
- package/src/tui/components/Messages.res +41 -0
- package/src/tui/components/Messages.res.mjs +75 -0
- package/src/tui/components/SyncETA.res +174 -0
- package/src/tui/components/SyncETA.res.mjs +263 -0
- package/src/tui/components/TuiData.res +47 -0
- package/src/tui/components/TuiData.res.mjs +34 -0
- package/svm.schema.json +112 -0
- package/bin.js +0 -48
- package/src/EventRegister.res +0 -241
- package/src/EventRegister.res.mjs +0 -240
- package/src/bindings/Ethers.gen.ts +0 -14
- package/src/bindings/Ethers.res +0 -204
- package/src/bindings/Ethers.res.mjs +0 -130
- /package/src/{Indexer.res.mjs → Ctx.res.mjs} +0 -0
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Env from "./Env.res.mjs";
|
|
4
|
+
import * as Svm from "./sources/Svm.res.mjs";
|
|
5
|
+
import * as Caml from "rescript/lib/es6/caml.js";
|
|
6
|
+
import * as Utils from "./Utils.res.mjs";
|
|
7
|
+
import * as Js_exn from "rescript/lib/es6/js_exn.js";
|
|
8
|
+
import * as Logging from "./Logging.res.mjs";
|
|
9
|
+
import * as $$Promise from "./bindings/Promise.res.mjs";
|
|
10
|
+
import * as ChainMap from "./ChainMap.res.mjs";
|
|
11
|
+
import * as EvmChain from "./sources/EvmChain.res.mjs";
|
|
12
|
+
import * as Belt_Array from "rescript/lib/es6/belt_Array.js";
|
|
13
|
+
import * as FetchState from "./FetchState.res.mjs";
|
|
14
|
+
import * as Prometheus from "./Prometheus.res.mjs";
|
|
15
|
+
import * as Belt_Option from "rescript/lib/es6/belt_Option.js";
|
|
16
|
+
import * as Caml_option from "rescript/lib/es6/caml_option.js";
|
|
17
|
+
import * as EventRouter from "./sources/EventRouter.res.mjs";
|
|
18
|
+
import * as UserContext from "./UserContext.res.mjs";
|
|
19
|
+
import * as ErrorHandling from "./ErrorHandling.res.mjs";
|
|
20
|
+
import * as SourceManager from "./sources/SourceManager.res.mjs";
|
|
21
|
+
import * as ReorgDetection from "./ReorgDetection.res.mjs";
|
|
22
|
+
import * as HyperFuelSource from "./sources/HyperFuelSource.res.mjs";
|
|
23
|
+
import * as Caml_js_exceptions from "rescript/lib/es6/caml_js_exceptions.js";
|
|
24
|
+
import * as SafeCheckpointTracking from "./SafeCheckpointTracking.res.mjs";
|
|
25
|
+
|
|
26
|
+
function make(chainConfig, dynamicContracts, startBlock, endBlock, firstEventBlockOpt, progressBlockNumber, config, registrations, targetBufferSize, logger, timestampCaughtUpToHeadOrEndblock, numEventsProcessed, isInReorgThreshold, reorgCheckpoints, maxReorgDepth, knownHeightOpt) {
|
|
27
|
+
var firstEventBlock = firstEventBlockOpt !== undefined ? Caml_option.valFromOption(firstEventBlockOpt) : undefined;
|
|
28
|
+
var knownHeight = knownHeightOpt !== undefined ? knownHeightOpt : 0;
|
|
29
|
+
var eventRouter = EventRouter.empty();
|
|
30
|
+
var contracts = [];
|
|
31
|
+
var eventConfigs = [];
|
|
32
|
+
var notRegisteredEvents = [];
|
|
33
|
+
Belt_Array.forEach(chainConfig.contracts, (function (contract) {
|
|
34
|
+
var contractName = contract.name;
|
|
35
|
+
Belt_Array.forEach(contract.events, (function (eventConfig) {
|
|
36
|
+
var hasContractRegister = Belt_Option.isSome(eventConfig.contractRegister);
|
|
37
|
+
EventRouter.addOrThrow(eventRouter, eventConfig.id, undefined, contractName, eventConfig.isWildcard, eventConfig.name, ChainMap.Chain.makeUnsafe(chainConfig.id));
|
|
38
|
+
var shouldBeIncluded;
|
|
39
|
+
if (config.enableRawEvents) {
|
|
40
|
+
shouldBeIncluded = true;
|
|
41
|
+
} else {
|
|
42
|
+
var isRegistered = hasContractRegister || Belt_Option.isSome(eventConfig.handler);
|
|
43
|
+
if (!isRegistered) {
|
|
44
|
+
notRegisteredEvents.push(eventConfig);
|
|
45
|
+
}
|
|
46
|
+
shouldBeIncluded = isRegistered;
|
|
47
|
+
}
|
|
48
|
+
var shouldSkip;
|
|
49
|
+
try {
|
|
50
|
+
var getEventFiltersOrThrow = eventConfig.getEventFiltersOrThrow;
|
|
51
|
+
if (getEventFiltersOrThrow) {
|
|
52
|
+
var match = getEventFiltersOrThrow(ChainMap.Chain.makeUnsafe(chainConfig.id));
|
|
53
|
+
shouldSkip = match.TAG === "Static" ? match._0.length === 0 : false;
|
|
54
|
+
} else {
|
|
55
|
+
shouldSkip = false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch (exn){
|
|
59
|
+
shouldSkip = false;
|
|
60
|
+
}
|
|
61
|
+
if (shouldBeIncluded && !shouldSkip) {
|
|
62
|
+
eventConfigs.push(eventConfig);
|
|
63
|
+
return ;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
}));
|
|
67
|
+
var startBlock = contract.startBlock;
|
|
68
|
+
if (startBlock !== undefined && startBlock < chainConfig.startBlock) {
|
|
69
|
+
Js_exn.raiseError("The start block for contract \"" + contractName + "\" is less than the chain start block. This is not supported yet.");
|
|
70
|
+
}
|
|
71
|
+
Belt_Array.forEach(contract.addresses, (function (address) {
|
|
72
|
+
var startBlock = contract.startBlock;
|
|
73
|
+
contracts.push({
|
|
74
|
+
address: address,
|
|
75
|
+
contractName: contract.name,
|
|
76
|
+
startBlock: startBlock !== undefined ? startBlock : chainConfig.startBlock,
|
|
77
|
+
registrationBlock: undefined
|
|
78
|
+
});
|
|
79
|
+
}));
|
|
80
|
+
}));
|
|
81
|
+
Belt_Array.forEach(dynamicContracts, (function (dc) {
|
|
82
|
+
contracts.push(dc);
|
|
83
|
+
}));
|
|
84
|
+
if (Utils.$$Array.notEmpty(notRegisteredEvents)) {
|
|
85
|
+
Logging.childInfo(logger, "The event" + (
|
|
86
|
+
notRegisteredEvents.length > 1 ? "s" : ""
|
|
87
|
+
) + " " + Belt_Array.map(notRegisteredEvents, (function (eventConfig) {
|
|
88
|
+
return eventConfig.contractName + "." + eventConfig.name;
|
|
89
|
+
})).join(", ") + " don't have an event handler and skipped for indexing.");
|
|
90
|
+
}
|
|
91
|
+
var onBlockConfigs = registrations.onBlockByChainId[String(chainConfig.id)];
|
|
92
|
+
if (onBlockConfigs !== undefined) {
|
|
93
|
+
Belt_Array.forEach(onBlockConfigs, (function (onBlockConfig) {
|
|
94
|
+
if (Belt_Option.getWithDefault(onBlockConfig.startBlock, startBlock) < startBlock) {
|
|
95
|
+
Js_exn.raiseError("The start block for onBlock handler \"" + onBlockConfig.name + "\" is less than the chain start block (" + String(startBlock) + "). This is not supported yet.");
|
|
96
|
+
}
|
|
97
|
+
if (endBlock !== undefined && Belt_Option.getWithDefault(onBlockConfig.endBlock, endBlock) > endBlock) {
|
|
98
|
+
return Js_exn.raiseError("The end block for onBlock handler \"" + onBlockConfig.name + "\" is greater than the chain end block (" + String(endBlock) + "). This is not supported yet.");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
}));
|
|
102
|
+
}
|
|
103
|
+
var fetchState = FetchState.make(startBlock, endBlock, eventConfigs, contracts, config.maxAddrInPartition, chainConfig.id, targetBufferSize, knownHeight, progressBlockNumber, onBlockConfigs, Caml.int_max(!config.shouldRollbackOnReorg || isInReorgThreshold ? 0 : chainConfig.maxReorgDepth, chainConfig.blockLag), Caml_option.some(firstEventBlock));
|
|
104
|
+
var chainReorgCheckpoints = Belt_Array.keepMapU(reorgCheckpoints, (function (reorgCheckpoint) {
|
|
105
|
+
if (reorgCheckpoint.chain_id === chainConfig.id) {
|
|
106
|
+
return reorgCheckpoint;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
}));
|
|
110
|
+
var chain = ChainMap.Chain.makeUnsafe(chainConfig.id);
|
|
111
|
+
var lowercaseAddresses = config.lowercaseAddresses;
|
|
112
|
+
var sources = chainConfig.sourceConfig;
|
|
113
|
+
var sources$1;
|
|
114
|
+
switch (sources.TAG) {
|
|
115
|
+
case "EvmSourceConfig" :
|
|
116
|
+
var evmContracts = Belt_Array.map(chainConfig.contracts, (function (contract) {
|
|
117
|
+
return {
|
|
118
|
+
name: contract.name,
|
|
119
|
+
abi: contract.abi,
|
|
120
|
+
events: contract.events
|
|
121
|
+
};
|
|
122
|
+
}));
|
|
123
|
+
var allEventSignatures = Belt_Array.flatMap(chainConfig.contracts, (function (contract) {
|
|
124
|
+
return contract.eventSignatures;
|
|
125
|
+
}));
|
|
126
|
+
var evmRpcs = Belt_Array.map(sources.rpcs, (function (rpc) {
|
|
127
|
+
var syncConfig = rpc.syncConfig;
|
|
128
|
+
var ws = rpc.ws;
|
|
129
|
+
return {
|
|
130
|
+
url: rpc.url,
|
|
131
|
+
sourceFor: rpc.sourceFor,
|
|
132
|
+
syncConfig: syncConfig,
|
|
133
|
+
ws: ws
|
|
134
|
+
};
|
|
135
|
+
}));
|
|
136
|
+
sources$1 = EvmChain.makeSources(chain, evmContracts, sources.hypersync, allEventSignatures, evmRpcs, lowercaseAddresses);
|
|
137
|
+
break;
|
|
138
|
+
case "FuelSourceConfig" :
|
|
139
|
+
sources$1 = [HyperFuelSource.make({
|
|
140
|
+
chain: chain,
|
|
141
|
+
endpointUrl: sources.hypersync
|
|
142
|
+
})];
|
|
143
|
+
break;
|
|
144
|
+
case "SvmSourceConfig" :
|
|
145
|
+
sources$1 = [Svm.makeRPCSource(chain, sources.rpc)];
|
|
146
|
+
break;
|
|
147
|
+
case "CustomSources" :
|
|
148
|
+
sources$1 = sources._0;
|
|
149
|
+
break;
|
|
150
|
+
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
logger: logger,
|
|
154
|
+
fetchState: fetchState,
|
|
155
|
+
sourceManager: SourceManager.make(sources$1, Env.maxPartitionConcurrency, Belt_Option.isSome(timestampCaughtUpToHeadOrEndblock), undefined, undefined, undefined, undefined, undefined),
|
|
156
|
+
chainConfig: chainConfig,
|
|
157
|
+
isProgressAtHead: false,
|
|
158
|
+
timestampCaughtUpToHeadOrEndblock: timestampCaughtUpToHeadOrEndblock,
|
|
159
|
+
committedProgressBlockNumber: progressBlockNumber,
|
|
160
|
+
numEventsProcessed: numEventsProcessed,
|
|
161
|
+
reorgDetection: ReorgDetection.make(chainReorgCheckpoints, maxReorgDepth, config.shouldRollbackOnReorg),
|
|
162
|
+
safeCheckpointTracking: SafeCheckpointTracking.make(maxReorgDepth, config.shouldRollbackOnReorg, chainReorgCheckpoints)
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function makeFromConfig(chainConfig, config, registrations, targetBufferSize, knownHeight) {
|
|
167
|
+
var logger = Logging.createChild({
|
|
168
|
+
chainId: chainConfig.id
|
|
169
|
+
});
|
|
170
|
+
return make(chainConfig, [], chainConfig.startBlock, chainConfig.endBlock, undefined, -1, config, registrations, targetBufferSize, logger, undefined, 0, false, [], chainConfig.maxReorgDepth, knownHeight);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
async function makeFromDbState(chainConfig, resumedChainState, reorgCheckpoints, isInReorgThreshold, config, registrations, targetBufferSize) {
|
|
174
|
+
var chainId = chainConfig.id;
|
|
175
|
+
var logger = Logging.createChild({
|
|
176
|
+
chainId: chainId
|
|
177
|
+
});
|
|
178
|
+
Prometheus.ProgressEventsCount.set(resumedChainState.numEventsProcessed, chainId);
|
|
179
|
+
var progressBlockNumber = resumedChainState.progressBlockNumber >= 0 ? resumedChainState.progressBlockNumber : resumedChainState.startBlock - 1 | 0;
|
|
180
|
+
return make(chainConfig, resumedChainState.dynamicContracts, resumedChainState.startBlock, resumedChainState.endBlock, Caml_option.some(resumedChainState.firstEventBlockNumber), progressBlockNumber, config, registrations, targetBufferSize, logger, Env.updateSyncTimeOnRestart ? undefined : resumedChainState.timestampCaughtUpToHeadOrEndblock, resumedChainState.numEventsProcessed, isInReorgThreshold, reorgCheckpoints, resumedChainState.maxReorgDepth, resumedChainState.sourceBlockNumber);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function getContractStartBlock(config, chain, contractName) {
|
|
184
|
+
var chainConfig = ChainMap.get(config.chainMap, chain);
|
|
185
|
+
return Belt_Option.flatMap(Caml_option.undefined_to_opt(chainConfig.contracts.find(function (contract) {
|
|
186
|
+
return contract.name === contractName;
|
|
187
|
+
})), (function (contract) {
|
|
188
|
+
return contract.startBlock;
|
|
189
|
+
}));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
async function runContractRegistersOrThrow(itemsWithContractRegister, chain, config) {
|
|
193
|
+
var itemsWithDcs = [];
|
|
194
|
+
var onRegister = function (item, contractAddress, contractName) {
|
|
195
|
+
var blockNumber = item.blockNumber;
|
|
196
|
+
var configuredStartBlock = getContractStartBlock(config, chain, contractName);
|
|
197
|
+
var contractStartBlock = configuredStartBlock !== undefined ? configuredStartBlock : blockNumber;
|
|
198
|
+
var dc_registrationBlock = blockNumber;
|
|
199
|
+
var dc = {
|
|
200
|
+
address: contractAddress,
|
|
201
|
+
contractName: contractName,
|
|
202
|
+
startBlock: contractStartBlock,
|
|
203
|
+
registrationBlock: dc_registrationBlock
|
|
204
|
+
};
|
|
205
|
+
var dcs = item.dcs;
|
|
206
|
+
if (dcs !== undefined) {
|
|
207
|
+
dcs.push(dc);
|
|
208
|
+
} else {
|
|
209
|
+
item.dcs = [dc];
|
|
210
|
+
itemsWithDcs.push(item);
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
var promises = [];
|
|
214
|
+
for(var idx = 0 ,idx_finish = itemsWithContractRegister.length; idx < idx_finish; ++idx){
|
|
215
|
+
var item = itemsWithContractRegister[idx];
|
|
216
|
+
var match = item.eventConfig;
|
|
217
|
+
var contractRegister = match.contractRegister;
|
|
218
|
+
var contractRegister$1 = contractRegister !== undefined ? contractRegister : Js_exn.raiseError("Contract register is not set for event " + match.name);
|
|
219
|
+
var errorMessage = "Event contractRegister failed, please fix the error to keep the indexer running smoothly";
|
|
220
|
+
try {
|
|
221
|
+
var params = {
|
|
222
|
+
item: item,
|
|
223
|
+
onRegister: onRegister,
|
|
224
|
+
config: config,
|
|
225
|
+
isResolved: false
|
|
226
|
+
};
|
|
227
|
+
var result = contractRegister$1(UserContext.getContractRegisterArgs(params));
|
|
228
|
+
if ($$Promise.isCatchable(result)) {
|
|
229
|
+
promises.push($$Promise.$$catch(result.then((function(params){
|
|
230
|
+
return function (r) {
|
|
231
|
+
params.isResolved = true;
|
|
232
|
+
|
|
233
|
+
}
|
|
234
|
+
}(params))), (function(item,params){
|
|
235
|
+
return function (exn) {
|
|
236
|
+
params.isResolved = true;
|
|
237
|
+
return ErrorHandling.mkLogAndRaise(Logging.getItemLogger(item), errorMessage, exn);
|
|
238
|
+
}
|
|
239
|
+
}(item,params))));
|
|
240
|
+
} else {
|
|
241
|
+
params.isResolved = true;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
catch (raw_exn){
|
|
245
|
+
var exn = Caml_js_exceptions.internalToOCamlException(raw_exn);
|
|
246
|
+
ErrorHandling.mkLogAndRaise(Logging.getItemLogger(item), errorMessage, exn);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
if (Utils.$$Array.notEmpty(promises)) {
|
|
250
|
+
await Promise.all(promises);
|
|
251
|
+
}
|
|
252
|
+
return itemsWithDcs;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function handleQueryResult(chainFetcher, query, newItems, newItemsWithDcs, latestFetchedBlock, knownHeight) {
|
|
256
|
+
var fs = newItemsWithDcs.length !== 0 ? FetchState.registerDynamicContracts(chainFetcher.fetchState, newItemsWithDcs) : chainFetcher.fetchState;
|
|
257
|
+
return {
|
|
258
|
+
logger: chainFetcher.logger,
|
|
259
|
+
fetchState: FetchState.updateKnownHeight(FetchState.handleQueryResult(fs, query, latestFetchedBlock, newItems), knownHeight),
|
|
260
|
+
sourceManager: chainFetcher.sourceManager,
|
|
261
|
+
chainConfig: chainFetcher.chainConfig,
|
|
262
|
+
isProgressAtHead: chainFetcher.isProgressAtHead,
|
|
263
|
+
timestampCaughtUpToHeadOrEndblock: chainFetcher.timestampCaughtUpToHeadOrEndblock,
|
|
264
|
+
committedProgressBlockNumber: chainFetcher.committedProgressBlockNumber,
|
|
265
|
+
numEventsProcessed: chainFetcher.numEventsProcessed,
|
|
266
|
+
reorgDetection: chainFetcher.reorgDetection,
|
|
267
|
+
safeCheckpointTracking: chainFetcher.safeCheckpointTracking
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function hasProcessedToEndblock(self) {
|
|
272
|
+
var endBlock = self.fetchState.endBlock;
|
|
273
|
+
if (endBlock !== undefined) {
|
|
274
|
+
return self.committedProgressBlockNumber >= endBlock;
|
|
275
|
+
} else {
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function hasNoMoreEventsToProcess(self) {
|
|
281
|
+
return FetchState.bufferSize(self.fetchState) === 0;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function getHighestBlockBelowThreshold(cf) {
|
|
285
|
+
var highestBlockBelowThreshold = cf.fetchState.knownHeight - cf.chainConfig.maxReorgDepth | 0;
|
|
286
|
+
if (highestBlockBelowThreshold < 0) {
|
|
287
|
+
return 0;
|
|
288
|
+
} else {
|
|
289
|
+
return highestBlockBelowThreshold;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
async function getLastKnownValidBlock(chainFetcher, reorgBlockNumber, getBlockHashesOpt) {
|
|
294
|
+
var getBlockHashes = getBlockHashesOpt !== undefined ? getBlockHashesOpt : SourceManager.getActiveSource(chainFetcher.sourceManager).getBlockHashes;
|
|
295
|
+
var scannedBlockNumbers = ReorgDetection.getThresholdBlockNumbersBelowBlock(chainFetcher.reorgDetection, reorgBlockNumber, chainFetcher.fetchState.knownHeight);
|
|
296
|
+
var getBlockHashes$1 = function (blockNumbers) {
|
|
297
|
+
return getBlockHashes(blockNumbers, chainFetcher.logger).then(function (res) {
|
|
298
|
+
if (res.TAG === "Ok") {
|
|
299
|
+
return res._0;
|
|
300
|
+
} else {
|
|
301
|
+
return ErrorHandling.mkLogAndRaise(undefined, "Failed to fetch blockHashes for given blockNumbers during rollback", res._0);
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
};
|
|
305
|
+
if (scannedBlockNumbers.length === 0) {
|
|
306
|
+
return getHighestBlockBelowThreshold(chainFetcher);
|
|
307
|
+
}
|
|
308
|
+
var blockNumbersAndHashes = await getBlockHashes$1(scannedBlockNumbers);
|
|
309
|
+
var blockNumber = ReorgDetection.getLatestValidScannedBlock(chainFetcher.reorgDetection, blockNumbersAndHashes);
|
|
310
|
+
if (blockNumber !== undefined) {
|
|
311
|
+
return blockNumber;
|
|
312
|
+
} else {
|
|
313
|
+
return getHighestBlockBelowThreshold(chainFetcher);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function isActivelyIndexing(chainFetcher) {
|
|
318
|
+
return FetchState.isActivelyIndexing(chainFetcher.fetchState);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function isReady(chainFetcher) {
|
|
322
|
+
return chainFetcher.timestampCaughtUpToHeadOrEndblock !== undefined;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
export {
|
|
326
|
+
make ,
|
|
327
|
+
makeFromConfig ,
|
|
328
|
+
makeFromDbState ,
|
|
329
|
+
getContractStartBlock ,
|
|
330
|
+
runContractRegistersOrThrow ,
|
|
331
|
+
handleQueryResult ,
|
|
332
|
+
hasProcessedToEndblock ,
|
|
333
|
+
hasNoMoreEventsToProcess ,
|
|
334
|
+
getHighestBlockBelowThreshold ,
|
|
335
|
+
getLastKnownValidBlock ,
|
|
336
|
+
isActivelyIndexing ,
|
|
337
|
+
isReady ,
|
|
338
|
+
}
|
|
339
|
+
/* Env Not a pure module */
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
open Belt
|
|
2
|
+
|
|
3
|
+
type t = {
|
|
4
|
+
committedCheckpointId: bigint,
|
|
5
|
+
chainFetchers: ChainMap.t<ChainFetcher.t>,
|
|
6
|
+
multichain: Config.multichain,
|
|
7
|
+
isInReorgThreshold: bool,
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Check if progress is past the reorg threshold (safe block).
|
|
11
|
+
// A chain is in reorg threshold when progressBlockNumber > sourceBlockNumber - maxReorgDepth.
|
|
12
|
+
// This matches the logic in InternalTable.Checkpoints.makeGetReorgCheckpointsQuery.
|
|
13
|
+
let isProgressInReorgThreshold = (~progressBlockNumber, ~sourceBlockNumber, ~maxReorgDepth) => {
|
|
14
|
+
maxReorgDepth > 0 &&
|
|
15
|
+
sourceBlockNumber > 0 &&
|
|
16
|
+
progressBlockNumber > sourceBlockNumber - maxReorgDepth
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let calculateTargetBufferSize = (~activeChainsCount) => {
|
|
20
|
+
switch Env.targetBufferSize {
|
|
21
|
+
| Some(size) => size
|
|
22
|
+
| None =>
|
|
23
|
+
switch activeChainsCount {
|
|
24
|
+
| 1 => 60_000
|
|
25
|
+
| 2 => 30_000
|
|
26
|
+
| 3 => 20_000
|
|
27
|
+
| 4 => 15_000
|
|
28
|
+
| 5 => 10_000
|
|
29
|
+
| _ => 5_000
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let makeFromDbState = async (
|
|
35
|
+
~initialState: Persistence.initialState,
|
|
36
|
+
~config: Config.t,
|
|
37
|
+
~registrations,
|
|
38
|
+
): t => {
|
|
39
|
+
let isInReorgThreshold = if initialState.cleanRun {
|
|
40
|
+
false
|
|
41
|
+
} else {
|
|
42
|
+
// Check if any chain is in reorg threshold by comparing progress with sourceBlock - maxReorgDepth.
|
|
43
|
+
initialState.chains->Array.some(chain =>
|
|
44
|
+
isProgressInReorgThreshold(
|
|
45
|
+
~progressBlockNumber=chain.progressBlockNumber,
|
|
46
|
+
~sourceBlockNumber=chain.sourceBlockNumber,
|
|
47
|
+
~maxReorgDepth=chain.maxReorgDepth,
|
|
48
|
+
)
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
let targetBufferSize = calculateTargetBufferSize(
|
|
53
|
+
~activeChainsCount=initialState.chains->Array.length,
|
|
54
|
+
)
|
|
55
|
+
Prometheus.ProcessingMaxBatchSize.set(~maxBatchSize=config.batchSize)
|
|
56
|
+
Prometheus.IndexingTargetBufferSize.set(~targetBufferSize)
|
|
57
|
+
Prometheus.ReorgThreshold.set(~isInReorgThreshold)
|
|
58
|
+
initialState.cache->Utils.Dict.forEach(({effectName, count}) => {
|
|
59
|
+
Prometheus.EffectCacheCount.set(~count, ~effectName)
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
let chainFetchersArr =
|
|
63
|
+
await initialState.chains
|
|
64
|
+
->Array.map(async (resumedChainState: Persistence.initialChainState) => {
|
|
65
|
+
let chain = Config.getChain(config, ~chainId=resumedChainState.id)
|
|
66
|
+
let chainConfig = config.chainMap->ChainMap.get(chain)
|
|
67
|
+
|
|
68
|
+
(
|
|
69
|
+
chain,
|
|
70
|
+
await chainConfig->ChainFetcher.makeFromDbState(
|
|
71
|
+
~resumedChainState,
|
|
72
|
+
~reorgCheckpoints=initialState.reorgCheckpoints,
|
|
73
|
+
~isInReorgThreshold,
|
|
74
|
+
~targetBufferSize,
|
|
75
|
+
~config,
|
|
76
|
+
~registrations,
|
|
77
|
+
),
|
|
78
|
+
)
|
|
79
|
+
})
|
|
80
|
+
->Promise.all
|
|
81
|
+
|
|
82
|
+
let chainFetchers = ChainMap.fromArrayUnsafe(chainFetchersArr)
|
|
83
|
+
|
|
84
|
+
// Set initial progress metrics from DB state so dashboards reflect
|
|
85
|
+
// the persisted state immediately on restart
|
|
86
|
+
let allChainsReady = ref(chainFetchersArr->Array.length > 0)
|
|
87
|
+
chainFetchersArr->Array.forEach(((chain, cf)) => {
|
|
88
|
+
let chainId = chain->ChainMap.Chain.toChainId
|
|
89
|
+
Prometheus.ProgressBlockNumber.set(~blockNumber=cf.committedProgressBlockNumber, ~chainId)
|
|
90
|
+
Prometheus.ProgressReady.init(~chainId)
|
|
91
|
+
if cf->ChainFetcher.isReady {
|
|
92
|
+
Prometheus.ProgressReady.set(~chainId)
|
|
93
|
+
} else {
|
|
94
|
+
allChainsReady := false
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
if allChainsReady.contents {
|
|
98
|
+
Prometheus.ProgressReady.setAllReady()
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
{
|
|
102
|
+
committedCheckpointId: initialState.checkpointId,
|
|
103
|
+
multichain: config.multichain,
|
|
104
|
+
chainFetchers,
|
|
105
|
+
isInReorgThreshold,
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
let getChainFetcher = (chainManager: t, ~chain: ChainMap.Chain.t): ChainFetcher.t => {
|
|
110
|
+
chainManager.chainFetchers->ChainMap.get(chain)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
let setChainFetcher = (chainManager: t, chainFetcher: ChainFetcher.t) => {
|
|
114
|
+
{
|
|
115
|
+
...chainManager,
|
|
116
|
+
chainFetchers: chainManager.chainFetchers->ChainMap.set(
|
|
117
|
+
ChainMap.Chain.makeUnsafe(~chainId=chainFetcher.chainConfig.id),
|
|
118
|
+
chainFetcher,
|
|
119
|
+
),
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
let nextItemIsNone = (chainManager: t): bool => {
|
|
124
|
+
!Batch.hasMultichainReadyItem(
|
|
125
|
+
chainManager.chainFetchers->ChainMap.map(cf => {
|
|
126
|
+
cf.fetchState
|
|
127
|
+
}),
|
|
128
|
+
~multichain=chainManager.multichain,
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
let createBatch = (chainManager: t, ~batchSizeTarget: int, ~isRollback: bool): Batch.t => {
|
|
133
|
+
Batch.make(
|
|
134
|
+
~checkpointIdBeforeBatch=chainManager.committedCheckpointId->BigInt.add(
|
|
135
|
+
// Since for rollback we have a diff checkpoint id.
|
|
136
|
+
// This is needed to currectly overwrite old state
|
|
137
|
+
// in an append-only ClickHouse insert.
|
|
138
|
+
isRollback ? 1n : 0n
|
|
139
|
+
),
|
|
140
|
+
~chainsBeforeBatch=chainManager.chainFetchers->ChainMap.map((cf): Batch.chainBeforeBatch => {
|
|
141
|
+
fetchState: cf.fetchState,
|
|
142
|
+
progressBlockNumber: cf.committedProgressBlockNumber,
|
|
143
|
+
totalEventsProcessed: cf.numEventsProcessed,
|
|
144
|
+
sourceBlockNumber: cf.fetchState.knownHeight,
|
|
145
|
+
reorgDetection: cf.reorgDetection,
|
|
146
|
+
chainConfig: cf.chainConfig,
|
|
147
|
+
}),
|
|
148
|
+
~multichain=chainManager.multichain,
|
|
149
|
+
~batchSizeTarget,
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
let isProgressAtHead = chainManager =>
|
|
154
|
+
chainManager.chainFetchers
|
|
155
|
+
->ChainMap.values
|
|
156
|
+
->Js.Array2.every(cf => cf.isProgressAtHead)
|
|
157
|
+
|
|
158
|
+
let isActivelyIndexing = chainManager =>
|
|
159
|
+
chainManager.chainFetchers
|
|
160
|
+
->ChainMap.values
|
|
161
|
+
->Js.Array2.every(ChainFetcher.isActivelyIndexing)
|
|
162
|
+
|
|
163
|
+
let getSafeCheckpointId = (chainManager: t) => {
|
|
164
|
+
let chainFetchers = chainManager.chainFetchers->ChainMap.values
|
|
165
|
+
|
|
166
|
+
let result: ref<option<bigint>> = ref(None)
|
|
167
|
+
|
|
168
|
+
for idx in 0 to chainFetchers->Array.length - 1 {
|
|
169
|
+
let chainFetcher = chainFetchers->Array.getUnsafe(idx)
|
|
170
|
+
switch chainFetcher.safeCheckpointTracking {
|
|
171
|
+
| None => () // Skip chains with maxReorgDepth = 0
|
|
172
|
+
| Some(safeCheckpointTracking) => {
|
|
173
|
+
let safeCheckpointId =
|
|
174
|
+
safeCheckpointTracking->SafeCheckpointTracking.getSafeCheckpointId(
|
|
175
|
+
~sourceBlockNumber=chainFetcher.fetchState.knownHeight,
|
|
176
|
+
)
|
|
177
|
+
switch result.contents {
|
|
178
|
+
| None => result := Some(safeCheckpointId)
|
|
179
|
+
| Some(current) if safeCheckpointId < current => result := Some(safeCheckpointId)
|
|
180
|
+
| _ => ()
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
switch result.contents {
|
|
187
|
+
| Some(id) if id > 0n => Some(id)
|
|
188
|
+
| _ => None // No safe checkpoint found
|
|
189
|
+
}
|
|
190
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Env from "./Env.res.mjs";
|
|
4
|
+
import * as Batch from "./Batch.res.mjs";
|
|
5
|
+
import * as Utils from "./Utils.res.mjs";
|
|
6
|
+
import * as $$BigInt from "./bindings/BigInt.res.mjs";
|
|
7
|
+
import * as Config from "./Config.res.mjs";
|
|
8
|
+
import * as ChainMap from "./ChainMap.res.mjs";
|
|
9
|
+
import * as Belt_Array from "rescript/lib/es6/belt_Array.js";
|
|
10
|
+
import * as Prometheus from "./Prometheus.res.mjs";
|
|
11
|
+
import * as ChainFetcher from "./ChainFetcher.res.mjs";
|
|
12
|
+
import * as SafeCheckpointTracking from "./SafeCheckpointTracking.res.mjs";
|
|
13
|
+
|
|
14
|
+
function isProgressInReorgThreshold(progressBlockNumber, sourceBlockNumber, maxReorgDepth) {
|
|
15
|
+
if (maxReorgDepth > 0 && sourceBlockNumber > 0) {
|
|
16
|
+
return progressBlockNumber > (sourceBlockNumber - maxReorgDepth | 0);
|
|
17
|
+
} else {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function calculateTargetBufferSize(activeChainsCount) {
|
|
23
|
+
if (Env.targetBufferSize !== undefined) {
|
|
24
|
+
return Env.targetBufferSize;
|
|
25
|
+
}
|
|
26
|
+
switch (activeChainsCount) {
|
|
27
|
+
case 1 :
|
|
28
|
+
return 60000;
|
|
29
|
+
case 2 :
|
|
30
|
+
return 30000;
|
|
31
|
+
case 3 :
|
|
32
|
+
return 20000;
|
|
33
|
+
case 4 :
|
|
34
|
+
return 15000;
|
|
35
|
+
case 5 :
|
|
36
|
+
return 10000;
|
|
37
|
+
default:
|
|
38
|
+
return 5000;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function makeFromDbState(initialState, config, registrations) {
|
|
43
|
+
var isInReorgThreshold = initialState.cleanRun ? false : Belt_Array.some(initialState.chains, (function (chain) {
|
|
44
|
+
return isProgressInReorgThreshold(chain.progressBlockNumber, chain.sourceBlockNumber, chain.maxReorgDepth);
|
|
45
|
+
}));
|
|
46
|
+
var targetBufferSize = calculateTargetBufferSize(initialState.chains.length);
|
|
47
|
+
Prometheus.ProcessingMaxBatchSize.set(config.batchSize);
|
|
48
|
+
Prometheus.IndexingTargetBufferSize.set(targetBufferSize);
|
|
49
|
+
Prometheus.ReorgThreshold.set(isInReorgThreshold);
|
|
50
|
+
Utils.Dict.forEach(initialState.cache, (function (param) {
|
|
51
|
+
var count = param.count;
|
|
52
|
+
Prometheus.EffectCacheCount.set(count, param.effectName);
|
|
53
|
+
}));
|
|
54
|
+
var chainFetchersArr = await Promise.all(Belt_Array.map(initialState.chains, (async function (resumedChainState) {
|
|
55
|
+
var chain = Config.getChain(config, resumedChainState.id);
|
|
56
|
+
var chainConfig = ChainMap.get(config.chainMap, chain);
|
|
57
|
+
return [
|
|
58
|
+
chain,
|
|
59
|
+
await ChainFetcher.makeFromDbState(chainConfig, resumedChainState, initialState.reorgCheckpoints, isInReorgThreshold, config, registrations, targetBufferSize)
|
|
60
|
+
];
|
|
61
|
+
})));
|
|
62
|
+
var chainFetchers = ChainMap.fromArrayUnsafe(chainFetchersArr);
|
|
63
|
+
var allChainsReady = {
|
|
64
|
+
contents: chainFetchersArr.length !== 0
|
|
65
|
+
};
|
|
66
|
+
Belt_Array.forEach(chainFetchersArr, (function (param) {
|
|
67
|
+
var cf = param[1];
|
|
68
|
+
var chain = param[0];
|
|
69
|
+
Prometheus.ProgressBlockNumber.set(cf.committedProgressBlockNumber, chain);
|
|
70
|
+
Prometheus.ProgressReady.init(chain);
|
|
71
|
+
if (ChainFetcher.isReady(cf)) {
|
|
72
|
+
return Prometheus.ProgressReady.set(chain);
|
|
73
|
+
} else {
|
|
74
|
+
allChainsReady.contents = false;
|
|
75
|
+
return ;
|
|
76
|
+
}
|
|
77
|
+
}));
|
|
78
|
+
if (allChainsReady.contents) {
|
|
79
|
+
Prometheus.ProgressReady.setAllReady();
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
committedCheckpointId: initialState.checkpointId,
|
|
83
|
+
chainFetchers: chainFetchers,
|
|
84
|
+
multichain: config.multichain,
|
|
85
|
+
isInReorgThreshold: isInReorgThreshold
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function getChainFetcher(chainManager, chain) {
|
|
90
|
+
return ChainMap.get(chainManager.chainFetchers, chain);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function setChainFetcher(chainManager, chainFetcher) {
|
|
94
|
+
return {
|
|
95
|
+
committedCheckpointId: chainManager.committedCheckpointId,
|
|
96
|
+
chainFetchers: ChainMap.set(chainManager.chainFetchers, ChainMap.Chain.makeUnsafe(chainFetcher.chainConfig.id), chainFetcher),
|
|
97
|
+
multichain: chainManager.multichain,
|
|
98
|
+
isInReorgThreshold: chainManager.isInReorgThreshold
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function nextItemIsNone(chainManager) {
|
|
103
|
+
return !Batch.hasMultichainReadyItem(ChainMap.map(chainManager.chainFetchers, (function (cf) {
|
|
104
|
+
return cf.fetchState;
|
|
105
|
+
})), chainManager.multichain);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function createBatch(chainManager, batchSizeTarget, isRollback) {
|
|
109
|
+
return Batch.make($$BigInt.add(chainManager.committedCheckpointId, isRollback ? 1n : 0n), ChainMap.map(chainManager.chainFetchers, (function (cf) {
|
|
110
|
+
return {
|
|
111
|
+
fetchState: cf.fetchState,
|
|
112
|
+
reorgDetection: cf.reorgDetection,
|
|
113
|
+
progressBlockNumber: cf.committedProgressBlockNumber,
|
|
114
|
+
sourceBlockNumber: cf.fetchState.knownHeight,
|
|
115
|
+
totalEventsProcessed: cf.numEventsProcessed,
|
|
116
|
+
chainConfig: cf.chainConfig
|
|
117
|
+
};
|
|
118
|
+
})), chainManager.multichain, batchSizeTarget);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function isProgressAtHead(chainManager) {
|
|
122
|
+
return ChainMap.values(chainManager.chainFetchers).every(function (cf) {
|
|
123
|
+
return cf.isProgressAtHead;
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function isActivelyIndexing(chainManager) {
|
|
128
|
+
return ChainMap.values(chainManager.chainFetchers).every(ChainFetcher.isActivelyIndexing);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function getSafeCheckpointId(chainManager) {
|
|
132
|
+
var chainFetchers = ChainMap.values(chainManager.chainFetchers);
|
|
133
|
+
var result;
|
|
134
|
+
for(var idx = 0 ,idx_finish = chainFetchers.length; idx < idx_finish; ++idx){
|
|
135
|
+
var chainFetcher = chainFetchers[idx];
|
|
136
|
+
var safeCheckpointTracking = chainFetcher.safeCheckpointTracking;
|
|
137
|
+
if (safeCheckpointTracking !== undefined) {
|
|
138
|
+
var safeCheckpointId = SafeCheckpointTracking.getSafeCheckpointId(safeCheckpointTracking, chainFetcher.fetchState.knownHeight);
|
|
139
|
+
var current = result;
|
|
140
|
+
if (!(current !== undefined && safeCheckpointId >= current)) {
|
|
141
|
+
result = safeCheckpointId;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
}
|
|
147
|
+
var id = result;
|
|
148
|
+
if (id !== undefined && id > 0n) {
|
|
149
|
+
return id;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export {
|
|
155
|
+
isProgressInReorgThreshold ,
|
|
156
|
+
calculateTargetBufferSize ,
|
|
157
|
+
makeFromDbState ,
|
|
158
|
+
getChainFetcher ,
|
|
159
|
+
setChainFetcher ,
|
|
160
|
+
nextItemIsNone ,
|
|
161
|
+
createBatch ,
|
|
162
|
+
isProgressAtHead ,
|
|
163
|
+
isActivelyIndexing ,
|
|
164
|
+
getSafeCheckpointId ,
|
|
165
|
+
}
|
|
166
|
+
/* Env Not a pure module */
|