envio 2.31.0-alpha.0 → 2.31.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/Batch.res +400 -28
- package/src/Batch.res.js +286 -24
- package/src/EventRegister.res +9 -3
- package/src/EventRegister.res.js +6 -3
- package/src/EventRegister.resi +4 -1
- package/src/FetchState.res +116 -155
- package/src/FetchState.res.js +116 -106
- package/src/Internal.res +49 -0
- package/src/InternalConfig.res +1 -1
- package/src/Persistence.res +16 -1
- package/src/Persistence.res.js +1 -1
- package/src/PgStorage.res +49 -61
- package/src/PgStorage.res.js +44 -37
- package/src/Prometheus.res +7 -1
- package/src/Prometheus.res.js +8 -1
- package/src/ReorgDetection.res +222 -235
- package/src/ReorgDetection.res.js +34 -28
- package/src/SafeCheckpointTracking.res +132 -0
- package/src/SafeCheckpointTracking.res.js +95 -0
- package/src/Utils.res +64 -21
- package/src/Utils.res.js +61 -30
- package/src/db/EntityHistory.res +172 -294
- package/src/db/EntityHistory.res.js +98 -218
- package/src/db/InternalTable.gen.ts +13 -13
- package/src/db/InternalTable.res +286 -77
- package/src/db/InternalTable.res.js +160 -79
- package/src/db/Table.res +1 -0
- package/src/db/Table.res.js +1 -1
- package/src/sources/EventRouter.res +1 -1
- package/src/sources/Source.res +1 -1
package/src/FetchState.res.js
CHANGED
|
@@ -8,7 +8,6 @@ var Js_dict = require("rescript/lib/js/js_dict.js");
|
|
|
8
8
|
var Js_math = require("rescript/lib/js/js_math.js");
|
|
9
9
|
var Logging = require("./Logging.res.js");
|
|
10
10
|
var Belt_Int = require("rescript/lib/js/belt_Int.js");
|
|
11
|
-
var Caml_obj = require("rescript/lib/js/caml_obj.js");
|
|
12
11
|
var Belt_Array = require("rescript/lib/js/belt_Array.js");
|
|
13
12
|
var Caml_int32 = require("rescript/lib/js/caml_int32.js");
|
|
14
13
|
var Prometheus = require("./Prometheus.res.js");
|
|
@@ -34,11 +33,11 @@ function mergeIntoPartition(p, target, maxAddrInPartition) {
|
|
|
34
33
|
var allowedAddressesNumber = {
|
|
35
34
|
contents: maxAddrInPartition
|
|
36
35
|
};
|
|
37
|
-
Utils.Dict.forEachWithKey(target.addressesByContractName, (function (
|
|
36
|
+
Utils.Dict.forEachWithKey(target.addressesByContractName, (function (addresses, contractName) {
|
|
38
37
|
allowedAddressesNumber.contents = allowedAddressesNumber.contents - addresses.length | 0;
|
|
39
38
|
mergedAddresses[contractName] = addresses;
|
|
40
39
|
}));
|
|
41
|
-
Utils.Dict.forEachWithKey(p.addressesByContractName, (function (
|
|
40
|
+
Utils.Dict.forEachWithKey(p.addressesByContractName, (function (addresses, contractName) {
|
|
42
41
|
allowedAddressesNumber.contents = allowedAddressesNumber.contents - addresses.length | 0;
|
|
43
42
|
var targetAddresses = mergedAddresses[contractName];
|
|
44
43
|
if (targetAddresses !== undefined) {
|
|
@@ -50,7 +49,7 @@ function mergeIntoPartition(p, target, maxAddrInPartition) {
|
|
|
50
49
|
var rest;
|
|
51
50
|
if (allowedAddressesNumber.contents < 0) {
|
|
52
51
|
var restAddresses = {};
|
|
53
|
-
Utils.Dict.forEachWithKey(mergedAddresses, (function (
|
|
52
|
+
Utils.Dict.forEachWithKey(mergedAddresses, (function (addresses, contractName) {
|
|
54
53
|
if (allowedAddressesNumber.contents === 0) {
|
|
55
54
|
return ;
|
|
56
55
|
}
|
|
@@ -123,11 +122,10 @@ function compareBufferItem(a, b) {
|
|
|
123
122
|
}
|
|
124
123
|
}
|
|
125
124
|
|
|
126
|
-
function updateInternal(fetchState, partitionsOpt, nextPartitionIndexOpt, indexingContractsOpt,
|
|
125
|
+
function updateInternal(fetchState, partitionsOpt, nextPartitionIndexOpt, indexingContractsOpt, mutItems, blockLagOpt) {
|
|
127
126
|
var partitions = partitionsOpt !== undefined ? partitionsOpt : fetchState.partitions;
|
|
128
127
|
var nextPartitionIndex = nextPartitionIndexOpt !== undefined ? nextPartitionIndexOpt : fetchState.nextPartitionIndex;
|
|
129
128
|
var indexingContracts = indexingContractsOpt !== undefined ? indexingContractsOpt : fetchState.indexingContracts;
|
|
130
|
-
var dcsToStore = dcsToStoreOpt !== undefined ? dcsToStoreOpt : fetchState.dcsToStore;
|
|
131
129
|
var blockLag = blockLagOpt !== undefined ? blockLagOpt : fetchState.blockLag;
|
|
132
130
|
var firstPartition = partitions[0];
|
|
133
131
|
var latestFullyFetchedBlock = firstPartition.latestFetchedBlock;
|
|
@@ -198,7 +196,6 @@ function updateInternal(fetchState, partitionsOpt, nextPartitionIndexOpt, indexi
|
|
|
198
196
|
normalSelection: updatedFetchState_normalSelection,
|
|
199
197
|
indexingContracts: indexingContracts,
|
|
200
198
|
contractConfigs: updatedFetchState_contractConfigs,
|
|
201
|
-
dcsToStore: dcsToStore,
|
|
202
199
|
chainId: updatedFetchState_chainId,
|
|
203
200
|
latestFullyFetchedBlock: latestFullyFetchedBlock$1,
|
|
204
201
|
latestOnBlockBlockNumber: latestOnBlockBlockNumber,
|
|
@@ -227,7 +224,7 @@ function warnDifferentContractType(fetchState, existingContract, dc) {
|
|
|
227
224
|
Logging.childWarn(logger, "Skipping contract registration: Contract address is already registered for one contract and cannot be registered for another contract.");
|
|
228
225
|
}
|
|
229
226
|
|
|
230
|
-
function registerDynamicContracts(fetchState,
|
|
227
|
+
function registerDynamicContracts(fetchState, items) {
|
|
231
228
|
if (Utils.$$Array.isEmpty(fetchState.normalSelection.eventConfigs)) {
|
|
232
229
|
Js_exn.raiseError("Invalid configuration. No events to fetch for the dynamic contract registration.");
|
|
233
230
|
}
|
|
@@ -236,55 +233,62 @@ function registerDynamicContracts(fetchState, dynamicContracts) {
|
|
|
236
233
|
var addressesByContractName = {};
|
|
237
234
|
var earliestRegisteringEventBlockNumber = Infinity;
|
|
238
235
|
var hasDCWithFilterByAddresses = false;
|
|
239
|
-
for(var
|
|
240
|
-
var
|
|
241
|
-
var
|
|
242
|
-
if (
|
|
243
|
-
var
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
if (registeringContract.contractName !== dc.contractName) {
|
|
262
|
-
warnDifferentContractType(fetchState, registeringContract, dc);
|
|
263
|
-
shouldUpdate = false;
|
|
236
|
+
for(var itemIdx = 0 ,itemIdx_finish = items.length; itemIdx < itemIdx_finish; ++itemIdx){
|
|
237
|
+
var item = items[itemIdx];
|
|
238
|
+
var dcs = item.dcs;
|
|
239
|
+
if (dcs !== undefined) {
|
|
240
|
+
for(var idx = 0 ,idx_finish = dcs.length; idx < idx_finish; ++idx){
|
|
241
|
+
var dc = dcs[idx];
|
|
242
|
+
var match = fetchState.contractConfigs[dc.contractName];
|
|
243
|
+
if (match !== undefined) {
|
|
244
|
+
var existingContract = indexingContracts[dc.address];
|
|
245
|
+
if (existingContract !== undefined) {
|
|
246
|
+
if (existingContract.contractName !== dc.contractName) {
|
|
247
|
+
warnDifferentContractType(fetchState, existingContract, dc);
|
|
248
|
+
} else if (existingContract.startBlock > dc.startBlock) {
|
|
249
|
+
var logger = Logging.createChild({
|
|
250
|
+
chainId: fetchState.chainId,
|
|
251
|
+
contractAddress: dc.address,
|
|
252
|
+
existingBlockNumber: existingContract.startBlock,
|
|
253
|
+
newBlockNumber: dc.startBlock
|
|
254
|
+
});
|
|
255
|
+
Logging.childWarn(logger, "Skipping contract registration: Contract address is already registered at a later block number. Currently registration of the same contract address is not supported by Envio. Reach out to us if it's a problem for you.");
|
|
256
|
+
}
|
|
257
|
+
dcs.splice(idx, 1);
|
|
264
258
|
} else {
|
|
265
|
-
var
|
|
266
|
-
var
|
|
267
|
-
|
|
259
|
+
var registeringContract = registeringContracts[dc.address];
|
|
260
|
+
var shouldUpdate;
|
|
261
|
+
if (registeringContract !== undefined) {
|
|
262
|
+
if (registeringContract.contractName !== dc.contractName) {
|
|
263
|
+
warnDifferentContractType(fetchState, registeringContract, dc);
|
|
264
|
+
shouldUpdate = false;
|
|
265
|
+
} else {
|
|
266
|
+
shouldUpdate = false;
|
|
267
|
+
}
|
|
268
|
+
} else {
|
|
269
|
+
hasDCWithFilterByAddresses = hasDCWithFilterByAddresses || match.filterByAddresses;
|
|
270
|
+
Utils.Dict.push(addressesByContractName, dc.contractName, dc.address);
|
|
271
|
+
shouldUpdate = true;
|
|
272
|
+
}
|
|
273
|
+
if (shouldUpdate) {
|
|
274
|
+
earliestRegisteringEventBlockNumber = earliestRegisteringEventBlockNumber < dc.startBlock ? earliestRegisteringEventBlockNumber : dc.startBlock;
|
|
275
|
+
registeringContracts[dc.address] = dc;
|
|
276
|
+
} else {
|
|
277
|
+
dcs.splice(idx, 1);
|
|
278
|
+
}
|
|
268
279
|
}
|
|
269
280
|
} else {
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
281
|
+
var logger$1 = Logging.createChild({
|
|
282
|
+
chainId: fetchState.chainId,
|
|
283
|
+
contractAddress: dc.address,
|
|
284
|
+
contractName: dc.contractName
|
|
285
|
+
});
|
|
286
|
+
Logging.childWarn(logger$1, "Skipping contract registration: Contract doesn't have any events to fetch.");
|
|
287
|
+
dcs.splice(idx, 1);
|
|
277
288
|
}
|
|
278
|
-
|
|
279
289
|
}
|
|
280
|
-
} else {
|
|
281
|
-
var logger$1 = Logging.createChild({
|
|
282
|
-
chainId: fetchState.chainId,
|
|
283
|
-
contractAddress: dc.address,
|
|
284
|
-
contractName: dc.contractName
|
|
285
|
-
});
|
|
286
|
-
Logging.childWarn(logger$1, "Skipping contract registration: Contract doesn't have any events to fetch.");
|
|
287
290
|
}
|
|
291
|
+
|
|
288
292
|
}
|
|
289
293
|
var dcsToStore = Js_dict.values(registeringContracts);
|
|
290
294
|
if (dcsToStore.length === 0) {
|
|
@@ -379,8 +383,7 @@ function registerDynamicContracts(fetchState, dynamicContracts) {
|
|
|
379
383
|
newPartitions = partitions;
|
|
380
384
|
}
|
|
381
385
|
Prometheus.IndexingAddresses.set(Object.keys(fetchState.indexingContracts).length + dcsToStore.length | 0, fetchState.chainId);
|
|
382
|
-
|
|
383
|
-
return updateInternal(fetchState, fetchState.partitions.concat(newPartitions), fetchState.nextPartitionIndex + newPartitions.length | 0, Object.assign(registeringContracts, indexingContracts), existingDcs.length !== 0 ? Belt_Array.concat(existingDcs, dcsToStore) : dcsToStore, undefined, undefined);
|
|
386
|
+
return updateInternal(fetchState, fetchState.partitions.concat(newPartitions), fetchState.nextPartitionIndex + newPartitions.length | 0, Object.assign(registeringContracts, indexingContracts), undefined, undefined);
|
|
384
387
|
}
|
|
385
388
|
|
|
386
389
|
var UnexpectedPartitionNotFound = /* @__PURE__ */Caml_exceptions.create("FetchState.UnexpectedPartitionNotFound");
|
|
@@ -457,7 +460,7 @@ function handleQueryResult(fetchState, query, latestFetchedBlock, newItems) {
|
|
|
457
460
|
};
|
|
458
461
|
}
|
|
459
462
|
return Belt_Result.map(tmp, (function (partitions) {
|
|
460
|
-
return updateInternal(fetchState, partitions, undefined, undefined,
|
|
463
|
+
return updateInternal(fetchState, partitions, undefined, undefined, newItems.length !== 0 ? Belt_Array.concat(fetchState.buffer, newItems) : undefined, undefined);
|
|
461
464
|
}));
|
|
462
465
|
}
|
|
463
466
|
|
|
@@ -835,7 +838,6 @@ function make(startBlock, endBlock, eventConfigs, contracts, maxAddrInPartition,
|
|
|
835
838
|
normalSelection: normalSelection,
|
|
836
839
|
indexingContracts: indexingContracts,
|
|
837
840
|
contractConfigs: contractConfigs,
|
|
838
|
-
dcsToStore: [],
|
|
839
841
|
chainId: chainId,
|
|
840
842
|
latestFullyFetchedBlock: latestFetchedBlock,
|
|
841
843
|
latestOnBlockBlockNumber: progressBlockNumber,
|
|
@@ -850,27 +852,10 @@ function bufferSize(param) {
|
|
|
850
852
|
return param.buffer.length;
|
|
851
853
|
}
|
|
852
854
|
|
|
853
|
-
function
|
|
854
|
-
|
|
855
|
-
var tmp;
|
|
856
|
-
tmp = item.kind === 0 ? [
|
|
857
|
-
item.blockNumber,
|
|
858
|
-
item.logIndex
|
|
859
|
-
] : [
|
|
860
|
-
item.blockNumber,
|
|
861
|
-
item.logIndex
|
|
862
|
-
];
|
|
863
|
-
return Caml_obj.lessthan(tmp, [
|
|
864
|
-
firstChangeEvent.blockNumber,
|
|
865
|
-
firstChangeEvent.logIndex
|
|
866
|
-
]);
|
|
867
|
-
}));
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
function rollbackPartition(p, firstChangeEvent, addressesToRemove) {
|
|
871
|
-
var shouldRollbackFetched = p.latestFetchedBlock.blockNumber >= firstChangeEvent.blockNumber;
|
|
855
|
+
function rollbackPartition(p, targetBlockNumber, addressesToRemove) {
|
|
856
|
+
var shouldRollbackFetched = p.latestFetchedBlock.blockNumber > targetBlockNumber;
|
|
872
857
|
var latestFetchedBlock = shouldRollbackFetched ? ({
|
|
873
|
-
blockNumber:
|
|
858
|
+
blockNumber: targetBlockNumber,
|
|
874
859
|
blockTimestamp: 0
|
|
875
860
|
}) : p.latestFetchedBlock;
|
|
876
861
|
if (!p.selection.dependsOnAddresses) {
|
|
@@ -885,7 +870,7 @@ function rollbackPartition(p, firstChangeEvent, addressesToRemove) {
|
|
|
885
870
|
};
|
|
886
871
|
}
|
|
887
872
|
var rollbackedAddressesByContractName = {};
|
|
888
|
-
Utils.Dict.forEachWithKey(p.addressesByContractName, (function (
|
|
873
|
+
Utils.Dict.forEachWithKey(p.addressesByContractName, (function (addresses, contractName) {
|
|
889
874
|
var keptAddresses = Belt_Array.keep(addresses, (function (address) {
|
|
890
875
|
return !addressesToRemove.has(address);
|
|
891
876
|
}));
|
|
@@ -910,24 +895,21 @@ function rollbackPartition(p, firstChangeEvent, addressesToRemove) {
|
|
|
910
895
|
}
|
|
911
896
|
}
|
|
912
897
|
|
|
913
|
-
function rollback(fetchState,
|
|
898
|
+
function rollback(fetchState, targetBlockNumber) {
|
|
914
899
|
var addressesToRemove = new Set();
|
|
915
900
|
var indexingContracts = {};
|
|
916
901
|
Belt_Array.forEach(Object.keys(fetchState.indexingContracts), (function (address) {
|
|
917
902
|
var indexingContract = fetchState.indexingContracts[address];
|
|
918
|
-
var
|
|
919
|
-
|
|
920
|
-
tmp = typeof dc !== "object" ? true : indexingContract.startBlock < firstChangeEvent.blockNumber || indexingContract.startBlock === firstChangeEvent.blockNumber && dc.registeringEventLogIndex < firstChangeEvent.logIndex;
|
|
921
|
-
if (tmp) {
|
|
922
|
-
indexingContracts[address] = indexingContract;
|
|
923
|
-
} else {
|
|
903
|
+
var registrationBlock = indexingContract.registrationBlock;
|
|
904
|
+
if (registrationBlock !== undefined && registrationBlock > targetBlockNumber) {
|
|
924
905
|
addressesToRemove.add(address);
|
|
906
|
+
} else {
|
|
907
|
+
indexingContracts[address] = indexingContract;
|
|
925
908
|
}
|
|
926
909
|
}));
|
|
927
910
|
var partitions = Belt_Array.keepMap(fetchState.partitions, (function (p) {
|
|
928
|
-
return rollbackPartition(p,
|
|
911
|
+
return rollbackPartition(p, targetBlockNumber, addressesToRemove);
|
|
929
912
|
}));
|
|
930
|
-
var empty = fetchState.dcsToStore;
|
|
931
913
|
return updateInternal({
|
|
932
914
|
partitions: fetchState.partitions,
|
|
933
915
|
nextPartitionIndex: fetchState.nextPartitionIndex,
|
|
@@ -937,17 +919,18 @@ function rollback(fetchState, firstChangeEvent) {
|
|
|
937
919
|
normalSelection: fetchState.normalSelection,
|
|
938
920
|
indexingContracts: fetchState.indexingContracts,
|
|
939
921
|
contractConfigs: fetchState.contractConfigs,
|
|
940
|
-
dcsToStore: fetchState.dcsToStore,
|
|
941
922
|
chainId: fetchState.chainId,
|
|
942
923
|
latestFullyFetchedBlock: fetchState.latestFullyFetchedBlock,
|
|
943
|
-
latestOnBlockBlockNumber:
|
|
924
|
+
latestOnBlockBlockNumber: targetBlockNumber,
|
|
944
925
|
blockLag: fetchState.blockLag,
|
|
945
926
|
buffer: fetchState.buffer,
|
|
946
927
|
targetBufferSize: fetchState.targetBufferSize,
|
|
947
928
|
onBlockConfigs: fetchState.onBlockConfigs
|
|
948
|
-
}, partitions, undefined, indexingContracts,
|
|
949
|
-
|
|
950
|
-
|
|
929
|
+
}, partitions, undefined, indexingContracts, Belt_Array.keep(fetchState.buffer, (function (item) {
|
|
930
|
+
var tmp;
|
|
931
|
+
tmp = item.kind === 0 ? item.blockNumber : item.blockNumber;
|
|
932
|
+
return tmp <= targetBlockNumber;
|
|
933
|
+
})), undefined);
|
|
951
934
|
}
|
|
952
935
|
|
|
953
936
|
function isActivelyIndexing(fetchState) {
|
|
@@ -994,33 +977,61 @@ function hasFullBatch(fetchState, batchSizeTarget) {
|
|
|
994
977
|
);
|
|
995
978
|
}
|
|
996
979
|
|
|
997
|
-
function
|
|
998
|
-
return
|
|
980
|
+
function sortForUnorderedBatch(fetchStates, batchSizeTarget) {
|
|
981
|
+
return fetchStates.slice(0).sort(function (a, b) {
|
|
999
982
|
var match = hasFullBatch(a, batchSizeTarget);
|
|
1000
983
|
var match$1 = hasFullBatch(b, batchSizeTarget);
|
|
984
|
+
var exit = 0;
|
|
1001
985
|
if (match) {
|
|
1002
986
|
if (!match$1) {
|
|
1003
987
|
return -1;
|
|
1004
988
|
}
|
|
1005
|
-
|
|
1006
|
-
} else if (match$1) {
|
|
1007
|
-
return 1;
|
|
1008
|
-
}
|
|
1009
|
-
var match$2 = a.buffer[0];
|
|
1010
|
-
var match$3 = b.buffer[0];
|
|
1011
|
-
if (match$2.kind === 0 && match$3.kind === 0) {
|
|
1012
|
-
return match$2.timestamp - match$3.timestamp | 0;
|
|
989
|
+
exit = 1;
|
|
1013
990
|
} else {
|
|
1014
|
-
|
|
991
|
+
if (match$1) {
|
|
992
|
+
return 1;
|
|
993
|
+
}
|
|
994
|
+
exit = 1;
|
|
1015
995
|
}
|
|
996
|
+
if (exit === 1) {
|
|
997
|
+
var match$2 = Belt_Array.get(a.buffer, 0);
|
|
998
|
+
var match$3 = Belt_Array.get(b.buffer, 0);
|
|
999
|
+
var exit$1 = 0;
|
|
1000
|
+
if (match$2 !== undefined) {
|
|
1001
|
+
if (match$2.kind !== 0) {
|
|
1002
|
+
return Js_math.random_int(-1, 1);
|
|
1003
|
+
}
|
|
1004
|
+
if (match$3 === undefined) {
|
|
1005
|
+
return -1;
|
|
1006
|
+
}
|
|
1007
|
+
if (match$3.kind === 0) {
|
|
1008
|
+
return match$2.timestamp - match$3.timestamp | 0;
|
|
1009
|
+
}
|
|
1010
|
+
exit$1 = 2;
|
|
1011
|
+
} else {
|
|
1012
|
+
if (match$3 === undefined) {
|
|
1013
|
+
return 0;
|
|
1014
|
+
}
|
|
1015
|
+
exit$1 = 2;
|
|
1016
|
+
}
|
|
1017
|
+
if (exit$1 === 2) {
|
|
1018
|
+
if (match$3.kind === 0) {
|
|
1019
|
+
return 1;
|
|
1020
|
+
} else {
|
|
1021
|
+
return Js_math.random_int(-1, 1);
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1016
1027
|
});
|
|
1017
1028
|
}
|
|
1018
1029
|
|
|
1019
|
-
function
|
|
1030
|
+
function getUnorderedMultichainProgressBlockNumberAt(fetchState, index) {
|
|
1020
1031
|
var latestOnBlockBlockNumber = fetchState.latestOnBlockBlockNumber;
|
|
1021
1032
|
var latestFullyFetchedBlock = fetchState.latestFullyFetchedBlock;
|
|
1022
1033
|
var bufferBlockNumber = latestOnBlockBlockNumber < latestFullyFetchedBlock.blockNumber ? latestOnBlockBlockNumber : latestFullyFetchedBlock.blockNumber;
|
|
1023
|
-
var item = Belt_Array.get(fetchState.buffer,
|
|
1034
|
+
var item = Belt_Array.get(fetchState.buffer, index);
|
|
1024
1035
|
if (item !== undefined && bufferBlockNumber >= item.blockNumber) {
|
|
1025
1036
|
return item.blockNumber - 1 | 0;
|
|
1026
1037
|
} else {
|
|
@@ -1053,11 +1064,10 @@ exports.hasReadyItem = hasReadyItem;
|
|
|
1053
1064
|
exports.getReadyItemsCount = getReadyItemsCount;
|
|
1054
1065
|
exports.make = make;
|
|
1055
1066
|
exports.bufferSize = bufferSize;
|
|
1056
|
-
exports.pruneQueueFromFirstChangeEvent = pruneQueueFromFirstChangeEvent;
|
|
1057
1067
|
exports.rollbackPartition = rollbackPartition;
|
|
1058
1068
|
exports.rollback = rollback;
|
|
1059
1069
|
exports.isActivelyIndexing = isActivelyIndexing;
|
|
1060
1070
|
exports.isReadyToEnterReorgThreshold = isReadyToEnterReorgThreshold;
|
|
1061
|
-
exports.
|
|
1062
|
-
exports.
|
|
1071
|
+
exports.sortForUnorderedBatch = sortForUnorderedBatch;
|
|
1072
|
+
exports.getUnorderedMultichainProgressBlockNumberAt = getUnorderedMultichainProgressBlockNumberAt;
|
|
1063
1073
|
/* Utils Not a pure module */
|
package/src/Internal.res
CHANGED
|
@@ -145,6 +145,18 @@ type evmContractConfig = {
|
|
|
145
145
|
events: array<evmEventConfig>,
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
+
type indexingContract = {
|
|
149
|
+
address: Address.t,
|
|
150
|
+
contractName: string,
|
|
151
|
+
startBlock: int,
|
|
152
|
+
// Needed for rollback
|
|
153
|
+
// If not set, assume the contract comes from config
|
|
154
|
+
// and shouldn't be rolled back
|
|
155
|
+
registrationBlock: option<int>,
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
type dcs = array<indexingContract>
|
|
159
|
+
|
|
148
160
|
// Duplicate the type from item
|
|
149
161
|
// to make item properly unboxed
|
|
150
162
|
type eventItem = private {
|
|
@@ -200,6 +212,11 @@ external getItemBlockNumber: item => int = "blockNumber"
|
|
|
200
212
|
@get
|
|
201
213
|
external getItemLogIndex: item => int = "logIndex"
|
|
202
214
|
|
|
215
|
+
@get
|
|
216
|
+
external getItemDcs: item => option<dcs> = "dcs"
|
|
217
|
+
@set
|
|
218
|
+
external setItemDcs: (item, dcs) => unit = "dcs"
|
|
219
|
+
|
|
203
220
|
@genType
|
|
204
221
|
type eventOptions<'eventFilters> = {
|
|
205
222
|
wildcard?: bool,
|
|
@@ -297,3 +314,35 @@ let makeCacheTable = (~effectName) => {
|
|
|
297
314
|
|
|
298
315
|
@genType.import(("./Types.ts", "Invalid"))
|
|
299
316
|
type noEventFilters
|
|
317
|
+
|
|
318
|
+
type reorgCheckpoint = {
|
|
319
|
+
@as("id")
|
|
320
|
+
checkpointId: int,
|
|
321
|
+
@as("chain_id")
|
|
322
|
+
chainId: int,
|
|
323
|
+
@as("block_number")
|
|
324
|
+
blockNumber: int,
|
|
325
|
+
@as("block_hash")
|
|
326
|
+
blockHash: string,
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
type entityValueAtStartOfBatch<'entityType> =
|
|
330
|
+
| NotSet // The entity isn't in the DB yet
|
|
331
|
+
| AlreadySet('entityType)
|
|
332
|
+
|
|
333
|
+
type updatedValue<'entityType> = {
|
|
334
|
+
latest: EntityHistory.entityUpdate<'entityType>,
|
|
335
|
+
history: array<EntityHistory.entityUpdate<'entityType>>,
|
|
336
|
+
// In the event of a rollback, some entity updates may have been
|
|
337
|
+
// been affected by a rollback diff. If there was no rollback diff
|
|
338
|
+
// this will always be false.
|
|
339
|
+
// If there was a rollback diff, this will be false in the case of a
|
|
340
|
+
// new entity update (where entity affected is not present in the diff) b
|
|
341
|
+
// but true if the update is related to an entity that is
|
|
342
|
+
// currently present in the diff
|
|
343
|
+
containsRollbackDiffChange: bool,
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
type inMemoryStoreRowEntity<'entityType> =
|
|
347
|
+
| Updated(updatedValue<'entityType>)
|
|
348
|
+
| InitialReadFromDb(entityValueAtStartOfBatch<'entityType>) // This means there is no change from the db.
|
package/src/InternalConfig.res
CHANGED
package/src/Persistence.res
CHANGED
|
@@ -13,10 +13,25 @@ type effectCacheRecord = {
|
|
|
13
13
|
mutable count: int,
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
type initialChainState = {
|
|
17
|
+
id: int,
|
|
18
|
+
startBlock: int,
|
|
19
|
+
endBlock: option<int>,
|
|
20
|
+
maxReorgDepth: int,
|
|
21
|
+
progressBlockNumber: int,
|
|
22
|
+
numEventsProcessed: int,
|
|
23
|
+
firstEventBlockNumber: option<int>,
|
|
24
|
+
timestampCaughtUpToHeadOrEndblock: option<Js.Date.t>,
|
|
25
|
+
dynamicContracts: array<Internal.indexingContract>,
|
|
26
|
+
}
|
|
27
|
+
|
|
16
28
|
type initialState = {
|
|
17
29
|
cleanRun: bool,
|
|
18
30
|
cache: dict<effectCacheRecord>,
|
|
19
|
-
chains: array<
|
|
31
|
+
chains: array<initialChainState>,
|
|
32
|
+
checkpointId: int,
|
|
33
|
+
// Needed to keep reorg detection logic between restarts
|
|
34
|
+
reorgCheckpoints: array<Internal.reorgCheckpoint>,
|
|
20
35
|
}
|
|
21
36
|
|
|
22
37
|
type operator = [#">" | #"="]
|
package/src/Persistence.res.js
CHANGED
|
@@ -84,7 +84,7 @@ async function init(persistence, chainConfigs, resetOpt) {
|
|
|
84
84
|
};
|
|
85
85
|
var checkpoints = {};
|
|
86
86
|
initialState$1.chains.forEach(function (c) {
|
|
87
|
-
checkpoints[c.id] = c.
|
|
87
|
+
checkpoints[c.id] = c.progressBlockNumber;
|
|
88
88
|
});
|
|
89
89
|
Logging.info({
|
|
90
90
|
msg: "Successfully resumed indexing state! Continuing from the last checkpoint.",
|