envio 3.3.0-alpha.6 → 3.3.0-alpha.7
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/Address.res +5 -2
- package/src/Address.res.mjs +3 -1
- package/src/ChainFetching.res +14 -25
- package/src/ChainFetching.res.mjs +19 -20
- package/src/ChainState.res +4 -4
- package/src/ChainState.res.mjs +2 -2
- package/src/ChainState.resi +1 -1
- package/src/Config.res +44 -0
- package/src/Config.res.mjs +38 -0
- package/src/ContractRegisterContext.res +2 -12
- package/src/ContractRegisterContext.res.mjs +3 -5
- package/src/CrossChainState.res +5 -3
- package/src/CrossChainState.res.mjs +5 -4
- package/src/FetchState.res +49 -52
- package/src/FetchState.res.mjs +45 -47
- package/src/SimulateItems.res +6 -1
- package/src/SimulateItems.res.mjs +4 -3
- package/src/sources/HyperFuelSource.res +1 -0
- package/src/sources/HyperFuelSource.res.mjs +1 -1
- package/src/sources/HyperSync.res +4 -0
- package/src/sources/HyperSync.res.mjs +5 -4
- package/src/sources/HyperSync.resi +1 -0
- package/src/sources/HyperSyncSource.res +2 -0
- package/src/sources/HyperSyncSource.res.mjs +2 -2
- package/src/sources/RpcSource.res +23 -10
- package/src/sources/RpcSource.res.mjs +1 -1
- package/src/sources/SimulateSource.res +1 -0
- package/src/sources/SimulateSource.res.mjs +1 -1
- package/src/sources/Source.res +6 -0
- package/src/sources/SourceManager.res +7 -0
- package/src/sources/SourceManager.res.mjs +2 -1
- package/src/sources/Svm.res +1 -0
- package/src/sources/Svm.res.mjs +1 -1
- package/src/sources/SvmHyperSyncSource.res +2 -0
- package/src/sources/SvmHyperSyncSource.res.mjs +4 -2
package/src/FetchState.res
CHANGED
|
@@ -90,23 +90,41 @@ let deriveContractNameByAddress: dict<array<Address.t>> => dict<
|
|
|
90
90
|
result
|
|
91
91
|
})
|
|
92
92
|
|
|
93
|
+
// Bounds for the no-history default estimate below. Also used by SourceManager
|
|
94
|
+
// as the floor for its own maxNumLogs-style safety net.
|
|
95
|
+
let minEstResponseSize = 2_000.
|
|
96
|
+
let maxEstResponseSize = 10_000.
|
|
97
|
+
|
|
93
98
|
// Default estimate for a query whose partition hasn't responded yet, so the
|
|
94
99
|
// shared budget still accounts for unknown queries instead of treating them as
|
|
95
|
-
// free.
|
|
96
|
-
|
|
100
|
+
// free. Scaled down as partitionsCount grows: assuming every partition's first
|
|
101
|
+
// query is "big" starves the rest of that tick's admission when many
|
|
102
|
+
// partitions share the same buffer, so the per-partition default shrinks
|
|
103
|
+
// accordingly — clamped to [minEstResponseSize, maxEstResponseSize] either way.
|
|
104
|
+
let calculateDefaultEstResponseSize = (~partitionsCount) =>
|
|
105
|
+
Pervasives.max(
|
|
106
|
+
minEstResponseSize,
|
|
107
|
+
Pervasives.min(maxEstResponseSize, 20_000. /. partitionsCount->Int.toFloat),
|
|
108
|
+
)
|
|
97
109
|
|
|
98
110
|
// Estimated items a query will return, from the partition's event density
|
|
99
111
|
// (items/block derived from its last response) and the query's block range.
|
|
100
|
-
// toBlock None is the open-ended tail, capped at
|
|
112
|
+
// toBlock None is the open-ended tail, capped at knownHeight. A partition
|
|
101
113
|
// that responded with no items has density 0, so its queries cost 0 — correct,
|
|
102
114
|
// they don't fill the buffer. Only a partition that has never responded
|
|
103
|
-
// (prevQueryRange 0) has no signal, so it falls back to
|
|
104
|
-
let calculateEstResponseSize = (
|
|
115
|
+
// (prevQueryRange 0) has no signal, so it falls back to calculateDefaultEstResponseSize.
|
|
116
|
+
let calculateEstResponseSize = (
|
|
117
|
+
p: partition,
|
|
118
|
+
~fromBlock,
|
|
119
|
+
~toBlock,
|
|
120
|
+
~knownHeight,
|
|
121
|
+
~partitionsCount,
|
|
122
|
+
) =>
|
|
105
123
|
if p.prevQueryRange > 0 {
|
|
106
124
|
let density = p.prevRangeSize->Int.toFloat /. p.prevQueryRange->Int.toFloat
|
|
107
|
-
(toBlock->Option.getOr(
|
|
125
|
+
(toBlock->Option.getOr(knownHeight) - fromBlock + 1)->Int.toFloat *. density
|
|
108
126
|
} else {
|
|
109
|
-
|
|
127
|
+
calculateDefaultEstResponseSize(~partitionsCount)
|
|
110
128
|
}
|
|
111
129
|
|
|
112
130
|
// Calculate the chunk range from history using min-of-last-3-ranges heuristic
|
|
@@ -545,8 +563,8 @@ type t = {
|
|
|
545
563
|
// Buffer of items ordered from earliest to latest
|
|
546
564
|
buffer: array<Internal.item>,
|
|
547
565
|
// Caps how far ahead onBlock items are pre-generated (set to 2x the batch
|
|
548
|
-
// size).
|
|
549
|
-
// chain
|
|
566
|
+
// size). Event fetch depth is bounded separately, by CrossChainState's
|
|
567
|
+
// cross-chain admission against the indexer-wide buffer pool.
|
|
550
568
|
maxOnBlockBufferSize: int,
|
|
551
569
|
onBlockConfigs: array<Internal.onBlockConfig>,
|
|
552
570
|
knownHeight: int,
|
|
@@ -1352,14 +1370,15 @@ let pushQueriesForRange = (
|
|
|
1352
1370
|
~partitionId: string,
|
|
1353
1371
|
~rangeFromBlock: int,
|
|
1354
1372
|
~rangeEndBlock: option<int>,
|
|
1355
|
-
~
|
|
1373
|
+
~knownHeight: int,
|
|
1356
1374
|
~maybeChunkRange: option<int>,
|
|
1357
1375
|
~maxChunks: int,
|
|
1358
1376
|
~partition: partition,
|
|
1359
1377
|
~selection: selection,
|
|
1360
1378
|
~addressesByContractName: dict<array<Address.t>>,
|
|
1379
|
+
~partitionsCount: int,
|
|
1361
1380
|
) => {
|
|
1362
|
-
if rangeFromBlock <=
|
|
1381
|
+
if rangeFromBlock <= knownHeight && maxChunks > 0 {
|
|
1363
1382
|
switch rangeEndBlock {
|
|
1364
1383
|
| Some(endBlock) if rangeFromBlock > endBlock => ()
|
|
1365
1384
|
| _ =>
|
|
@@ -1375,7 +1394,8 @@ let pushQueriesForRange = (
|
|
|
1375
1394
|
partition,
|
|
1376
1395
|
~fromBlock=rangeFromBlock,
|
|
1377
1396
|
~toBlock=rangeEndBlock,
|
|
1378
|
-
~
|
|
1397
|
+
~knownHeight,
|
|
1398
|
+
~partitionsCount,
|
|
1379
1399
|
),
|
|
1380
1400
|
chainId: 0,
|
|
1381
1401
|
progress: 0.,
|
|
@@ -1384,7 +1404,7 @@ let pushQueriesForRange = (
|
|
|
1384
1404
|
| Some(chunkRange) =>
|
|
1385
1405
|
let maxBlock = switch rangeEndBlock {
|
|
1386
1406
|
| Some(eb) => eb
|
|
1387
|
-
| None =>
|
|
1407
|
+
| None => knownHeight
|
|
1388
1408
|
}
|
|
1389
1409
|
let chunkSize = Js.Math.ceil_int(chunkRange->Int.toFloat *. 1.8)
|
|
1390
1410
|
if rangeFromBlock + chunkSize * 2 - 1 <= maxBlock {
|
|
@@ -1404,7 +1424,8 @@ let pushQueriesForRange = (
|
|
|
1404
1424
|
partition,
|
|
1405
1425
|
~fromBlock=chunkFromBlock.contents,
|
|
1406
1426
|
~toBlock=Some(chunkToBlock),
|
|
1407
|
-
~
|
|
1427
|
+
~knownHeight,
|
|
1428
|
+
~partitionsCount,
|
|
1408
1429
|
),
|
|
1409
1430
|
chainId: 0,
|
|
1410
1431
|
progress: 0.,
|
|
@@ -1425,7 +1446,8 @@ let pushQueriesForRange = (
|
|
|
1425
1446
|
partition,
|
|
1426
1447
|
~fromBlock=rangeFromBlock,
|
|
1427
1448
|
~toBlock=rangeEndBlock,
|
|
1428
|
-
~
|
|
1449
|
+
~knownHeight,
|
|
1450
|
+
~partitionsCount,
|
|
1429
1451
|
),
|
|
1430
1452
|
chainId: 0,
|
|
1431
1453
|
progress: 0.,
|
|
@@ -1437,45 +1459,27 @@ let pushQueriesForRange = (
|
|
|
1437
1459
|
}
|
|
1438
1460
|
}
|
|
1439
1461
|
|
|
1462
|
+
// Candidate queries are sized against the natural ceiling (head/endBlock/mergeBlock),
|
|
1463
|
+
// not a share of the shared buffer — CrossChainState.checkAndFetch's admission loop
|
|
1464
|
+
// is what actually bounds how much gets fetched per tick, by estResponseSize (which
|
|
1465
|
+
// the HyperSync/SVM sources also enforce server-side via a maxNumLogs-style cap, so
|
|
1466
|
+
// a wrong estimate truncates the response instead of overshooting the buffer).
|
|
1440
1467
|
let getNextQuery = (
|
|
1441
|
-
{
|
|
1442
|
-
~budget,
|
|
1443
|
-
~chainPendingBudget,
|
|
1468
|
+
{optimizedPartitions, blockLag, latestOnBlockBlockNumber, knownHeight, endBlock}: t,
|
|
1444
1469
|
) => {
|
|
1445
1470
|
let headBlockNumber = knownHeight - blockLag
|
|
1446
1471
|
if headBlockNumber <= 0 {
|
|
1447
1472
|
WaitingForNewBlock
|
|
1448
|
-
} else if budget <= 0 {
|
|
1449
|
-
// No room left in the shared buffer pool for this chain; wait for processing
|
|
1450
|
-
// to drain before fetching more.
|
|
1451
|
-
NothingToQuery
|
|
1452
1473
|
} else {
|
|
1453
1474
|
let isOnBlockBehindTheHead = latestOnBlockBlockNumber < headBlockNumber
|
|
1454
1475
|
let shouldWaitForNewBlock = ref(
|
|
1455
|
-
switch
|
|
1476
|
+
switch endBlock {
|
|
1456
1477
|
| Some(endBlock) => headBlockNumber < endBlock
|
|
1457
1478
|
| None => true
|
|
1458
1479
|
} &&
|
|
1459
1480
|
!isOnBlockBehindTheHead,
|
|
1460
1481
|
)
|
|
1461
1482
|
|
|
1462
|
-
// Fetch at most `budget` items past the ready frontier (plus what's already
|
|
1463
|
-
// in flight) so processing always has buffer without ballooning memory.
|
|
1464
|
-
// budget already excludes items at/below the frontier (they're in the shared
|
|
1465
|
-
// totalReadyCount), so offset the index by bufferReadyCount — otherwise the
|
|
1466
|
-
// ready prefix is subtracted twice and the buffer caps at a fraction of its
|
|
1467
|
-
// target. A partition that fetched further is skipped until the buffer drains.
|
|
1468
|
-
let maxQueryBlockNumber = {
|
|
1469
|
-
switch buffer->Array.get(
|
|
1470
|
-
fetchState->bufferReadyCount + budget + chainPendingBudget->Float.toInt - 1,
|
|
1471
|
-
) {
|
|
1472
|
-
| Some(item) =>
|
|
1473
|
-
// Just in case check that we don't query beyond the current block
|
|
1474
|
-
Pervasives.min(item->Internal.getItemBlockNumber, knownHeight)
|
|
1475
|
-
| None => knownHeight
|
|
1476
|
-
}
|
|
1477
|
-
}
|
|
1478
|
-
|
|
1479
1483
|
let queries = []
|
|
1480
1484
|
|
|
1481
1485
|
let partitionsCount = optimizedPartitions.idsInAscOrder->Array.length
|
|
@@ -1501,7 +1505,7 @@ let getNextQuery = (
|
|
|
1501
1505
|
let partitionQueriesStart = queries->Array.length
|
|
1502
1506
|
|
|
1503
1507
|
// Compute queryEndBlock for this partition
|
|
1504
|
-
let queryEndBlock = Utils.Math.minOptInt(
|
|
1508
|
+
let queryEndBlock = Utils.Math.minOptInt(endBlock, p.mergeBlock)
|
|
1505
1509
|
let queryEndBlock = switch blockLag {
|
|
1506
1510
|
| 0 => queryEndBlock
|
|
1507
1511
|
| _ =>
|
|
@@ -1509,15 +1513,6 @@ let getNextQuery = (
|
|
|
1509
1513
|
// because otherwise HyperSync might return bigger range
|
|
1510
1514
|
Utils.Math.minOptInt(Some(headBlockNumber), queryEndBlock)
|
|
1511
1515
|
}
|
|
1512
|
-
// Enforce the response range up until target block
|
|
1513
|
-
// Otherwise for indexers with 100+ partitions
|
|
1514
|
-
// we might blow up the buffer size to more than 600k events
|
|
1515
|
-
// simply because of HyperSync returning extra blocks
|
|
1516
|
-
let queryEndBlock = switch (queryEndBlock, maxQueryBlockNumber < knownHeight) {
|
|
1517
|
-
| (Some(endBlock), true) => Some(Pervasives.min(maxQueryBlockNumber, endBlock))
|
|
1518
|
-
| (None, true) => Some(maxQueryBlockNumber)
|
|
1519
|
-
| (_, false) => queryEndBlock
|
|
1520
|
-
}
|
|
1521
1516
|
|
|
1522
1517
|
let maybeChunkRange = getMinHistoryRange(p)
|
|
1523
1518
|
|
|
@@ -1535,7 +1530,7 @@ let getNextQuery = (
|
|
|
1535
1530
|
~partitionId,
|
|
1536
1531
|
~rangeFromBlock=cursor.contents,
|
|
1537
1532
|
~rangeEndBlock=Utils.Math.minOptInt(Some(pq.fromBlock - 1), queryEndBlock),
|
|
1538
|
-
~
|
|
1533
|
+
~knownHeight,
|
|
1539
1534
|
~maybeChunkRange,
|
|
1540
1535
|
~maxChunks=maxPendingChunksPerPartition -
|
|
1541
1536
|
pendingCount -
|
|
@@ -1544,6 +1539,7 @@ let getNextQuery = (
|
|
|
1544
1539
|
~partition=p,
|
|
1545
1540
|
~selection=p.selection,
|
|
1546
1541
|
~addressesByContractName=p.addressesByContractName,
|
|
1542
|
+
~partitionsCount,
|
|
1547
1543
|
)
|
|
1548
1544
|
}
|
|
1549
1545
|
switch pq {
|
|
@@ -1563,7 +1559,7 @@ let getNextQuery = (
|
|
|
1563
1559
|
~partitionId,
|
|
1564
1560
|
~rangeFromBlock=cursor.contents,
|
|
1565
1561
|
~rangeEndBlock=queryEndBlock,
|
|
1566
|
-
~
|
|
1562
|
+
~knownHeight,
|
|
1567
1563
|
~maybeChunkRange,
|
|
1568
1564
|
~maxChunks=maxPendingChunksPerPartition -
|
|
1569
1565
|
pendingCount -
|
|
@@ -1572,6 +1568,7 @@ let getNextQuery = (
|
|
|
1572
1568
|
~partition=p,
|
|
1573
1569
|
~selection=p.selection,
|
|
1574
1570
|
~addressesByContractName=p.addressesByContractName,
|
|
1571
|
+
~partitionsCount,
|
|
1575
1572
|
)
|
|
1576
1573
|
}
|
|
1577
1574
|
|
package/src/FetchState.res.mjs
CHANGED
|
@@ -8,6 +8,7 @@ import * as Stdlib_Int from "@rescript/runtime/lib/es6/Stdlib_Int.js";
|
|
|
8
8
|
import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
|
|
9
9
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
10
10
|
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
11
|
+
import * as Primitive_float from "@rescript/runtime/lib/es6/Primitive_float.js";
|
|
11
12
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
12
13
|
import * as IndexingAddresses from "./IndexingAddresses.res.mjs";
|
|
13
14
|
|
|
@@ -21,12 +22,16 @@ let deriveContractNameByAddress = Utils.$$WeakMap.memoize(addressesByContractNam
|
|
|
21
22
|
return result;
|
|
22
23
|
});
|
|
23
24
|
|
|
24
|
-
function
|
|
25
|
+
function calculateDefaultEstResponseSize(partitionsCount) {
|
|
26
|
+
return Primitive_float.max(2000, Primitive_float.min(10000, 20000 / partitionsCount));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function calculateEstResponseSize(p, fromBlock, toBlock, knownHeight, partitionsCount) {
|
|
25
30
|
if (p.prevQueryRange <= 0) {
|
|
26
|
-
return
|
|
31
|
+
return calculateDefaultEstResponseSize(partitionsCount);
|
|
27
32
|
}
|
|
28
33
|
let density = p.prevRangeSize / p.prevQueryRange;
|
|
29
|
-
return ((Stdlib_Option.getOr(toBlock,
|
|
34
|
+
return ((Stdlib_Option.getOr(toBlock, knownHeight) - fromBlock | 0) + 1 | 0) * density;
|
|
30
35
|
}
|
|
31
36
|
|
|
32
37
|
function getMinHistoryRange(p) {
|
|
@@ -977,15 +982,15 @@ function startFetchingQueries(param, queries) {
|
|
|
977
982
|
}
|
|
978
983
|
}
|
|
979
984
|
|
|
980
|
-
function pushQueriesForRange(queries, partitionId, rangeFromBlock, rangeEndBlock,
|
|
981
|
-
if (!(rangeFromBlock <=
|
|
985
|
+
function pushQueriesForRange(queries, partitionId, rangeFromBlock, rangeEndBlock, knownHeight, maybeChunkRange, maxChunks, partition, selection, addressesByContractName, partitionsCount) {
|
|
986
|
+
if (!(rangeFromBlock <= knownHeight && maxChunks > 0)) {
|
|
982
987
|
return;
|
|
983
988
|
}
|
|
984
989
|
if (rangeEndBlock !== undefined && rangeFromBlock > rangeEndBlock) {
|
|
985
990
|
return;
|
|
986
991
|
}
|
|
987
992
|
if (maybeChunkRange !== undefined) {
|
|
988
|
-
let maxBlock = rangeEndBlock !== undefined ? rangeEndBlock :
|
|
993
|
+
let maxBlock = rangeEndBlock !== undefined ? rangeEndBlock : knownHeight;
|
|
989
994
|
let chunkSize = Js_math.ceil_int(maybeChunkRange * 1.8);
|
|
990
995
|
if (((rangeFromBlock + (chunkSize << 1) | 0) - 1 | 0) <= maxBlock) {
|
|
991
996
|
let chunkFromBlock = rangeFromBlock;
|
|
@@ -997,7 +1002,7 @@ function pushQueriesForRange(queries, partitionId, rangeFromBlock, rangeEndBlock
|
|
|
997
1002
|
fromBlock: chunkFromBlock,
|
|
998
1003
|
toBlock: chunkToBlock,
|
|
999
1004
|
isChunk: true,
|
|
1000
|
-
estResponseSize: calculateEstResponseSize(partition, chunkFromBlock, chunkToBlock,
|
|
1005
|
+
estResponseSize: calculateEstResponseSize(partition, chunkFromBlock, chunkToBlock, knownHeight, partitionsCount),
|
|
1001
1006
|
chainId: 0,
|
|
1002
1007
|
progress: 0,
|
|
1003
1008
|
selection: selection,
|
|
@@ -1013,7 +1018,7 @@ function pushQueriesForRange(queries, partitionId, rangeFromBlock, rangeEndBlock
|
|
|
1013
1018
|
fromBlock: rangeFromBlock,
|
|
1014
1019
|
toBlock: rangeEndBlock,
|
|
1015
1020
|
isChunk: rangeEndBlock !== undefined,
|
|
1016
|
-
estResponseSize: calculateEstResponseSize(partition, rangeFromBlock, rangeEndBlock,
|
|
1021
|
+
estResponseSize: calculateEstResponseSize(partition, rangeFromBlock, rangeEndBlock, knownHeight, partitionsCount),
|
|
1017
1022
|
chainId: 0,
|
|
1018
1023
|
progress: 0,
|
|
1019
1024
|
selection: selection,
|
|
@@ -1026,7 +1031,7 @@ function pushQueriesForRange(queries, partitionId, rangeFromBlock, rangeEndBlock
|
|
|
1026
1031
|
fromBlock: rangeFromBlock,
|
|
1027
1032
|
toBlock: rangeEndBlock,
|
|
1028
1033
|
isChunk: false,
|
|
1029
|
-
estResponseSize: calculateEstResponseSize(partition, rangeFromBlock, rangeEndBlock,
|
|
1034
|
+
estResponseSize: calculateEstResponseSize(partition, rangeFromBlock, rangeEndBlock, knownHeight, partitionsCount),
|
|
1030
1035
|
chainId: 0,
|
|
1031
1036
|
progress: 0,
|
|
1032
1037
|
selection: selection,
|
|
@@ -1034,24 +1039,19 @@ function pushQueriesForRange(queries, partitionId, rangeFromBlock, rangeEndBlock
|
|
|
1034
1039
|
});
|
|
1035
1040
|
}
|
|
1036
1041
|
|
|
1037
|
-
function getNextQuery(
|
|
1038
|
-
let knownHeight =
|
|
1039
|
-
let blockLag =
|
|
1040
|
-
let
|
|
1042
|
+
function getNextQuery(param) {
|
|
1043
|
+
let knownHeight = param.knownHeight;
|
|
1044
|
+
let blockLag = param.blockLag;
|
|
1045
|
+
let endBlock = param.endBlock;
|
|
1046
|
+
let optimizedPartitions = param.optimizedPartitions;
|
|
1041
1047
|
let headBlockNumber = knownHeight - blockLag | 0;
|
|
1042
1048
|
if (headBlockNumber <= 0) {
|
|
1043
1049
|
return "WaitingForNewBlock";
|
|
1044
1050
|
}
|
|
1045
|
-
|
|
1046
|
-
return "NothingToQuery";
|
|
1047
|
-
}
|
|
1048
|
-
let isOnBlockBehindTheHead = fetchState.latestOnBlockBlockNumber < headBlockNumber;
|
|
1049
|
-
let endBlock = fetchState.endBlock;
|
|
1051
|
+
let isOnBlockBehindTheHead = param.latestOnBlockBlockNumber < headBlockNumber;
|
|
1050
1052
|
let shouldWaitForNewBlock = (
|
|
1051
1053
|
endBlock !== undefined ? headBlockNumber < endBlock : true
|
|
1052
1054
|
) && !isOnBlockBehindTheHead;
|
|
1053
|
-
let item = fetchState.buffer[((bufferReadyCount(fetchState) + budget | 0) + (chainPendingBudget | 0) | 0) - 1 | 0];
|
|
1054
|
-
let maxQueryBlockNumber = item !== undefined ? Primitive_int.min(item.blockNumber, knownHeight) : knownHeight;
|
|
1055
1055
|
let queries = [];
|
|
1056
1056
|
let partitionsCount = optimizedPartitions.idsInAscOrder.length;
|
|
1057
1057
|
let idxRef = 0;
|
|
@@ -1066,14 +1066,8 @@ function getNextQuery(fetchState, budget, chainPendingBudget) {
|
|
|
1066
1066
|
shouldWaitForNewBlock = false;
|
|
1067
1067
|
}
|
|
1068
1068
|
let partitionQueriesStart = queries.length;
|
|
1069
|
-
let queryEndBlock = Utils.$$Math.minOptInt(
|
|
1069
|
+
let queryEndBlock = Utils.$$Math.minOptInt(endBlock, p.mergeBlock);
|
|
1070
1070
|
let queryEndBlock$1 = blockLag !== 0 ? Utils.$$Math.minOptInt(headBlockNumber, queryEndBlock) : queryEndBlock;
|
|
1071
|
-
let match = maxQueryBlockNumber < knownHeight;
|
|
1072
|
-
let queryEndBlock$2 = queryEndBlock$1 !== undefined ? (
|
|
1073
|
-
match ? Primitive_int.min(maxQueryBlockNumber, queryEndBlock$1) : queryEndBlock$1
|
|
1074
|
-
) : (
|
|
1075
|
-
match ? maxQueryBlockNumber : queryEndBlock$1
|
|
1076
|
-
);
|
|
1077
1071
|
let maybeChunkRange = getMinHistoryRange(p);
|
|
1078
1072
|
let cursor = p.latestFetchedBlock.blockNumber + 1 | 0;
|
|
1079
1073
|
let canContinue = true;
|
|
@@ -1084,16 +1078,16 @@ function getNextQuery(fetchState, budget, chainPendingBudget) {
|
|
|
1084
1078
|
let addressesByContractName = p.addressesByContractName;
|
|
1085
1079
|
let selection = p.selection;
|
|
1086
1080
|
let maxChunks = (10 - pendingCount | 0) - (queries.length - partitionQueriesStart | 0) | 0;
|
|
1087
|
-
let rangeEndBlock = Utils.$$Math.minOptInt(pq.fromBlock - 1 | 0, queryEndBlock$
|
|
1081
|
+
let rangeEndBlock = Utils.$$Math.minOptInt(pq.fromBlock - 1 | 0, queryEndBlock$1);
|
|
1088
1082
|
let rangeFromBlock = cursor;
|
|
1089
|
-
if (rangeFromBlock <=
|
|
1083
|
+
if (rangeFromBlock <= knownHeight && maxChunks > 0) {
|
|
1090
1084
|
let exit = 0;
|
|
1091
1085
|
if (!(rangeEndBlock !== undefined && rangeFromBlock > rangeEndBlock)) {
|
|
1092
1086
|
exit = 1;
|
|
1093
1087
|
}
|
|
1094
1088
|
if (exit === 1) {
|
|
1095
1089
|
if (maybeChunkRange !== undefined) {
|
|
1096
|
-
let maxBlock = rangeEndBlock !== undefined ? rangeEndBlock :
|
|
1090
|
+
let maxBlock = rangeEndBlock !== undefined ? rangeEndBlock : knownHeight;
|
|
1097
1091
|
let chunkSize = Js_math.ceil_int(maybeChunkRange * 1.8);
|
|
1098
1092
|
if (((rangeFromBlock + (chunkSize << 1) | 0) - 1 | 0) <= maxBlock) {
|
|
1099
1093
|
let chunkFromBlock = rangeFromBlock;
|
|
@@ -1105,7 +1099,7 @@ function getNextQuery(fetchState, budget, chainPendingBudget) {
|
|
|
1105
1099
|
fromBlock: chunkFromBlock,
|
|
1106
1100
|
toBlock: chunkToBlock,
|
|
1107
1101
|
isChunk: true,
|
|
1108
|
-
estResponseSize: calculateEstResponseSize(p, chunkFromBlock, chunkToBlock,
|
|
1102
|
+
estResponseSize: calculateEstResponseSize(p, chunkFromBlock, chunkToBlock, knownHeight, partitionsCount),
|
|
1109
1103
|
chainId: 0,
|
|
1110
1104
|
progress: 0,
|
|
1111
1105
|
selection: selection,
|
|
@@ -1120,7 +1114,7 @@ function getNextQuery(fetchState, budget, chainPendingBudget) {
|
|
|
1120
1114
|
fromBlock: rangeFromBlock,
|
|
1121
1115
|
toBlock: rangeEndBlock,
|
|
1122
1116
|
isChunk: rangeEndBlock !== undefined,
|
|
1123
|
-
estResponseSize: calculateEstResponseSize(p, rangeFromBlock, rangeEndBlock,
|
|
1117
|
+
estResponseSize: calculateEstResponseSize(p, rangeFromBlock, rangeEndBlock, knownHeight, partitionsCount),
|
|
1124
1118
|
chainId: 0,
|
|
1125
1119
|
progress: 0,
|
|
1126
1120
|
selection: selection,
|
|
@@ -1133,7 +1127,7 @@ function getNextQuery(fetchState, budget, chainPendingBudget) {
|
|
|
1133
1127
|
fromBlock: rangeFromBlock,
|
|
1134
1128
|
toBlock: rangeEndBlock,
|
|
1135
1129
|
isChunk: false,
|
|
1136
|
-
estResponseSize: calculateEstResponseSize(p, rangeFromBlock, rangeEndBlock,
|
|
1130
|
+
estResponseSize: calculateEstResponseSize(p, rangeFromBlock, rangeEndBlock, knownHeight, partitionsCount),
|
|
1137
1131
|
chainId: 0,
|
|
1138
1132
|
progress: 0,
|
|
1139
1133
|
selection: selection,
|
|
@@ -1145,9 +1139,9 @@ function getNextQuery(fetchState, budget, chainPendingBudget) {
|
|
|
1145
1139
|
}
|
|
1146
1140
|
let toBlock = pq.toBlock;
|
|
1147
1141
|
if (toBlock !== undefined && pq.isChunk) {
|
|
1148
|
-
let match
|
|
1149
|
-
if (match
|
|
1150
|
-
let blockNumber = match
|
|
1142
|
+
let match = pq.fetchedBlock;
|
|
1143
|
+
if (match !== undefined) {
|
|
1144
|
+
let blockNumber = match.blockNumber;
|
|
1151
1145
|
cursor = blockNumber < toBlock ? blockNumber + 1 | 0 : toBlock + 1 | 0;
|
|
1152
1146
|
} else {
|
|
1153
1147
|
cursor = toBlock + 1 | 0;
|
|
@@ -1162,14 +1156,14 @@ function getNextQuery(fetchState, budget, chainPendingBudget) {
|
|
|
1162
1156
|
let selection$1 = p.selection;
|
|
1163
1157
|
let maxChunks$1 = (10 - pendingCount | 0) - (queries.length - partitionQueriesStart | 0) | 0;
|
|
1164
1158
|
let rangeFromBlock$1 = cursor;
|
|
1165
|
-
if (rangeFromBlock$1 <=
|
|
1159
|
+
if (rangeFromBlock$1 <= knownHeight && maxChunks$1 > 0) {
|
|
1166
1160
|
let exit$1 = 0;
|
|
1167
|
-
if (!(queryEndBlock$
|
|
1161
|
+
if (!(queryEndBlock$1 !== undefined && rangeFromBlock$1 > queryEndBlock$1)) {
|
|
1168
1162
|
exit$1 = 1;
|
|
1169
1163
|
}
|
|
1170
1164
|
if (exit$1 === 1) {
|
|
1171
1165
|
if (maybeChunkRange !== undefined) {
|
|
1172
|
-
let maxBlock$1 = queryEndBlock$
|
|
1166
|
+
let maxBlock$1 = queryEndBlock$1 !== undefined ? queryEndBlock$1 : knownHeight;
|
|
1173
1167
|
let chunkSize$1 = Js_math.ceil_int(maybeChunkRange * 1.8);
|
|
1174
1168
|
if (((rangeFromBlock$1 + (chunkSize$1 << 1) | 0) - 1 | 0) <= maxBlock$1) {
|
|
1175
1169
|
let chunkFromBlock$1 = rangeFromBlock$1;
|
|
@@ -1181,7 +1175,7 @@ function getNextQuery(fetchState, budget, chainPendingBudget) {
|
|
|
1181
1175
|
fromBlock: chunkFromBlock$1,
|
|
1182
1176
|
toBlock: chunkToBlock$1,
|
|
1183
1177
|
isChunk: true,
|
|
1184
|
-
estResponseSize: calculateEstResponseSize(p, chunkFromBlock$1, chunkToBlock$1,
|
|
1178
|
+
estResponseSize: calculateEstResponseSize(p, chunkFromBlock$1, chunkToBlock$1, knownHeight, partitionsCount),
|
|
1185
1179
|
chainId: 0,
|
|
1186
1180
|
progress: 0,
|
|
1187
1181
|
selection: selection$1,
|
|
@@ -1194,9 +1188,9 @@ function getNextQuery(fetchState, budget, chainPendingBudget) {
|
|
|
1194
1188
|
queries.push({
|
|
1195
1189
|
partitionId: partitionId,
|
|
1196
1190
|
fromBlock: rangeFromBlock$1,
|
|
1197
|
-
toBlock: queryEndBlock$
|
|
1198
|
-
isChunk: queryEndBlock$
|
|
1199
|
-
estResponseSize: calculateEstResponseSize(p, rangeFromBlock$1, queryEndBlock$
|
|
1191
|
+
toBlock: queryEndBlock$1,
|
|
1192
|
+
isChunk: queryEndBlock$1 !== undefined,
|
|
1193
|
+
estResponseSize: calculateEstResponseSize(p, rangeFromBlock$1, queryEndBlock$1, knownHeight, partitionsCount),
|
|
1200
1194
|
chainId: 0,
|
|
1201
1195
|
progress: 0,
|
|
1202
1196
|
selection: selection$1,
|
|
@@ -1207,9 +1201,9 @@ function getNextQuery(fetchState, budget, chainPendingBudget) {
|
|
|
1207
1201
|
queries.push({
|
|
1208
1202
|
partitionId: partitionId,
|
|
1209
1203
|
fromBlock: rangeFromBlock$1,
|
|
1210
|
-
toBlock: queryEndBlock$
|
|
1204
|
+
toBlock: queryEndBlock$1,
|
|
1211
1205
|
isChunk: false,
|
|
1212
|
-
estResponseSize: calculateEstResponseSize(p, rangeFromBlock$1, queryEndBlock$
|
|
1206
|
+
estResponseSize: calculateEstResponseSize(p, rangeFromBlock$1, queryEndBlock$1, knownHeight, partitionsCount),
|
|
1213
1207
|
chainId: 0,
|
|
1214
1208
|
progress: 0,
|
|
1215
1209
|
selection: selection$1,
|
|
@@ -1656,7 +1650,9 @@ function updateKnownHeight(fetchState, knownHeight) {
|
|
|
1656
1650
|
}
|
|
1657
1651
|
}
|
|
1658
1652
|
|
|
1659
|
-
let
|
|
1653
|
+
let minEstResponseSize = 2000;
|
|
1654
|
+
|
|
1655
|
+
let maxEstResponseSize = 10000;
|
|
1660
1656
|
|
|
1661
1657
|
let blockItemLogIndex = 16777216;
|
|
1662
1658
|
|
|
@@ -1664,7 +1660,9 @@ let maxPendingChunksPerPartition = 10;
|
|
|
1664
1660
|
|
|
1665
1661
|
export {
|
|
1666
1662
|
deriveContractNameByAddress,
|
|
1667
|
-
|
|
1663
|
+
minEstResponseSize,
|
|
1664
|
+
maxEstResponseSize,
|
|
1665
|
+
calculateDefaultEstResponseSize,
|
|
1668
1666
|
calculateEstResponseSize,
|
|
1669
1667
|
getMinHistoryRange,
|
|
1670
1668
|
getMinQueryRange,
|
package/src/SimulateItems.res
CHANGED
|
@@ -216,9 +216,13 @@ let deriveSrcAddress = (
|
|
|
216
216
|
~providedSrcAddress: option<Address.t>,
|
|
217
217
|
~eventConfig: Internal.eventConfig,
|
|
218
218
|
~chainConfig: Config.chain,
|
|
219
|
+
~config: Config.t,
|
|
219
220
|
): Address.t => {
|
|
220
221
|
switch providedSrcAddress {
|
|
221
|
-
|
|
222
|
+
// Canonicalize to the configured casing; the fallback addresses below already
|
|
223
|
+
// come from the parsed config and need no normalization. Relaxed (not
|
|
224
|
+
// Config.normalizeUserAddress) so test placeholders like "0xfoo" are allowed.
|
|
225
|
+
| Some(addr) => config->Config.normalizeSimulateAddress(addr)
|
|
222
226
|
| None =>
|
|
223
227
|
if eventConfig.isWildcard {
|
|
224
228
|
dummySrcAddress
|
|
@@ -287,6 +291,7 @@ let parse = (~simulateItems: array<JSON.t>, ~config: Config.t, ~chainConfig: Con
|
|
|
287
291
|
~providedSrcAddress=item.srcAddress,
|
|
288
292
|
~eventConfig,
|
|
289
293
|
~chainConfig,
|
|
294
|
+
~config,
|
|
290
295
|
)
|
|
291
296
|
|
|
292
297
|
let rawItem = rawJson->(Utils.magic: JSON.t => {..})
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
+
import * as Config from "./Config.res.mjs";
|
|
3
4
|
import * as Address from "./Address.res.mjs";
|
|
4
5
|
import * as ChainMap from "./ChainMap.res.mjs";
|
|
5
6
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
@@ -150,9 +151,9 @@ function firstContractAddress(chainConfig, contractName) {
|
|
|
150
151
|
return found.contents;
|
|
151
152
|
}
|
|
152
153
|
|
|
153
|
-
function deriveSrcAddress(providedSrcAddress, eventConfig, chainConfig) {
|
|
154
|
+
function deriveSrcAddress(providedSrcAddress, eventConfig, chainConfig, config) {
|
|
154
155
|
if (providedSrcAddress !== undefined) {
|
|
155
|
-
return Primitive_option.valFromOption(providedSrcAddress);
|
|
156
|
+
return Config.normalizeSimulateAddress(config, Primitive_option.valFromOption(providedSrcAddress));
|
|
156
157
|
}
|
|
157
158
|
if (eventConfig.isWildcard) {
|
|
158
159
|
return dummySrcAddress;
|
|
@@ -203,7 +204,7 @@ function parse(simulateItems, config, chainConfig) {
|
|
|
203
204
|
currentLogIndex.contents = li$1 + 1 | 0;
|
|
204
205
|
logIndex = li$1;
|
|
205
206
|
}
|
|
206
|
-
let srcAddress = deriveSrcAddress(rawJson.srcAddress, eventConfig, chainConfig);
|
|
207
|
+
let srcAddress = deriveSrcAddress(rawJson.srcAddress, eventConfig, chainConfig, config);
|
|
207
208
|
let blockJson = rawJson.block;
|
|
208
209
|
let blockJson$1 = (blockJson == null) ? undefined : Primitive_option.some(blockJson);
|
|
209
210
|
let transactionJson = rawJson.transaction;
|
|
@@ -196,7 +196,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
196
196
|
client = ErrorHandling.mkLogAndRaise(undefined, "Failed to instantiate the HyperFuel client", exn);
|
|
197
197
|
}
|
|
198
198
|
let getSelectionConfig = memoGetSelectionConfig(chain);
|
|
199
|
-
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, contractNameByAddress, knownHeight, param, selection, retry, logger) => {
|
|
199
|
+
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, contractNameByAddress, knownHeight, param, selection, param$1, retry, logger) => {
|
|
200
200
|
let totalTimeRef = Performance.now();
|
|
201
201
|
let selectionConfig = getSelectionConfig(selection);
|
|
202
202
|
let recieptsSelection = selectionConfig.getRecieptsSelection(addressesByContractName);
|
|
@@ -64,6 +64,7 @@ module GetLogs = {
|
|
|
64
64
|
~toBlockInclusive,
|
|
65
65
|
~addressesWithTopics,
|
|
66
66
|
~fieldSelection,
|
|
67
|
+
~maxNumLogs,
|
|
67
68
|
): HyperSyncClient.QueryTypes.query => {
|
|
68
69
|
fromBlock,
|
|
69
70
|
toBlockExclusive: ?switch toBlockInclusive {
|
|
@@ -72,6 +73,7 @@ module GetLogs = {
|
|
|
72
73
|
},
|
|
73
74
|
logs: addressesWithTopics,
|
|
74
75
|
fieldSelection,
|
|
76
|
+
maxNumLogs,
|
|
75
77
|
}
|
|
76
78
|
|
|
77
79
|
// Rust encodes structured failures as a JSON payload in the napi error's
|
|
@@ -105,6 +107,7 @@ module GetLogs = {
|
|
|
105
107
|
~toBlock,
|
|
106
108
|
~logSelections: array<LogSelection.t>,
|
|
107
109
|
~fieldSelection,
|
|
110
|
+
~maxNumLogs,
|
|
108
111
|
): logsQueryPage => {
|
|
109
112
|
let addressesWithTopics = logSelections->Array.flatMap(({addresses, topicSelections}) =>
|
|
110
113
|
topicSelections->Array.map(({topic0, topic1, topic2, topic3}) => {
|
|
@@ -123,6 +126,7 @@ module GetLogs = {
|
|
|
123
126
|
~toBlockInclusive=toBlock,
|
|
124
127
|
~addressesWithTopics,
|
|
125
128
|
~fieldSelection,
|
|
129
|
+
~maxNumLogs,
|
|
126
130
|
)
|
|
127
131
|
|
|
128
132
|
let (res, transactionStore) = switch await client.getEventItems(~query) {
|
|
@@ -62,12 +62,13 @@ function mapExn(queryResponse) {
|
|
|
62
62
|
|
|
63
63
|
let $$Error = /* @__PURE__ */Primitive_exceptions.create("HyperSync.GetLogs.Error");
|
|
64
64
|
|
|
65
|
-
function makeRequestBody(fromBlock, toBlockInclusive, addressesWithTopics, fieldSelection) {
|
|
65
|
+
function makeRequestBody(fromBlock, toBlockInclusive, addressesWithTopics, fieldSelection, maxNumLogs) {
|
|
66
66
|
return {
|
|
67
67
|
fromBlock: fromBlock,
|
|
68
68
|
toBlock: toBlockInclusive !== undefined ? toBlockInclusive + 1 | 0 : undefined,
|
|
69
69
|
logs: addressesWithTopics,
|
|
70
|
-
fieldSelection: fieldSelection
|
|
70
|
+
fieldSelection: fieldSelection,
|
|
71
|
+
maxNumLogs: maxNumLogs
|
|
71
72
|
};
|
|
72
73
|
}
|
|
73
74
|
|
|
@@ -92,7 +93,7 @@ function extractMissingParams(exn) {
|
|
|
92
93
|
}
|
|
93
94
|
}
|
|
94
95
|
|
|
95
|
-
async function query(client, fromBlock, toBlock, logSelections, fieldSelection) {
|
|
96
|
+
async function query(client, fromBlock, toBlock, logSelections, fieldSelection, maxNumLogs) {
|
|
96
97
|
let addressesWithTopics = logSelections.flatMap(param => {
|
|
97
98
|
let addresses = param.addresses;
|
|
98
99
|
return param.topicSelections.map(param => {
|
|
@@ -100,7 +101,7 @@ async function query(client, fromBlock, toBlock, logSelections, fieldSelection)
|
|
|
100
101
|
return HyperSyncClient.QueryTypes.makeLogSelection(addresses, topics);
|
|
101
102
|
});
|
|
102
103
|
});
|
|
103
|
-
let query$1 = makeRequestBody(fromBlock, toBlock, addressesWithTopics, fieldSelection);
|
|
104
|
+
let query$1 = makeRequestBody(fromBlock, toBlock, addressesWithTopics, fieldSelection, maxNumLogs);
|
|
104
105
|
let match;
|
|
105
106
|
try {
|
|
106
107
|
match = await client.getEventItems(query$1);
|
|
@@ -232,6 +232,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
232
232
|
~knownHeight,
|
|
233
233
|
~partitionId as _,
|
|
234
234
|
~selection,
|
|
235
|
+
~itemsTarget,
|
|
235
236
|
~retry,
|
|
236
237
|
~logger,
|
|
237
238
|
) => {
|
|
@@ -258,6 +259,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
258
259
|
~toBlock,
|
|
259
260
|
~logSelections,
|
|
260
261
|
~fieldSelection=selectionConfig.fieldSelection,
|
|
262
|
+
~maxNumLogs=itemsTarget,
|
|
261
263
|
) catch {
|
|
262
264
|
| HyperSync.GetLogs.Error(error) =>
|
|
263
265
|
throw(
|
|
@@ -149,7 +149,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
149
149
|
}
|
|
150
150
|
};
|
|
151
151
|
};
|
|
152
|
-
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, contractNameByAddress, knownHeight, param, selection, retry, logger) => {
|
|
152
|
+
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, contractNameByAddress, knownHeight, param, selection, itemsTarget, retry, logger) => {
|
|
153
153
|
let totalTimeRef = Performance.now();
|
|
154
154
|
let selectionConfig = getSelectionConfig(selection);
|
|
155
155
|
let logSelections;
|
|
@@ -163,7 +163,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
163
163
|
Prometheus.SourceRequestCount.increment(name, chain, "getLogs");
|
|
164
164
|
let pageUnsafe;
|
|
165
165
|
try {
|
|
166
|
-
pageUnsafe = await HyperSync.GetLogs.query(client, fromBlock, toBlock, logSelections, selectionConfig.fieldSelection);
|
|
166
|
+
pageUnsafe = await HyperSync.GetLogs.query(client, fromBlock, toBlock, logSelections, selectionConfig.fieldSelection, itemsTarget);
|
|
167
167
|
} catch (raw_error) {
|
|
168
168
|
let error = Primitive_exceptions.internalToException(raw_error);
|
|
169
169
|
if (error.RE_EXN_ID === HyperSync.GetLogs.$$Error) {
|