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.
@@ -23,9 +23,8 @@ let deriveContractNameByAddress = Utils.$$WeakMap.memoize(addressesByContractNam
23
23
  return result;
24
24
  });
25
25
 
26
- function densityItemsTarget(p, fromBlock, toBlock, chainTargetBlock) {
27
- let density = p.prevRangeSize / p.prevQueryRange;
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 = 0;
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
- if (maybeChunkRange !== undefined) {
988
- let maxBlock = rangeEndBlock !== undefined ? rangeEndBlock : chainTargetBlock;
989
- let chunkSize = Js_math.ceil_int(maybeChunkRange * 1.8);
990
- if (((rangeFromBlock + (chunkSize << 1) | 0) - 1 | 0) <= maxBlock) {
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: false,
1029
- itemsTarget: itemsTarget$2,
1005
+ isChunk: isChunk,
1006
+ itemsTarget: itemsTarget,
1030
1007
  selection: selection,
1031
1008
  addressesByContractName: addressesByContractName
1032
1009
  });
1033
- cost = cost + itemsTarget$2;
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 minHistoryRange = fs.maybeChunkRange;
1144
- if (minHistoryRange !== undefined) {
1145
- let density = p.prevRangeSize / p.prevQueryRange;
1146
- let chunkSize = Js_math.ceil_int(minHistoryRange * 1.8);
1147
- let chunkCost = density * chunkSize;
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 = chunkCost > 0 ? Math.floor(budget / chunkCost) | 0 : maxChunksRemaining;
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 = density * ((chunkToBlock - chunkFromBlock | 0) + 1 | 0);
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 = Primitive_float.min(Math.round(budget), 10000);
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 isInRange = fs => {
1189
- let tmp = false;
1190
- if (fs.cursor <= chainTargetBlock) {
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 && reservedFromRange.contents < rangeItemsTarget) {
1205
- let n = notFilledPartitions.length;
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 = line - reserved;
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
- reservedFromRange.contents = reservedFromRange.contents + consumed;
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,
@@ -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(~ecosystem=config.ecosystem)
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.ecosystem);
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);