envio 3.5.0-alpha.1 → 3.5.0-alpha.3
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/index.d.ts +10 -6
- package/package.json +6 -6
- package/src/BatchProcessing.res +27 -0
- package/src/BatchProcessing.res.mjs +12 -0
- package/src/ChainFetching.res +5 -5
- package/src/ChainFetching.res.mjs +3 -4
- package/src/ChainState.res +48 -25
- package/src/ChainState.res.mjs +23 -29
- package/src/ChainState.resi +2 -6
- package/src/Change.res +3 -3
- package/src/Config.res +2 -6
- package/src/Config.res.mjs +2 -12
- package/src/Core.res +3 -0
- package/src/CrossChainState.res +33 -10
- package/src/CrossChainState.res.mjs +21 -6
- package/src/CrossChainState.resi +3 -0
- package/src/EntityId.res +15 -0
- package/src/EntityId.res.mjs +9 -0
- package/src/EventConfigBuilder.res +1 -58
- package/src/EventConfigBuilder.res.mjs +1 -33
- package/src/FetchState.res +510 -460
- package/src/FetchState.res.mjs +413 -428
- package/src/FinalizeBackfill.res +34 -0
- package/src/FinalizeBackfill.res.mjs +26 -0
- package/src/HandlerRegister.res +45 -0
- package/src/HandlerRegister.res.mjs +43 -0
- package/src/InMemoryStore.res +11 -4
- package/src/InMemoryTable.res +26 -24
- package/src/InMemoryTable.res.mjs +19 -18
- package/src/IndexerState.res +71 -2
- package/src/IndexerState.res.mjs +67 -3
- package/src/IndexerState.resi +5 -0
- package/src/Internal.res +17 -8
- package/src/LoadLayer.res +9 -1
- package/src/LoadLayer.res.mjs +1 -0
- package/src/LogSelection.res +2 -1
- package/src/Metrics.res +37 -6
- package/src/Metrics.res.mjs +5 -1
- package/src/Persistence.res +12 -1
- package/src/PgStorage.res +411 -57
- package/src/PgStorage.res.mjs +262 -41
- package/src/SimulateItems.res +2 -2
- package/src/TestIndexer.res +9 -5
- package/src/TestIndexer.res.mjs +5 -2
- package/src/UserContext.res +3 -3
- package/src/Writing.res +12 -2
- package/src/Writing.res.mjs +13 -2
- package/src/bindings/ClickHouse.res +5 -3
- package/src/bindings/ClickHouse.res.mjs +2 -5
- package/src/bindings/Vitest.res +22 -1
- package/src/bindings/Vitest.res.mjs +15 -0
- package/src/db/EntityFilter.res +0 -4
- package/src/db/EntityFilter.res.mjs +1 -8
- package/src/db/EntityHistory.res +16 -7
- package/src/db/EntityHistory.res.mjs +7 -6
- package/src/db/IndexRegistry.res +219 -0
- package/src/db/IndexRegistry.res.mjs +195 -0
- package/src/db/InternalTable.res +7 -0
- package/src/db/InternalTable.res.mjs +7 -0
- package/src/db/Table.res +53 -22
- package/src/db/Table.res.mjs +56 -18
- package/src/sources/AddressSet.res +48 -0
- package/src/sources/AddressSet.res.mjs +11 -0
- package/src/sources/AddressStore.res +152 -0
- package/src/sources/AddressStore.res.mjs +97 -0
- package/src/sources/EvmChain.res +3 -0
- package/src/sources/EvmChain.res.mjs +4 -2
- package/src/sources/EvmHyperSyncSource.res +6 -3
- package/src/sources/EvmHyperSyncSource.res.mjs +3 -3
- package/src/sources/EvmRpcClient.res +6 -3
- package/src/sources/EvmRpcClient.res.mjs +3 -3
- package/src/sources/FuelHyperSync.res +4 -3
- package/src/sources/FuelHyperSync.res.mjs +3 -3
- package/src/sources/FuelHyperSync.resi +2 -1
- package/src/sources/FuelHyperSyncClient.res +12 -6
- package/src/sources/FuelHyperSyncClient.res.mjs +2 -2
- package/src/sources/FuelHyperSyncSource.res +7 -4
- package/src/sources/FuelHyperSyncSource.res.mjs +3 -3
- package/src/sources/HyperSync.res +6 -4
- package/src/sources/HyperSync.res.mjs +2 -3
- package/src/sources/HyperSync.resi +1 -1
- package/src/sources/HyperSyncClient.res +18 -9
- package/src/sources/HyperSyncClient.res.mjs +4 -4
- package/src/sources/RpcSource.res +15 -10
- package/src/sources/RpcSource.res.mjs +3 -4
- package/src/sources/SimulateSource.res +26 -11
- package/src/sources/SimulateSource.res.mjs +13 -5
- package/src/sources/Source.res +4 -2
- package/src/sources/SourceManager.res +2 -3
- package/src/sources/SourceManager.res.mjs +2 -3
- package/src/sources/Svm.res +1 -2
- package/src/sources/Svm.res.mjs +1 -1
- package/src/sources/SvmHyperSyncClient.res +12 -3
- package/src/sources/SvmHyperSyncClient.res.mjs +2 -2
- package/src/sources/SvmHyperSyncSource.res +10 -5
- package/src/sources/SvmHyperSyncSource.res.mjs +5 -4
- package/src/IndexingAddresses.res +0 -151
- package/src/IndexingAddresses.res.mjs +0 -130
- package/src/IndexingAddresses.resi +0 -39
package/index.d.ts
CHANGED
|
@@ -585,14 +585,18 @@ export type SvmOnSlotContext<Config extends IndexerConfigTypes = GlobalConfig> =
|
|
|
585
585
|
BaseHandlerContext<Config, SvmChainIds<Config>>
|
|
586
586
|
>;
|
|
587
587
|
|
|
588
|
+
/** The entity's `id` type. `ID!`/`String!` ids are `string`; `Int!` is `number`
|
|
589
|
+
* and `BigInt!` is `bigint`, so id-keyed operations accept the real scalar. */
|
|
590
|
+
type EntityId<Entity> = Entity extends { readonly id: infer Id } ? Id : string;
|
|
591
|
+
|
|
588
592
|
/** Entity operations available in handler contexts. */
|
|
589
593
|
type EntityOperations<Entity> = {
|
|
590
|
-
readonly get: (id:
|
|
591
|
-
readonly getOrThrow: (id:
|
|
594
|
+
readonly get: (id: EntityId<Entity>) => Promise<Entity | undefined>;
|
|
595
|
+
readonly getOrThrow: (id: EntityId<Entity>, message?: string) => Promise<Entity>;
|
|
592
596
|
readonly getWhere: (filter: GetWhereFilter<Entity>) => Promise<Entity[]>;
|
|
593
597
|
readonly getOrCreate: (entity: Entity) => Promise<Entity>;
|
|
594
598
|
readonly set: (entity: Entity) => void;
|
|
595
|
-
readonly deleteUnsafe: (id:
|
|
599
|
+
readonly deleteUnsafe: (id: EntityId<Entity>) => void;
|
|
596
600
|
};
|
|
597
601
|
|
|
598
602
|
/** Contract registration handle. */
|
|
@@ -1510,7 +1514,7 @@ type EntityChangeValue<Entity> = {
|
|
|
1510
1514
|
/** Entities that were created or updated. */
|
|
1511
1515
|
readonly sets?: readonly Entity[];
|
|
1512
1516
|
/** IDs of entities that were deleted. */
|
|
1513
|
-
readonly deleted?: readonly
|
|
1517
|
+
readonly deleted?: readonly EntityId<Entity>[];
|
|
1514
1518
|
};
|
|
1515
1519
|
|
|
1516
1520
|
/** A dynamic contract address registration. */
|
|
@@ -1528,9 +1532,9 @@ type ConfigEntities<Config extends IndexerConfigTypes = GlobalConfig> =
|
|
|
1528
1532
|
/** Entity operations available on test indexer for direct entity manipulation. */
|
|
1529
1533
|
type TestIndexerEntityOperations<Entity> = {
|
|
1530
1534
|
/** Get an entity by ID. Returns undefined if not found. */
|
|
1531
|
-
readonly get: (id:
|
|
1535
|
+
readonly get: (id: EntityId<Entity>) => Promise<Entity | undefined>;
|
|
1532
1536
|
/** Get an entity by ID or throw if not found. */
|
|
1533
|
-
readonly getOrThrow: (id:
|
|
1537
|
+
readonly getOrThrow: (id: EntityId<Entity>, message?: string) => Promise<Entity>;
|
|
1534
1538
|
/** Get all entities. */
|
|
1535
1539
|
readonly getAll: () => Promise<Entity[]>;
|
|
1536
1540
|
/** Set (create or update) an entity. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "envio",
|
|
3
|
-
"version": "3.5.0-alpha.
|
|
3
|
+
"version": "3.5.0-alpha.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A latency and sync speed optimized, developer friendly blockchain data indexer.",
|
|
6
6
|
"bin": "./bin.mjs",
|
|
@@ -69,10 +69,10 @@
|
|
|
69
69
|
"tsx": "4.21.0"
|
|
70
70
|
},
|
|
71
71
|
"optionalDependencies": {
|
|
72
|
-
"envio-linux-x64": "3.5.0-alpha.
|
|
73
|
-
"envio-linux-x64-musl": "3.5.0-alpha.
|
|
74
|
-
"envio-linux-arm64": "3.5.0-alpha.
|
|
75
|
-
"envio-darwin-x64": "3.5.0-alpha.
|
|
76
|
-
"envio-darwin-arm64": "3.5.0-alpha.
|
|
72
|
+
"envio-linux-x64": "3.5.0-alpha.3",
|
|
73
|
+
"envio-linux-x64-musl": "3.5.0-alpha.3",
|
|
74
|
+
"envio-linux-arm64": "3.5.0-alpha.3",
|
|
75
|
+
"envio-darwin-x64": "3.5.0-alpha.3",
|
|
76
|
+
"envio-darwin-arm64": "3.5.0-alpha.3"
|
|
77
77
|
}
|
|
78
78
|
}
|
package/src/BatchProcessing.res
CHANGED
|
@@ -45,6 +45,19 @@ let rec startProcessing = async (state: IndexerState.t, ~scheduleFetch, ~schedul
|
|
|
45
45
|
// Hand off now that no batch is in flight.
|
|
46
46
|
if state->IndexerState.isResolvingReorg {
|
|
47
47
|
scheduleRollback()
|
|
48
|
+
} else if (
|
|
49
|
+
!(state->IndexerState.isStopped) &&
|
|
50
|
+
// Only a genuine fetch stall when some chain still has blocks to bring in.
|
|
51
|
+
// If every chain has buffered up to its known head, the loop is idling at
|
|
52
|
+
// the tip waiting for new blocks, not bottlenecked on fetch.
|
|
53
|
+
!(
|
|
54
|
+
state
|
|
55
|
+
->IndexerState.chainStates
|
|
56
|
+
->Dict.valuesToArray
|
|
57
|
+
->Array.every(ChainState.isFetchingAtHead)
|
|
58
|
+
)
|
|
59
|
+
) {
|
|
60
|
+
state->IndexerState.markProcessingStalledOnFetch
|
|
48
61
|
}
|
|
49
62
|
}
|
|
50
63
|
}
|
|
@@ -91,6 +104,13 @@ and processNextBatch = async (state: IndexerState.t, ~scheduleFetch): unit => {
|
|
|
91
104
|
// When resuming from persisted state, all events may already be processed.
|
|
92
105
|
if EventProcessing.allChainsEventsProcessedToEndblock(state->IndexerState.chainStates) {
|
|
93
106
|
Logging.info("All chains are caught up to end blocks.")
|
|
107
|
+
// A run that has nothing left to process still owes the schema its
|
|
108
|
+
// deferred indexes — otherwise a resume of a backfill that died right
|
|
109
|
+
// before finalizing would report ready without them.
|
|
110
|
+
state->IndexerState.markCaughtUp
|
|
111
|
+
if state->IndexerState.isFinalizingIndexes {
|
|
112
|
+
await FinalizeBackfill.run(state)
|
|
113
|
+
}
|
|
94
114
|
if !(state->IndexerState.keepProcessAlive) {
|
|
95
115
|
await ExitOnCaughtUp.run(state)
|
|
96
116
|
}
|
|
@@ -143,6 +163,13 @@ and processNextBatch = async (state: IndexerState.t, ~scheduleFetch): unit => {
|
|
|
143
163
|
state->IndexerState.clearRollback
|
|
144
164
|
state->IndexerState.applyBatchProgress(~batch)
|
|
145
165
|
|
|
166
|
+
// Backfilling → FinalizingIndexes → Ready. Awaiting here holds the
|
|
167
|
+
// processing loop for the whole finalize, which is what pauses
|
|
168
|
+
// processing while the indexes are built.
|
|
169
|
+
if state->IndexerState.isFinalizingIndexes {
|
|
170
|
+
await FinalizeBackfill.run(state)
|
|
171
|
+
}
|
|
172
|
+
|
|
146
173
|
if !isRealtimeBeforeUpdate && state->IndexerState.isRealtime {
|
|
147
174
|
// Catching up just flipped the chain to realtime, which changes the
|
|
148
175
|
// active source for waitForNewBlock (eg sync -> live). The waiter that
|
|
@@ -9,6 +9,7 @@ import * as ErrorHandling from "./ErrorHandling.res.mjs";
|
|
|
9
9
|
import * as InMemoryStore from "./InMemoryStore.res.mjs";
|
|
10
10
|
import * as ExitOnCaughtUp from "./ExitOnCaughtUp.res.mjs";
|
|
11
11
|
import * as EventProcessing from "./EventProcessing.res.mjs";
|
|
12
|
+
import * as FinalizeBackfill from "./FinalizeBackfill.res.mjs";
|
|
12
13
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
13
14
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
14
15
|
import * as SimulateDeadInputTracker from "./SimulateDeadInputTracker.res.mjs";
|
|
@@ -38,6 +39,10 @@ async function processNextBatch(state, scheduleFetch) {
|
|
|
38
39
|
}
|
|
39
40
|
if (EventProcessing.allChainsEventsProcessedToEndblock(IndexerState.chainStates(state))) {
|
|
40
41
|
Logging.info("All chains are caught up to end blocks.");
|
|
42
|
+
IndexerState.markCaughtUp(state);
|
|
43
|
+
if (IndexerState.isFinalizingIndexes(state)) {
|
|
44
|
+
await FinalizeBackfill.run(state);
|
|
45
|
+
}
|
|
41
46
|
if (!IndexerState.keepProcessAlive(state)) {
|
|
42
47
|
return await ExitOnCaughtUp.run(state);
|
|
43
48
|
} else {
|
|
@@ -64,6 +69,9 @@ async function processNextBatch(state, scheduleFetch) {
|
|
|
64
69
|
}
|
|
65
70
|
IndexerState.clearRollback(state);
|
|
66
71
|
IndexerState.applyBatchProgress(state, batch);
|
|
72
|
+
if (IndexerState.isFinalizingIndexes(state)) {
|
|
73
|
+
await FinalizeBackfill.run(state);
|
|
74
|
+
}
|
|
67
75
|
if (!isRealtimeBeforeUpdate && IndexerState.isRealtime(state)) {
|
|
68
76
|
IndexerState.invalidateInflight(state);
|
|
69
77
|
scheduleFetch();
|
|
@@ -108,6 +116,10 @@ async function startProcessing(state, scheduleFetch, scheduleRollback) {
|
|
|
108
116
|
IndexerState.endProcessing(state);
|
|
109
117
|
if (IndexerState.isResolvingReorg(state)) {
|
|
110
118
|
return scheduleRollback();
|
|
119
|
+
} else if (!IndexerState.isStopped(state) && !Object.values(IndexerState.chainStates(state)).every(ChainState.isFetchingAtHead)) {
|
|
120
|
+
return IndexerState.markProcessingStalledOnFetch(state);
|
|
121
|
+
} else {
|
|
122
|
+
return;
|
|
111
123
|
}
|
|
112
124
|
}
|
|
113
125
|
|
package/src/ChainFetching.res
CHANGED
|
@@ -209,11 +209,11 @@ let rec onQueryResponse = async (
|
|
|
209
209
|
// kick (eg from the processing loop quiescing) collapses into this one.
|
|
210
210
|
scheduleRollback()
|
|
211
211
|
| None =>
|
|
212
|
-
//
|
|
213
|
-
//
|
|
214
|
-
// registered after the log's block)
|
|
215
|
-
//
|
|
216
|
-
let newItems =
|
|
212
|
+
// Over-fetched events (a merged partition returning an address before its
|
|
213
|
+
// effectiveStartBlock, or a wildcard param referencing an address
|
|
214
|
+
// registered after the log's block) are already dropped by the source's
|
|
215
|
+
// native address gate, so everything here is indexable.
|
|
216
|
+
let newItems = parsedQueueItems
|
|
217
217
|
let itemsWithContractRegister = []
|
|
218
218
|
for idx in 0 to newItems->Array.length - 1 {
|
|
219
219
|
let item = newItems->Array.getUnsafe(idx)
|
|
@@ -145,17 +145,16 @@ async function onQueryResponse(state, param, stateId, scheduleFetch, schedulePro
|
|
|
145
145
|
IndexerState.beginReorg(state, chain, rollbackWithReorgDetectedBlockNumber);
|
|
146
146
|
return scheduleRollback();
|
|
147
147
|
}
|
|
148
|
-
let newItems = ChainState.filterByClientAddress(chainState, parsedQueueItems);
|
|
149
148
|
let itemsWithContractRegister = [];
|
|
150
|
-
for (let idx = 0, idx_finish =
|
|
151
|
-
let item =
|
|
149
|
+
for (let idx = 0, idx_finish = parsedQueueItems.length; idx < idx_finish; ++idx) {
|
|
150
|
+
let item = parsedQueueItems[idx];
|
|
152
151
|
if (item.onEventRegistration.contractRegister !== undefined) {
|
|
153
152
|
itemsWithContractRegister.push(item);
|
|
154
153
|
}
|
|
155
154
|
}
|
|
156
155
|
let proceed = newItemsWithDcs => {
|
|
157
156
|
if (!IndexerState.isStale(state, stateId)) {
|
|
158
|
-
applyQueryResponse(state, chain,
|
|
157
|
+
applyQueryResponse(state, chain, parsedQueueItems, newItemsWithDcs, knownHeight, {
|
|
159
158
|
blockNumber: latestFetchedBlockNumber,
|
|
160
159
|
blockTimestamp: latestFetchedBlockTimestamp
|
|
161
160
|
}, query, transactionStore, blockStore);
|
package/src/ChainState.res
CHANGED
|
@@ -7,9 +7,10 @@ type t = {
|
|
|
7
7
|
// The registrations used to build this chain's sources and route native items.
|
|
8
8
|
onEventRegistrations: array<Internal.onEventRegistration>,
|
|
9
9
|
mutable fetchState: FetchState.t,
|
|
10
|
-
// The chain-wide address index. Not `mutable`:
|
|
11
|
-
//
|
|
12
|
-
|
|
10
|
+
// The chain-wide address index, kept in Rust. Not `mutable`: registration and
|
|
11
|
+
// rollback mutate it in place, so the handle is stable across fetchState
|
|
12
|
+
// versions — and it's the same handle this chain's source clients hold.
|
|
13
|
+
addressStore: AddressStore.t,
|
|
13
14
|
sourceManager: SourceManager.t,
|
|
14
15
|
chainConfig: Config.chain,
|
|
15
16
|
mutable isProgressAtHead: bool,
|
|
@@ -83,7 +84,7 @@ let make = (
|
|
|
83
84
|
~chainConfig: Config.chain,
|
|
84
85
|
~fetchState: FetchState.t,
|
|
85
86
|
~onEventRegistrations=[],
|
|
86
|
-
~
|
|
87
|
+
~addressStore: AddressStore.t,
|
|
87
88
|
~sourceManager: SourceManager.t,
|
|
88
89
|
~reorgDetection: ReorgDetection.t,
|
|
89
90
|
~committedProgressBlockNumber: int,
|
|
@@ -102,7 +103,7 @@ let make = (
|
|
|
102
103
|
logger,
|
|
103
104
|
onEventRegistrations,
|
|
104
105
|
fetchState,
|
|
105
|
-
|
|
106
|
+
addressStore,
|
|
106
107
|
sourceManager,
|
|
107
108
|
chainConfig,
|
|
108
109
|
isProgressAtHead,
|
|
@@ -146,6 +147,7 @@ let makeInternal = (
|
|
|
146
147
|
~reorgCheckpoints: array<Internal.reorgCheckpoint>,
|
|
147
148
|
~maxReorgDepth,
|
|
148
149
|
~knownHeight=0,
|
|
150
|
+
~isResumed=false,
|
|
149
151
|
~reducedPollingInterval=?,
|
|
150
152
|
): t => {
|
|
151
153
|
// Handler binding + `where`-derived fetch state, and onBlock registrations,
|
|
@@ -166,12 +168,18 @@ let makeInternal = (
|
|
|
166
168
|
}
|
|
167
169
|
})
|
|
168
170
|
|
|
169
|
-
let
|
|
170
|
-
|
|
171
|
+
let lowercaseAddresses = config.lowercaseAddresses
|
|
172
|
+
// Created before the fetch state and the sources: `make` registers this
|
|
173
|
+
// chain's addresses into it, and every source client holds the same handle.
|
|
174
|
+
let addressStore = AddressStore.make(
|
|
175
|
+
~ecosystem=config.ecosystem.name,
|
|
176
|
+
~shouldChecksum=!lowercaseAddresses,
|
|
177
|
+
~contracts=AddressStore.contractsOf(~onEventRegistrations),
|
|
178
|
+
)
|
|
171
179
|
|
|
172
180
|
let fetchState = FetchState.make(
|
|
173
181
|
~maxAddrInPartition=config.maxAddrInPartition,
|
|
174
|
-
~
|
|
182
|
+
~addressStore,
|
|
175
183
|
~addresses=indexingAddresses,
|
|
176
184
|
~progressBlockNumber,
|
|
177
185
|
~startBlock,
|
|
@@ -187,12 +195,16 @@ let makeInternal = (
|
|
|
187
195
|
),
|
|
188
196
|
~onBlockRegistrations,
|
|
189
197
|
~firstEventBlock,
|
|
190
|
-
//
|
|
191
|
-
//
|
|
198
|
+
// Fuel and SVM route through the address store like EVM does, so the
|
|
199
|
+
// client-side path works for them — but their address counts are nowhere
|
|
200
|
+
// near the threshold, so switching would only trade a server-side filter
|
|
201
|
+
// that costs nothing today for an over-fetch. Keep them server-side until a
|
|
202
|
+
// chain actually needs it.
|
|
192
203
|
~clientFilterAddressThreshold=switch config.ecosystem.name {
|
|
193
204
|
| Evm => Some(config.clientFilterAddressThreshold)
|
|
194
205
|
| Fuel | Svm => None
|
|
195
206
|
},
|
|
207
|
+
~isResumed,
|
|
196
208
|
)
|
|
197
209
|
|
|
198
210
|
let chainReorgCheckpoints = reorgCheckpoints->Array.filterMap(reorgCheckpoint => {
|
|
@@ -205,7 +217,6 @@ let makeInternal = (
|
|
|
205
217
|
|
|
206
218
|
// Create sources lazily here - this is where API token validation happens
|
|
207
219
|
let chain = ChainMap.Chain.makeUnsafe(~chainId=chainConfig.id)
|
|
208
|
-
let lowercaseAddresses = config.lowercaseAddresses
|
|
209
220
|
let sources = switch chainConfig.sourceConfig {
|
|
210
221
|
| Config.EvmSourceConfig({hypersync, rpcs}) =>
|
|
211
222
|
let evmRpcs: array<EvmChain.rpc> = rpcs->Array.map((rpc): EvmChain.rpc => {
|
|
@@ -228,6 +239,7 @@ let makeInternal = (
|
|
|
228
239
|
~hyperSync=hypersync,
|
|
229
240
|
~rpcs=evmRpcs,
|
|
230
241
|
~lowercaseAddresses,
|
|
242
|
+
~addressStore,
|
|
231
243
|
)
|
|
232
244
|
| Config.FuelSourceConfig({hypersync}) => [
|
|
233
245
|
FuelHyperSyncSource.make({
|
|
@@ -235,6 +247,7 @@ let makeInternal = (
|
|
|
235
247
|
endpointUrl: hypersync,
|
|
236
248
|
apiToken: Env.envioApiToken,
|
|
237
249
|
onEventRegistrations,
|
|
250
|
+
addressStore,
|
|
238
251
|
}),
|
|
239
252
|
]
|
|
240
253
|
| Config.SvmSourceConfig({hypersync, rpc}) =>
|
|
@@ -255,6 +268,7 @@ let makeInternal = (
|
|
|
255
268
|
apiToken,
|
|
256
269
|
onEventRegistrations,
|
|
257
270
|
clientTimeoutMillis: Env.hyperSyncClientTimeoutMillis,
|
|
271
|
+
addressStore,
|
|
258
272
|
}),
|
|
259
273
|
]
|
|
260
274
|
}
|
|
@@ -274,7 +288,7 @@ let makeInternal = (
|
|
|
274
288
|
~chainConfig,
|
|
275
289
|
~fetchState,
|
|
276
290
|
~onEventRegistrations,
|
|
277
|
-
~
|
|
291
|
+
~addressStore,
|
|
278
292
|
~sourceManager=SourceManager.make(~sources, ~isRealtime, ~reducedPollingInterval?),
|
|
279
293
|
~reorgDetection=ReorgDetection.make(
|
|
280
294
|
~chainReorgCheckpoints,
|
|
@@ -371,6 +385,7 @@ let makeFromDbState = (
|
|
|
371
385
|
~isInReorgThreshold,
|
|
372
386
|
~isRealtime,
|
|
373
387
|
~knownHeight=resumedChainState.sourceBlockNumber,
|
|
388
|
+
~isResumed=true,
|
|
374
389
|
~reducedPollingInterval?,
|
|
375
390
|
)
|
|
376
391
|
}
|
|
@@ -415,7 +430,7 @@ let setRollbackTargetBlock = (cs: t, ~blockNumber) => cs.rollbackTargetBlock = S
|
|
|
415
430
|
// rather than reaching into it.
|
|
416
431
|
let knownHeight = (cs: t) => cs.fetchState.knownHeight
|
|
417
432
|
let contractAddresses = (cs: t, ~contractName) =>
|
|
418
|
-
cs.
|
|
433
|
+
cs.addressStore->AddressStore.contractAddresses(contractName)
|
|
419
434
|
let bufferSize = (cs: t) => cs.fetchState->FetchState.bufferSize
|
|
420
435
|
let bufferReadyCount = (cs: t) => cs.fetchState->FetchState.bufferReadyCount
|
|
421
436
|
let getProgressPercentage = (cs: t) => cs.fetchState->FetchState.getProgressPercentage
|
|
@@ -706,6 +721,9 @@ let groupBatchItems = (items: array<Internal.item>, ~includeBlocks: bool): (
|
|
|
706
721
|
}
|
|
707
722
|
}
|
|
708
723
|
}
|
|
724
|
+
// onBlock items build their block from the handler's own block number, not
|
|
725
|
+
// from the stores — which is what lets the sources keep only the blocks and
|
|
726
|
+
// transactions an event item references.
|
|
709
727
|
| Internal.Block(_) => ()
|
|
710
728
|
}
|
|
711
729
|
)
|
|
@@ -802,15 +820,12 @@ let materializePageItems = async (
|
|
|
802
820
|
))
|
|
803
821
|
}
|
|
804
822
|
|
|
805
|
-
let filterByClientAddress = (cs: t, items: array<Internal.item>): array<Internal.item> =>
|
|
806
|
-
items->FetchState.filterByClientAddress(~indexingAddresses=cs.indexingAddresses)
|
|
807
|
-
|
|
808
823
|
let handleQueryResult = (
|
|
809
824
|
cs: t,
|
|
810
825
|
~query: FetchState.query,
|
|
811
826
|
~newItems,
|
|
812
827
|
~newItemsWithDcs,
|
|
813
|
-
~latestFetchedBlock,
|
|
828
|
+
~latestFetchedBlock: FetchState.blockNumberAndTimestamp,
|
|
814
829
|
~knownHeight,
|
|
815
830
|
~transactionStore as txPage: option<TransactionStore.t>,
|
|
816
831
|
~blockStore as blockPage: option<BlockStore.t>,
|
|
@@ -830,7 +845,12 @@ let handleQueryResult = (
|
|
|
830
845
|
| [] => cs.fetchState
|
|
831
846
|
| _ =>
|
|
832
847
|
cs.fetchState->FetchState.registerDynamicContracts(
|
|
833
|
-
~
|
|
848
|
+
~addressStore=cs.addressStore,
|
|
849
|
+
// This response is applied below, after the addresses land. It was routed
|
|
850
|
+
// before they existed, so whatever it claims has to be inside the
|
|
851
|
+
// catch-up range — and an unbounded query can reach past the height that
|
|
852
|
+
// was known when it went out.
|
|
853
|
+
~claimCeiling=Pervasives.max(knownHeight, latestFetchedBlock.blockNumber),
|
|
834
854
|
newItemsWithDcs,
|
|
835
855
|
)
|
|
836
856
|
}
|
|
@@ -906,7 +926,7 @@ let toMetrics = (cs: t): Metrics.chainMetrics => {
|
|
|
906
926
|
numBatchesFetched: 0,
|
|
907
927
|
startBlock: cs.fetchState.startBlock,
|
|
908
928
|
endBlock: cs.fetchState.endBlock,
|
|
909
|
-
numAddresses: cs.
|
|
929
|
+
numAddresses: cs.addressStore->AddressStore.size,
|
|
910
930
|
isReady: cs->isReady,
|
|
911
931
|
sourceBlockNumber: cs.fetchState.knownHeight,
|
|
912
932
|
progressBlockNumber: cs.committedProgressBlockNumber,
|
|
@@ -1065,11 +1085,14 @@ let applyBatchProgress = (cs: t, ~batch: Batch.t, ~blockTimestampName: string) =
|
|
|
1065
1085
|
}
|
|
1066
1086
|
|
|
1067
1087
|
// Mark the chain caught up to head/endblock. Called by CrossChainState only once
|
|
1068
|
-
// every chain in the indexer is caught up
|
|
1069
|
-
//
|
|
1070
|
-
|
|
1088
|
+
// every chain in the indexer is caught up and the deferred schema indexes are
|
|
1089
|
+
// committed, so no chain flips to ready while another is still backfilling or
|
|
1090
|
+
// while an index the schema promises is still missing. `readyAt` is the
|
|
1091
|
+
// timestamp already committed to `envio_chains.ready_at` in that same
|
|
1092
|
+
// transaction. Sticky: a chain stays ready once set.
|
|
1093
|
+
let markReady = (cs: t, ~readyAt) =>
|
|
1071
1094
|
if !(cs->isReady) {
|
|
1072
|
-
cs.timestampCaughtUpToHeadOrEndblock =
|
|
1095
|
+
cs.timestampCaughtUpToHeadOrEndblock = Some(readyAt)
|
|
1073
1096
|
}
|
|
1074
1097
|
|
|
1075
1098
|
// Roll a chain back to a reorg target. With a progress diff, restore fetch/
|
|
@@ -1111,7 +1134,7 @@ let rollback = (
|
|
|
1111
1134
|
}
|
|
1112
1135
|
cs.fetchState =
|
|
1113
1136
|
cs.fetchState->FetchState.rollback(
|
|
1114
|
-
~
|
|
1137
|
+
~addressStore=cs.addressStore,
|
|
1115
1138
|
~targetBlockNumber=newProgressBlockNumber,
|
|
1116
1139
|
)
|
|
1117
1140
|
cs.transactionStore->TransactionStore.rollback(newProgressBlockNumber)
|
|
@@ -1127,7 +1150,7 @@ let rollback = (
|
|
|
1127
1150
|
)
|
|
1128
1151
|
cs.fetchState =
|
|
1129
1152
|
cs.fetchState->FetchState.rollback(
|
|
1130
|
-
~
|
|
1153
|
+
~addressStore=cs.addressStore,
|
|
1131
1154
|
~targetBlockNumber=rollbackTargetBlockNumber,
|
|
1132
1155
|
)
|
|
1133
1156
|
cs.transactionStore->TransactionStore.rollback(rollbackTargetBlockNumber)
|
package/src/ChainState.res.mjs
CHANGED
|
@@ -11,6 +11,7 @@ import * as FieldMask from "./sources/FieldMask.res.mjs";
|
|
|
11
11
|
import * as BlockStore from "./sources/BlockStore.res.mjs";
|
|
12
12
|
import * as FetchState from "./FetchState.res.mjs";
|
|
13
13
|
import * as Stdlib_Null from "@rescript/runtime/lib/es6/Stdlib_Null.js";
|
|
14
|
+
import * as AddressStore from "./sources/AddressStore.res.mjs";
|
|
14
15
|
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
15
16
|
import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
|
|
16
17
|
import * as SourceManager from "./sources/SourceManager.res.mjs";
|
|
@@ -20,7 +21,6 @@ import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
|
20
21
|
import * as Primitive_float from "@rescript/runtime/lib/es6/Primitive_float.js";
|
|
21
22
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
22
23
|
import * as TransactionStore from "./sources/TransactionStore.res.mjs";
|
|
23
|
-
import * as IndexingAddresses from "./IndexingAddresses.res.mjs";
|
|
24
24
|
import * as SvmHyperSyncSource from "./sources/SvmHyperSyncSource.res.mjs";
|
|
25
25
|
import * as FuelHyperSyncSource from "./sources/FuelHyperSyncSource.res.mjs";
|
|
26
26
|
import * as SafeCheckpointTracking from "./SafeCheckpointTracking.res.mjs";
|
|
@@ -47,7 +47,7 @@ function validateOnEventRegistrations(chainId, registrations) {
|
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
function make(chainConfig, fetchState, onEventRegistrationsOpt,
|
|
50
|
+
function make(chainConfig, fetchState, onEventRegistrationsOpt, addressStore, sourceManager, reorgDetection, committedProgressBlockNumber, safeCheckpointTrackingOpt, numEventsProcessedOpt, timestampCaughtUpToHeadOrEndblockOpt, isProgressAtHeadOpt, transactionStoreOpt, chainDensityOpt, blockStoreOpt, reorgThresholdReadyToleranceOpt, logger) {
|
|
51
51
|
let onEventRegistrations = onEventRegistrationsOpt !== undefined ? onEventRegistrationsOpt : [];
|
|
52
52
|
let safeCheckpointTracking = safeCheckpointTrackingOpt !== undefined ? Primitive_option.valFromOption(safeCheckpointTrackingOpt) : undefined;
|
|
53
53
|
let numEventsProcessed = numEventsProcessedOpt !== undefined ? numEventsProcessedOpt : 0;
|
|
@@ -62,7 +62,7 @@ function make(chainConfig, fetchState, onEventRegistrationsOpt, indexingAddresse
|
|
|
62
62
|
logger: logger,
|
|
63
63
|
onEventRegistrations: onEventRegistrations,
|
|
64
64
|
fetchState: fetchState,
|
|
65
|
-
|
|
65
|
+
addressStore: addressStore,
|
|
66
66
|
sourceManager: sourceManager,
|
|
67
67
|
chainConfig: chainConfig,
|
|
68
68
|
isProgressAtHead: isProgressAtHead,
|
|
@@ -89,9 +89,10 @@ function make(chainConfig, fetchState, onEventRegistrationsOpt, indexingAddresse
|
|
|
89
89
|
};
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
function makeInternal(chainConfig, indexingAddresses, startBlock, endBlock, firstEventBlockOpt, progressBlockNumber, config, registrationsByChainId, logger, timestampCaughtUpToHeadOrEndblock, numEventsProcessed, isInReorgThreshold, isRealtime, reorgCheckpoints, maxReorgDepth, knownHeightOpt, reducedPollingInterval) {
|
|
92
|
+
function makeInternal(chainConfig, indexingAddresses, startBlock, endBlock, firstEventBlockOpt, progressBlockNumber, config, registrationsByChainId, logger, timestampCaughtUpToHeadOrEndblock, numEventsProcessed, isInReorgThreshold, isRealtime, reorgCheckpoints, maxReorgDepth, knownHeightOpt, isResumedOpt, reducedPollingInterval) {
|
|
93
93
|
let firstEventBlock = firstEventBlockOpt !== undefined ? Primitive_option.valFromOption(firstEventBlockOpt) : undefined;
|
|
94
94
|
let knownHeight = knownHeightOpt !== undefined ? knownHeightOpt : 0;
|
|
95
|
+
let isResumed = isResumedOpt !== undefined ? isResumedOpt : false;
|
|
95
96
|
let match = Stdlib_Option.getOr(registrationsByChainId[chainConfig.id.toString()], {
|
|
96
97
|
onEventRegistrations: [],
|
|
97
98
|
onBlockRegistrations: []
|
|
@@ -103,8 +104,8 @@ function makeInternal(chainConfig, indexingAddresses, startBlock, endBlock, firs
|
|
|
103
104
|
return Stdlib_JsError.throwWithMessage(`The start block for contract "` + contract.name + `" is less than the chain start block. This is not supported yet.`);
|
|
104
105
|
}
|
|
105
106
|
});
|
|
106
|
-
let
|
|
107
|
-
let
|
|
107
|
+
let lowercaseAddresses = config.lowercaseAddresses;
|
|
108
|
+
let addressStore = AddressStore.make(config.ecosystem.name, !lowercaseAddresses, AddressStore.contractsOf(onEventRegistrations));
|
|
108
109
|
let match$1 = config.ecosystem.name;
|
|
109
110
|
let tmp;
|
|
110
111
|
switch (match$1) {
|
|
@@ -116,14 +117,13 @@ function makeInternal(chainConfig, indexingAddresses, startBlock, endBlock, firs
|
|
|
116
117
|
tmp = undefined;
|
|
117
118
|
break;
|
|
118
119
|
}
|
|
119
|
-
let fetchState = FetchState.make(startBlock, endBlock, onEventRegistrations,
|
|
120
|
+
let fetchState = FetchState.make(startBlock, endBlock, onEventRegistrations, addressStore, indexingAddresses, config.maxAddrInPartition, chainConfig.id, (config.batchSize << 1), knownHeight, progressBlockNumber, match.onBlockRegistrations, Primitive_int.max(!config.shouldRollbackOnReorg || isInReorgThreshold ? 0 : chainConfig.maxReorgDepth, chainConfig.blockLag), Primitive_option.some(firstEventBlock), Primitive_option.some(tmp), isResumed);
|
|
120
121
|
let chainReorgCheckpoints = Stdlib_Array.filterMap(reorgCheckpoints, reorgCheckpoint => {
|
|
121
122
|
if (reorgCheckpoint.chain_id === chainConfig.id) {
|
|
122
123
|
return reorgCheckpoint;
|
|
123
124
|
}
|
|
124
125
|
});
|
|
125
126
|
let chain = ChainMap.Chain.makeUnsafe(chainConfig.id);
|
|
126
|
-
let lowercaseAddresses = config.lowercaseAddresses;
|
|
127
127
|
let sources = chainConfig.sourceConfig;
|
|
128
128
|
let sources$1;
|
|
129
129
|
switch (sources.TAG) {
|
|
@@ -140,14 +140,15 @@ function makeInternal(chainConfig, indexingAddresses, startBlock, endBlock, firs
|
|
|
140
140
|
headers: headers
|
|
141
141
|
};
|
|
142
142
|
});
|
|
143
|
-
sources$1 = EvmChain.makeSources(chain, onEventRegistrations, sources.hypersync, evmRpcs, lowercaseAddresses);
|
|
143
|
+
sources$1 = EvmChain.makeSources(chain, onEventRegistrations, sources.hypersync, evmRpcs, lowercaseAddresses, addressStore);
|
|
144
144
|
break;
|
|
145
145
|
case "FuelSourceConfig" :
|
|
146
146
|
sources$1 = [FuelHyperSyncSource.make({
|
|
147
147
|
chain: chain,
|
|
148
148
|
endpointUrl: sources.hypersync,
|
|
149
149
|
apiToken: Env.envioApiToken,
|
|
150
|
-
onEventRegistrations: onEventRegistrations
|
|
150
|
+
onEventRegistrations: onEventRegistrations,
|
|
151
|
+
addressStore: addressStore
|
|
151
152
|
})];
|
|
152
153
|
break;
|
|
153
154
|
case "SvmSourceConfig" :
|
|
@@ -158,7 +159,8 @@ function makeInternal(chainConfig, indexingAddresses, startBlock, endBlock, firs
|
|
|
158
159
|
endpointUrl: hypersync,
|
|
159
160
|
apiToken: Env.envioApiToken,
|
|
160
161
|
onEventRegistrations: onEventRegistrations,
|
|
161
|
-
clientTimeoutMillis: Env.hyperSyncClientTimeoutMillis
|
|
162
|
+
clientTimeoutMillis: Env.hyperSyncClientTimeoutMillis,
|
|
163
|
+
addressStore: addressStore
|
|
162
164
|
})] : (
|
|
163
165
|
rpc !== undefined ? [Svm.makeRPCSource(chain, rpc, undefined)] : Stdlib_JsError.throwWithMessage(`Chain ` + chain.toString() + ` has no SVM data source`)
|
|
164
166
|
);
|
|
@@ -169,14 +171,14 @@ function makeInternal(chainConfig, indexingAddresses, startBlock, endBlock, firs
|
|
|
169
171
|
}
|
|
170
172
|
let firstEventBlock$1 = fetchState.firstEventBlock;
|
|
171
173
|
let chainDensity = firstEventBlock$1 !== undefined && progressBlockNumber > firstEventBlock$1 && numEventsProcessed > 0 ? numEventsProcessed / (progressBlockNumber - firstEventBlock$1 | 0) : undefined;
|
|
172
|
-
return make(chainConfig, fetchState, onEventRegistrations,
|
|
174
|
+
return make(chainConfig, fetchState, onEventRegistrations, addressStore, SourceManager.make(sources$1, isRealtime, undefined, undefined, undefined, reducedPollingInterval, undefined, undefined), ReorgDetection.make(chainReorgCheckpoints, maxReorgDepth, config.shouldRollbackOnReorg), progressBlockNumber, Primitive_option.some(SafeCheckpointTracking.make(maxReorgDepth, config.shouldRollbackOnReorg, chainReorgCheckpoints)), numEventsProcessed, Primitive_option.some(timestampCaughtUpToHeadOrEndblock), undefined, Primitive_option.some(TransactionStore.make(config.ecosystem.name, !lowercaseAddresses)), Primitive_option.some(chainDensity), Primitive_option.some(BlockStore.make(config.ecosystem.name, !lowercaseAddresses)), config.reorgThresholdReadyTolerance, logger);
|
|
173
175
|
}
|
|
174
176
|
|
|
175
177
|
function makeFromConfig(chainConfig, config, registrationsByChainId, knownHeight) {
|
|
176
178
|
let logger = Logging.createChild({
|
|
177
179
|
chainId: chainConfig.id
|
|
178
180
|
});
|
|
179
|
-
return makeInternal(chainConfig, configAddresses(chainConfig), chainConfig.startBlock, chainConfig.endBlock, undefined, -1, config, registrationsByChainId, logger, undefined, 0, false, false, [], chainConfig.maxReorgDepth, knownHeight, undefined);
|
|
181
|
+
return makeInternal(chainConfig, configAddresses(chainConfig), chainConfig.startBlock, chainConfig.endBlock, undefined, -1, config, registrationsByChainId, logger, undefined, 0, false, false, [], chainConfig.maxReorgDepth, knownHeight, undefined, undefined);
|
|
180
182
|
}
|
|
181
183
|
|
|
182
184
|
function makeFromDbState(chainConfig, resumedChainState, reorgCheckpoints, isInReorgThreshold, isRealtime, config, registrationsByChainId, reducedPollingInterval) {
|
|
@@ -185,7 +187,7 @@ function makeFromDbState(chainConfig, resumedChainState, reorgCheckpoints, isInR
|
|
|
185
187
|
chainId: chainId
|
|
186
188
|
});
|
|
187
189
|
let progressBlockNumber = resumedChainState.progressBlockNumber >= 0 ? resumedChainState.progressBlockNumber : resumedChainState.startBlock - 1 | 0;
|
|
188
|
-
return makeInternal(chainConfig, resumedChainState.indexingAddresses, resumedChainState.startBlock, resumedChainState.endBlock, Primitive_option.some(resumedChainState.firstEventBlockNumber), progressBlockNumber, config, registrationsByChainId, logger, Env.updateSyncTimeOnRestart ? undefined : resumedChainState.timestampCaughtUpToHeadOrEndblock, resumedChainState.numEventsProcessed, isInReorgThreshold, isRealtime, reorgCheckpoints, resumedChainState.maxReorgDepth, resumedChainState.sourceBlockNumber, reducedPollingInterval);
|
|
190
|
+
return makeInternal(chainConfig, resumedChainState.indexingAddresses, resumedChainState.startBlock, resumedChainState.endBlock, Primitive_option.some(resumedChainState.firstEventBlockNumber), progressBlockNumber, config, registrationsByChainId, logger, Env.updateSyncTimeOnRestart ? undefined : resumedChainState.timestampCaughtUpToHeadOrEndblock, resumedChainState.numEventsProcessed, isInReorgThreshold, isRealtime, reorgCheckpoints, resumedChainState.maxReorgDepth, resumedChainState.sourceBlockNumber, true, reducedPollingInterval);
|
|
189
191
|
}
|
|
190
192
|
|
|
191
193
|
function logger(cs) {
|
|
@@ -250,7 +252,7 @@ function knownHeight(cs) {
|
|
|
250
252
|
}
|
|
251
253
|
|
|
252
254
|
function contractAddresses(cs, contractName) {
|
|
253
|
-
return
|
|
255
|
+
return cs.addressStore.contractAddresses(contractName);
|
|
254
256
|
}
|
|
255
257
|
|
|
256
258
|
function bufferSize(cs) {
|
|
@@ -541,10 +543,6 @@ async function materializePageItems(items, transactionStore, blockStore, ecosyst
|
|
|
541
543
|
]);
|
|
542
544
|
}
|
|
543
545
|
|
|
544
|
-
function filterByClientAddress(cs, items) {
|
|
545
|
-
return FetchState.filterByClientAddress(items, cs.indexingAddresses);
|
|
546
|
-
}
|
|
547
|
-
|
|
548
546
|
function handleQueryResult(cs, query, newItems, newItemsWithDcs, latestFetchedBlock, knownHeight, txPage, blockPage) {
|
|
549
547
|
if (txPage !== undefined) {
|
|
550
548
|
cs.transactionStore.merge(Primitive_option.valFromOption(txPage));
|
|
@@ -552,7 +550,7 @@ function handleQueryResult(cs, query, newItems, newItemsWithDcs, latestFetchedBl
|
|
|
552
550
|
if (blockPage !== undefined) {
|
|
553
551
|
cs.blockStore.merge(Primitive_option.valFromOption(blockPage));
|
|
554
552
|
}
|
|
555
|
-
let fs = newItemsWithDcs.length !== 0 ? FetchState.registerDynamicContracts(cs.fetchState, cs.
|
|
553
|
+
let fs = newItemsWithDcs.length !== 0 ? FetchState.registerDynamicContracts(cs.fetchState, cs.addressStore, Primitive_int.max(knownHeight, latestFetchedBlock.blockNumber), newItemsWithDcs) : cs.fetchState;
|
|
556
554
|
cs.fetchState = FetchState.updateKnownHeight(FetchState.handleQueryResult(fs, query, latestFetchedBlock, newItems), knownHeight);
|
|
557
555
|
cs.pendingBudget = Primitive_float.max(0, cs.pendingBudget - query.itemsEst);
|
|
558
556
|
}
|
|
@@ -587,7 +585,6 @@ function setEndBlockToFirstEvent(cs, blockNumber) {
|
|
|
587
585
|
startBlock: init.startBlock,
|
|
588
586
|
endBlock: blockNumber,
|
|
589
587
|
normalSelection: init.normalSelection,
|
|
590
|
-
contractConfigs: init.contractConfigs,
|
|
591
588
|
chainId: init.chainId,
|
|
592
589
|
latestOnBlockBlockNumber: init.latestOnBlockBlockNumber,
|
|
593
590
|
blockLag: init.blockLag,
|
|
@@ -606,7 +603,6 @@ function setEndBlockToFirstEvent(cs, blockNumber) {
|
|
|
606
603
|
startBlock: init$1.startBlock,
|
|
607
604
|
endBlock: blockNumber,
|
|
608
605
|
normalSelection: init$1.normalSelection,
|
|
609
|
-
contractConfigs: init$1.contractConfigs,
|
|
610
606
|
chainId: init$1.chainId,
|
|
611
607
|
latestOnBlockBlockNumber: init$1.latestOnBlockBlockNumber,
|
|
612
608
|
blockLag: init$1.blockLag,
|
|
@@ -645,7 +641,7 @@ function toMetrics(cs) {
|
|
|
645
641
|
numBatchesFetched: 0,
|
|
646
642
|
startBlock: cs.fetchState.startBlock,
|
|
647
643
|
endBlock: cs.fetchState.endBlock,
|
|
648
|
-
numAddresses:
|
|
644
|
+
numAddresses: cs.addressStore.size(),
|
|
649
645
|
isReady: cs.timestampCaughtUpToHeadOrEndblock !== undefined,
|
|
650
646
|
sourceBlockNumber: cs.fetchState.knownHeight,
|
|
651
647
|
progressBlockNumber: cs.committedProgressBlockNumber,
|
|
@@ -715,7 +711,6 @@ function applyBatchProgress(cs, batch, blockTimestampName) {
|
|
|
715
711
|
startBlock: init.startBlock,
|
|
716
712
|
endBlock: init.endBlock,
|
|
717
713
|
normalSelection: init.normalSelection,
|
|
718
|
-
contractConfigs: init.contractConfigs,
|
|
719
714
|
chainId: init.chainId,
|
|
720
715
|
latestOnBlockBlockNumber: init.latestOnBlockBlockNumber,
|
|
721
716
|
blockLag: init.blockLag,
|
|
@@ -763,9 +758,9 @@ function applyBatchProgress(cs, batch, blockTimestampName) {
|
|
|
763
758
|
}
|
|
764
759
|
}
|
|
765
760
|
|
|
766
|
-
function markReady(cs) {
|
|
761
|
+
function markReady(cs, readyAt) {
|
|
767
762
|
if (cs.timestampCaughtUpToHeadOrEndblock === undefined) {
|
|
768
|
-
cs.timestampCaughtUpToHeadOrEndblock =
|
|
763
|
+
cs.timestampCaughtUpToHeadOrEndblock = readyAt;
|
|
769
764
|
return;
|
|
770
765
|
}
|
|
771
766
|
}
|
|
@@ -774,7 +769,7 @@ function rollback(cs, newProgressBlockNumber, eventsProcessedDiff, rollbackTarge
|
|
|
774
769
|
if (newProgressBlockNumber === undefined) {
|
|
775
770
|
if (isReorgChain) {
|
|
776
771
|
cs.reorgDetection = ReorgDetection.rollbackToValidBlockNumber(cs.reorgDetection, rollbackTargetBlockNumber);
|
|
777
|
-
cs.fetchState = FetchState.rollback(cs.fetchState, cs.
|
|
772
|
+
cs.fetchState = FetchState.rollback(cs.fetchState, cs.addressStore, rollbackTargetBlockNumber);
|
|
778
773
|
cs.transactionStore.rollback(rollbackTargetBlockNumber);
|
|
779
774
|
cs.blockStore.rollback(rollbackTargetBlockNumber);
|
|
780
775
|
cs.committedProgressBlockNumber = Primitive_int.min(cs.committedProgressBlockNumber, rollbackTargetBlockNumber);
|
|
@@ -792,7 +787,7 @@ function rollback(cs, newProgressBlockNumber, eventsProcessedDiff, rollbackTarge
|
|
|
792
787
|
if (safeCheckpointTracking !== undefined) {
|
|
793
788
|
cs.safeCheckpointTracking = SafeCheckpointTracking.rollback(safeCheckpointTracking, newProgressBlockNumber);
|
|
794
789
|
}
|
|
795
|
-
cs.fetchState = FetchState.rollback(cs.fetchState, cs.
|
|
790
|
+
cs.fetchState = FetchState.rollback(cs.fetchState, cs.addressStore, newProgressBlockNumber);
|
|
796
791
|
cs.transactionStore.rollback(newProgressBlockNumber);
|
|
797
792
|
cs.blockStore.rollback(newProgressBlockNumber);
|
|
798
793
|
cs.committedProgressBlockNumber = newProgressBlockNumber;
|
|
@@ -842,7 +837,6 @@ export {
|
|
|
842
837
|
isReady,
|
|
843
838
|
isFetchingAtHead,
|
|
844
839
|
isAtHeadWithoutEndBlock,
|
|
845
|
-
filterByClientAddress,
|
|
846
840
|
handleQueryResult,
|
|
847
841
|
materializeBatchItems,
|
|
848
842
|
materializePageItems,
|