envio 3.2.1 → 3.3.0-alpha.0
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 -7
- package/src/Batch.res +12 -15
- package/src/Batch.res.mjs +4 -5
- package/src/BatchProcessing.res +199 -0
- package/src/BatchProcessing.res.mjs +125 -0
- package/src/ChainFetching.res +375 -0
- package/src/ChainFetching.res.mjs +206 -0
- package/src/ChainMetadata.res +27 -0
- package/src/ChainMetadata.res.mjs +27 -0
- package/src/ChainState.res +618 -0
- package/src/ChainState.res.mjs +461 -0
- package/src/ChainState.resi +85 -0
- package/src/Config.res +13 -4
- package/src/Config.res.mjs +8 -3
- package/src/ContractRegisterContext.res +106 -0
- package/src/ContractRegisterContext.res.mjs +76 -0
- package/src/Core.res +3 -0
- package/src/CrossChainState.res +269 -0
- package/src/CrossChainState.res.mjs +197 -0
- package/src/CrossChainState.resi +47 -0
- package/src/Ecosystem.res +58 -0
- package/src/Ecosystem.res.mjs +43 -1
- package/src/Env.res +7 -2
- package/src/Env.res.mjs +5 -2
- package/src/EventConfigBuilder.res +2 -2
- package/src/EventProcessing.res +60 -46
- package/src/EventProcessing.res.mjs +33 -32
- package/src/EventUtils.res +0 -4
- package/src/EventUtils.res.mjs +0 -4
- package/src/ExitOnCaughtUp.res +10 -0
- package/src/ExitOnCaughtUp.res.mjs +22 -0
- package/src/FetchState.res +124 -62
- package/src/FetchState.res.mjs +159 -93
- package/src/InMemoryStore.res +36 -451
- package/src/InMemoryStore.res.mjs +20 -369
- package/src/IndexerLoop.res +44 -0
- package/src/IndexerLoop.res.mjs +46 -0
- package/src/IndexerState.res +544 -0
- package/src/IndexerState.res.mjs +547 -0
- package/src/IndexerState.resi +132 -0
- package/src/Internal.res +29 -8
- package/src/LoadLayer.res +20 -18
- package/src/LoadLayer.res.mjs +14 -12
- package/src/LoadLayer.resi +6 -3
- package/src/Logging.res +11 -44
- package/src/Logging.res.mjs +10 -42
- package/src/Main.res +54 -79
- package/src/Main.res.mjs +44 -56
- package/src/PgStorage.res +8 -71
- package/src/PgStorage.res.mjs +3 -47
- package/src/Prometheus.res +7 -8
- package/src/Prometheus.res.mjs +7 -4
- package/src/PruneStaleHistory.res +45 -0
- package/src/PruneStaleHistory.res.mjs +46 -0
- package/src/RawEvent.res +73 -0
- package/src/RawEvent.res.mjs +51 -0
- package/src/Rollback.res +204 -0
- package/src/Rollback.res.mjs +118 -0
- package/src/SimulateItems.res +12 -10
- package/src/SimulateItems.res.mjs +1 -1
- package/src/UserContext.res +26 -114
- package/src/UserContext.res.mjs +15 -78
- package/src/Writing.res +242 -0
- package/src/Writing.res.mjs +215 -0
- package/src/db/InternalTable.res +14 -27
- package/src/sources/Evm.res +40 -1
- package/src/sources/Evm.res.mjs +94 -84
- package/src/sources/Fuel.res +40 -1
- package/src/sources/Fuel.res.mjs +36 -26
- package/src/sources/HyperFuel.res +41 -120
- package/src/sources/HyperFuel.res.mjs +42 -80
- package/src/sources/HyperFuel.resi +1 -24
- package/src/sources/HyperFuelClient.res +16 -297
- package/src/sources/HyperFuelClient.res.mjs +5 -4
- package/src/sources/HyperFuelSource.res +33 -8
- package/src/sources/HyperFuelSource.res.mjs +56 -10
- package/src/sources/HyperSyncSource.res +5 -3
- package/src/sources/HyperSyncSource.res.mjs +1 -1
- package/src/sources/RpcSource.res +2 -2
- package/src/sources/RpcSource.res.mjs +1 -1
- package/src/sources/SourceManager.res +8 -18
- package/src/sources/SourceManager.res.mjs +8 -5
- package/src/sources/SourceManager.resi +4 -1
- package/src/sources/Svm.res +18 -1
- package/src/sources/Svm.res.mjs +30 -22
- package/src/sources/SvmHyperSyncSource.res +1 -1
- package/src/sources/SvmHyperSyncSource.res.mjs +1 -1
- package/src/tui/Tui.res +38 -36
- package/src/tui/Tui.res.mjs +51 -51
- package/src/ChainFetcher.res +0 -519
- package/src/ChainFetcher.res.mjs +0 -314
- package/src/ChainManager.res +0 -358
- package/src/ChainManager.res.mjs +0 -291
- package/src/Ctx.res +0 -6
- package/src/Ctx.res.mjs +0 -2
- package/src/GlobalState.res +0 -1056
- package/src/GlobalState.res.mjs +0 -1086
- package/src/GlobalStateManager.res +0 -57
- package/src/GlobalStateManager.res.mjs +0 -68
- package/src/GlobalStateManager.resi +0 -7
- package/src/Ports.res +0 -5
- package/src/Ports.res.mjs +0 -9
- package/src/adapters/MarkBatchProcessedAdapter.res +0 -5
- package/src/adapters/MarkBatchProcessedAdapter.res.mjs +0 -14
- package/src/sources/EnvioApiClient.res +0 -15
- package/src/sources/EnvioApiClient.res.mjs +0 -24
package/src/EventUtils.res.mjs
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
-
import * as Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js";
|
|
4
|
-
|
|
5
|
-
let isEarlierUnordered = Primitive_object.lessthan;
|
|
6
3
|
|
|
7
4
|
function packEventIndex(blockNumber, logIndex) {
|
|
8
5
|
let blockNumber$1 = BigInt(blockNumber);
|
|
@@ -12,7 +9,6 @@ function packEventIndex(blockNumber, logIndex) {
|
|
|
12
9
|
}
|
|
13
10
|
|
|
14
11
|
export {
|
|
15
|
-
isEarlierUnordered,
|
|
16
12
|
packEventIndex,
|
|
17
13
|
}
|
|
18
14
|
/* No side effect */
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Flush, then exit unless a reorg landed during the flush (which parks a
|
|
2
|
+
// rollback to recover instead).
|
|
3
|
+
let run = async (state: IndexerState.t) => {
|
|
4
|
+
ChainMetadata.stage(state)
|
|
5
|
+
await state->Writing.flush
|
|
6
|
+
if !(state->IndexerState.isStopped) && !(state->IndexerState.isResolvingReorg) {
|
|
7
|
+
Logging.info("Exiting with success")
|
|
8
|
+
NodeJs.process->NodeJs.exitWithCode(Success)
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Logging from "./Logging.res.mjs";
|
|
4
|
+
import * as Writing from "./Writing.res.mjs";
|
|
5
|
+
import * as Process from "process";
|
|
6
|
+
import * as IndexerState from "./IndexerState.res.mjs";
|
|
7
|
+
import * as ChainMetadata from "./ChainMetadata.res.mjs";
|
|
8
|
+
|
|
9
|
+
async function run(state) {
|
|
10
|
+
ChainMetadata.stage(state);
|
|
11
|
+
await Writing.flush(state);
|
|
12
|
+
if (!IndexerState.isStopped(state) && !IndexerState.isResolvingReorg(state)) {
|
|
13
|
+
Logging.info("Exiting with success");
|
|
14
|
+
Process.exit(0);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export {
|
|
20
|
+
run,
|
|
21
|
+
}
|
|
22
|
+
/* Logging Not a pure module */
|
package/src/FetchState.res
CHANGED
|
@@ -496,9 +496,10 @@ type t = {
|
|
|
496
496
|
blockLag: int,
|
|
497
497
|
// Buffer of items ordered from earliest to latest
|
|
498
498
|
buffer: array<Internal.item>,
|
|
499
|
-
//
|
|
500
|
-
//
|
|
501
|
-
|
|
499
|
+
// Caps how far ahead onBlock items are pre-generated (set to 2x the batch
|
|
500
|
+
// size). Fetch depth is bounded separately by getNextQuery's bufferLimit, the
|
|
501
|
+
// chain's per-tick slice of the indexer-wide pool.
|
|
502
|
+
maxOnBlockBufferSize: int,
|
|
502
503
|
onBlockConfigs: array<Internal.onBlockConfig>,
|
|
503
504
|
knownHeight: int,
|
|
504
505
|
firstEventBlock: option<int>,
|
|
@@ -554,7 +555,7 @@ let numAddresses = fetchState => fetchState.indexingAddresses->Utils.Dict.size
|
|
|
554
555
|
|
|
555
556
|
// Appends Block items produced by the onBlock handlers for every block in
|
|
556
557
|
// (fromBlock, maxBlockNumber] into mutItems and returns the new
|
|
557
|
-
// latestOnBlockBlockNumber pointer.
|
|
558
|
+
// latestOnBlockBlockNumber pointer. maxOnBlockBufferSize bounds how many items
|
|
558
559
|
// are generated at once to prevent OOM.
|
|
559
560
|
let appendOnBlockItems = (
|
|
560
561
|
~mutItems: array<Internal.item>,
|
|
@@ -562,7 +563,7 @@ let appendOnBlockItems = (
|
|
|
562
563
|
~indexerStartBlock,
|
|
563
564
|
~fromBlock,
|
|
564
565
|
~maxBlockNumber,
|
|
565
|
-
~
|
|
566
|
+
~maxOnBlockBufferSize,
|
|
566
567
|
) => {
|
|
567
568
|
let newItemsCounter = ref(0)
|
|
568
569
|
let latestOnBlockBlockNumber = ref(fromBlock)
|
|
@@ -573,7 +574,7 @@ let appendOnBlockItems = (
|
|
|
573
574
|
while (
|
|
574
575
|
latestOnBlockBlockNumber.contents < maxBlockNumber &&
|
|
575
576
|
// Additional safeguard to prevent OOM
|
|
576
|
-
newItemsCounter.contents <=
|
|
577
|
+
newItemsCounter.contents <= maxOnBlockBufferSize
|
|
577
578
|
) {
|
|
578
579
|
let blockNumber = latestOnBlockBlockNumber.contents + 1
|
|
579
580
|
latestOnBlockBlockNumber := blockNumber
|
|
@@ -627,7 +628,7 @@ let updateInternal = (
|
|
|
627
628
|
| [] => knownHeight
|
|
628
629
|
| onBlockConfigs => {
|
|
629
630
|
// Calculate the max block number we are going to create items for
|
|
630
|
-
// Use
|
|
631
|
+
// Use maxOnBlockBufferSize to get the last target item in the buffer
|
|
631
632
|
//
|
|
632
633
|
// mutItems is not very reliable, since it might not be sorted,
|
|
633
634
|
// but the chances for it happen are very low and not critical
|
|
@@ -636,7 +637,7 @@ let updateInternal = (
|
|
|
636
637
|
let maxBlockNumber = switch switch mutItemsRef.contents {
|
|
637
638
|
| Some(mutItems) => mutItems
|
|
638
639
|
| None => fetchState.buffer
|
|
639
|
-
}->Array.get(fetchState.
|
|
640
|
+
}->Array.get(fetchState.maxOnBlockBufferSize - 1) {
|
|
640
641
|
| Some(item) => item->Internal.getItemBlockNumber
|
|
641
642
|
| None =>
|
|
642
643
|
switch optimizedPartitions->OptimizedPartitions.getLatestFullyFetchedBlock {
|
|
@@ -657,7 +658,7 @@ let updateInternal = (
|
|
|
657
658
|
~indexerStartBlock=fetchState.startBlock,
|
|
658
659
|
~fromBlock=fetchState.latestOnBlockBlockNumber,
|
|
659
660
|
~maxBlockNumber,
|
|
660
|
-
~
|
|
661
|
+
~maxOnBlockBufferSize=fetchState.maxOnBlockBufferSize,
|
|
661
662
|
)
|
|
662
663
|
}
|
|
663
664
|
}
|
|
@@ -669,7 +670,7 @@ let updateInternal = (
|
|
|
669
670
|
normalSelection: fetchState.normalSelection,
|
|
670
671
|
chainId: fetchState.chainId,
|
|
671
672
|
onBlockConfigs: fetchState.onBlockConfigs,
|
|
672
|
-
|
|
673
|
+
maxOnBlockBufferSize: fetchState.maxOnBlockBufferSize,
|
|
673
674
|
optimizedPartitions,
|
|
674
675
|
latestOnBlockBlockNumber,
|
|
675
676
|
indexingAddresses,
|
|
@@ -1228,9 +1229,9 @@ let handleQueryResult = (
|
|
|
1228
1229
|
// param-level analogue of EventRouter's srcAddress effectiveStartBlock check.
|
|
1229
1230
|
let newItems = newItems->Array.filter(item =>
|
|
1230
1231
|
switch item {
|
|
1231
|
-
| Internal.Event({eventConfig,
|
|
1232
|
+
| Internal.Event({eventConfig, payload, blockNumber}) =>
|
|
1232
1233
|
switch eventConfig.clientAddressFilter {
|
|
1233
|
-
| Some(filter) => filter(
|
|
1234
|
+
| Some(filter) => filter(payload, blockNumber, fetchState.indexingAddresses)
|
|
1234
1235
|
| None => true
|
|
1235
1236
|
}
|
|
1236
1237
|
| _ => true
|
|
@@ -1319,26 +1320,30 @@ let pushQueriesForRange = (
|
|
|
1319
1320
|
| None => maxQueryBlockNumber
|
|
1320
1321
|
}
|
|
1321
1322
|
let chunkSize = Js.Math.ceil_int(chunkRange->Int.toFloat *. 1.8)
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1323
|
+
// Probe with two smaller chunks first so their responses come back
|
|
1324
|
+
// quickly and refresh the chunking heuristic, then three full-size chunks.
|
|
1325
|
+
let probeSize = Js.Math.ceil_int(chunkRange->Int.toFloat *. 0.9)
|
|
1326
|
+
let getChunkSize = chunkIdx => chunkIdx < 2 ? probeSize : chunkSize
|
|
1327
|
+
if rangeFromBlock + getChunkSize(0) + getChunkSize(1) - 1 <= maxBlock {
|
|
1328
|
+
let chunkFromBlock = ref(rangeFromBlock)
|
|
1329
|
+
let chunkIdx = ref(0)
|
|
1330
|
+
while (
|
|
1331
|
+
chunkIdx.contents < 5 &&
|
|
1332
|
+
chunkFromBlock.contents + getChunkSize(chunkIdx.contents) - 1 <= maxBlock
|
|
1333
|
+
) {
|
|
1334
|
+
let chunkToBlock = chunkFromBlock.contents + getChunkSize(chunkIdx.contents) - 1
|
|
1335
|
+
queries->Array.push({
|
|
1336
|
+
partitionId,
|
|
1337
|
+
fromBlock: chunkFromBlock.contents,
|
|
1338
|
+
toBlock: Some(chunkToBlock),
|
|
1339
|
+
isChunk: true,
|
|
1340
|
+
selection,
|
|
1341
|
+
addressesByContractName,
|
|
1342
|
+
indexingAddresses,
|
|
1343
|
+
})
|
|
1344
|
+
chunkFromBlock := chunkToBlock + 1
|
|
1345
|
+
chunkIdx := chunkIdx.contents + 1
|
|
1346
|
+
}
|
|
1342
1347
|
} else {
|
|
1343
1348
|
// Not enough room for 2 chunks, fall back to a single query
|
|
1344
1349
|
queries->Array.push({
|
|
@@ -1356,23 +1361,30 @@ let pushQueriesForRange = (
|
|
|
1356
1361
|
}
|
|
1357
1362
|
}
|
|
1358
1363
|
|
|
1364
|
+
// Most parallel in-flight chunk queries a single partition may have at once.
|
|
1365
|
+
let maxPendingChunksPerPartition = 10
|
|
1366
|
+
|
|
1359
1367
|
let getNextQuery = (
|
|
1360
1368
|
{
|
|
1361
1369
|
buffer,
|
|
1362
1370
|
optimizedPartitions,
|
|
1363
|
-
targetBufferSize,
|
|
1364
1371
|
indexingAddresses,
|
|
1365
1372
|
blockLag,
|
|
1366
1373
|
latestOnBlockBlockNumber,
|
|
1367
1374
|
knownHeight,
|
|
1368
1375
|
} as fetchState: t,
|
|
1369
1376
|
~concurrencyLimit,
|
|
1377
|
+
~bufferLimit,
|
|
1370
1378
|
) => {
|
|
1371
1379
|
let headBlockNumber = knownHeight - blockLag
|
|
1372
1380
|
if headBlockNumber <= 0 {
|
|
1373
1381
|
WaitingForNewBlock
|
|
1374
1382
|
} else if concurrencyLimit === 0 {
|
|
1375
1383
|
ReachedMaxConcurrency
|
|
1384
|
+
} else if bufferLimit <= 0 {
|
|
1385
|
+
// No room left in the shared buffer pool for this chain; wait for processing
|
|
1386
|
+
// to drain before fetching more.
|
|
1387
|
+
NothingToQuery
|
|
1376
1388
|
} else {
|
|
1377
1389
|
let isOnBlockBehindTheHead = latestOnBlockBlockNumber < headBlockNumber
|
|
1378
1390
|
let shouldWaitForNewBlock = ref(
|
|
@@ -1383,13 +1395,12 @@ let getNextQuery = (
|
|
|
1383
1395
|
!isOnBlockBehindTheHead,
|
|
1384
1396
|
)
|
|
1385
1397
|
|
|
1386
|
-
//
|
|
1387
|
-
//
|
|
1388
|
-
//
|
|
1389
|
-
//
|
|
1390
|
-
// it should be skipped until the buffer is consumed
|
|
1398
|
+
// Limit how far ahead we fetch to bufferLimit items (this chain's share of
|
|
1399
|
+
// the indexer-wide buffer pool) so processing always has buffer without
|
|
1400
|
+
// ballooning memory. A partition that fetched further is skipped until the
|
|
1401
|
+
// buffer drains.
|
|
1391
1402
|
let maxQueryBlockNumber = {
|
|
1392
|
-
switch buffer->Array.get(
|
|
1403
|
+
switch buffer->Array.get(bufferLimit - 1) {
|
|
1393
1404
|
| Some(item) =>
|
|
1394
1405
|
// Just in case check that we don't query beyond the current block
|
|
1395
1406
|
Pervasives.min(item->Internal.getItemBlockNumber, knownHeight)
|
|
@@ -1406,8 +1417,9 @@ let getNextQuery = (
|
|
|
1406
1417
|
let partitionId = optimizedPartitions.idsInAscOrder->Array.getUnsafe(idx)
|
|
1407
1418
|
let p = optimizedPartitions.entities->Dict.getUnsafe(partitionId)
|
|
1408
1419
|
|
|
1420
|
+
let pendingCount = p.mutPendingQueries->Array.length
|
|
1409
1421
|
let isBehindTheHead = p.latestFetchedBlock.blockNumber < headBlockNumber
|
|
1410
|
-
let hasPendingQueries =
|
|
1422
|
+
let hasPendingQueries = pendingCount > 0
|
|
1411
1423
|
|
|
1412
1424
|
if hasPendingQueries || isBehindTheHead {
|
|
1413
1425
|
// Even if there are some partitions waiting for the new block
|
|
@@ -1418,6 +1430,8 @@ let getNextQuery = (
|
|
|
1418
1430
|
shouldWaitForNewBlock := false
|
|
1419
1431
|
}
|
|
1420
1432
|
|
|
1433
|
+
let partitionQueriesStart = queries->Array.length
|
|
1434
|
+
|
|
1421
1435
|
// Compute queryEndBlock for this partition
|
|
1422
1436
|
let queryEndBlock = Utils.Math.minOptInt(fetchState.endBlock, p.mergeBlock)
|
|
1423
1437
|
let queryEndBlock = switch blockLag {
|
|
@@ -1485,6 +1499,22 @@ let getNextQuery = (
|
|
|
1485
1499
|
)
|
|
1486
1500
|
}
|
|
1487
1501
|
|
|
1502
|
+
// Cap parallel in-flight chunks per partition so a single partition can't
|
|
1503
|
+
// drain the whole concurrency budget (especially the high realtime one).
|
|
1504
|
+
// Keep the earliest new chunks; the furthest-ahead ones wait for the next
|
|
1505
|
+
// round once these resolve.
|
|
1506
|
+
let maxNewChunks = Pervasives.max(0, maxPendingChunksPerPartition - pendingCount)
|
|
1507
|
+
let generatedCount = queries->Array.length - partitionQueriesStart
|
|
1508
|
+
if generatedCount > maxNewChunks {
|
|
1509
|
+
queries
|
|
1510
|
+
->Array.splice(
|
|
1511
|
+
~start=partitionQueriesStart + maxNewChunks,
|
|
1512
|
+
~remove=generatedCount - maxNewChunks,
|
|
1513
|
+
~insert=[],
|
|
1514
|
+
)
|
|
1515
|
+
->ignore
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1488
1518
|
idxRef := idxRef.contents + 1
|
|
1489
1519
|
}
|
|
1490
1520
|
|
|
@@ -1547,7 +1577,7 @@ let make = (
|
|
|
1547
1577
|
~addresses: array<Internal.indexingAddress>,
|
|
1548
1578
|
~maxAddrInPartition,
|
|
1549
1579
|
~chainId,
|
|
1550
|
-
~
|
|
1580
|
+
~maxOnBlockBufferSize,
|
|
1551
1581
|
~knownHeight,
|
|
1552
1582
|
~progressBlockNumber=startBlock - 1,
|
|
1553
1583
|
~onBlockConfigs=[],
|
|
@@ -1696,7 +1726,7 @@ let make = (
|
|
|
1696
1726
|
~indexerStartBlock=startBlock,
|
|
1697
1727
|
~fromBlock=progressBlockNumber,
|
|
1698
1728
|
~maxBlockNumber,
|
|
1699
|
-
~
|
|
1729
|
+
~maxOnBlockBufferSize,
|
|
1700
1730
|
)
|
|
1701
1731
|
} else {
|
|
1702
1732
|
progressBlockNumber
|
|
@@ -1713,7 +1743,7 @@ let make = (
|
|
|
1713
1743
|
indexingAddresses,
|
|
1714
1744
|
blockLag,
|
|
1715
1745
|
onBlockConfigs,
|
|
1716
|
-
|
|
1746
|
+
maxOnBlockBufferSize,
|
|
1717
1747
|
knownHeight,
|
|
1718
1748
|
buffer,
|
|
1719
1749
|
firstEventBlock,
|
|
@@ -1737,6 +1767,25 @@ let make = (
|
|
|
1737
1767
|
|
|
1738
1768
|
let bufferSize = ({buffer}: t) => buffer->Array.length
|
|
1739
1769
|
|
|
1770
|
+
// Number of buffered items at or below the ready frontier (processable now,
|
|
1771
|
+
// i.e. not stuck behind a gap from a lagging partition or out-of-order chunk).
|
|
1772
|
+
// The buffer is kept sorted, so binary-search the frontier in O(log n).
|
|
1773
|
+
let bufferReadyCount = (fetchState: t) => {
|
|
1774
|
+
let frontier = fetchState->bufferBlockNumber
|
|
1775
|
+
let buffer = fetchState.buffer
|
|
1776
|
+
let lo = ref(0)
|
|
1777
|
+
let hi = ref(buffer->Array.length)
|
|
1778
|
+
while lo.contents < hi.contents {
|
|
1779
|
+
let mid = (lo.contents + hi.contents) / 2
|
|
1780
|
+
if buffer->Array.getUnsafe(mid)->Internal.getItemBlockNumber <= frontier {
|
|
1781
|
+
lo := mid + 1
|
|
1782
|
+
} else {
|
|
1783
|
+
hi := mid
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1786
|
+
lo.contents
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1740
1789
|
let rollbackPendingQueries = (mutPendingQueries: array<pendingQuery>, ~targetBlockNumber) => {
|
|
1741
1790
|
// - Remove queries where fromBlock > target
|
|
1742
1791
|
// - Cap fetchedBlock at target where fetchedBlock > target
|
|
@@ -1935,6 +1984,18 @@ let isActivelyIndexing = ({endBlock} as fetchState: t) => {
|
|
|
1935
1984
|
}
|
|
1936
1985
|
}
|
|
1937
1986
|
|
|
1987
|
+
// True once the fetch frontier has reached the (lagged) head or endBlock,
|
|
1988
|
+
// regardless of whether the buffer has been consumed yet. Unlike
|
|
1989
|
+
// isReadyToEnterReorgThreshold, fetched-but-unprocessed items still count.
|
|
1990
|
+
let isFetchingAtHead = ({endBlock, blockLag, knownHeight} as fetchState: t) => {
|
|
1991
|
+
let bufferBlockNumber = fetchState->bufferBlockNumber
|
|
1992
|
+
knownHeight !== 0 &&
|
|
1993
|
+
switch endBlock {
|
|
1994
|
+
| Some(endBlock) if bufferBlockNumber >= endBlock => true
|
|
1995
|
+
| _ => bufferBlockNumber >= knownHeight - blockLag
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1998
|
+
|
|
1938
1999
|
let isReadyToEnterReorgThreshold = ({endBlock, blockLag, buffer, knownHeight} as fetchState: t) => {
|
|
1939
2000
|
let bufferBlockNumber = fetchState->bufferBlockNumber
|
|
1940
2001
|
knownHeight !== 0 &&
|
|
@@ -1945,7 +2006,26 @@ let isReadyToEnterReorgThreshold = ({endBlock, blockLag, buffer, knownHeight} as
|
|
|
1945
2006
|
buffer->Utils.Array.isEmpty
|
|
1946
2007
|
}
|
|
1947
2008
|
|
|
1948
|
-
|
|
2009
|
+
// Lower progress percentage = further behind = higher priority. Shared by the
|
|
2010
|
+
// batch ordering and the cross-chain fetch priority.
|
|
2011
|
+
let getProgressPercentage = (fetchState: t) => {
|
|
2012
|
+
switch fetchState.firstEventBlock {
|
|
2013
|
+
| None => 0.
|
|
2014
|
+
| Some(firstEventBlock) =>
|
|
2015
|
+
let totalRange = fetchState.knownHeight - firstEventBlock
|
|
2016
|
+
if totalRange <= 0 {
|
|
2017
|
+
0.
|
|
2018
|
+
} else {
|
|
2019
|
+
let progress = switch fetchState.buffer->Array.get(0) {
|
|
2020
|
+
| Some(item) => item->Internal.getItemBlockNumber - firstEventBlock
|
|
2021
|
+
| None => fetchState->bufferBlockNumber - firstEventBlock
|
|
2022
|
+
}
|
|
2023
|
+
progress->Int.toFloat /. totalRange->Int.toFloat
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2026
|
+
}
|
|
2027
|
+
|
|
2028
|
+
let sortForBatch = {
|
|
1949
2029
|
let hasFullBatch = ({buffer} as fetchState: t, ~batchSizeTarget) => {
|
|
1950
2030
|
switch buffer->Array.get(batchSizeTarget - 1) {
|
|
1951
2031
|
| Some(item) => item->Internal.getItemBlockNumber <= fetchState->bufferBlockNumber
|
|
@@ -1953,24 +2033,6 @@ let sortForUnorderedBatch = {
|
|
|
1953
2033
|
}
|
|
1954
2034
|
}
|
|
1955
2035
|
|
|
1956
|
-
// Lower progress percentage = further behind = higher priority
|
|
1957
|
-
let getProgressPercentage = (fetchState: t) => {
|
|
1958
|
-
switch fetchState.firstEventBlock {
|
|
1959
|
-
| None => 0.
|
|
1960
|
-
| Some(firstEventBlock) =>
|
|
1961
|
-
let totalRange = fetchState.knownHeight - firstEventBlock
|
|
1962
|
-
if totalRange <= 0 {
|
|
1963
|
-
0.
|
|
1964
|
-
} else {
|
|
1965
|
-
let progress = switch fetchState.buffer->Array.get(0) {
|
|
1966
|
-
| Some(item) => item->Internal.getItemBlockNumber - firstEventBlock
|
|
1967
|
-
| None => fetchState->bufferBlockNumber - firstEventBlock
|
|
1968
|
-
}
|
|
1969
|
-
progress->Int.toFloat /. totalRange->Int.toFloat
|
|
1970
|
-
}
|
|
1971
|
-
}
|
|
1972
|
-
}
|
|
1973
|
-
|
|
1974
2036
|
(fetchStates: array<t>, ~batchSizeTarget: int) => {
|
|
1975
2037
|
let copied = fetchStates->Array.copy
|
|
1976
2038
|
copied->Array.sort((a: t, b: t) => {
|