envio 3.3.0-alpha.0 → 3.3.0-alpha.10
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/evm.schema.json +10 -0
- package/index.d.ts +45 -25
- package/package.json +7 -7
- package/src/Address.res +5 -2
- package/src/Address.res.mjs +3 -1
- package/src/Api.res +1 -1
- package/src/Api.res.mjs +1 -1
- package/src/Batch.res +0 -6
- package/src/Batch.res.mjs +1 -12
- package/src/BatchProcessing.res +7 -12
- package/src/BatchProcessing.res.mjs +8 -7
- package/src/Bin.res +3 -0
- package/src/Bin.res.mjs +4 -0
- package/src/ChainFetching.res +48 -16
- package/src/ChainFetching.res.mjs +36 -17
- package/src/ChainMetadata.res +1 -11
- package/src/ChainMetadata.res.mjs +1 -10
- package/src/ChainState.res +628 -149
- package/src/ChainState.res.mjs +440 -102
- package/src/ChainState.resi +74 -4
- package/src/Config.res +61 -33
- package/src/Config.res.mjs +50 -10
- package/src/ContractRegisterContext.res +2 -12
- package/src/ContractRegisterContext.res.mjs +3 -5
- package/src/Core.res +14 -3
- package/src/CrossChainState.res +142 -93
- package/src/CrossChainState.res.mjs +88 -60
- package/src/CrossChainState.resi +2 -10
- package/src/Ecosystem.res +5 -6
- package/src/Ecosystem.res.mjs +3 -3
- package/src/Env.res +0 -7
- package/src/Env.res.mjs +0 -6
- package/src/Envio.res +17 -11
- package/src/EnvioGlobal.res +53 -0
- package/src/EnvioGlobal.res.mjs +31 -0
- package/src/EventConfigBuilder.res +177 -88
- package/src/EventConfigBuilder.res.mjs +99 -42
- package/src/EventProcessing.res +74 -28
- package/src/EventProcessing.res.mjs +55 -29
- package/src/ExitOnCaughtUp.res +10 -2
- package/src/ExitOnCaughtUp.res.mjs +10 -1
- package/src/FetchState.res +558 -300
- package/src/FetchState.res.mjs +437 -423
- package/src/HandlerLoader.res +8 -104
- package/src/HandlerLoader.res.mjs +2 -81
- package/src/HandlerRegister.res +518 -144
- package/src/HandlerRegister.res.mjs +285 -133
- package/src/HandlerRegister.resi +24 -8
- package/src/IndexerLoop.res +2 -3
- package/src/IndexerLoop.res.mjs +1 -1
- package/src/IndexerState.res +10 -11
- package/src/IndexerState.res.mjs +14 -11
- package/src/IndexerState.resi +2 -5
- package/src/IndexingAddresses.res +108 -0
- package/src/IndexingAddresses.res.mjs +101 -0
- package/src/IndexingAddresses.resi +34 -0
- package/src/Internal.res +155 -46
- package/src/Internal.res.mjs +30 -2
- package/src/LoadLayer.res +5 -5
- package/src/LoadLayer.res.mjs +6 -6
- package/src/LogSelection.res +102 -165
- package/src/LogSelection.res.mjs +101 -116
- package/src/Main.res +71 -236
- package/src/Main.res.mjs +60 -145
- package/src/Metrics.res +74 -0
- package/src/Metrics.res.mjs +75 -0
- package/src/PgStorage.res +4 -4
- package/src/PgStorage.res.mjs +5 -5
- package/src/Prometheus.res +10 -74
- package/src/Prometheus.res.mjs +124 -186
- package/src/PruneStaleHistory.res +2 -2
- package/src/PruneStaleHistory.res.mjs +3 -3
- package/src/RawEvent.res +7 -2
- package/src/RawEvent.res.mjs +4 -4
- package/src/Rollback.res +3 -3
- package/src/Rollback.res.mjs +4 -4
- package/src/RollbackCommit.res +4 -1
- package/src/RollbackCommit.res.mjs +3 -2
- package/src/SimulateDeadInputTracker.res +85 -0
- package/src/SimulateDeadInputTracker.res.mjs +73 -0
- package/src/SimulateDeadInputTracker.resi +12 -0
- package/src/SimulateItems.res +91 -23
- package/src/SimulateItems.res.mjs +55 -32
- package/src/TestIndexer.res +54 -40
- package/src/TestIndexer.res.mjs +37 -30
- package/src/bindings/Performance.res +7 -0
- package/src/bindings/Performance.res.mjs +21 -0
- package/src/bindings/Performance.resi +7 -0
- package/src/bindings/Viem.res +0 -41
- package/src/bindings/Viem.res.mjs +1 -43
- package/src/sources/BlockStore.res +46 -0
- package/src/sources/BlockStore.res.mjs +24 -0
- package/src/sources/EventRouter.res +36 -33
- package/src/sources/EventRouter.res.mjs +13 -14
- package/src/sources/Evm.res +83 -72
- package/src/sources/Evm.res.mjs +53 -69
- package/src/sources/EvmChain.res +18 -20
- package/src/sources/EvmChain.res.mjs +15 -15
- package/src/sources/EvmRpcClient.res +74 -5
- package/src/sources/EvmRpcClient.res.mjs +13 -4
- package/src/sources/FieldMask.res +39 -0
- package/src/sources/FieldMask.res.mjs +42 -0
- package/src/sources/Fuel.res +9 -6
- package/src/sources/Fuel.res.mjs +5 -10
- package/src/sources/HyperFuelSource.res +46 -50
- package/src/sources/HyperFuelSource.res.mjs +64 -54
- package/src/sources/HyperSync.res +39 -7
- package/src/sources/HyperSync.res.mjs +57 -37
- package/src/sources/HyperSync.resi +12 -2
- package/src/sources/HyperSyncClient.res +22 -111
- package/src/sources/HyperSyncClient.res.mjs +2 -30
- package/src/sources/HyperSyncHeightStream.res +1 -8
- package/src/sources/HyperSyncHeightStream.res.mjs +0 -2
- package/src/sources/HyperSyncSource.res +94 -107
- package/src/sources/HyperSyncSource.res.mjs +82 -86
- package/src/sources/Rpc.res +15 -47
- package/src/sources/Rpc.res.mjs +25 -56
- package/src/sources/RpcSource.res +320 -467
- package/src/sources/RpcSource.res.mjs +268 -385
- package/src/sources/RpcWebSocketHeightStream.res +0 -5
- package/src/sources/RpcWebSocketHeightStream.res.mjs +0 -2
- package/src/sources/SimulateSource.res +10 -4
- package/src/sources/SimulateSource.res.mjs +16 -6
- package/src/sources/Source.res +34 -6
- package/src/sources/SourceManager.res +86 -27
- package/src/sources/SourceManager.res.mjs +84 -47
- package/src/sources/SourceManager.resi +12 -3
- package/src/sources/Svm.res +31 -16
- package/src/sources/Svm.res.mjs +36 -13
- package/src/sources/SvmHyperSyncClient.res +5 -32
- package/src/sources/SvmHyperSyncSource.res +159 -134
- package/src/sources/SvmHyperSyncSource.res.mjs +164 -129
- package/src/sources/TransactionStore.res +49 -0
- package/src/sources/TransactionStore.res.mjs +30 -0
- package/src/tui/Tui.res +13 -16
- package/src/tui/Tui.res.mjs +12 -14
- package/svm.schema.json +49 -37
- package/src/bindings/Hrtime.res +0 -58
- package/src/bindings/Hrtime.res.mjs +0 -90
- package/src/bindings/Hrtime.resi +0 -30
package/src/IndexerState.res.mjs
CHANGED
|
@@ -18,6 +18,7 @@ import * as CrossChainState from "./CrossChainState.res.mjs";
|
|
|
18
18
|
import * as Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js";
|
|
19
19
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
20
20
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
21
|
+
import * as SimulateDeadInputTracker from "./SimulateDeadInputTracker.res.mjs";
|
|
21
22
|
|
|
22
23
|
function make() {
|
|
23
24
|
let intervalMillis = Env.ThrottleWrites.pruneStaleDataIntervalMillis;
|
|
@@ -53,9 +54,7 @@ function get(self, entityName) {
|
|
|
53
54
|
}
|
|
54
55
|
}
|
|
55
56
|
|
|
56
|
-
function make$2(config, persistence, chainStates, isInReorgThreshold, isRealtime,
|
|
57
|
-
let maxBackfillConcurrency = maxBackfillConcurrencyOpt !== undefined ? maxBackfillConcurrencyOpt : Env.maxBackfillConcurrency;
|
|
58
|
-
let maxRealtimeConcurrency = maxRealtimeConcurrencyOpt !== undefined ? maxRealtimeConcurrencyOpt : Env.maxRealtimeConcurrency;
|
|
57
|
+
function make$2(config, persistence, chainStates, isInReorgThreshold, isRealtime, targetBufferSizeOpt, committedCheckpointIdOpt, isDevelopmentModeOpt, shouldUseTuiOpt, exitAfterFirstEventBlockOpt, onError) {
|
|
59
58
|
let targetBufferSize = targetBufferSizeOpt !== undefined ? targetBufferSizeOpt : CrossChainState.calculateTargetBufferSize();
|
|
60
59
|
let committedCheckpointId = committedCheckpointIdOpt !== undefined ? committedCheckpointIdOpt : Internal.initialCheckpointId;
|
|
61
60
|
let isDevelopmentMode = isDevelopmentModeOpt !== undefined ? isDevelopmentModeOpt : false;
|
|
@@ -84,7 +83,7 @@ function make$2(config, persistence, chainStates, isInReorgThreshold, isRealtime
|
|
|
84
83
|
chainMetaDirty: false,
|
|
85
84
|
chainMetaThrottler: chainMetaThrottler,
|
|
86
85
|
isProcessing: false,
|
|
87
|
-
crossChainState: CrossChainState.make(chainStates, isInReorgThreshold, isRealtime,
|
|
86
|
+
crossChainState: CrossChainState.make(chainStates, isInReorgThreshold, isRealtime, targetBufferSize),
|
|
88
87
|
rollbackState: "NoRollback",
|
|
89
88
|
indexerStartTime: new Date(),
|
|
90
89
|
writeThrottlers: make(),
|
|
@@ -93,16 +92,15 @@ function make$2(config, persistence, chainStates, isInReorgThreshold, isRealtime
|
|
|
93
92
|
exitAfterFirstEventBlock: exitAfterFirstEventBlock,
|
|
94
93
|
onError: onError,
|
|
95
94
|
isStopped: false,
|
|
96
|
-
epoch: 0
|
|
95
|
+
epoch: 0,
|
|
96
|
+
simulateDeadInputTracker: SimulateDeadInputTracker.makeFromConfig(config)
|
|
97
97
|
};
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
function makeFromDbState(config, persistence, initialState,
|
|
100
|
+
function makeFromDbState(config, persistence, initialState, registrationsByChainId, isDevelopmentModeOpt, shouldUseTuiOpt, exitAfterFirstEventBlockOpt, reducedPollingInterval, targetBufferSizeOpt, onError) {
|
|
101
101
|
let isDevelopmentMode = isDevelopmentModeOpt !== undefined ? isDevelopmentModeOpt : false;
|
|
102
102
|
let shouldUseTui = shouldUseTuiOpt !== undefined ? shouldUseTuiOpt : false;
|
|
103
103
|
let exitAfterFirstEventBlock = exitAfterFirstEventBlockOpt !== undefined ? exitAfterFirstEventBlockOpt : false;
|
|
104
|
-
let maxBackfillConcurrency = maxBackfillConcurrencyOpt !== undefined ? maxBackfillConcurrencyOpt : Env.maxBackfillConcurrency;
|
|
105
|
-
let maxRealtimeConcurrency = maxRealtimeConcurrencyOpt !== undefined ? maxRealtimeConcurrencyOpt : Env.maxRealtimeConcurrency;
|
|
106
104
|
let targetBufferSize = targetBufferSizeOpt !== undefined ? targetBufferSizeOpt : CrossChainState.calculateTargetBufferSize();
|
|
107
105
|
let isInReorgThreshold = initialState.cleanRun ? false : initialState.chains.some(chain => {
|
|
108
106
|
let progressBlockNumber = chain.progressBlockNumber;
|
|
@@ -125,7 +123,7 @@ function makeFromDbState(config, persistence, initialState, registrations, isDev
|
|
|
125
123
|
initialState.chains.forEach(resumedChainState => {
|
|
126
124
|
let chain = Config.getChain(config, resumedChainState.id);
|
|
127
125
|
let chainConfig = ChainMap.get(config.chainMap, chain);
|
|
128
|
-
chainStates[resumedChainState.id] = ChainState.makeFromDbState(chainConfig, resumedChainState, initialState.reorgCheckpoints, isInReorgThreshold, isRealtime, config,
|
|
126
|
+
chainStates[resumedChainState.id] = ChainState.makeFromDbState(chainConfig, resumedChainState, initialState.reorgCheckpoints, isInReorgThreshold, isRealtime, config, registrationsByChainId, reducedPollingInterval);
|
|
129
127
|
});
|
|
130
128
|
let allChainsReady = {
|
|
131
129
|
contents: initialState.chains.length !== 0
|
|
@@ -144,7 +142,7 @@ function makeFromDbState(config, persistence, initialState, registrations, isDev
|
|
|
144
142
|
if (allChainsReady.contents) {
|
|
145
143
|
Prometheus.ProgressReady.setAllReady();
|
|
146
144
|
}
|
|
147
|
-
return make$2(config, persistence, chainStates, isInReorgThreshold, isRealtime,
|
|
145
|
+
return make$2(config, persistence, chainStates, isInReorgThreshold, isRealtime, targetBufferSize, initialState.checkpointId, isDevelopmentMode, shouldUseTui, exitAfterFirstEventBlock, onError);
|
|
148
146
|
}
|
|
149
147
|
|
|
150
148
|
function isStale(state, stateId) {
|
|
@@ -233,7 +231,7 @@ function invalidateInflight(state) {
|
|
|
233
231
|
}
|
|
234
232
|
|
|
235
233
|
function applyBatchProgress(state, batch) {
|
|
236
|
-
CrossChainState.applyBatchProgress(state.crossChainState, batch);
|
|
234
|
+
CrossChainState.applyBatchProgress(state.crossChainState, batch, state.config.ecosystem.blockTimestampName);
|
|
237
235
|
}
|
|
238
236
|
|
|
239
237
|
function isProcessing(state) {
|
|
@@ -352,6 +350,10 @@ function pruneStaleEntityHistoryThrottler(state) {
|
|
|
352
350
|
return state.writeThrottlers.pruneStaleEntityHistory;
|
|
353
351
|
}
|
|
354
352
|
|
|
353
|
+
function simulateDeadInputTracker(state) {
|
|
354
|
+
return state.simulateDeadInputTracker;
|
|
355
|
+
}
|
|
356
|
+
|
|
355
357
|
function queueProcessedBatch(state, batch) {
|
|
356
358
|
state.processedBatches.push(batch);
|
|
357
359
|
let checkpointId = Utils.$$Array.last(batch.checkpointIds);
|
|
@@ -531,6 +533,7 @@ export {
|
|
|
531
533
|
isStopped,
|
|
532
534
|
epoch,
|
|
533
535
|
pruneStaleEntityHistoryThrottler,
|
|
536
|
+
simulateDeadInputTracker,
|
|
534
537
|
queueProcessedBatch,
|
|
535
538
|
drainBatchRun,
|
|
536
539
|
takeRollback,
|
package/src/IndexerState.resi
CHANGED
|
@@ -32,8 +32,6 @@ let make: (
|
|
|
32
32
|
~chainStates: dict<ChainState.t>,
|
|
33
33
|
~isInReorgThreshold: bool,
|
|
34
34
|
~isRealtime: bool,
|
|
35
|
-
~maxBackfillConcurrency: int=?,
|
|
36
|
-
~maxRealtimeConcurrency: int=?,
|
|
37
35
|
~targetBufferSize: int=?,
|
|
38
36
|
~committedCheckpointId: Internal.checkpointId=?,
|
|
39
37
|
~isDevelopmentMode: bool=?,
|
|
@@ -46,13 +44,11 @@ let makeFromDbState: (
|
|
|
46
44
|
~config: Config.t,
|
|
47
45
|
~persistence: Persistence.t,
|
|
48
46
|
~initialState: Persistence.initialState,
|
|
49
|
-
~
|
|
47
|
+
~registrationsByChainId: HandlerRegister.registrationsByChainId,
|
|
50
48
|
~isDevelopmentMode: bool=?,
|
|
51
49
|
~shouldUseTui: bool=?,
|
|
52
50
|
~exitAfterFirstEventBlock: bool=?,
|
|
53
51
|
~reducedPollingInterval: int=?,
|
|
54
|
-
~maxBackfillConcurrency: int=?,
|
|
55
|
-
~maxRealtimeConcurrency: int=?,
|
|
56
52
|
~targetBufferSize: int=?,
|
|
57
53
|
~onError: ErrorHandling.t => unit,
|
|
58
54
|
) => t
|
|
@@ -111,6 +107,7 @@ let exitAfterFirstEventBlock: t => bool
|
|
|
111
107
|
let isStopped: t => bool
|
|
112
108
|
let epoch: t => int
|
|
113
109
|
let pruneStaleEntityHistoryThrottler: t => Throttler.t
|
|
110
|
+
let simulateDeadInputTracker: t => option<SimulateDeadInputTracker.t>
|
|
114
111
|
|
|
115
112
|
// Store domain operations.
|
|
116
113
|
let queueProcessedBatch: (t, ~batch: Batch.t) => unit
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
type indexingAddress = Internal.indexingContract
|
|
2
|
+
|
|
3
|
+
type contractConfig = {startBlock: option<int>}
|
|
4
|
+
|
|
5
|
+
type t = dict<indexingAddress>
|
|
6
|
+
|
|
7
|
+
let deriveEffectiveStartBlock = (~registrationBlock: int, ~contractStartBlock: option<int>) => {
|
|
8
|
+
Pervasives.max(Pervasives.max(registrationBlock, 0), contractStartBlock->Option.getOr(0))
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
let makeContractConfigs = (~onEventRegistrations: array<Internal.onEventRegistration>): dict<
|
|
12
|
+
contractConfig,
|
|
13
|
+
> => {
|
|
14
|
+
let contractConfigs: dict<contractConfig> = Dict.make()
|
|
15
|
+
onEventRegistrations->Array.forEach(reg => {
|
|
16
|
+
let contractName = reg.eventConfig.contractName
|
|
17
|
+
switch contractConfigs->Utils.Dict.dangerouslyGetNonOption(contractName) {
|
|
18
|
+
| Some({startBlock}) =>
|
|
19
|
+
contractConfigs->Dict.set(
|
|
20
|
+
contractName,
|
|
21
|
+
{
|
|
22
|
+
startBlock: switch (startBlock, reg.startBlock) {
|
|
23
|
+
| (Some(a), Some(b)) => Some(Pervasives.min(a, b))
|
|
24
|
+
| (Some(_) as s, None) | (None, Some(_) as s) => s
|
|
25
|
+
| (None, None) => None
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
)
|
|
29
|
+
| None =>
|
|
30
|
+
contractConfigs->Dict.set(
|
|
31
|
+
contractName,
|
|
32
|
+
{
|
|
33
|
+
startBlock: reg.startBlock,
|
|
34
|
+
},
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
contractConfigs
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let makeIndexingAddress = (
|
|
42
|
+
~contract: Internal.indexingAddress,
|
|
43
|
+
~contractConfigs: dict<contractConfig>,
|
|
44
|
+
): indexingAddress => {
|
|
45
|
+
let contractStartBlock = switch contractConfigs->Utils.Dict.dangerouslyGetNonOption(
|
|
46
|
+
contract.contractName,
|
|
47
|
+
) {
|
|
48
|
+
| Some({startBlock}) => startBlock
|
|
49
|
+
| None => None
|
|
50
|
+
}
|
|
51
|
+
{
|
|
52
|
+
address: contract.address,
|
|
53
|
+
contractName: contract.contractName,
|
|
54
|
+
registrationBlock: contract.registrationBlock,
|
|
55
|
+
effectiveStartBlock: deriveEffectiveStartBlock(
|
|
56
|
+
~registrationBlock=contract.registrationBlock,
|
|
57
|
+
~contractStartBlock,
|
|
58
|
+
),
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
let make = (
|
|
63
|
+
~contractConfigs: dict<contractConfig>,
|
|
64
|
+
~addresses: array<Internal.indexingAddress>,
|
|
65
|
+
): t => {
|
|
66
|
+
let indexingAddresses = Dict.make()
|
|
67
|
+
addresses->Array.forEach(contract => {
|
|
68
|
+
indexingAddresses->Dict.set(
|
|
69
|
+
contract.address->Address.toString,
|
|
70
|
+
makeIndexingAddress(~contract, ~contractConfigs),
|
|
71
|
+
)
|
|
72
|
+
})
|
|
73
|
+
indexingAddresses
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
let get = (indexingAddresses: t, address) =>
|
|
77
|
+
indexingAddresses->Utils.Dict.dangerouslyGetNonOption(address)
|
|
78
|
+
|
|
79
|
+
let size = (indexingAddresses: t) => indexingAddresses->Utils.Dict.size
|
|
80
|
+
|
|
81
|
+
let getContractAddresses = (indexingAddresses: t, ~contractName): array<Address.t> => {
|
|
82
|
+
let addresses = []
|
|
83
|
+
indexingAddresses->Utils.Dict.forEach(ia => {
|
|
84
|
+
if ia.contractName === contractName {
|
|
85
|
+
addresses->Array.push(ia.address)
|
|
86
|
+
}
|
|
87
|
+
})
|
|
88
|
+
addresses
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Underlying dict for the precompiled `clientAddressFilter` only — it does raw
|
|
92
|
+
// `indexingAddresses[srcAddress]` access in generated JS and can't take the opaque
|
|
93
|
+
// type. Don't reach for this elsewhere; use the domain accessors above.
|
|
94
|
+
let rawForFilter = (indexingAddresses: t): dict<indexingAddress> => indexingAddresses
|
|
95
|
+
|
|
96
|
+
let register = (indexingAddresses: t, additions: dict<indexingAddress>) => {
|
|
97
|
+
let _ = Utils.Dict.mergeInPlace(indexingAddresses, additions)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
let rollbackInPlace = (indexingAddresses: t, ~targetBlockNumber: int): unit => {
|
|
101
|
+
// forEachWithKey is a `for..in`, so deleting the key currently being visited is
|
|
102
|
+
// safe — it doesn't affect enumeration of the remaining keys.
|
|
103
|
+
indexingAddresses->Utils.Dict.forEachWithKey((indexingContract, address) => {
|
|
104
|
+
if indexingContract.registrationBlock > targetBlockNumber {
|
|
105
|
+
indexingAddresses->Utils.Dict.deleteInPlace(address)
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Utils from "./Utils.res.mjs";
|
|
4
|
+
import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
|
|
5
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
6
|
+
|
|
7
|
+
function deriveEffectiveStartBlock(registrationBlock, contractStartBlock) {
|
|
8
|
+
return Primitive_int.max(Primitive_int.max(registrationBlock, 0), Stdlib_Option.getOr(contractStartBlock, 0));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function makeContractConfigs(onEventRegistrations) {
|
|
12
|
+
let contractConfigs = {};
|
|
13
|
+
onEventRegistrations.forEach(reg => {
|
|
14
|
+
let contractName = reg.eventConfig.contractName;
|
|
15
|
+
let match = contractConfigs[contractName];
|
|
16
|
+
if (match !== undefined) {
|
|
17
|
+
let startBlock = match.startBlock;
|
|
18
|
+
let match$1 = reg.startBlock;
|
|
19
|
+
contractConfigs[contractName] = {
|
|
20
|
+
startBlock: startBlock !== undefined ? (
|
|
21
|
+
match$1 !== undefined ? Primitive_int.min(startBlock, match$1) : startBlock
|
|
22
|
+
) : (
|
|
23
|
+
match$1 !== undefined ? match$1 : undefined
|
|
24
|
+
)
|
|
25
|
+
};
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
contractConfigs[contractName] = {
|
|
29
|
+
startBlock: reg.startBlock
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
return contractConfigs;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function makeIndexingAddress(contract, contractConfigs) {
|
|
36
|
+
let match = contractConfigs[contract.contractName];
|
|
37
|
+
let contractStartBlock = match !== undefined ? match.startBlock : undefined;
|
|
38
|
+
return {
|
|
39
|
+
address: contract.address,
|
|
40
|
+
contractName: contract.contractName,
|
|
41
|
+
registrationBlock: contract.registrationBlock,
|
|
42
|
+
effectiveStartBlock: deriveEffectiveStartBlock(contract.registrationBlock, contractStartBlock)
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function make(contractConfigs, addresses) {
|
|
47
|
+
let indexingAddresses = {};
|
|
48
|
+
addresses.forEach(contract => {
|
|
49
|
+
indexingAddresses[contract.address] = makeIndexingAddress(contract, contractConfigs);
|
|
50
|
+
});
|
|
51
|
+
return indexingAddresses;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function get(indexingAddresses, address) {
|
|
55
|
+
return indexingAddresses[address];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function size(indexingAddresses) {
|
|
59
|
+
return Utils.Dict.size(indexingAddresses);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function getContractAddresses(indexingAddresses, contractName) {
|
|
63
|
+
let addresses = [];
|
|
64
|
+
Utils.Dict.forEach(indexingAddresses, ia => {
|
|
65
|
+
if (ia.contractName === contractName) {
|
|
66
|
+
addresses.push(ia.address);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
return addresses;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function rawForFilter(indexingAddresses) {
|
|
74
|
+
return indexingAddresses;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function register(indexingAddresses, additions) {
|
|
78
|
+
Object.assign(indexingAddresses, additions);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function rollbackInPlace(indexingAddresses, targetBlockNumber) {
|
|
82
|
+
Utils.Dict.forEachWithKey(indexingAddresses, (indexingContract, address) => {
|
|
83
|
+
if (indexingContract.registrationBlock > targetBlockNumber) {
|
|
84
|
+
return Utils.Dict.deleteInPlace(indexingAddresses, address);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export {
|
|
90
|
+
deriveEffectiveStartBlock,
|
|
91
|
+
makeContractConfigs,
|
|
92
|
+
makeIndexingAddress,
|
|
93
|
+
make,
|
|
94
|
+
get,
|
|
95
|
+
size,
|
|
96
|
+
getContractAddresses,
|
|
97
|
+
rawForFilter,
|
|
98
|
+
register,
|
|
99
|
+
rollbackInPlace,
|
|
100
|
+
}
|
|
101
|
+
/* Utils Not a pure module */
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
type indexingAddress = Internal.indexingContract
|
|
2
|
+
|
|
3
|
+
type contractConfig = {startBlock: option<int>}
|
|
4
|
+
|
|
5
|
+
type t
|
|
6
|
+
|
|
7
|
+
let deriveEffectiveStartBlock: (~registrationBlock: int, ~contractStartBlock: option<int>) => int
|
|
8
|
+
|
|
9
|
+
let makeContractConfigs: (
|
|
10
|
+
~onEventRegistrations: array<Internal.onEventRegistration>,
|
|
11
|
+
) => dict<contractConfig>
|
|
12
|
+
|
|
13
|
+
let makeIndexingAddress: (
|
|
14
|
+
~contract: Internal.indexingAddress,
|
|
15
|
+
~contractConfigs: dict<contractConfig>,
|
|
16
|
+
) => indexingAddress
|
|
17
|
+
|
|
18
|
+
let make: (~contractConfigs: dict<contractConfig>, ~addresses: array<Internal.indexingAddress>) => t
|
|
19
|
+
|
|
20
|
+
let get: (t, string) => option<indexingAddress>
|
|
21
|
+
|
|
22
|
+
let size: t => int
|
|
23
|
+
|
|
24
|
+
let getContractAddresses: (t, ~contractName: string) => array<Address.t>
|
|
25
|
+
|
|
26
|
+
// Underlying dict for the precompiled `clientAddressFilter` only, which does raw
|
|
27
|
+
// `indexingAddresses[srcAddress]` access in generated JS. Don't use elsewhere —
|
|
28
|
+
// prefer the domain accessors so the opaque type stays enforced.
|
|
29
|
+
let rawForFilter: t => dict<indexingAddress>
|
|
30
|
+
|
|
31
|
+
let register: (t, dict<indexingAddress>) => unit
|
|
32
|
+
|
|
33
|
+
// Deletes addresses registered after `targetBlockNumber` from the index in place.
|
|
34
|
+
let rollbackInPlace: (t, ~targetBlockNumber: int) => unit
|