envio 3.3.0-alpha.10 → 3.3.0-alpha.11
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/licenses/CLA.md +35 -0
- package/licenses/EULA.md +67 -0
- package/licenses/LICENSE.md +45 -0
- package/licenses/README.md +35 -0
- package/package.json +9 -8
- package/src/Batch.res.mjs +1 -1
- package/src/ChainFetching.res +13 -10
- package/src/ChainFetching.res.mjs +3 -4
- package/src/ChainState.res +45 -30
- package/src/ChainState.res.mjs +22 -8
- package/src/ChainState.resi +5 -0
- package/src/Config.res +9 -5
- package/src/Config.res.mjs +2 -2
- package/src/Core.res +20 -0
- package/src/Core.res.mjs +12 -0
- package/src/CrossChainState.res +18 -1
- package/src/CrossChainState.res.mjs +2 -1
- package/src/EventConfigBuilder.res +21 -46
- package/src/EventConfigBuilder.res.mjs +18 -25
- package/src/EventProcessing.res +8 -5
- package/src/EventProcessing.res.mjs +2 -1
- package/src/FetchState.res +344 -263
- package/src/FetchState.res.mjs +209 -131
- package/src/HandlerRegister.res +3 -1
- package/src/HandlerRegister.res.mjs +3 -2
- package/src/Internal.res +11 -2
- package/src/LogSelection.res +0 -62
- package/src/LogSelection.res.mjs +0 -74
- package/src/RawEvent.res +2 -2
- package/src/SimulateDeadInputTracker.res +1 -1
- package/src/SimulateItems.res +38 -6
- package/src/SimulateItems.res.mjs +28 -9
- package/src/TestIndexer.res +2 -2
- package/src/TestIndexer.res.mjs +2 -2
- package/src/TopicFilter.res +1 -25
- package/src/TopicFilter.res.mjs +0 -74
- package/src/bindings/Viem.res +0 -5
- package/src/sources/EventRouter.res +0 -21
- package/src/sources/EventRouter.res.mjs +0 -12
- package/src/sources/EvmChain.res +2 -27
- package/src/sources/EvmChain.res.mjs +2 -23
- package/src/sources/EvmRpcClient.res +12 -15
- package/src/sources/EvmRpcClient.res.mjs +3 -3
- package/src/sources/HyperSync.res +9 -38
- package/src/sources/HyperSync.res.mjs +16 -28
- package/src/sources/HyperSync.resi +2 -2
- package/src/sources/HyperSyncClient.res +88 -11
- package/src/sources/HyperSyncClient.res.mjs +39 -6
- package/src/sources/HyperSyncSource.res +18 -199
- package/src/sources/HyperSyncSource.res.mjs +9 -128
- package/src/sources/Rpc.res +0 -32
- package/src/sources/Rpc.res.mjs +1 -46
- package/src/sources/RpcSource.res +29 -175
- package/src/sources/RpcSource.res.mjs +32 -110
- package/src/sources/SimulateSource.res +37 -19
- package/src/sources/SimulateSource.res.mjs +27 -10
- package/src/sources/SvmHyperSyncSource.res +3 -3
package/src/FetchState.res.mjs
CHANGED
|
@@ -484,13 +484,90 @@ function bufferReadyCount(fetchState) {
|
|
|
484
484
|
return lo;
|
|
485
485
|
}
|
|
486
486
|
|
|
487
|
+
function getRegistrationIndex(item) {
|
|
488
|
+
if (item.kind === 0) {
|
|
489
|
+
return item.onEventRegistration.index;
|
|
490
|
+
} else {
|
|
491
|
+
return item.onBlockRegistration.index;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
487
495
|
function compareBufferItem(a, b) {
|
|
488
|
-
let
|
|
489
|
-
|
|
490
|
-
|
|
496
|
+
let ba = a.blockNumber;
|
|
497
|
+
let bb = b.blockNumber;
|
|
498
|
+
if (ba !== bb) {
|
|
499
|
+
if (ba < bb) {
|
|
500
|
+
return -1;
|
|
501
|
+
} else {
|
|
502
|
+
return 1;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
let la = a.logIndex;
|
|
506
|
+
let lb = b.logIndex;
|
|
507
|
+
if (la !== lb) {
|
|
508
|
+
if (la < lb) {
|
|
509
|
+
return -1;
|
|
510
|
+
} else {
|
|
511
|
+
return 1;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
let ia = getRegistrationIndex(a);
|
|
515
|
+
let ib = getRegistrationIndex(b);
|
|
516
|
+
if (ia < ib) {
|
|
517
|
+
return -1;
|
|
518
|
+
} else if (ia > ib) {
|
|
519
|
+
return 1;
|
|
491
520
|
} else {
|
|
492
|
-
return
|
|
521
|
+
return 0;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
function mergeIntoBuffer(buffer, newItems) {
|
|
526
|
+
let n = newItems.length;
|
|
527
|
+
for (let i = 1; i < n; ++i) {
|
|
528
|
+
let x = newItems[i];
|
|
529
|
+
let j = i - 1 | 0;
|
|
530
|
+
while (j >= 0 && compareBufferItem(newItems[j], x) > 0) {
|
|
531
|
+
newItems[j + 1 | 0] = newItems[j];
|
|
532
|
+
j = j - 1 | 0;
|
|
533
|
+
};
|
|
534
|
+
newItems[j + 1 | 0] = x;
|
|
493
535
|
}
|
|
536
|
+
let m = buffer.length;
|
|
537
|
+
let merged = [];
|
|
538
|
+
let last = {
|
|
539
|
+
contents: undefined
|
|
540
|
+
};
|
|
541
|
+
let push = item => {
|
|
542
|
+
let l = last.contents;
|
|
543
|
+
if (l !== undefined && compareBufferItem(l, item) === 0) {
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
merged.push(item);
|
|
547
|
+
last.contents = item;
|
|
548
|
+
};
|
|
549
|
+
let i$1 = 0;
|
|
550
|
+
let j$1 = 0;
|
|
551
|
+
while (i$1 < m && j$1 < n) {
|
|
552
|
+
let a = buffer[i$1];
|
|
553
|
+
let b = newItems[j$1];
|
|
554
|
+
if (compareBufferItem(a, b) <= 0) {
|
|
555
|
+
push(a);
|
|
556
|
+
i$1 = i$1 + 1 | 0;
|
|
557
|
+
} else {
|
|
558
|
+
push(b);
|
|
559
|
+
j$1 = j$1 + 1 | 0;
|
|
560
|
+
}
|
|
561
|
+
};
|
|
562
|
+
while (i$1 < m) {
|
|
563
|
+
push(buffer[i$1]);
|
|
564
|
+
i$1 = i$1 + 1 | 0;
|
|
565
|
+
};
|
|
566
|
+
while (j$1 < n) {
|
|
567
|
+
push(newItems[j$1]);
|
|
568
|
+
j$1 = j$1 + 1 | 0;
|
|
569
|
+
};
|
|
570
|
+
return merged;
|
|
494
571
|
}
|
|
495
572
|
|
|
496
573
|
function appendOnBlockItems(mutItems, onBlockRegistrations, indexerStartBlock, fromBlock, maxBlockNumber, maxOnBlockBufferSize) {
|
|
@@ -522,18 +599,19 @@ function appendOnBlockItems(mutItems, onBlockRegistrations, indexerStartBlock, f
|
|
|
522
599
|
return latestOnBlockBlockNumber;
|
|
523
600
|
}
|
|
524
601
|
|
|
525
|
-
function updateInternal(fetchState, optimizedPartitionsOpt, mutItems, blockLagOpt, knownHeightOpt) {
|
|
602
|
+
function updateInternal(fetchState, optimizedPartitionsOpt, mutItems, mutItemsSortedOpt, blockLagOpt, knownHeightOpt) {
|
|
526
603
|
let optimizedPartitions = optimizedPartitionsOpt !== undefined ? optimizedPartitionsOpt : fetchState.optimizedPartitions;
|
|
604
|
+
let mutItemsSorted = mutItemsSortedOpt !== undefined ? mutItemsSortedOpt : false;
|
|
527
605
|
let blockLag = blockLagOpt !== undefined ? blockLagOpt : fetchState.blockLag;
|
|
528
606
|
let knownHeight = knownHeightOpt !== undefined ? knownHeightOpt : fetchState.knownHeight;
|
|
529
|
-
let
|
|
607
|
+
let base = mutItems !== undefined ? (
|
|
608
|
+
mutItemsSorted ? mutItems : mergeIntoBuffer([], mutItems)
|
|
609
|
+
) : fetchState.buffer;
|
|
610
|
+
let blockItems = [];
|
|
530
611
|
let onBlockRegistrations = fetchState.onBlockRegistrations;
|
|
531
612
|
let latestOnBlockBlockNumber;
|
|
532
613
|
if (onBlockRegistrations.length !== 0) {
|
|
533
|
-
let
|
|
534
|
-
let item = (
|
|
535
|
-
mutItems$1 !== undefined ? mutItems$1 : fetchState.buffer
|
|
536
|
-
)[fetchState.maxOnBlockBufferSize - 1 | 0];
|
|
614
|
+
let item = base[fetchState.maxOnBlockBufferSize - 1 | 0];
|
|
537
615
|
let maxBlockNumber;
|
|
538
616
|
if (item !== undefined) {
|
|
539
617
|
maxBlockNumber = item.blockNumber;
|
|
@@ -542,20 +620,16 @@ function updateInternal(fetchState, optimizedPartitionsOpt, mutItems, blockLagOp
|
|
|
542
620
|
let latestFullyFetchedBlock = id !== undefined ? optimizedPartitions.entities[id].latestFetchedBlock : undefined;
|
|
543
621
|
maxBlockNumber = latestFullyFetchedBlock !== undefined ? latestFullyFetchedBlock.blockNumber : knownHeight;
|
|
544
622
|
}
|
|
545
|
-
|
|
546
|
-
let mutItems$3 = mutItems$2 !== undefined ? mutItems$2 : fetchState.buffer.slice();
|
|
547
|
-
mutItemsRef = mutItems$3;
|
|
548
|
-
latestOnBlockBlockNumber = appendOnBlockItems(mutItems$3, onBlockRegistrations, fetchState.startBlock, fetchState.latestOnBlockBlockNumber, maxBlockNumber, fetchState.maxOnBlockBufferSize);
|
|
623
|
+
latestOnBlockBlockNumber = appendOnBlockItems(blockItems, onBlockRegistrations, fetchState.startBlock, fetchState.latestOnBlockBlockNumber, maxBlockNumber, fetchState.maxOnBlockBufferSize);
|
|
549
624
|
} else {
|
|
550
625
|
latestOnBlockBlockNumber = knownHeight;
|
|
551
626
|
}
|
|
552
|
-
let mutItems$4 = mutItemsRef;
|
|
553
627
|
let updatedFetchState_startBlock = fetchState.startBlock;
|
|
554
628
|
let updatedFetchState_endBlock = fetchState.endBlock;
|
|
555
629
|
let updatedFetchState_normalSelection = fetchState.normalSelection;
|
|
556
630
|
let updatedFetchState_contractConfigs = fetchState.contractConfigs;
|
|
557
631
|
let updatedFetchState_chainId = fetchState.chainId;
|
|
558
|
-
let updatedFetchState_buffer =
|
|
632
|
+
let updatedFetchState_buffer = blockItems.length !== 0 ? mergeIntoBuffer(base, blockItems) : base;
|
|
559
633
|
let updatedFetchState_maxOnBlockBufferSize = fetchState.maxOnBlockBufferSize;
|
|
560
634
|
let updatedFetchState_onBlockRegistrations = fetchState.onBlockRegistrations;
|
|
561
635
|
let updatedFetchState_firstEventBlock = fetchState.firstEventBlock;
|
|
@@ -937,11 +1011,11 @@ function registerDynamicContracts(fetchState, indexingAddresses, items) {
|
|
|
937
1011
|
}
|
|
938
1012
|
IndexingAddresses.register(indexingAddresses, noEventsAddresses);
|
|
939
1013
|
let optimizedPartitions = createPartitionsFromIndexingAddresses(registeringContractsByContract, dynamicContractsRef, fetchState.normalSelection, fetchState.optimizedPartitions.maxAddrInPartition, fetchState.optimizedPartitions.nextPartitionIndex + newPartitions.length | 0, mutExistingPartitions.concat(newPartitions), 0);
|
|
940
|
-
return updateInternal(fetchState, optimizedPartitions, undefined, undefined, undefined);
|
|
1014
|
+
return updateInternal(fetchState, optimizedPartitions, undefined, undefined, undefined, undefined);
|
|
941
1015
|
}
|
|
942
1016
|
|
|
943
|
-
function
|
|
944
|
-
|
|
1017
|
+
function filterByClientAddress(items, indexingAddresses) {
|
|
1018
|
+
return items.filter(item => {
|
|
945
1019
|
if (item.kind !== 0) {
|
|
946
1020
|
return true;
|
|
947
1021
|
}
|
|
@@ -952,7 +1026,10 @@ function handleQueryResult(fetchState, indexingAddresses, query, latestFetchedBl
|
|
|
952
1026
|
return true;
|
|
953
1027
|
}
|
|
954
1028
|
});
|
|
955
|
-
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
function handleQueryResult(fetchState, query, latestFetchedBlock, newItems) {
|
|
1032
|
+
return updateInternal(fetchState, handleQueryResponse(fetchState.optimizedPartitions, query, fetchState.knownHeight, newItems.length, latestFetchedBlock), newItems.length !== 0 ? mergeIntoBuffer(fetchState.buffer, newItems) : undefined, true, undefined, undefined);
|
|
956
1033
|
}
|
|
957
1034
|
|
|
958
1035
|
function startFetchingQueries(param, queries) {
|
|
@@ -1051,24 +1128,6 @@ function pushGapFillQueries(queries, partitionId, rangeFromBlock, rangeEndBlock,
|
|
|
1051
1128
|
return cost.contents;
|
|
1052
1129
|
}
|
|
1053
1130
|
|
|
1054
|
-
function waterLevel(budget, footprints) {
|
|
1055
|
-
let sorted = footprints.toSorted(Primitive_float.compare);
|
|
1056
|
-
let n = sorted.length;
|
|
1057
|
-
let prefix = 0;
|
|
1058
|
-
let level;
|
|
1059
|
-
let idx = 0;
|
|
1060
|
-
while (level === undefined && idx < n) {
|
|
1061
|
-
let i = idx;
|
|
1062
|
-
prefix = prefix + sorted[i];
|
|
1063
|
-
let candidate = (budget + prefix) / (i + 1 | 0);
|
|
1064
|
-
if (i === (n - 1 | 0) || candidate <= sorted[i + 1 | 0]) {
|
|
1065
|
-
level = candidate;
|
|
1066
|
-
}
|
|
1067
|
-
idx = idx + 1 | 0;
|
|
1068
|
-
};
|
|
1069
|
-
return Stdlib_Option.getOr(level, 0);
|
|
1070
|
-
}
|
|
1071
|
-
|
|
1072
1131
|
function getNextQuery(param, chainTargetBlock, chainTargetItems, $staropt$star) {
|
|
1073
1132
|
let knownHeight = param.knownHeight;
|
|
1074
1133
|
let blockLag = param.blockLag;
|
|
@@ -1100,42 +1159,42 @@ function getNextQuery(param, chainTargetBlock, chainTargetItems, $staropt$star)
|
|
|
1100
1159
|
return queryEndBlock;
|
|
1101
1160
|
}
|
|
1102
1161
|
};
|
|
1103
|
-
let existingReservedByPartition = {};
|
|
1104
1162
|
let chainReserved = 0;
|
|
1163
|
+
let reservations = [];
|
|
1164
|
+
let partitionIndexById = {};
|
|
1165
|
+
let candidates = [];
|
|
1166
|
+
let fillStates = [];
|
|
1105
1167
|
for (let idx$1 = 0; idx$1 < partitionsCount; ++idx$1) {
|
|
1106
1168
|
let partitionId$1 = optimizedPartitions.idsInAscOrder[idx$1];
|
|
1107
1169
|
let p$1 = optimizedPartitions.entities[partitionId$1];
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1170
|
+
partitionIndexById[partitionId$1] = idx$1;
|
|
1171
|
+
let pendingCount = p$1.mutPendingQueries.length;
|
|
1172
|
+
for (let pqIdx = 0; pqIdx < pendingCount; ++pqIdx) {
|
|
1173
|
+
let pq = p$1.mutPendingQueries[pqIdx];
|
|
1174
|
+
if (pq.fetchedBlock === undefined) {
|
|
1175
|
+
chainReserved = chainReserved + pq.itemsEst;
|
|
1176
|
+
reservations.push([
|
|
1177
|
+
pq.fromBlock,
|
|
1178
|
+
pq.itemsEst
|
|
1179
|
+
]);
|
|
1180
|
+
}
|
|
1111
1181
|
}
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
let fillStates = [];
|
|
1116
|
-
let gapFillCost = 0;
|
|
1117
|
-
for (let idx$2 = 0; idx$2 < partitionsCount; ++idx$2) {
|
|
1118
|
-
let partitionId$2 = optimizedPartitions.idsInAscOrder[idx$2];
|
|
1119
|
-
let p$2 = optimizedPartitions.entities[partitionId$2];
|
|
1120
|
-
let bucket = queriesByPartitionIndex[idx$2];
|
|
1121
|
-
let pendingCount = p$2.mutPendingQueries.length;
|
|
1122
|
-
let queryEndBlock = computeQueryEndBlock(p$2);
|
|
1123
|
-
let maybeChunkRange = getMinHistoryRange(p$2);
|
|
1124
|
-
let cursor = p$2.latestFetchedBlock.blockNumber + 1 | 0;
|
|
1182
|
+
let queryEndBlock = computeQueryEndBlock(p$1);
|
|
1183
|
+
let maybeChunkRange = getMinHistoryRange(p$1);
|
|
1184
|
+
let cursor = p$1.latestFetchedBlock.blockNumber + 1 | 0;
|
|
1125
1185
|
let canContinue = true;
|
|
1126
1186
|
let chunksUsedThisCall = 0;
|
|
1127
1187
|
let pqIdx$1 = 0;
|
|
1128
1188
|
while (pqIdx$1 < pendingCount && canContinue) {
|
|
1129
|
-
let pq = p$
|
|
1130
|
-
if (pq.fromBlock > cursor) {
|
|
1131
|
-
let beforeLen =
|
|
1132
|
-
|
|
1133
|
-
chunksUsedThisCall = chunksUsedThisCall + (
|
|
1134
|
-
gapFillCost = gapFillCost + cost$1;
|
|
1189
|
+
let pq$1 = p$1.mutPendingQueries[pqIdx$1];
|
|
1190
|
+
if (pq$1.fromBlock > cursor) {
|
|
1191
|
+
let beforeLen = candidates.length;
|
|
1192
|
+
pushGapFillQueries(candidates, partitionId$1, cursor, Utils.$$Math.minOptInt(pq$1.fromBlock - 1 | 0, queryEndBlock), knownHeight, chainTargetBlock, maybeChunkRange, (12 - pendingCount | 0) - chunksUsedThisCall | 0, p$1, chainTargetItems / partitionsCount, chunkItemsMultiplier, p$1.selection, p$1.addressesByContractName);
|
|
1193
|
+
chunksUsedThisCall = chunksUsedThisCall + (candidates.length - beforeLen | 0) | 0;
|
|
1135
1194
|
}
|
|
1136
|
-
let toBlock = pq.toBlock;
|
|
1137
|
-
if (toBlock !== undefined && pq.isChunk) {
|
|
1138
|
-
let match = pq.fetchedBlock;
|
|
1195
|
+
let toBlock = pq$1.toBlock;
|
|
1196
|
+
if (toBlock !== undefined && pq$1.isChunk) {
|
|
1197
|
+
let match = pq$1.fetchedBlock;
|
|
1139
1198
|
if (match !== undefined) {
|
|
1140
1199
|
let blockNumber = match.blockNumber;
|
|
1141
1200
|
cursor = blockNumber < toBlock ? blockNumber + 1 | 0 : toBlock + 1 | 0;
|
|
@@ -1149,26 +1208,17 @@ function getNextQuery(param, chainTargetBlock, chainTargetItems, $staropt$star)
|
|
|
1149
1208
|
};
|
|
1150
1209
|
if (canContinue) {
|
|
1151
1210
|
fillStates.push({
|
|
1152
|
-
partitionId: partitionId$
|
|
1153
|
-
p: p$
|
|
1211
|
+
partitionId: partitionId$1,
|
|
1212
|
+
p: p$1,
|
|
1154
1213
|
cursor: cursor,
|
|
1155
1214
|
chunksUsedThisCall: chunksUsedThisCall,
|
|
1156
1215
|
pendingCount: pendingCount,
|
|
1157
1216
|
queryEndBlock: queryEndBlock,
|
|
1158
|
-
maybeChunkRange: maybeChunkRange
|
|
1159
|
-
bucket: bucket
|
|
1217
|
+
maybeChunkRange: maybeChunkRange
|
|
1160
1218
|
});
|
|
1161
1219
|
}
|
|
1162
1220
|
}
|
|
1163
|
-
let
|
|
1164
|
-
let reservedByPartition = {};
|
|
1165
|
-
fillStates.forEach(fs => {
|
|
1166
|
-
let cost = existingReservedByPartition[fs.partitionId];
|
|
1167
|
-
for (let i = 0, i_finish = fs.bucket.length; i < i_finish; ++i) {
|
|
1168
|
-
cost = cost + fs.bucket[i].itemsEst;
|
|
1169
|
-
}
|
|
1170
|
-
reservedByPartition[fs.partitionId] = cost;
|
|
1171
|
-
});
|
|
1221
|
+
let freshBudget = Primitive_float.max(0, chainTargetItems - chainReserved);
|
|
1172
1222
|
let isInRange = fs => {
|
|
1173
1223
|
let tmp = false;
|
|
1174
1224
|
if (fs.cursor <= chainTargetBlock) {
|
|
@@ -1182,7 +1232,18 @@ function getNextQuery(param, chainTargetBlock, chainTargetItems, $staropt$star)
|
|
|
1182
1232
|
}
|
|
1183
1233
|
};
|
|
1184
1234
|
let inRangeStates = fillStates.filter(isInRange);
|
|
1185
|
-
let
|
|
1235
|
+
let inRangeCount = inRangeStates.length;
|
|
1236
|
+
let probeShare = inRangeCount === 0 ? 0 : freshBudget / inRangeCount;
|
|
1237
|
+
let frontierCursor = Stdlib_Array.reduce(inRangeStates, chainTargetBlock, (min, fs) => {
|
|
1238
|
+
if (fs.cursor < min) {
|
|
1239
|
+
return fs.cursor;
|
|
1240
|
+
} else {
|
|
1241
|
+
return min;
|
|
1242
|
+
}
|
|
1243
|
+
});
|
|
1244
|
+
let rangeToTarget = (chainTargetBlock - frontierCursor | 0) + 1 | 0;
|
|
1245
|
+
let rangeTargetDensity = inRangeCount > 0 && rangeToTarget > 0 ? freshBudget / rangeToTarget : 0;
|
|
1246
|
+
inRangeStates.forEach(fs => {
|
|
1186
1247
|
let p = fs.p;
|
|
1187
1248
|
let eb = fs.queryEndBlock;
|
|
1188
1249
|
let maxBlock = eb !== undefined ? eb : chainTargetBlock;
|
|
@@ -1191,39 +1252,33 @@ function getNextQuery(param, chainTargetBlock, chainTargetItems, $staropt$star)
|
|
|
1191
1252
|
if (match !== undefined && match$1 !== undefined && match$1 > 0) {
|
|
1192
1253
|
let chunkSize = Js_math.ceil_int(match * 1.8);
|
|
1193
1254
|
let maxChunksRemaining = (12 - fs.pendingCount | 0) - fs.chunksUsedThisCall | 0;
|
|
1194
|
-
let
|
|
1255
|
+
let chunkStartCeiling = Primitive_int.min(maxBlock, chainTargetBlock);
|
|
1195
1256
|
let created = 0;
|
|
1196
1257
|
let chunkFromBlock = fs.cursor;
|
|
1197
|
-
let
|
|
1198
|
-
while (
|
|
1258
|
+
let generatedItems = 0;
|
|
1259
|
+
while (created < maxChunksRemaining && chunkFromBlock <= chunkStartCeiling && generatedItems <= freshBudget) {
|
|
1199
1260
|
let chunkToBlock = Primitive_int.min((chunkFromBlock + chunkSize | 0) - 1 | 0, maxBlock);
|
|
1200
1261
|
let rawEst = match$1 * ((chunkToBlock - chunkFromBlock | 0) + 1 | 0);
|
|
1201
1262
|
let itemsEst = Primitive_int.max(1, Math.ceil(rawEst) | 0);
|
|
1202
1263
|
let itemsTarget = Primitive_int.max(1, Math.ceil(rawEst * chunkItemsMultiplier) | 0);
|
|
1203
|
-
|
|
1204
|
-
fs.
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
created = created + 1 | 0;
|
|
1217
|
-
} else {
|
|
1218
|
-
budgetLeft = false;
|
|
1219
|
-
}
|
|
1264
|
+
candidates.push({
|
|
1265
|
+
partitionId: fs.partitionId,
|
|
1266
|
+
fromBlock: chunkFromBlock,
|
|
1267
|
+
toBlock: chunkToBlock,
|
|
1268
|
+
isChunk: true,
|
|
1269
|
+
itemsTarget: itemsTarget,
|
|
1270
|
+
itemsEst: itemsEst,
|
|
1271
|
+
selection: p.selection,
|
|
1272
|
+
addressesByContractName: p.addressesByContractName
|
|
1273
|
+
});
|
|
1274
|
+
generatedItems = generatedItems + itemsEst;
|
|
1275
|
+
chunkFromBlock = chunkToBlock + 1 | 0;
|
|
1276
|
+
created = created + 1 | 0;
|
|
1220
1277
|
};
|
|
1221
|
-
|
|
1222
|
-
fs.chunksUsedThisCall = fs.chunksUsedThisCall + created | 0;
|
|
1223
|
-
return consumed;
|
|
1278
|
+
return;
|
|
1224
1279
|
}
|
|
1225
|
-
let itemsTarget$1 = Primitive_int.max(1, Math.round(
|
|
1226
|
-
|
|
1280
|
+
let itemsTarget$1 = rangeToTarget > 0 ? Primitive_int.max(1, Math.round(rangeTargetDensity * ((chainTargetBlock - fs.cursor | 0) + 1 | 0) / inRangeCount) | 0) : Primitive_int.max(1, Math.round(probeShare) | 0);
|
|
1281
|
+
candidates.push({
|
|
1227
1282
|
partitionId: fs.partitionId,
|
|
1228
1283
|
fromBlock: fs.cursor,
|
|
1229
1284
|
toBlock: fs.queryEndBlock,
|
|
@@ -1233,32 +1288,53 @@ function getNextQuery(param, chainTargetBlock, chainTargetItems, $staropt$star)
|
|
|
1233
1288
|
selection: p.selection,
|
|
1234
1289
|
addressesByContractName: p.addressesByContractName
|
|
1235
1290
|
});
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1291
|
+
});
|
|
1292
|
+
let acceptanceStream = [];
|
|
1293
|
+
candidates.forEach(query => {
|
|
1294
|
+
acceptanceStream.push([
|
|
1295
|
+
query.fromBlock,
|
|
1296
|
+
query.itemsEst,
|
|
1297
|
+
query
|
|
1298
|
+
]);
|
|
1299
|
+
});
|
|
1300
|
+
reservations.forEach(param => {
|
|
1301
|
+
acceptanceStream.push([
|
|
1302
|
+
param[0],
|
|
1303
|
+
param[1],
|
|
1304
|
+
undefined
|
|
1305
|
+
]);
|
|
1306
|
+
});
|
|
1307
|
+
acceptanceStream.sort((param, param$1) => {
|
|
1308
|
+
let bFrom = param$1[0];
|
|
1309
|
+
let aFrom = param[0];
|
|
1310
|
+
if (aFrom !== bFrom) {
|
|
1311
|
+
return Primitive_int.compare(aFrom, bFrom);
|
|
1312
|
+
}
|
|
1313
|
+
let bQuery = param$1[2];
|
|
1314
|
+
if (param[2] !== undefined) {
|
|
1315
|
+
if (bQuery !== undefined) {
|
|
1316
|
+
return 0;
|
|
1317
|
+
} else {
|
|
1318
|
+
return 1;
|
|
1259
1319
|
}
|
|
1260
|
-
})
|
|
1261
|
-
|
|
1320
|
+
} else if (bQuery !== undefined) {
|
|
1321
|
+
return -1;
|
|
1322
|
+
} else {
|
|
1323
|
+
return 0;
|
|
1324
|
+
}
|
|
1325
|
+
});
|
|
1326
|
+
let streamCount = acceptanceStream.length;
|
|
1327
|
+
let remainingBudget = chainTargetItems;
|
|
1328
|
+
let acceptIdx = 0;
|
|
1329
|
+
while (remainingBudget > 0 && acceptIdx < streamCount) {
|
|
1330
|
+
let match$1 = acceptanceStream[acceptIdx];
|
|
1331
|
+
let maybeQuery = match$1[2];
|
|
1332
|
+
if (maybeQuery !== undefined) {
|
|
1333
|
+
let partitionIdx = partitionIndexById[maybeQuery.partitionId];
|
|
1334
|
+
queriesByPartitionIndex[partitionIdx].push(maybeQuery);
|
|
1335
|
+
}
|
|
1336
|
+
remainingBudget = remainingBudget - match$1[1];
|
|
1337
|
+
acceptIdx = acceptIdx + 1 | 0;
|
|
1262
1338
|
};
|
|
1263
1339
|
let queries = queriesByPartitionIndex.flat();
|
|
1264
1340
|
if (Utils.$$Array.isEmpty(queries)) {
|
|
@@ -1525,7 +1601,7 @@ function rollback(fetchState, indexingAddresses, targetBlockNumber) {
|
|
|
1525
1601
|
let tmp;
|
|
1526
1602
|
tmp = item.kind === 0 ? item.blockNumber : item.blockNumber;
|
|
1527
1603
|
return tmp <= targetBlockNumber;
|
|
1528
|
-
}), undefined, undefined);
|
|
1604
|
+
}), true, undefined, undefined);
|
|
1529
1605
|
}
|
|
1530
1606
|
|
|
1531
1607
|
function resetPendingQueries(fetchState) {
|
|
@@ -1678,7 +1754,7 @@ function getProgressBlockNumberAt(fetchState, index) {
|
|
|
1678
1754
|
function updateKnownHeight(fetchState, knownHeight) {
|
|
1679
1755
|
if (knownHeight > fetchState.knownHeight) {
|
|
1680
1756
|
Prometheus.IndexingKnownHeight.set(knownHeight, fetchState.chainId);
|
|
1681
|
-
return updateInternal(fetchState, undefined, undefined, undefined, knownHeight);
|
|
1757
|
+
return updateInternal(fetchState, undefined, undefined, undefined, undefined, knownHeight);
|
|
1682
1758
|
} else {
|
|
1683
1759
|
return fetchState;
|
|
1684
1760
|
}
|
|
@@ -1698,7 +1774,9 @@ export {
|
|
|
1698
1774
|
bufferBlockNumber,
|
|
1699
1775
|
bufferBlock,
|
|
1700
1776
|
bufferReadyCount,
|
|
1777
|
+
getRegistrationIndex,
|
|
1701
1778
|
compareBufferItem,
|
|
1779
|
+
mergeIntoBuffer,
|
|
1702
1780
|
blockItemLogIndex,
|
|
1703
1781
|
appendOnBlockItems,
|
|
1704
1782
|
updateInternal,
|
|
@@ -1707,11 +1785,11 @@ export {
|
|
|
1707
1785
|
addressesByContractNameGetAll,
|
|
1708
1786
|
createPartitionsFromIndexingAddresses,
|
|
1709
1787
|
registerDynamicContracts,
|
|
1788
|
+
filterByClientAddress,
|
|
1710
1789
|
handleQueryResult,
|
|
1711
1790
|
startFetchingQueries,
|
|
1712
1791
|
maxPendingChunksPerPartition,
|
|
1713
1792
|
pushGapFillQueries,
|
|
1714
|
-
waterLevel,
|
|
1715
1793
|
getNextQuery,
|
|
1716
1794
|
hasReadyItem,
|
|
1717
1795
|
getReadyItemsCount,
|
package/src/HandlerRegister.res
CHANGED
|
@@ -679,7 +679,9 @@ let finishRegistration = (~config: Config.t): registrationsByChainId => {
|
|
|
679
679
|
config.ecosystem.name === Evm &&
|
|
680
680
|
(registration->getResolvedWhere).topicSelections->Utils.Array.isEmpty
|
|
681
681
|
if !isDroppedByWhere {
|
|
682
|
-
onEventRegistrations
|
|
682
|
+
onEventRegistrations
|
|
683
|
+
->Array.push({...registration, index: onEventRegistrations->Array.length})
|
|
684
|
+
->ignore
|
|
683
685
|
}
|
|
684
686
|
| None => ()
|
|
685
687
|
}
|
|
@@ -388,10 +388,11 @@ function finishRegistration(config) {
|
|
|
388
388
|
return;
|
|
389
389
|
}
|
|
390
390
|
let isDroppedByWhere = config.ecosystem.name === "evm" && Utils.$$Array.isEmpty(registration$1.resolvedWhere.topicSelections);
|
|
391
|
-
if (
|
|
392
|
-
onEventRegistrations.push(registration$1);
|
|
391
|
+
if (isDroppedByWhere) {
|
|
393
392
|
return;
|
|
394
393
|
}
|
|
394
|
+
let newrecord = {...registration$1};
|
|
395
|
+
onEventRegistrations.push((newrecord.index = onEventRegistrations.length, newrecord));
|
|
395
396
|
});
|
|
396
397
|
});
|
|
397
398
|
registrationsByChainId[key] = {
|
package/src/Internal.res
CHANGED
|
@@ -330,6 +330,9 @@ type eventPayload
|
|
|
330
330
|
@get external getPayloadBlock: eventPayload => Nullable.t<eventBlock> = "block"
|
|
331
331
|
@set external setPayloadBlock: (eventPayload, eventBlock) => unit = "block"
|
|
332
332
|
|
|
333
|
+
// The log's emitting address (EVM/Fuel; the program id carries it for SVM).
|
|
334
|
+
@get external getPayloadSrcAddress: eventPayload => Address.t = "srcAddress"
|
|
335
|
+
|
|
333
336
|
type genericLoaderArgs<'event, 'context> = {
|
|
334
337
|
event: 'event,
|
|
335
338
|
context: 'context,
|
|
@@ -555,6 +558,11 @@ type svmInstructionEventConfig = {
|
|
|
555
558
|
// must stay directly constructable), and the evm→base cast in sources is sound
|
|
556
559
|
// by ecosystem homogeneity — an EVM chain only ever holds `evmOnEventRegistration`s.
|
|
557
560
|
type onEventRegistration = {
|
|
561
|
+
// Chain-scoped sequential index — the registration's position in the
|
|
562
|
+
// chain's onEventRegistrations array, assigned when registration finishes
|
|
563
|
+
// (-1 until then). Native-routed items reference their registration by this
|
|
564
|
+
// index across the napi boundary; sources resolve it before creating an item.
|
|
565
|
+
index: int,
|
|
558
566
|
eventConfig: eventConfig,
|
|
559
567
|
handler: option<handler>,
|
|
560
568
|
contractRegister: option<contractRegister>,
|
|
@@ -601,8 +609,9 @@ type indexingAddress = {
|
|
|
601
609
|
|
|
602
610
|
type dcs = array<indexingAddress>
|
|
603
611
|
|
|
604
|
-
// Duplicate the type from item
|
|
605
|
-
//
|
|
612
|
+
// Duplicate the type from item to keep item properly unboxed. Runtime event
|
|
613
|
+
// items carry the registration their source already resolved from the
|
|
614
|
+
// ChainState-owned registration array.
|
|
606
615
|
type eventItem = private {
|
|
607
616
|
kind: [#0],
|
|
608
617
|
onEventRegistration: onEventRegistration,
|
package/src/LogSelection.res
CHANGED
|
@@ -1,65 +1,3 @@
|
|
|
1
|
-
exception MissingRequiredTopic0
|
|
2
|
-
let makeTopicSelection = (~topic0, ~topic1=[], ~topic2=[], ~topic3=[]): result<
|
|
3
|
-
Internal.topicSelection,
|
|
4
|
-
exn,
|
|
5
|
-
> =>
|
|
6
|
-
if topic0->Utils.Array.isEmpty {
|
|
7
|
-
Error(MissingRequiredTopic0)
|
|
8
|
-
} else {
|
|
9
|
-
{
|
|
10
|
-
Internal.topic0,
|
|
11
|
-
topic1,
|
|
12
|
-
topic2,
|
|
13
|
-
topic3,
|
|
14
|
-
}->Ok
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
let hasFilters = ({topic1, topic2, topic3}: Internal.topicSelection) => {
|
|
18
|
-
[topic1, topic2, topic3]->Array.find(topic => !Utils.Array.isEmpty(topic))->Option.isSome
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
For a group of topic selections, if multiple only use topic0, then they can be compressed into one
|
|
23
|
-
selection combining the topic0s
|
|
24
|
-
*/
|
|
25
|
-
let compressTopicSelections = (topicSelections: array<Internal.topicSelection>) => {
|
|
26
|
-
let topic0sOfSelectionsWithoutFilters = []
|
|
27
|
-
|
|
28
|
-
let selectionsWithFilters = []
|
|
29
|
-
|
|
30
|
-
topicSelections->Array.forEach(selection => {
|
|
31
|
-
if selection->hasFilters {
|
|
32
|
-
selectionsWithFilters->Array.push(selection)->ignore
|
|
33
|
-
} else {
|
|
34
|
-
selection.topic0->Array.forEach(topic0 => {
|
|
35
|
-
topic0sOfSelectionsWithoutFilters->Array.push(topic0)->ignore
|
|
36
|
-
})
|
|
37
|
-
}
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
switch topic0sOfSelectionsWithoutFilters {
|
|
41
|
-
| [] => selectionsWithFilters
|
|
42
|
-
| topic0 =>
|
|
43
|
-
let selectionWithoutFilters: Internal.topicSelection = {
|
|
44
|
-
topic0,
|
|
45
|
-
topic1: [],
|
|
46
|
-
topic2: [],
|
|
47
|
-
topic3: [],
|
|
48
|
-
}
|
|
49
|
-
Array.concat([selectionWithoutFilters], selectionsWithFilters)
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
type t = {
|
|
54
|
-
addresses: array<Address.t>,
|
|
55
|
-
topicSelections: array<Internal.topicSelection>,
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
let make = (~addresses, ~topicSelections) => {
|
|
59
|
-
let topicSelections = compressTopicSelections(topicSelections)
|
|
60
|
-
{addresses, topicSelections}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
1
|
// Expand a resolved topic selection into concrete topic values for a query:
|
|
64
2
|
// `ContractAddresses` markers become the given partition addresses encoded as
|
|
65
3
|
// topics; `Values` pass through.
|