envio 3.15.0-subgraph → 3.16.0-subgraph
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/README.md +40 -34
- package/evm.schema.json +3 -3
- package/fuel.schema.json +2 -2
- package/index.d.ts +3 -3
- package/licenses/README.md +1 -1
- package/package.json +8 -8
- package/src/Batch.res.mjs +5 -5
- package/src/BatchProcessing.res +1 -0
- package/src/BatchProcessing.res.mjs +1 -0
- package/src/ChainFetching.res +1 -6
- package/src/ChainFetching.res.mjs +1 -1
- package/src/ChainState.res +48 -7
- package/src/ChainState.res.mjs +21 -8
- package/src/Clock.res +57 -0
- package/src/Clock.res.mjs +72 -0
- package/src/Config.res +16 -4
- package/src/Config.res.mjs +5 -3
- package/src/Core.res +4 -40
- package/src/CrossChainState.res +10 -6
- package/src/CrossChainState.res.mjs +1 -1
- package/src/EffectState.res +10 -2
- package/src/EffectState.res.mjs +8 -4
- package/src/EffectState.resi +3 -1
- package/src/EntityId.res +2 -7
- package/src/EntityId.res.mjs +1 -8
- package/src/EntityTables.res +4 -1
- package/src/EntityTables.res.mjs +1 -1
- package/src/Env.res +4 -0
- package/src/Env.res.mjs +5 -0
- package/src/FetchState.res +157 -69
- package/src/FetchState.res.mjs +112 -47
- package/src/FinalizeBackfill.res +2 -4
- package/src/FinalizeBackfill.res.mjs +3 -4
- package/src/InMemoryTable.res +17 -16
- package/src/InMemoryTable.res.mjs +14 -15
- package/src/IndexerState.res +28 -4
- package/src/IndexerState.res.mjs +19 -6
- package/src/IndexerState.resi +4 -0
- package/src/Internal.res +0 -49
- package/src/Internal.res.mjs +1 -80
- package/src/LoadLayer.res +17 -10
- package/src/LoadLayer.res.mjs +11 -8
- package/src/Main.res.mjs +1 -1
- package/src/Persistence.res +3 -23
- package/src/Persistence.res.mjs +3 -3
- package/src/PreloadLookahead.res +42 -24
- package/src/PreloadLookahead.res.mjs +51 -30
- package/src/Rollback.res +0 -1
- package/src/Rollback.res.mjs +1 -1
- package/src/SafeCheckpointTracking.res +4 -4
- package/src/SafeCheckpointTracking.res.mjs +1 -1
- package/src/StagedRows.res +106 -0
- package/src/StagedRows.res.mjs +102 -0
- package/src/Staging.res +32 -14
- package/src/Staging.res.mjs +17 -20
- package/src/Storage.res +278 -973
- package/src/Storage.res.mjs +218 -720
- package/src/Supervisor.res +75 -56
- package/src/Supervisor.res.mjs +55 -26
- package/src/SyncWrites.res +24 -18
- package/src/SyncWrites.res.mjs +11 -11
- package/src/TestIndexer.res +22 -27
- package/src/TestIndexer.res.mjs +20 -17
- package/src/Throttler.res +15 -8
- package/src/Throttler.res.mjs +9 -6
- package/src/Throttler.resi +1 -1
- package/src/UserContext.res +13 -4
- package/src/UserContext.res.mjs +5 -5
- package/src/Utils.res +0 -6
- package/src/Utils.res.mjs +0 -5
- package/src/Writing.res +0 -1
- package/src/Writing.res.mjs +1 -1
- package/src/bindings/ClickHouse.res +0 -322
- package/src/bindings/ClickHouse.res.mjs +0 -338
- package/src/bindings/StorageClient.res +107 -174
- package/src/bindings/StorageClient.res.mjs +19 -8
- package/src/bindings/Vitest.res +0 -26
- package/src/bindings/Vitest.res.mjs +0 -3
- package/src/db/Table.res +24 -150
- package/src/db/Table.res.mjs +38 -272
- package/src/sources/ChainSources.res +2 -0
- package/src/sources/ChainSources.res.mjs +2 -2
- package/src/sources/EvmChain.res +3 -0
- package/src/sources/EvmChain.res.mjs +4 -2
- package/src/sources/EvmHyperSyncSource.res +2 -2
- package/src/sources/EvmHyperSyncSource.res.mjs +1 -1
- package/src/sources/EvmRpcClient.res +13 -3
- package/src/sources/EvmRpcClient.res.mjs +4 -3
- package/src/sources/EvmRpcWs.res +4 -3
- package/src/sources/EvmRpcWs.res.mjs +2 -2
- package/src/sources/HeightFeed.res +31 -10
- package/src/sources/HeightFeed.res.mjs +10 -6
- package/src/sources/HeightStream.res +32 -17
- package/src/sources/HeightStream.res.mjs +10 -10
- package/src/sources/HyperSyncSSE.res +4 -6
- package/src/sources/HyperSyncSSE.res.mjs +2 -2
- package/src/sources/RpcSource.res +10 -1
- package/src/sources/RpcSource.res.mjs +4 -3
- package/src/sources/Source.res +3 -0
- package/src/sources/SourceManager.res +85 -104
- package/src/sources/SourceManager.res.mjs +18 -37
- package/src/sources/SourceManager.resi +3 -5
- package/src/sources/StartBlockResolver.res +1 -0
- package/src/sources/StartBlockResolver.res.mjs +4 -3
- package/src/sources/SvmHyperSyncSource.res +2 -2
- package/src/sources/SvmHyperSyncSource.res.mjs +1 -1
- package/src/subgraph/graph-ts.ts +87 -28
- package/src/subgraph/runtime.ts +0 -1
- package/src/subgraph/scope.ts +0 -1
- package/svm.schema.json +3 -3
- package/src/PgWriting.res +0 -36
- package/src/PgWriting.res.mjs +0 -34
- package/src/db/IndexDefinition.res +0 -47
- package/src/db/IndexDefinition.res.mjs +0 -60
package/src/FetchState.res
CHANGED
|
@@ -869,6 +869,17 @@ module OptimizedPartitions = {
|
|
|
869
869
|
// triggers, 2 for one created by those, and so on).
|
|
870
870
|
type creationBlock = {block: int, round: int}
|
|
871
871
|
|
|
872
|
+
// When a contract's addresses leave the server-side filter. A switched contract
|
|
873
|
+
// is fetched by the single address-free partition and gated against the address
|
|
874
|
+
// store on our side. The switch is sticky for the run.
|
|
875
|
+
type clientFilterPolicy = {
|
|
876
|
+
// Past this many registered addresses. None never switches on count alone.
|
|
877
|
+
addressThreshold: option<int>,
|
|
878
|
+
// Every dynamic contract, whatever its address count. Keeps a chain at one
|
|
879
|
+
// query per block, of one shape, however many contracts it registers.
|
|
880
|
+
allDynamicContracts: bool,
|
|
881
|
+
}
|
|
882
|
+
|
|
872
883
|
type t = {
|
|
873
884
|
optimizedPartitions: OptimizedPartitions.t,
|
|
874
885
|
startBlock: int,
|
|
@@ -884,6 +895,7 @@ type t = {
|
|
|
884
895
|
// How much blocks behind the head we should query
|
|
885
896
|
// Needed to query before entering reorg threshold
|
|
886
897
|
blockLag: int,
|
|
898
|
+
blockThrottle: int,
|
|
887
899
|
// Buffer of items ordered from earliest to latest
|
|
888
900
|
buffer: array<Internal.item>,
|
|
889
901
|
// Caps how far ahead onBlock items are pre-generated (set to 2x the batch
|
|
@@ -895,10 +907,7 @@ type t = {
|
|
|
895
907
|
onBlockRegistrations: array<Internal.onBlockRegistration>,
|
|
896
908
|
knownHeight: int,
|
|
897
909
|
firstEventBlock: option<int>,
|
|
898
|
-
|
|
899
|
-
// switched to client-side filtering. None disables the switch, leaving every
|
|
900
|
-
// contract filtered server-side.
|
|
901
|
-
clientFilterAddressThreshold: option<int>,
|
|
910
|
+
clientFilterPolicy: clientFilterPolicy,
|
|
902
911
|
// Subgraph mode only: the block each dynamically registered address was
|
|
903
912
|
// registered in, keyed by contract and lowercase address, until fetching
|
|
904
913
|
// passes it. Its events in that block run after the rest of the block, as
|
|
@@ -1293,6 +1302,7 @@ let updateInternal = (
|
|
|
1293
1302
|
optimizedPartitions,
|
|
1294
1303
|
latestOnBlockBlockNumber,
|
|
1295
1304
|
blockLag,
|
|
1305
|
+
blockThrottle: fetchState.blockThrottle,
|
|
1296
1306
|
knownHeight,
|
|
1297
1307
|
// Single merge point: fold any onBlock items into the sorted base buffer.
|
|
1298
1308
|
buffer: switch blockItems {
|
|
@@ -1300,7 +1310,7 @@ let updateInternal = (
|
|
|
1300
1310
|
| blockItems => base->mergeIntoBuffer(blockItems)
|
|
1301
1311
|
},
|
|
1302
1312
|
firstEventBlock: fetchState.firstEventBlock,
|
|
1303
|
-
|
|
1313
|
+
clientFilterPolicy: fetchState.clientFilterPolicy,
|
|
1304
1314
|
creationBlocks: ?fetchState.creationBlocks,
|
|
1305
1315
|
blockRegisterThrough: ?fetchState.blockRegisterThrough,
|
|
1306
1316
|
}
|
|
@@ -1330,22 +1340,40 @@ type notice =
|
|
|
1330
1340
|
requestedFromBlock: int,
|
|
1331
1341
|
})
|
|
1332
1342
|
|
|
1333
|
-
//
|
|
1334
|
-
|
|
1343
|
+
// The client-filtered set once `policy` has judged `contractNames`. A copy, so
|
|
1344
|
+
// older fetch state snapshots keep theirs: Utils.Set.add mutates in place.
|
|
1345
|
+
let switchToClientSideFiltering = (
|
|
1335
1346
|
clientFilteredContracts: Utils.Set.t<string>,
|
|
1336
|
-
~
|
|
1347
|
+
~contractNames: array<string>,
|
|
1348
|
+
~policy: clientFilterPolicy,
|
|
1349
|
+
~dynamicContracts: Utils.Set.t<string>,
|
|
1350
|
+
~addressStore: AddressStore.t,
|
|
1337
1351
|
~onNotice,
|
|
1338
|
-
~addressCount,
|
|
1339
|
-
~threshold,
|
|
1340
1352
|
// A resumed fetch state re-derives the switch from the persisted addresses,
|
|
1341
|
-
// but it already happened - and was reported - in
|
|
1342
|
-
// threshold.
|
|
1353
|
+
// but it already happened - and was reported - in an earlier run.
|
|
1343
1354
|
~isAlreadyReported=false,
|
|
1344
1355
|
) => {
|
|
1345
|
-
clientFilteredContracts->Utils.Set.
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1356
|
+
let switched = clientFilteredContracts->Utils.Set.toArray->Utils.Set.fromArray
|
|
1357
|
+
contractNames->Array.forEach(contractName =>
|
|
1358
|
+
if !(switched->Utils.Set.has(contractName)) {
|
|
1359
|
+
if policy.allDynamicContracts && dynamicContracts->Utils.Set.has(contractName) {
|
|
1360
|
+
switched->Utils.Set.add(contractName)->ignore
|
|
1361
|
+
} else {
|
|
1362
|
+
switch policy.addressThreshold {
|
|
1363
|
+
| Some(threshold) =>
|
|
1364
|
+
let addressCount = addressStore->AddressStore.contractCount(contractName)
|
|
1365
|
+
if addressCount > threshold {
|
|
1366
|
+
switched->Utils.Set.add(contractName)->ignore
|
|
1367
|
+
if !isAlreadyReported {
|
|
1368
|
+
onNotice(SwitchedToClientSideFiltering({contractName, addressCount, threshold}))
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
| None => ()
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
)
|
|
1376
|
+
switched
|
|
1349
1377
|
}
|
|
1350
1378
|
|
|
1351
1379
|
// The block a partition will have fetched to once everything on its pending
|
|
@@ -2019,34 +2047,16 @@ let registerDynamicContracts = (
|
|
|
2019
2047
|
}
|
|
2020
2048
|
}
|
|
2021
2049
|
|
|
2022
|
-
//
|
|
2023
|
-
//
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
->Utils.Set.toArray
|
|
2033
|
-
->Utils.Set.fromArray
|
|
2034
|
-
dynamicContractsRef.contents
|
|
2035
|
-
->Utils.Set.toArray
|
|
2036
|
-
->Array.forEach(contractName => {
|
|
2037
|
-
let addressCount = addressStore->AddressStore.contractCount(contractName)
|
|
2038
|
-
if !(clientFilteredContracts->Utils.Set.has(contractName)) && addressCount > threshold {
|
|
2039
|
-
clientFilteredContracts->addClientFilteredContract(
|
|
2040
|
-
~contractName,
|
|
2041
|
-
~onNotice,
|
|
2042
|
-
~addressCount,
|
|
2043
|
-
~threshold,
|
|
2044
|
-
)
|
|
2045
|
-
}
|
|
2046
|
-
})
|
|
2047
|
-
clientFilteredContracts
|
|
2048
|
-
| None => fetchState.optimizedPartitions.clientFilteredContracts
|
|
2049
|
-
}
|
|
2050
|
+
// Collapse in createPartitions folds a switched contract's partitions
|
|
2051
|
+
// into the single address-free partition.
|
|
2052
|
+
let clientFilteredContracts =
|
|
2053
|
+
fetchState.optimizedPartitions.clientFilteredContracts->switchToClientSideFiltering(
|
|
2054
|
+
~contractNames=dynamicContractsRef.contents->Utils.Set.toArray,
|
|
2055
|
+
~policy=fetchState.clientFilterPolicy,
|
|
2056
|
+
~dynamicContracts=dynamicContractsRef.contents,
|
|
2057
|
+
~addressStore,
|
|
2058
|
+
~onNotice,
|
|
2059
|
+
)
|
|
2050
2060
|
|
|
2051
2061
|
// Only this batch's additions need partitions; everything already
|
|
2052
2062
|
// registered has one.
|
|
@@ -2077,6 +2087,48 @@ let registerDynamicContracts = (
|
|
|
2077
2087
|
}
|
|
2078
2088
|
}
|
|
2079
2089
|
|
|
2090
|
+
// Every dynamic contract, the ones registered from now on included, is fetched
|
|
2091
|
+
// address-free and filtered on our side. Its partitions fold into the single
|
|
2092
|
+
// address-free partition through the same collapse the address threshold uses.
|
|
2093
|
+
let switchDynamicContractsToClientSideFiltering = (fetchState: t, ~addressStore: AddressStore.t) =>
|
|
2094
|
+
if fetchState.clientFilterPolicy.allDynamicContracts {
|
|
2095
|
+
fetchState
|
|
2096
|
+
} else {
|
|
2097
|
+
let fetchState = {
|
|
2098
|
+
...fetchState,
|
|
2099
|
+
clientFilterPolicy: {...fetchState.clientFilterPolicy, allDynamicContracts: true},
|
|
2100
|
+
}
|
|
2101
|
+
let {
|
|
2102
|
+
dynamicContracts,
|
|
2103
|
+
clientFilteredContracts,
|
|
2104
|
+
maxAddrInPartition,
|
|
2105
|
+
nextPartitionIndex,
|
|
2106
|
+
} = fetchState.optimizedPartitions
|
|
2107
|
+
let switched =
|
|
2108
|
+
clientFilteredContracts
|
|
2109
|
+
->Utils.Set.toArray
|
|
2110
|
+
->Array.concat(dynamicContracts->Utils.Set.toArray)
|
|
2111
|
+
->Utils.Set.fromArray
|
|
2112
|
+
if switched->Utils.Set.size === clientFilteredContracts->Utils.Set.size {
|
|
2113
|
+
fetchState
|
|
2114
|
+
} else {
|
|
2115
|
+
fetchState->updateInternal(
|
|
2116
|
+
~optimizedPartitions=createPartitions(
|
|
2117
|
+
~registeringSetsByContract=Dict.make(),
|
|
2118
|
+
~addressStore,
|
|
2119
|
+
~dynamicContracts,
|
|
2120
|
+
~clientFilteredContracts=switched,
|
|
2121
|
+
~normalSelection=fetchState.normalSelection,
|
|
2122
|
+
~maxAddrInPartition,
|
|
2123
|
+
~nextPartitionIndex,
|
|
2124
|
+
~existingPartitions=fetchState.optimizedPartitions.entities->Dict.valuesToArray,
|
|
2125
|
+
~progressBlockNumber=0,
|
|
2126
|
+
~knownHeight=fetchState.knownHeight,
|
|
2127
|
+
),
|
|
2128
|
+
)
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2131
|
+
|
|
2080
2132
|
/*
|
|
2081
2133
|
Updates fetchState with a response for a given query.
|
|
2082
2134
|
Throws if the partition with given query cannot be found (unexpected)
|
|
@@ -2612,6 +2664,20 @@ let acceptCandidates = (
|
|
|
2612
2664
|
}
|
|
2613
2665
|
}
|
|
2614
2666
|
|
|
2667
|
+
// A throttled chain lets `blockThrottle - 1` new blocks build up before it
|
|
2668
|
+
// fetches them, so a frontier that far behind the lagged head is waiting, not
|
|
2669
|
+
// behind. An end block the head has reached is fetched without waiting.
|
|
2670
|
+
let blocksBehindHeadAllowedByThrottle = ({blockThrottle, endBlock, knownHeight, blockLag}: t) =>
|
|
2671
|
+
switch endBlock {
|
|
2672
|
+
| Some(endBlock) if knownHeight - blockLag >= endBlock => 0
|
|
2673
|
+
| _ => Pervasives.max(0, blockThrottle - 1)
|
|
2674
|
+
}
|
|
2675
|
+
|
|
2676
|
+
// The highest block the chain fetches up to right now: the lagged head, less the
|
|
2677
|
+
// blocks a throttled chain lets build up first.
|
|
2678
|
+
let headFetchTarget = ({knownHeight, blockLag} as fetchState: t) =>
|
|
2679
|
+
knownHeight - blockLag - fetchState->blocksBehindHeadAllowedByThrottle
|
|
2680
|
+
|
|
2615
2681
|
// Candidate queries are sized against chainTargetBlock, the soft querying
|
|
2616
2682
|
// horizon the owning chain wants to reach this tick — derived by ChainState
|
|
2617
2683
|
// from its share of the indexer-wide buffer budget and its chain-level event
|
|
@@ -2640,7 +2706,7 @@ let acceptCandidates = (
|
|
|
2640
2706
|
// rangeTargetDensity × (chainTargetBlock − fromBlock + 1) / inRangeCount — so
|
|
2641
2707
|
// unknown-density partitions probe in parallel within one budget.
|
|
2642
2708
|
let getNextQuery = (
|
|
2643
|
-
{optimizedPartitions, blockLag, latestOnBlockBlockNumber, knownHeight, endBlock}: t,
|
|
2709
|
+
{optimizedPartitions, blockLag, latestOnBlockBlockNumber, knownHeight, endBlock} as fetchState: t,
|
|
2644
2710
|
~chainTargetBlock: int,
|
|
2645
2711
|
~chainTargetItems: float,
|
|
2646
2712
|
) => {
|
|
@@ -2648,7 +2714,8 @@ let getNextQuery = (
|
|
|
2648
2714
|
if headBlockNumber <= 0 {
|
|
2649
2715
|
WaitingForNewBlock
|
|
2650
2716
|
} else {
|
|
2651
|
-
let
|
|
2717
|
+
let caughtUpBlockNumber = headBlockNumber - fetchState->blocksBehindHeadAllowedByThrottle
|
|
2718
|
+
let isOnBlockBehindTheHead = latestOnBlockBlockNumber < caughtUpBlockNumber
|
|
2652
2719
|
let shouldWaitForNewBlock = ref(
|
|
2653
2720
|
switch endBlock {
|
|
2654
2721
|
| Some(endBlock) => headBlockNumber < endBlock
|
|
@@ -2693,7 +2760,7 @@ let getNextQuery = (
|
|
|
2693
2760
|
}
|
|
2694
2761
|
}
|
|
2695
2762
|
inFlightCounts->Array.setUnsafe(idx, inFlightCount.contents)
|
|
2696
|
-
if p.mutPendingQueries->Array.length > 0 || p.latestFetchedBlock <
|
|
2763
|
+
if p.mutPendingQueries->Array.length > 0 || p.latestFetchedBlock < caughtUpBlockNumber {
|
|
2697
2764
|
// Even if there are some partitions waiting for the new block
|
|
2698
2765
|
// We still want to wait for all partitions reaching the head
|
|
2699
2766
|
// because they might update knownHeight in their response
|
|
@@ -2872,6 +2939,7 @@ let make = (
|
|
|
2872
2939
|
~progressBlockNumber=startBlock - 1,
|
|
2873
2940
|
~onBlockRegistrations=[],
|
|
2874
2941
|
~blockLag=0,
|
|
2942
|
+
~blockThrottle=0,
|
|
2875
2943
|
~firstEventBlock=None,
|
|
2876
2944
|
~clientFilterAddressThreshold=None,
|
|
2877
2945
|
~isResumed=false,
|
|
@@ -2955,7 +3023,6 @@ let make = (
|
|
|
2955
3023
|
})
|
|
2956
3024
|
|
|
2957
3025
|
let dynamicContracts = Utils.Set.make()
|
|
2958
|
-
let clientFilteredContracts = Utils.Set.make()
|
|
2959
3026
|
let registeringSetsByContract = Dict.make()
|
|
2960
3027
|
|
|
2961
3028
|
// What each contract needs a partition for is read back off the store rather
|
|
@@ -2979,26 +3046,24 @@ let make = (
|
|
|
2979
3046
|
}
|
|
2980
3047
|
})
|
|
2981
3048
|
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
switch clientFilterAddressThreshold {
|
|
2986
|
-
| Some(threshold) =>
|
|
2987
|
-
registeringSetsByContract->Utils.Dict.forEachWithKey((set, contractName) => {
|
|
2988
|
-
let addressCount = set->AddressSet.size
|
|
2989
|
-
if addressCount > threshold {
|
|
2990
|
-
clientFilteredContracts->addClientFilteredContract(
|
|
2991
|
-
~contractName,
|
|
2992
|
-
~onNotice,
|
|
2993
|
-
~addressCount,
|
|
2994
|
-
~threshold,
|
|
2995
|
-
~isAlreadyReported=isResumed,
|
|
2996
|
-
)
|
|
2997
|
-
}
|
|
2998
|
-
})
|
|
2999
|
-
| None => ()
|
|
3049
|
+
let clientFilterPolicy = {
|
|
3050
|
+
addressThreshold: clientFilterAddressThreshold,
|
|
3051
|
+
allDynamicContracts: false,
|
|
3000
3052
|
}
|
|
3001
3053
|
|
|
3054
|
+
// Switch at creation whatever the threshold already covers: a config
|
|
3055
|
+
// contract with a large static address list, or a dynamic contract restored
|
|
3056
|
+
// from a large persisted set.
|
|
3057
|
+
let clientFilteredContracts =
|
|
3058
|
+
Utils.Set.make()->switchToClientSideFiltering(
|
|
3059
|
+
~contractNames=registeringSetsByContract->Dict.keysToArray,
|
|
3060
|
+
~policy=clientFilterPolicy,
|
|
3061
|
+
~dynamicContracts,
|
|
3062
|
+
~addressStore,
|
|
3063
|
+
~onNotice,
|
|
3064
|
+
~isAlreadyReported=isResumed,
|
|
3065
|
+
)
|
|
3066
|
+
|
|
3002
3067
|
let optimizedPartitions = createPartitions(
|
|
3003
3068
|
~registeringSetsByContract,
|
|
3004
3069
|
~addressStore,
|
|
@@ -3074,12 +3139,13 @@ let make = (
|
|
|
3074
3139
|
latestOnBlockBlockNumber,
|
|
3075
3140
|
normalSelection,
|
|
3076
3141
|
blockLag,
|
|
3142
|
+
blockThrottle,
|
|
3077
3143
|
onBlockRegistrations,
|
|
3078
3144
|
maxOnBlockBufferSize,
|
|
3079
3145
|
knownHeight,
|
|
3080
3146
|
buffer,
|
|
3081
3147
|
firstEventBlock,
|
|
3082
|
-
|
|
3148
|
+
clientFilterPolicy,
|
|
3083
3149
|
creationBlocks: ?(deferCreationBlockEvents ? Some(Dict.make()) : None),
|
|
3084
3150
|
?blockRegisterThrough,
|
|
3085
3151
|
}
|
|
@@ -3301,15 +3367,37 @@ let isActivelyIndexing = ({endBlock} as fetchState: t) => {
|
|
|
3301
3367
|
// True once the fetch frontier has reached the (lagged) head or endBlock,
|
|
3302
3368
|
// regardless of whether the buffer has been consumed yet. Unlike
|
|
3303
3369
|
// isReadyToEnterReorgThreshold, fetched-but-unprocessed items still count.
|
|
3304
|
-
let isFetchingAtHead = ({endBlock,
|
|
3370
|
+
let isFetchingAtHead = ({endBlock, knownHeight} as fetchState: t) => {
|
|
3305
3371
|
let bufferBlockNumber = fetchState->bufferBlockNumber
|
|
3306
3372
|
knownHeight !== 0 &&
|
|
3307
3373
|
switch endBlock {
|
|
3308
3374
|
| Some(endBlock) if bufferBlockNumber >= endBlock => true
|
|
3309
|
-
| _ => bufferBlockNumber >=
|
|
3375
|
+
| _ => bufferBlockNumber >= fetchState->headFetchTarget
|
|
3310
3376
|
}
|
|
3311
3377
|
}
|
|
3312
3378
|
|
|
3379
|
+
// Counted in blocks whatever the chain's block time: the chain still fetches
|
|
3380
|
+
// block by block near the head, and an address-free query must never reach back
|
|
3381
|
+
// into a range a partition is still backfilling.
|
|
3382
|
+
let headClientFilteringDistance = 200
|
|
3383
|
+
|
|
3384
|
+
// Every partition is within `headClientFilteringDistance` of the fetch target. A
|
|
3385
|
+
// chain with no head to follow never is: no known height yet, or an end block it
|
|
3386
|
+
// stops at before the head.
|
|
3387
|
+
let isWithinHeadClientFilteringDistance = (
|
|
3388
|
+
{endBlock, blockLag, knownHeight, optimizedPartitions} as fetchState: t,
|
|
3389
|
+
) =>
|
|
3390
|
+
knownHeight !== 0 &&
|
|
3391
|
+
switch endBlock {
|
|
3392
|
+
| Some(endBlock) => endBlock > knownHeight - blockLag
|
|
3393
|
+
| None => true
|
|
3394
|
+
} &&
|
|
3395
|
+
switch optimizedPartitions->OptimizedPartitions.getLatestFullyFetchedBlock {
|
|
3396
|
+
| Some(latestFetchedBlock) =>
|
|
3397
|
+
fetchState->headFetchTarget - latestFetchedBlock <= headClientFilteringDistance
|
|
3398
|
+
| None => true
|
|
3399
|
+
}
|
|
3400
|
+
|
|
3313
3401
|
// Frontier at (or within `tolerance` of) the lagged head with no processable
|
|
3314
3402
|
// items left — the moment the chain can cross into the reorg threshold.
|
|
3315
3403
|
// `tolerance` absorbs the head advancing between a chain catching up and this
|
package/src/FetchState.res.mjs
CHANGED
|
@@ -1036,28 +1036,49 @@ function updateInternal(fetchState, optimizedPartitionsOpt, mutItems, mutItemsSo
|
|
|
1036
1036
|
chainId: fetchState.chainId,
|
|
1037
1037
|
latestOnBlockBlockNumber: latestOnBlockBlockNumber,
|
|
1038
1038
|
blockLag: blockLag,
|
|
1039
|
+
blockThrottle: fetchState.blockThrottle,
|
|
1039
1040
|
buffer: blockItems.length !== 0 ? mergeIntoBuffer(base, blockItems) : base,
|
|
1040
1041
|
maxOnBlockBufferSize: fetchState.maxOnBlockBufferSize,
|
|
1041
1042
|
onBlockRegistrations: fetchState.onBlockRegistrations,
|
|
1042
1043
|
knownHeight: knownHeight,
|
|
1043
1044
|
firstEventBlock: fetchState.firstEventBlock,
|
|
1044
|
-
|
|
1045
|
+
clientFilterPolicy: fetchState.clientFilterPolicy,
|
|
1045
1046
|
creationBlocks: fetchState.creationBlocks,
|
|
1046
1047
|
blockRegisterThrough: fetchState.blockRegisterThrough
|
|
1047
1048
|
};
|
|
1048
1049
|
}
|
|
1049
1050
|
|
|
1050
|
-
function
|
|
1051
|
+
function switchToClientSideFiltering(clientFilteredContracts, contractNames, policy, dynamicContracts, addressStore, onNotice, isAlreadyReportedOpt) {
|
|
1051
1052
|
let isAlreadyReported = isAlreadyReportedOpt !== undefined ? isAlreadyReportedOpt : false;
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1053
|
+
let switched = new Set(Array.from(clientFilteredContracts));
|
|
1054
|
+
contractNames.forEach(contractName => {
|
|
1055
|
+
if (switched.has(contractName)) {
|
|
1056
|
+
return;
|
|
1057
|
+
}
|
|
1058
|
+
if (policy.allDynamicContracts && dynamicContracts.has(contractName)) {
|
|
1059
|
+
switched.add(contractName);
|
|
1060
|
+
return;
|
|
1061
|
+
}
|
|
1062
|
+
let threshold = policy.addressThreshold;
|
|
1063
|
+
if (threshold === undefined) {
|
|
1064
|
+
return;
|
|
1065
|
+
}
|
|
1066
|
+
let addressCount = addressStore.contractCount(contractName);
|
|
1067
|
+
if (addressCount > threshold) {
|
|
1068
|
+
switched.add(contractName);
|
|
1069
|
+
if (!isAlreadyReported) {
|
|
1070
|
+
return onNotice({
|
|
1071
|
+
TAG: "SwitchedToClientSideFiltering",
|
|
1072
|
+
contractName: contractName,
|
|
1073
|
+
addressCount: addressCount,
|
|
1074
|
+
threshold: threshold
|
|
1075
|
+
});
|
|
1076
|
+
} else {
|
|
1077
|
+
return;
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
});
|
|
1081
|
+
return switched;
|
|
1061
1082
|
}
|
|
1062
1083
|
|
|
1063
1084
|
function claimedFetchedBlock(p, knownHeight) {
|
|
@@ -1505,20 +1526,7 @@ function registerDynamicContracts(fetchState, addressStore, onNotice, claimCeili
|
|
|
1505
1526
|
}
|
|
1506
1527
|
}
|
|
1507
1528
|
}
|
|
1508
|
-
let
|
|
1509
|
-
let clientFilteredContracts;
|
|
1510
|
-
if (threshold !== undefined) {
|
|
1511
|
-
let clientFilteredContracts$1 = new Set(Array.from(fetchState.optimizedPartitions.clientFilteredContracts));
|
|
1512
|
-
Array.from(dynamicContractsRef).forEach(contractName => {
|
|
1513
|
-
let addressCount = addressStore.contractCount(contractName);
|
|
1514
|
-
if (!clientFilteredContracts$1.has(contractName) && addressCount > threshold) {
|
|
1515
|
-
return addClientFilteredContract(clientFilteredContracts$1, contractName, onNotice, addressCount, threshold, undefined);
|
|
1516
|
-
}
|
|
1517
|
-
});
|
|
1518
|
-
clientFilteredContracts = clientFilteredContracts$1;
|
|
1519
|
-
} else {
|
|
1520
|
-
clientFilteredContracts = fetchState.optimizedPartitions.clientFilteredContracts;
|
|
1521
|
-
}
|
|
1529
|
+
let clientFilteredContracts = switchToClientSideFiltering(fetchState.optimizedPartitions.clientFilteredContracts, Array.from(dynamicContractsRef), fetchState.clientFilterPolicy, dynamicContractsRef, addressStore, onNotice, undefined);
|
|
1522
1530
|
let registeringSetsByContract = {};
|
|
1523
1531
|
registeringContractNames.forEach(contractName => {
|
|
1524
1532
|
registeringSetsByContract[contractName] = AddressStore.makeSet(addressStore, contractName, {
|
|
@@ -1529,6 +1537,27 @@ function registerDynamicContracts(fetchState, addressStore, onNotice, claimCeili
|
|
|
1529
1537
|
return updateInternal(fetchState, optimizedPartitions, undefined, undefined, undefined, undefined);
|
|
1530
1538
|
}
|
|
1531
1539
|
|
|
1540
|
+
function switchDynamicContractsToClientSideFiltering(fetchState, addressStore) {
|
|
1541
|
+
if (fetchState.clientFilterPolicy.allDynamicContracts) {
|
|
1542
|
+
return fetchState;
|
|
1543
|
+
}
|
|
1544
|
+
let newrecord = {...fetchState};
|
|
1545
|
+
let init = fetchState.clientFilterPolicy;
|
|
1546
|
+
newrecord.clientFilterPolicy = {
|
|
1547
|
+
addressThreshold: init.addressThreshold,
|
|
1548
|
+
allDynamicContracts: true
|
|
1549
|
+
};
|
|
1550
|
+
let match = newrecord.optimizedPartitions;
|
|
1551
|
+
let clientFilteredContracts = match.clientFilteredContracts;
|
|
1552
|
+
let dynamicContracts = match.dynamicContracts;
|
|
1553
|
+
let switched = new Set(Array.from(clientFilteredContracts).concat(Array.from(dynamicContracts)));
|
|
1554
|
+
if (switched.size === clientFilteredContracts.size) {
|
|
1555
|
+
return newrecord;
|
|
1556
|
+
} else {
|
|
1557
|
+
return updateInternal(newrecord, createPartitions({}, addressStore, dynamicContracts, switched, newrecord.normalSelection, match.maxAddrInPartition, match.nextPartitionIndex, Object.values(newrecord.optimizedPartitions.entities), 0, newrecord.knownHeight), undefined, undefined, undefined, undefined);
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1532
1561
|
function handleQueryResult(fetchState, query, latestFetchedBlock, newItems) {
|
|
1533
1562
|
let tmp;
|
|
1534
1563
|
if (newItems.length !== 0) {
|
|
@@ -1838,15 +1867,30 @@ function acceptCandidates(candidates, reservations, chainTargetItems, partitionI
|
|
|
1838
1867
|
};
|
|
1839
1868
|
}
|
|
1840
1869
|
|
|
1841
|
-
function
|
|
1842
|
-
let
|
|
1870
|
+
function blocksBehindHeadAllowedByThrottle(param) {
|
|
1871
|
+
let blockThrottle = param.blockThrottle;
|
|
1843
1872
|
let endBlock = param.endBlock;
|
|
1844
|
-
|
|
1845
|
-
|
|
1873
|
+
if (endBlock !== undefined && (param.knownHeight - param.blockLag | 0) >= endBlock) {
|
|
1874
|
+
return 0;
|
|
1875
|
+
} else {
|
|
1876
|
+
return Primitive_int.max(0, blockThrottle - 1 | 0);
|
|
1877
|
+
}
|
|
1878
|
+
}
|
|
1879
|
+
|
|
1880
|
+
function headFetchTarget(fetchState) {
|
|
1881
|
+
return (fetchState.knownHeight - fetchState.blockLag | 0) - blocksBehindHeadAllowedByThrottle(fetchState) | 0;
|
|
1882
|
+
}
|
|
1883
|
+
|
|
1884
|
+
function getNextQuery(fetchState, chainTargetBlock, chainTargetItems) {
|
|
1885
|
+
let blockLag = fetchState.blockLag;
|
|
1886
|
+
let endBlock = fetchState.endBlock;
|
|
1887
|
+
let optimizedPartitions = fetchState.optimizedPartitions;
|
|
1888
|
+
let headBlockNumber = fetchState.knownHeight - blockLag | 0;
|
|
1846
1889
|
if (headBlockNumber <= 0) {
|
|
1847
1890
|
return "WaitingForNewBlock";
|
|
1848
1891
|
}
|
|
1849
|
-
let
|
|
1892
|
+
let caughtUpBlockNumber = headBlockNumber - blocksBehindHeadAllowedByThrottle(fetchState) | 0;
|
|
1893
|
+
let isOnBlockBehindTheHead = fetchState.latestOnBlockBlockNumber < caughtUpBlockNumber;
|
|
1850
1894
|
let shouldWaitForNewBlock = (
|
|
1851
1895
|
endBlock !== undefined ? headBlockNumber < endBlock : true
|
|
1852
1896
|
) && !isOnBlockBehindTheHead;
|
|
@@ -1872,7 +1916,7 @@ function getNextQuery(param, chainTargetBlock, chainTargetItems) {
|
|
|
1872
1916
|
}
|
|
1873
1917
|
}
|
|
1874
1918
|
inFlightCounts[idx] = inFlightCount;
|
|
1875
|
-
if (p.mutPendingQueries.length !== 0 || p.latestFetchedBlock <
|
|
1919
|
+
if (p.mutPendingQueries.length !== 0 || p.latestFetchedBlock < caughtUpBlockNumber) {
|
|
1876
1920
|
shouldWaitForNewBlock = false;
|
|
1877
1921
|
}
|
|
1878
1922
|
}
|
|
@@ -1963,10 +2007,11 @@ function getReadyItemsCount(fetchState, targetSize, fromItem) {
|
|
|
1963
2007
|
return acc;
|
|
1964
2008
|
}
|
|
1965
2009
|
|
|
1966
|
-
function make$1(startBlock, endBlock, onEventRegistrations, addressStore, addressRows, maxAddrInPartition, chainId, onNotice, maxOnBlockBufferSize, knownHeight, progressBlockNumberOpt, onBlockRegistrationsOpt, blockLagOpt, firstEventBlockOpt, clientFilterAddressThresholdOpt, isResumedOpt, deferCreationBlockEventsOpt) {
|
|
2010
|
+
function make$1(startBlock, endBlock, onEventRegistrations, addressStore, addressRows, maxAddrInPartition, chainId, onNotice, maxOnBlockBufferSize, knownHeight, progressBlockNumberOpt, onBlockRegistrationsOpt, blockLagOpt, blockThrottleOpt, firstEventBlockOpt, clientFilterAddressThresholdOpt, isResumedOpt, deferCreationBlockEventsOpt) {
|
|
1967
2011
|
let progressBlockNumber = progressBlockNumberOpt !== undefined ? progressBlockNumberOpt : startBlock - 1 | 0;
|
|
1968
2012
|
let onBlockRegistrations = onBlockRegistrationsOpt !== undefined ? onBlockRegistrationsOpt : [];
|
|
1969
2013
|
let blockLag = blockLagOpt !== undefined ? blockLagOpt : 0;
|
|
2014
|
+
let blockThrottle = blockThrottleOpt !== undefined ? blockThrottleOpt : 0;
|
|
1970
2015
|
let firstEventBlock = firstEventBlockOpt !== undefined ? Primitive_option.valFromOption(firstEventBlockOpt) : undefined;
|
|
1971
2016
|
let clientFilterAddressThreshold = clientFilterAddressThresholdOpt !== undefined ? Primitive_option.valFromOption(clientFilterAddressThresholdOpt) : undefined;
|
|
1972
2017
|
let isResumed = isResumedOpt !== undefined ? isResumedOpt : false;
|
|
@@ -2016,7 +2061,6 @@ function make$1(startBlock, endBlock, onEventRegistrations, addressStore, addres
|
|
|
2016
2061
|
requestedFromBlock: rejected.effectiveStartBlock
|
|
2017
2062
|
}));
|
|
2018
2063
|
let dynamicContracts = new Set();
|
|
2019
|
-
let clientFilteredContracts = new Set();
|
|
2020
2064
|
let registeringSetsByContract = {};
|
|
2021
2065
|
Array.from(contractNamesWithNormalEvents).forEach(contractName => {
|
|
2022
2066
|
if (addressStore.contractCount(contractName) > 0) {
|
|
@@ -2030,14 +2074,11 @@ function make$1(startBlock, endBlock, onEventRegistrations, addressStore, addres
|
|
|
2030
2074
|
return;
|
|
2031
2075
|
}
|
|
2032
2076
|
});
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
}
|
|
2039
|
-
});
|
|
2040
|
-
}
|
|
2077
|
+
let clientFilterPolicy = {
|
|
2078
|
+
addressThreshold: clientFilterAddressThreshold,
|
|
2079
|
+
allDynamicContracts: false
|
|
2080
|
+
};
|
|
2081
|
+
let clientFilteredContracts = switchToClientSideFiltering(new Set(), Object.keys(registeringSetsByContract), clientFilterPolicy, dynamicContracts, addressStore, onNotice, isResumed);
|
|
2041
2082
|
let optimizedPartitions = createPartitions(registeringSetsByContract, addressStore, dynamicContracts, clientFilteredContracts, normalSelection, maxAddrInPartition, partitions.length, partitions, progressBlockNumber, knownHeight);
|
|
2042
2083
|
if (optimizedPartitions.idsInAscOrder.length === 0 && Utils.$$Array.isEmpty(onBlockRegistrations$1)) {
|
|
2043
2084
|
Stdlib_JsError.throwWithMessage(`Invalid configuration: Nothing to fetch on chain ` + ChainId.toString(chainId) + `. ` + (`addresses=` + addressRows.addresses.length.toString() + `, `) + (`onEventRegistrations=` + onEventRegistrations.length.toString() + `, `) + (`normalRegistrations=` + normalRegistrations.length.toString() + `. `) + `Make sure that you provided at least one contract address to index, or have events with Wildcard mode enabled, or have onBlock handlers.`);
|
|
@@ -2070,12 +2111,13 @@ function make$1(startBlock, endBlock, onEventRegistrations, addressStore, addres
|
|
|
2070
2111
|
chainId: chainId,
|
|
2071
2112
|
latestOnBlockBlockNumber: latestOnBlockBlockNumber,
|
|
2072
2113
|
blockLag: blockLag,
|
|
2114
|
+
blockThrottle: blockThrottle,
|
|
2073
2115
|
buffer: buffer,
|
|
2074
2116
|
maxOnBlockBufferSize: maxOnBlockBufferSize,
|
|
2075
2117
|
onBlockRegistrations: onBlockRegistrations$1,
|
|
2076
2118
|
knownHeight: knownHeight,
|
|
2077
2119
|
firstEventBlock: firstEventBlock,
|
|
2078
|
-
|
|
2120
|
+
clientFilterPolicy: clientFilterPolicy,
|
|
2079
2121
|
creationBlocks: deferCreationBlockEvents ? ({}) : undefined,
|
|
2080
2122
|
blockRegisterThrough: blockRegisterThrough
|
|
2081
2123
|
};
|
|
@@ -2238,21 +2280,37 @@ function isActivelyIndexing(fetchState) {
|
|
|
2238
2280
|
}
|
|
2239
2281
|
|
|
2240
2282
|
function isFetchingAtHead(fetchState) {
|
|
2241
|
-
let knownHeight = fetchState.knownHeight;
|
|
2242
|
-
let blockLag = fetchState.blockLag;
|
|
2243
2283
|
let endBlock = fetchState.endBlock;
|
|
2244
2284
|
let bufferBlockNumber$1 = bufferBlockNumber(fetchState);
|
|
2245
|
-
if (knownHeight !== 0) {
|
|
2285
|
+
if (fetchState.knownHeight !== 0) {
|
|
2246
2286
|
if (endBlock !== undefined && bufferBlockNumber$1 >= endBlock) {
|
|
2247
2287
|
return true;
|
|
2248
2288
|
} else {
|
|
2249
|
-
return bufferBlockNumber$1 >= (
|
|
2289
|
+
return bufferBlockNumber$1 >= headFetchTarget(fetchState);
|
|
2250
2290
|
}
|
|
2251
2291
|
} else {
|
|
2252
2292
|
return false;
|
|
2253
2293
|
}
|
|
2254
2294
|
}
|
|
2255
2295
|
|
|
2296
|
+
function isWithinHeadClientFilteringDistance(fetchState) {
|
|
2297
|
+
let knownHeight = fetchState.knownHeight;
|
|
2298
|
+
let endBlock = fetchState.endBlock;
|
|
2299
|
+
let optimizedPartitions = fetchState.optimizedPartitions;
|
|
2300
|
+
if (!(knownHeight !== 0 && (
|
|
2301
|
+
endBlock !== undefined ? endBlock > (knownHeight - fetchState.blockLag | 0) : true
|
|
2302
|
+
))) {
|
|
2303
|
+
return false;
|
|
2304
|
+
}
|
|
2305
|
+
let id = optimizedPartitions.idsInAscOrder[0];
|
|
2306
|
+
let latestFetchedBlock = id !== undefined ? optimizedPartitions.entities[id].latestFetchedBlock : undefined;
|
|
2307
|
+
if (latestFetchedBlock !== undefined) {
|
|
2308
|
+
return (headFetchTarget(fetchState) - latestFetchedBlock | 0) <= 200;
|
|
2309
|
+
} else {
|
|
2310
|
+
return true;
|
|
2311
|
+
}
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2256
2314
|
function isReadyToEnterReorgThreshold(tolerance, fetchState) {
|
|
2257
2315
|
let knownHeight = fetchState.knownHeight;
|
|
2258
2316
|
let endBlock = fetchState.endBlock;
|
|
@@ -2339,6 +2397,8 @@ let maxChainConcurrency = Env.maxChainConcurrency;
|
|
|
2339
2397
|
|
|
2340
2398
|
let chunkRangeGrowthFactor = 1.8;
|
|
2341
2399
|
|
|
2400
|
+
let headClientFilteringDistance = 200;
|
|
2401
|
+
|
|
2342
2402
|
export {
|
|
2343
2403
|
deriveSelectionStartBlock,
|
|
2344
2404
|
makeSelection,
|
|
@@ -2364,7 +2424,7 @@ export {
|
|
|
2364
2424
|
mergeIntoBuffer,
|
|
2365
2425
|
appendOnBlockItems,
|
|
2366
2426
|
updateInternal,
|
|
2367
|
-
|
|
2427
|
+
switchToClientSideFiltering,
|
|
2368
2428
|
claimedFetchedBlock,
|
|
2369
2429
|
collapseClientFilteredContracts,
|
|
2370
2430
|
reportRejectedRegistration,
|
|
@@ -2373,6 +2433,7 @@ export {
|
|
|
2373
2433
|
markCreationBlockEvents,
|
|
2374
2434
|
creationRoundOfRegistration,
|
|
2375
2435
|
registerDynamicContracts,
|
|
2436
|
+
switchDynamicContractsToClientSideFiltering,
|
|
2376
2437
|
handleQueryResult,
|
|
2377
2438
|
capAtEndBlock,
|
|
2378
2439
|
canAdvanceBlockRegisters,
|
|
@@ -2389,6 +2450,8 @@ export {
|
|
|
2389
2450
|
walkPartitionPending,
|
|
2390
2451
|
pushForwardCandidates,
|
|
2391
2452
|
acceptCandidates,
|
|
2453
|
+
blocksBehindHeadAllowedByThrottle,
|
|
2454
|
+
headFetchTarget,
|
|
2392
2455
|
getNextQuery,
|
|
2393
2456
|
hasReadyItem,
|
|
2394
2457
|
getReadyItemsCount,
|
|
@@ -2400,6 +2463,8 @@ export {
|
|
|
2400
2463
|
resetPendingQueries,
|
|
2401
2464
|
isActivelyIndexing,
|
|
2402
2465
|
isFetchingAtHead,
|
|
2466
|
+
headClientFilteringDistance,
|
|
2467
|
+
isWithinHeadClientFilteringDistance,
|
|
2403
2468
|
isReadyToEnterReorgThreshold,
|
|
2404
2469
|
getProgressPercentage,
|
|
2405
2470
|
sortForBatch,
|
package/src/FinalizeBackfill.res
CHANGED
|
@@ -40,7 +40,7 @@ let runOnce = async (state: IndexerState.t) => {
|
|
|
40
40
|
let storage = persistence->Persistence.getInitializedStorageOrThrow
|
|
41
41
|
let readyAt = Date.make()
|
|
42
42
|
|
|
43
|
-
await storage.finalizeBackfill(~
|
|
43
|
+
await storage.finalizeBackfill(~chainIds, ~readyAt)
|
|
44
44
|
|
|
45
45
|
// Only after the commit: in-memory readiness must never run ahead of the
|
|
46
46
|
// `ready_at` a restart would read back.
|
|
@@ -68,10 +68,8 @@ let run = (state: IndexerState.t) =>
|
|
|
68
68
|
// Best-effort and not awaited by the loop: indexing is already live and correct
|
|
69
69
|
// without the index, just slower.
|
|
70
70
|
let repairSchemaIndexes = (state: IndexerState.t) => {
|
|
71
|
-
let
|
|
72
|
-
let storage = persistence->Persistence.getInitializedStorageOrThrow
|
|
71
|
+
let storage = state->IndexerState.persistence->Persistence.getInitializedStorageOrThrow
|
|
73
72
|
storage.ensureSchemaIndexes(
|
|
74
|
-
~entities=persistence.allEntities,
|
|
75
73
|
~chainIds=state->IndexerState.crossChainState->CrossChainState.chainIds,
|
|
76
74
|
)
|
|
77
75
|
}
|