envio 3.3.0-alpha.8 → 3.3.0-alpha.9
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 +6 -6
- package/src/ChainState.res +104 -37
- package/src/ChainState.res.mjs +80 -19
- package/src/ChainState.resi +4 -1
- package/src/CrossChainState.res +56 -29
- package/src/CrossChainState.res.mjs +11 -2
- package/src/EnvioGlobal.res +53 -0
- package/src/EnvioGlobal.res.mjs +31 -0
- package/src/EventConfigBuilder.res +16 -17
- package/src/EventConfigBuilder.res.mjs +7 -6
- package/src/FetchState.res +151 -130
- package/src/FetchState.res.mjs +105 -88
- package/src/HandlerLoader.res +1 -1
- package/src/HandlerLoader.res.mjs +1 -1
- package/src/HandlerRegister.res +476 -305
- package/src/HandlerRegister.res.mjs +276 -209
- package/src/HandlerRegister.resi +11 -6
- package/src/Internal.res +23 -4
- package/src/LogSelection.res +102 -165
- package/src/LogSelection.res.mjs +101 -116
- package/src/Main.res +29 -143
- package/src/Main.res.mjs +25 -88
- package/src/RollbackCommit.res +4 -1
- package/src/RollbackCommit.res.mjs +3 -2
- package/src/SimulateItems.res +1 -1
- package/src/sources/Evm.res +4 -1
- package/src/sources/Evm.res.mjs +1 -1
- package/src/sources/Fuel.res +3 -1
- package/src/sources/Fuel.res.mjs +1 -1
- package/src/sources/HyperSyncSource.res +22 -33
- package/src/sources/HyperSyncSource.res.mjs +17 -26
- package/src/sources/RpcSource.res +28 -39
- package/src/sources/RpcSource.res.mjs +18 -31
- package/src/sources/SourceManager.res +1 -7
- package/src/sources/SourceManager.res.mjs +1 -2
package/src/FetchState.res.mjs
CHANGED
|
@@ -23,9 +23,8 @@ let deriveContractNameByAddress = Utils.$$WeakMap.memoize(addressesByContractNam
|
|
|
23
23
|
return result;
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
-
function densityItemsTarget(
|
|
27
|
-
|
|
28
|
-
return ((Stdlib_Option.getOr(toBlock, chainTargetBlock) - fromBlock | 0) + 1 | 0) * density;
|
|
26
|
+
function densityItemsTarget(density, fromBlock, toBlock, chainTargetBlock) {
|
|
27
|
+
return Primitive_int.max(1, Math.ceil(((Stdlib_Option.getOr(toBlock, chainTargetBlock) - fromBlock | 0) + 1 | 0) * density) | 0);
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
function getMinHistoryRange(p) {
|
|
@@ -36,6 +35,14 @@ function getMinHistoryRange(p) {
|
|
|
36
35
|
}
|
|
37
36
|
}
|
|
38
37
|
|
|
38
|
+
function getTrustedDensity(p) {
|
|
39
|
+
let match = p.prevQueryRange;
|
|
40
|
+
let match$1 = p.prevPrevQueryRange;
|
|
41
|
+
if (match !== 0 && match$1 !== 0) {
|
|
42
|
+
return p.prevRangeSize / match;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
39
46
|
function getMinQueryRange(partitions) {
|
|
40
47
|
let min = 0;
|
|
41
48
|
for (let i = 0, i_finish = partitions.length; i < i_finish; ++i) {
|
|
@@ -105,6 +112,7 @@ function mergePartitionsAtBlock(p1, p2, potentialMergeBlock, contractName, maxAd
|
|
|
105
112
|
p1,
|
|
106
113
|
p2
|
|
107
114
|
]);
|
|
115
|
+
let inheritedDensity = Stdlib_Option.getOr(getTrustedDensity(p1), 0) + Stdlib_Option.getOr(getTrustedDensity(p2), 0);
|
|
108
116
|
continuingBase = {
|
|
109
117
|
id: newId,
|
|
110
118
|
latestFetchedBlock: {
|
|
@@ -118,7 +126,7 @@ function mergePartitionsAtBlock(p1, p2, potentialMergeBlock, contractName, maxAd
|
|
|
118
126
|
mutPendingQueries: [],
|
|
119
127
|
prevQueryRange: minRange,
|
|
120
128
|
prevPrevQueryRange: minRange,
|
|
121
|
-
prevRangeSize: 0,
|
|
129
|
+
prevRangeSize: Math.ceil(inheritedDensity * minRange) | 0,
|
|
122
130
|
latestBlockRangeUpdateBlock: 0
|
|
123
131
|
};
|
|
124
132
|
} else {
|
|
@@ -976,65 +984,84 @@ function startFetchingQueries(param, queries) {
|
|
|
976
984
|
}
|
|
977
985
|
}
|
|
978
986
|
|
|
979
|
-
function pushGapFillQueries(queries, partitionId, rangeFromBlock, rangeEndBlock, knownHeight, chainTargetBlock, maybeChunkRange, maxChunks, partition, selection, addressesByContractName) {
|
|
980
|
-
let cost =
|
|
987
|
+
function pushGapFillQueries(queries, partitionId, rangeFromBlock, rangeEndBlock, knownHeight, chainTargetBlock, maybeChunkRange, maxChunks, partition, partitionBudget, selection, addressesByContractName) {
|
|
988
|
+
let cost = {
|
|
989
|
+
contents: 0
|
|
990
|
+
};
|
|
981
991
|
if (rangeFromBlock <= knownHeight && maxChunks > 0) {
|
|
982
992
|
let exit = 0;
|
|
983
993
|
if (!(rangeEndBlock !== undefined && rangeFromBlock > rangeEndBlock)) {
|
|
984
994
|
exit = 1;
|
|
985
995
|
}
|
|
986
996
|
if (exit === 1) {
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
let chunkFromBlock = rangeFromBlock;
|
|
992
|
-
let chunkIdx = 0;
|
|
993
|
-
while (chunkIdx < maxChunks && ((chunkFromBlock + chunkSize | 0) - 1 | 0) <= maxBlock) {
|
|
994
|
-
let chunkToBlock = (chunkFromBlock + chunkSize | 0) - 1 | 0;
|
|
995
|
-
let itemsTarget = densityItemsTarget(partition, chunkFromBlock, chunkToBlock, chainTargetBlock);
|
|
996
|
-
queries.push({
|
|
997
|
-
partitionId: partitionId,
|
|
998
|
-
fromBlock: chunkFromBlock,
|
|
999
|
-
toBlock: chunkToBlock,
|
|
1000
|
-
isChunk: true,
|
|
1001
|
-
itemsTarget: itemsTarget,
|
|
1002
|
-
selection: selection,
|
|
1003
|
-
addressesByContractName: addressesByContractName
|
|
1004
|
-
});
|
|
1005
|
-
cost = cost + itemsTarget;
|
|
1006
|
-
chunkFromBlock = chunkToBlock + 1 | 0;
|
|
1007
|
-
chunkIdx = chunkIdx + 1 | 0;
|
|
1008
|
-
};
|
|
1009
|
-
} else {
|
|
1010
|
-
let itemsTarget$1 = densityItemsTarget(partition, rangeFromBlock, rangeEndBlock, chainTargetBlock);
|
|
1011
|
-
queries.push({
|
|
1012
|
-
partitionId: partitionId,
|
|
1013
|
-
fromBlock: rangeFromBlock,
|
|
1014
|
-
toBlock: rangeEndBlock,
|
|
1015
|
-
isChunk: rangeEndBlock !== undefined,
|
|
1016
|
-
itemsTarget: itemsTarget$1,
|
|
1017
|
-
selection: selection,
|
|
1018
|
-
addressesByContractName: addressesByContractName
|
|
1019
|
-
});
|
|
1020
|
-
cost = cost + itemsTarget$1;
|
|
1021
|
-
}
|
|
1022
|
-
} else {
|
|
1023
|
-
let itemsTarget$2 = densityItemsTarget(partition, rangeFromBlock, rangeEndBlock, chainTargetBlock);
|
|
997
|
+
let trustedDensity = getTrustedDensity(partition);
|
|
998
|
+
let maxBlock = rangeEndBlock !== undefined ? rangeEndBlock : chainTargetBlock;
|
|
999
|
+
let pushSingleQuery = (density, isChunk) => {
|
|
1000
|
+
let itemsTarget = densityItemsTarget(density, rangeFromBlock, rangeEndBlock, chainTargetBlock);
|
|
1024
1001
|
queries.push({
|
|
1025
1002
|
partitionId: partitionId,
|
|
1026
1003
|
fromBlock: rangeFromBlock,
|
|
1027
1004
|
toBlock: rangeEndBlock,
|
|
1028
|
-
isChunk:
|
|
1029
|
-
itemsTarget: itemsTarget
|
|
1005
|
+
isChunk: isChunk,
|
|
1006
|
+
itemsTarget: itemsTarget,
|
|
1030
1007
|
selection: selection,
|
|
1031
1008
|
addressesByContractName: addressesByContractName
|
|
1032
1009
|
});
|
|
1033
|
-
cost = cost + itemsTarget
|
|
1010
|
+
cost.contents = cost.contents + itemsTarget;
|
|
1011
|
+
};
|
|
1012
|
+
if (trustedDensity !== undefined) {
|
|
1013
|
+
if (maybeChunkRange !== undefined && trustedDensity > 0) {
|
|
1014
|
+
let chunkSize = Js_math.ceil_int(maybeChunkRange * 1.8);
|
|
1015
|
+
if (((rangeFromBlock + (chunkSize << 1) | 0) - 1 | 0) <= maxBlock) {
|
|
1016
|
+
let chunkFromBlock = rangeFromBlock;
|
|
1017
|
+
let chunkIdx = 0;
|
|
1018
|
+
while (chunkIdx < maxChunks && ((chunkFromBlock + chunkSize | 0) - 1 | 0) <= maxBlock) {
|
|
1019
|
+
let chunkToBlock = (chunkFromBlock + chunkSize | 0) - 1 | 0;
|
|
1020
|
+
let itemsTarget = densityItemsTarget(trustedDensity, chunkFromBlock, chunkToBlock, chainTargetBlock);
|
|
1021
|
+
queries.push({
|
|
1022
|
+
partitionId: partitionId,
|
|
1023
|
+
fromBlock: chunkFromBlock,
|
|
1024
|
+
toBlock: chunkToBlock,
|
|
1025
|
+
isChunk: true,
|
|
1026
|
+
itemsTarget: itemsTarget,
|
|
1027
|
+
selection: selection,
|
|
1028
|
+
addressesByContractName: addressesByContractName
|
|
1029
|
+
});
|
|
1030
|
+
cost.contents = cost.contents + itemsTarget;
|
|
1031
|
+
chunkFromBlock = chunkToBlock + 1 | 0;
|
|
1032
|
+
chunkIdx = chunkIdx + 1 | 0;
|
|
1033
|
+
};
|
|
1034
|
+
} else {
|
|
1035
|
+
pushSingleQuery(trustedDensity, rangeEndBlock !== undefined);
|
|
1036
|
+
}
|
|
1037
|
+
} else {
|
|
1038
|
+
pushSingleQuery(trustedDensity, false);
|
|
1039
|
+
}
|
|
1040
|
+
} else {
|
|
1041
|
+
let remainingRange = Primitive_int.max(1, (chainTargetBlock - rangeFromBlock | 0) + 1 | 0);
|
|
1042
|
+
pushSingleQuery(partitionBudget / remainingRange, false);
|
|
1034
1043
|
}
|
|
1035
1044
|
}
|
|
1036
1045
|
}
|
|
1037
|
-
return cost;
|
|
1046
|
+
return cost.contents;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
function waterLevel(budget, footprints) {
|
|
1050
|
+
let sorted = footprints.toSorted(Primitive_float.compare);
|
|
1051
|
+
let n = sorted.length;
|
|
1052
|
+
let prefix = 0;
|
|
1053
|
+
let level;
|
|
1054
|
+
let idx = 0;
|
|
1055
|
+
while (level === undefined && idx < n) {
|
|
1056
|
+
let i = idx;
|
|
1057
|
+
prefix = prefix + sorted[i];
|
|
1058
|
+
let candidate = (budget + prefix) / (i + 1 | 0);
|
|
1059
|
+
if (i === (n - 1 | 0) || candidate <= sorted[i + 1 | 0]) {
|
|
1060
|
+
level = candidate;
|
|
1061
|
+
}
|
|
1062
|
+
idx = idx + 1 | 0;
|
|
1063
|
+
};
|
|
1064
|
+
return Stdlib_Option.getOr(level, 0);
|
|
1038
1065
|
}
|
|
1039
1066
|
|
|
1040
1067
|
function getNextQuery(param, chainTargetBlock, chainTargetItems) {
|
|
@@ -1096,7 +1123,7 @@ function getNextQuery(param, chainTargetBlock, chainTargetItems) {
|
|
|
1096
1123
|
let pq = p$2.mutPendingQueries[pqIdx$1];
|
|
1097
1124
|
if (pq.fromBlock > cursor) {
|
|
1098
1125
|
let beforeLen = bucket.length;
|
|
1099
|
-
let cost$1 = pushGapFillQueries(bucket, partitionId$2, cursor, Utils.$$Math.minOptInt(pq.fromBlock - 1 | 0, queryEndBlock), knownHeight, chainTargetBlock, maybeChunkRange, (10 - pendingCount | 0) - chunksUsedThisCall | 0, p$2, p$2.selection, p$2.addressesByContractName);
|
|
1126
|
+
let cost$1 = pushGapFillQueries(bucket, partitionId$2, cursor, Utils.$$Math.minOptInt(pq.fromBlock - 1 | 0, queryEndBlock), knownHeight, chainTargetBlock, maybeChunkRange, (10 - pendingCount | 0) - chunksUsedThisCall | 0, p$2, chainTargetItems / partitionsCount, p$2.selection, p$2.addressesByContractName);
|
|
1100
1127
|
chunksUsedThisCall = chunksUsedThisCall + (bucket.length - beforeLen | 0) | 0;
|
|
1101
1128
|
gapFillCost = gapFillCost + cost$1;
|
|
1102
1129
|
}
|
|
@@ -1136,24 +1163,37 @@ function getNextQuery(param, chainTargetBlock, chainTargetItems) {
|
|
|
1136
1163
|
}
|
|
1137
1164
|
reservedByPartition[fs.partitionId] = cost;
|
|
1138
1165
|
});
|
|
1166
|
+
let isInRange = fs => {
|
|
1167
|
+
let tmp = false;
|
|
1168
|
+
if (fs.cursor <= chainTargetBlock) {
|
|
1169
|
+
let eb = fs.queryEndBlock;
|
|
1170
|
+
tmp = eb !== undefined ? fs.cursor <= eb : true;
|
|
1171
|
+
}
|
|
1172
|
+
if (tmp) {
|
|
1173
|
+
return (fs.pendingCount + fs.chunksUsedThisCall | 0) < 10;
|
|
1174
|
+
} else {
|
|
1175
|
+
return false;
|
|
1176
|
+
}
|
|
1177
|
+
};
|
|
1178
|
+
let inRangeStates = fillStates.filter(isInRange);
|
|
1139
1179
|
let emitQueries = (fs, budget) => {
|
|
1140
1180
|
let p = fs.p;
|
|
1141
1181
|
let eb = fs.queryEndBlock;
|
|
1142
1182
|
let maxBlock = eb !== undefined ? eb : chainTargetBlock;
|
|
1143
|
-
let
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
let chunkSize = Js_math.ceil_int(
|
|
1147
|
-
let chunkCost =
|
|
1183
|
+
let match = fs.maybeChunkRange;
|
|
1184
|
+
let match$1 = getTrustedDensity(p);
|
|
1185
|
+
if (match !== undefined && match$1 !== undefined && match$1 > 0) {
|
|
1186
|
+
let chunkSize = Js_math.ceil_int(match * 1.8);
|
|
1187
|
+
let chunkCost = match$1 * chunkSize;
|
|
1148
1188
|
let maxChunksRemaining = (10 - fs.pendingCount | 0) - fs.chunksUsedThisCall | 0;
|
|
1149
|
-
let affordable =
|
|
1189
|
+
let affordable = Math.floor(budget / chunkCost) | 0;
|
|
1150
1190
|
let numChunks = Primitive_int.max(1, Primitive_int.min(affordable, maxChunksRemaining));
|
|
1151
1191
|
let consumed = 0;
|
|
1152
1192
|
let created = 0;
|
|
1153
1193
|
let chunkFromBlock = fs.cursor;
|
|
1154
1194
|
while (created < numChunks && chunkFromBlock <= maxBlock) {
|
|
1155
1195
|
let chunkToBlock = Primitive_int.min((chunkFromBlock + chunkSize | 0) - 1 | 0, maxBlock);
|
|
1156
|
-
let itemsTarget =
|
|
1196
|
+
let itemsTarget = Primitive_int.max(1, Math.ceil(match$1 * ((chunkToBlock - chunkFromBlock | 0) + 1 | 0)) | 0);
|
|
1157
1197
|
fs.bucket.push({
|
|
1158
1198
|
partitionId: fs.partitionId,
|
|
1159
1199
|
fromBlock: chunkFromBlock,
|
|
@@ -1171,7 +1211,7 @@ function getNextQuery(param, chainTargetBlock, chainTargetItems) {
|
|
|
1171
1211
|
fs.chunksUsedThisCall = fs.chunksUsedThisCall + created | 0;
|
|
1172
1212
|
return consumed;
|
|
1173
1213
|
}
|
|
1174
|
-
let itemsTarget$1 =
|
|
1214
|
+
let itemsTarget$1 = Primitive_int.max(1, Math.round(budget) | 0);
|
|
1175
1215
|
fs.bucket.push({
|
|
1176
1216
|
partitionId: fs.partitionId,
|
|
1177
1217
|
fromBlock: fs.cursor,
|
|
@@ -1185,41 +1225,22 @@ function getNextQuery(param, chainTargetBlock, chainTargetItems) {
|
|
|
1185
1225
|
fs.chunksUsedThisCall = fs.chunksUsedThisCall + 1 | 0;
|
|
1186
1226
|
return itemsTarget$1;
|
|
1187
1227
|
};
|
|
1188
|
-
let
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
let eb = fs.queryEndBlock;
|
|
1192
|
-
tmp = eb !== undefined ? fs.cursor <= eb : true;
|
|
1193
|
-
}
|
|
1194
|
-
if (tmp) {
|
|
1195
|
-
return (fs.pendingCount + fs.chunksUsedThisCall | 0) < 10;
|
|
1196
|
-
} else {
|
|
1197
|
-
return false;
|
|
1198
|
-
}
|
|
1199
|
-
};
|
|
1200
|
-
let notFilledPartitions = fillStates.filter(isInRange);
|
|
1201
|
-
let reservedFromRange = {
|
|
1202
|
-
contents: 0
|
|
1228
|
+
let notFilledPartitions = inRangeStates;
|
|
1229
|
+
let remainingBudget = {
|
|
1230
|
+
contents: rangeItemsTarget
|
|
1203
1231
|
};
|
|
1204
|
-
while (notFilledPartitions.length !== 0 &&
|
|
1205
|
-
let
|
|
1206
|
-
let footprintSum = {
|
|
1207
|
-
contents: 0
|
|
1208
|
-
};
|
|
1209
|
-
notFilledPartitions.forEach(fs => {
|
|
1210
|
-
footprintSum.contents = footprintSum.contents + reservedByPartition[fs.partitionId];
|
|
1211
|
-
});
|
|
1212
|
-
let line = (rangeItemsTarget - reservedFromRange.contents + footprintSum.contents) / n;
|
|
1232
|
+
while (notFilledPartitions.length !== 0 && remainingBudget.contents > 0) {
|
|
1233
|
+
let level = waterLevel(remainingBudget.contents, notFilledPartitions.map(fs => reservedByPartition[fs.partitionId]));
|
|
1213
1234
|
let next = [];
|
|
1214
1235
|
notFilledPartitions.forEach(fs => {
|
|
1215
1236
|
let reserved = reservedByPartition[fs.partitionId];
|
|
1216
|
-
let budget =
|
|
1237
|
+
let budget = level - reserved;
|
|
1217
1238
|
if (budget <= 0) {
|
|
1218
1239
|
return;
|
|
1219
1240
|
}
|
|
1220
1241
|
let consumed = emitQueries(fs, budget);
|
|
1221
1242
|
reservedByPartition[fs.partitionId] = reserved + consumed;
|
|
1222
|
-
|
|
1243
|
+
remainingBudget.contents = remainingBudget.contents - consumed;
|
|
1223
1244
|
if (isInRange(fs)) {
|
|
1224
1245
|
next.push(fs);
|
|
1225
1246
|
return;
|
|
@@ -1650,20 +1671,15 @@ function updateKnownHeight(fetchState, knownHeight) {
|
|
|
1650
1671
|
}
|
|
1651
1672
|
}
|
|
1652
1673
|
|
|
1653
|
-
let minItemsTarget = 2000;
|
|
1654
|
-
|
|
1655
|
-
let maxItemsTarget = 10000;
|
|
1656
|
-
|
|
1657
1674
|
let blockItemLogIndex = 16777216;
|
|
1658
1675
|
|
|
1659
1676
|
let maxPendingChunksPerPartition = 10;
|
|
1660
1677
|
|
|
1661
1678
|
export {
|
|
1662
1679
|
deriveContractNameByAddress,
|
|
1663
|
-
minItemsTarget,
|
|
1664
|
-
maxItemsTarget,
|
|
1665
1680
|
densityItemsTarget,
|
|
1666
1681
|
getMinHistoryRange,
|
|
1682
|
+
getTrustedDensity,
|
|
1667
1683
|
getMinQueryRange,
|
|
1668
1684
|
OptimizedPartitions,
|
|
1669
1685
|
bufferBlockNumber,
|
|
@@ -1682,6 +1698,7 @@ export {
|
|
|
1682
1698
|
startFetchingQueries,
|
|
1683
1699
|
maxPendingChunksPerPartition,
|
|
1684
1700
|
pushGapFillQueries,
|
|
1701
|
+
waterLevel,
|
|
1685
1702
|
getNextQuery,
|
|
1686
1703
|
hasReadyItem,
|
|
1687
1704
|
getReadyItemsCount,
|
package/src/HandlerLoader.res
CHANGED
|
@@ -78,7 +78,7 @@ let autoLoadFromSrcHandlers = async (~handlers: string) => {
|
|
|
78
78
|
// (populating the global `HandlerRegister` registry as a side effect) and
|
|
79
79
|
// returns the resulting per-chain registrations.
|
|
80
80
|
let registerAllHandlers = async (~config: Config.t): HandlerRegister.registrationsByChainId => {
|
|
81
|
-
HandlerRegister.startRegistration(~
|
|
81
|
+
HandlerRegister.startRegistration(~config)
|
|
82
82
|
|
|
83
83
|
// Auto-load all .js files from src/handlers directory
|
|
84
84
|
await autoLoadFromSrcHandlers(~handlers=config.handlers)
|
|
@@ -57,7 +57,7 @@ async function autoLoadFromSrcHandlers(handlers) {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
async function registerAllHandlers(config) {
|
|
60
|
-
HandlerRegister.startRegistration(config
|
|
60
|
+
HandlerRegister.startRegistration(config);
|
|
61
61
|
await autoLoadFromSrcHandlers(config.handlers);
|
|
62
62
|
await Promise.all(config.contractHandlers.map(param => registerContractHandlers(param.name, param.handler)));
|
|
63
63
|
return HandlerRegister.finishRegistration(config);
|