envio 3.8.0 → 3.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/index.d.ts +158 -104
- package/package.json +6 -6
- package/src/AddressRows.res +121 -0
- package/src/AddressRows.res.mjs +143 -0
- package/src/Batch.res +2 -0
- package/src/Batch.res.mjs +2 -1
- package/src/ChainState.res +76 -70
- package/src/ChainState.res.mjs +76 -65
- package/src/ChainState.resi +14 -9
- package/src/Config.res +23 -82
- package/src/Config.res.mjs +19 -63
- package/src/ContractMapping.res +66 -0
- package/src/ContractMapping.res.mjs +73 -0
- package/src/Core.res +20 -0
- package/src/Core.res.mjs +4 -0
- package/src/EventConfigBuilder.res +0 -2
- package/src/EventConfigBuilder.res.mjs +0 -2
- package/src/FetchState.res +59 -67
- package/src/FetchState.res.mjs +34 -44
- package/src/InMemoryStore.res +17 -30
- package/src/InMemoryStore.res.mjs +11 -23
- package/src/IndexerState.res +21 -1
- package/src/IndexerState.res.mjs +9 -3
- package/src/IndexerState.resi +1 -0
- package/src/Main.res +25 -15
- package/src/Main.res.mjs +19 -14
- package/src/MemoryStorage.res +39 -66
- package/src/MemoryStorage.res.mjs +28 -65
- package/src/Metrics.res +15 -1
- package/src/Metrics.res.mjs +5 -1
- package/src/Persistence.res +30 -16
- package/src/Persistence.res.mjs +8 -5
- package/src/PgStorage.res +183 -65
- package/src/PgStorage.res.mjs +92 -58
- package/src/Rollback.res +14 -10
- package/src/Rollback.res.mjs +4 -2
- package/src/SimulateItems.res +5 -12
- package/src/SimulateItems.res.mjs +6 -10
- package/src/TestIndexer.res +93 -111
- package/src/TestIndexer.res.mjs +61 -88
- package/src/Utils.res +7 -0
- package/src/Utils.res.mjs +9 -2
- package/src/Writing.res +2 -0
- package/src/Writing.res.mjs +2 -1
- package/src/bindings/ClickHouse.res +6 -0
- package/src/bindings/ClickHouse.res.mjs +4 -0
- package/src/bindings/NodeJs.res +9 -0
- package/src/bindings/NodeJs.res.mjs +8 -1
- package/src/bindings/Postgres.res +9 -0
- package/src/bindings/Postgres.res.mjs +3 -0
- package/src/db/EntityHistory.res +12 -18
- package/src/db/EntityHistory.res.mjs +3 -14
- package/src/db/InternalTable.res +171 -65
- package/src/db/InternalTable.res.mjs +176 -73
- package/src/db/Table.res +24 -0
- package/src/db/Table.res.mjs +20 -1
- package/src/sources/AddressSet.res +0 -22
- package/src/sources/AddressStore.res +48 -88
- package/src/sources/AddressStore.res.mjs +11 -22
- package/src/sources/SvmHyperSyncClient.res +17 -21
- package/src/sources/SvmHyperSyncSource.res +4 -9
- package/src/sources/SvmHyperSyncSource.res.mjs +5 -13
- package/svm.schema.json +10 -4
|
@@ -6,6 +6,8 @@ import * as Config from "./Config.res.mjs";
|
|
|
6
6
|
import * as ChainId from "./ChainId.res.mjs";
|
|
7
7
|
import * as EntityId from "./EntityId.res.mjs";
|
|
8
8
|
import * as Internal from "./Internal.res.mjs";
|
|
9
|
+
import * as ChainState from "./ChainState.res.mjs";
|
|
10
|
+
import * as AddressRows from "./AddressRows.res.mjs";
|
|
9
11
|
import * as Stdlib_Null from "@rescript/runtime/lib/es6/Stdlib_Null.js";
|
|
10
12
|
import * as EntityFilter from "./db/EntityFilter.res.mjs";
|
|
11
13
|
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
@@ -26,6 +28,7 @@ function make() {
|
|
|
26
28
|
cache: {},
|
|
27
29
|
effectCache: {},
|
|
28
30
|
envioInfo: undefined,
|
|
31
|
+
addresses: AddressRows.Table.make(),
|
|
29
32
|
isInitialized: false
|
|
30
33
|
};
|
|
31
34
|
}
|
|
@@ -76,58 +79,17 @@ function registerEntities(state, entities) {
|
|
|
76
79
|
});
|
|
77
80
|
}
|
|
78
81
|
|
|
79
|
-
function
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
chainConfig.contracts.forEach(contract => {
|
|
83
|
-
contract.addresses.forEach(address => {
|
|
84
|
-
let entity_id = Config.EnvioAddresses.makeId(chainConfig.id, address);
|
|
85
|
-
let entity_chain_id = chainConfig.id;
|
|
86
|
-
let entity_contract_name = contract.name;
|
|
87
|
-
let entity = {
|
|
88
|
-
id: entity_id,
|
|
89
|
-
chain_id: entity_chain_id,
|
|
90
|
-
registration_block: -1,
|
|
91
|
-
registration_log_index: -1,
|
|
92
|
-
contract_name: entity_contract_name
|
|
93
|
-
};
|
|
94
|
-
dict[entity_id] = entity;
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function toIndexingAddress(dc) {
|
|
101
|
-
return {
|
|
102
|
-
address: Config.EnvioAddresses.getAddress(dc),
|
|
103
|
-
contractName: dc.contract_name,
|
|
104
|
-
registrationBlock: dc.registration_block
|
|
105
|
-
};
|
|
82
|
+
function seedConfigAddresses(state, chainConfigs, contractMapping, ecosystem) {
|
|
83
|
+
AddressRows.Table.clear(state.addresses);
|
|
84
|
+
ChainState.seedConfigAddresses(state.addresses, chainConfigs, ecosystem, contractMapping);
|
|
106
85
|
}
|
|
107
86
|
|
|
108
|
-
function
|
|
109
|
-
|
|
110
|
-
let dcDict = state.entities[Config.EnvioAddresses.name];
|
|
111
|
-
if (dcDict !== undefined) {
|
|
112
|
-
Object.values(dcDict).forEach(entity => {
|
|
113
|
-
let chainIdStr = ChainId.toString(entity.chain_id);
|
|
114
|
-
let arr = byChain[chainIdStr];
|
|
115
|
-
let contracts;
|
|
116
|
-
if (arr !== undefined) {
|
|
117
|
-
contracts = arr;
|
|
118
|
-
} else {
|
|
119
|
-
let arr$1 = [];
|
|
120
|
-
byChain[chainIdStr] = arr$1;
|
|
121
|
-
contracts = arr$1;
|
|
122
|
-
}
|
|
123
|
-
contracts.push(toIndexingAddress(entity));
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
return byChain;
|
|
87
|
+
function addressRowsByChain(state) {
|
|
88
|
+
return AddressRows.Table.groupByChain(state.addresses);
|
|
127
89
|
}
|
|
128
90
|
|
|
129
91
|
function toInitialChainStates(state) {
|
|
130
|
-
let addressesByChain =
|
|
92
|
+
let addressesByChain = AddressRows.Table.groupByChain(state.addresses);
|
|
131
93
|
return Object.values(state.chains).map(chain => ({
|
|
132
94
|
id: chain.id,
|
|
133
95
|
startBlock: chain.startBlock,
|
|
@@ -137,7 +99,7 @@ function toInitialChainStates(state) {
|
|
|
137
99
|
numEventsProcessed: chain.numEventsProcessed,
|
|
138
100
|
firstEventBlockNumber: chain.firstEventBlockNumber,
|
|
139
101
|
timestampCaughtUpToHeadOrEndblock: chain.timestampCaughtUpToHeadOrEndblock,
|
|
140
|
-
|
|
102
|
+
addressRows: Stdlib_Option.getOr(addressesByChain[ChainId.toString(chain.id)], AddressRows.emptySeedRows()),
|
|
141
103
|
sourceBlockNumber: chain.sourceBlockNumber
|
|
142
104
|
}));
|
|
143
105
|
}
|
|
@@ -174,14 +136,15 @@ function reorgCheckpoints(state) {
|
|
|
174
136
|
});
|
|
175
137
|
}
|
|
176
138
|
|
|
177
|
-
function toInitialState(state, cleanRun) {
|
|
139
|
+
function toInitialState(state, cleanRun, contractMapping) {
|
|
178
140
|
return {
|
|
179
141
|
cleanRun: cleanRun,
|
|
142
|
+
contractMapping: contractMapping,
|
|
143
|
+
envioInfo: state.envioInfo,
|
|
180
144
|
cache: state.cache,
|
|
181
145
|
chains: toInitialChainStates(state),
|
|
182
146
|
checkpointId: committedCheckpointId(state),
|
|
183
|
-
reorgCheckpoints: reorgCheckpoints(state)
|
|
184
|
-
envioInfo: state.envioInfo
|
|
147
|
+
reorgCheckpoints: reorgCheckpoints(state)
|
|
185
148
|
};
|
|
186
149
|
}
|
|
187
150
|
|
|
@@ -227,18 +190,20 @@ function backfillHistory(state, entityConfig, scope, entityId, rows) {
|
|
|
227
190
|
}
|
|
228
191
|
}
|
|
229
192
|
|
|
230
|
-
function applyRollback(state, targetCheckpointId) {
|
|
193
|
+
function applyRollback(state, targetCheckpointId, rolledBackAddresses) {
|
|
231
194
|
state.checkpoints = state.checkpoints.filter(cp => cp.id <= targetCheckpointId);
|
|
195
|
+
rolledBackAddresses.forEach(key => AddressRows.Table.$$delete(state.addresses, key));
|
|
232
196
|
Object.entries(state.history).forEach(param => {
|
|
233
197
|
state.history[param[0]] = param[1].filter(row => row.checkpointId <= targetCheckpointId);
|
|
234
198
|
});
|
|
235
199
|
}
|
|
236
200
|
|
|
237
|
-
function writeBatch(state, batch, rollback, isInReorgThreshold, config, updatedEntities, updatedEffectsCache, chainMetaData) {
|
|
201
|
+
function writeBatch(state, batch, rollback, isInReorgThreshold, config, updatedEntities, registeredAddresses, updatedEffectsCache, chainMetaData) {
|
|
238
202
|
let shouldSaveHistory = Config.shouldSaveHistory(config, isInReorgThreshold);
|
|
239
203
|
if (rollback !== undefined) {
|
|
240
|
-
applyRollback(state, rollback.targetCheckpointId);
|
|
204
|
+
applyRollback(state, rollback.targetCheckpointId, rollback.rolledBackAddresses);
|
|
241
205
|
}
|
|
206
|
+
registeredAddresses.forEach(param => AddressRows.Table.insert(state.addresses, param.row));
|
|
242
207
|
let diffCheckpointId = Stdlib_Option.map(rollback, param => param.diffCheckpointId);
|
|
243
208
|
let isDiff = change => {
|
|
244
209
|
if (diffCheckpointId !== undefined) {
|
|
@@ -431,12 +396,12 @@ function toStorage(state, config) {
|
|
|
431
396
|
return {
|
|
432
397
|
name: "memory",
|
|
433
398
|
isInitialized: async () => state.isInitialized,
|
|
434
|
-
initialize: async (chainConfigsOpt, entitiesOpt, $staropt$star, envioInfo) => {
|
|
399
|
+
initialize: async (chainConfigsOpt, entitiesOpt, $staropt$star, contractMapping, envioInfo) => {
|
|
435
400
|
let chainConfigs = chainConfigsOpt !== undefined ? chainConfigsOpt : [];
|
|
436
401
|
let entities = entitiesOpt !== undefined ? entitiesOpt : [];
|
|
437
402
|
$staropt$star !== undefined;
|
|
438
403
|
registerEntities(state, entities);
|
|
439
|
-
|
|
404
|
+
seedConfigAddresses(state, chainConfigs, contractMapping, config.ecosystem.name);
|
|
440
405
|
chainConfigs.forEach(chainConfig => {
|
|
441
406
|
state.chains[ChainId.toString(chainConfig.id)] = {
|
|
442
407
|
id: chainConfig.id,
|
|
@@ -453,9 +418,9 @@ function toStorage(state, config) {
|
|
|
453
418
|
});
|
|
454
419
|
state.envioInfo = envioInfo;
|
|
455
420
|
state.isInitialized = true;
|
|
456
|
-
return toInitialState(state, true);
|
|
421
|
+
return toInitialState(state, true, contractMapping);
|
|
457
422
|
},
|
|
458
|
-
resumeInitialState: async () => toInitialState(state, false),
|
|
423
|
+
resumeInitialState: async () => toInitialState(state, false, config.contractMapping),
|
|
459
424
|
loadOrThrow: async (filter, table) => handleLoad(state, table.tableName, filter),
|
|
460
425
|
ensureQueryIndexes: async (param, param$1) => {},
|
|
461
426
|
ensureSchemaIndexes: async param => {},
|
|
@@ -470,15 +435,14 @@ function toStorage(state, config) {
|
|
|
470
435
|
},
|
|
471
436
|
dumpEffectCache: async () => {},
|
|
472
437
|
reset: async () => {
|
|
473
|
-
let clear =
|
|
474
|
-
Object.keys(dict).forEach(key => Utils.Dict.deleteInPlace(dict, key));
|
|
475
|
-
};
|
|
438
|
+
let clear = Utils.Dict.clearInPlace;
|
|
476
439
|
clear(state.entities);
|
|
477
440
|
clear(state.history);
|
|
478
441
|
clear(state.chains);
|
|
479
442
|
clear(state.effectCache);
|
|
480
443
|
clear(state.cache);
|
|
481
444
|
state.checkpoints = [];
|
|
445
|
+
AddressRows.Table.clear(state.addresses);
|
|
482
446
|
state.envioInfo = undefined;
|
|
483
447
|
state.isInitialized = false;
|
|
484
448
|
},
|
|
@@ -539,7 +503,7 @@ function toStorage(state, config) {
|
|
|
539
503
|
}),
|
|
540
504
|
getRollbackProgressDiff: async rollbackTargetCheckpointId => getRollbackProgressDiff(state, rollbackTargetCheckpointId),
|
|
541
505
|
getRollbackData: async (entityConfig, rollbackTargetCheckpointId) => getRollbackData(state, entityConfig, rollbackTargetCheckpointId),
|
|
542
|
-
writeBatch: async (batch, rollback, isInReorgThreshold, param, param$1, updatedEffectsCache, updatedEntities, chainMetaData, param$2) => writeBatch(state, batch, rollback, isInReorgThreshold, config, updatedEntities, updatedEffectsCache, chainMetaData),
|
|
506
|
+
writeBatch: async (batch, rollback, isInReorgThreshold, param, param$1, updatedEffectsCache, updatedEntities, registeredAddresses, chainMetaData, param$2) => writeBatch(state, batch, rollback, isInReorgThreshold, config, updatedEntities, registeredAddresses, updatedEffectsCache, chainMetaData),
|
|
543
507
|
close: async () => {}
|
|
544
508
|
};
|
|
545
509
|
}
|
|
@@ -601,9 +565,8 @@ export {
|
|
|
601
565
|
getEntityDict,
|
|
602
566
|
getHistory,
|
|
603
567
|
registerEntities,
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
getIndexingAddressesByChain,
|
|
568
|
+
seedConfigAddresses,
|
|
569
|
+
addressRowsByChain,
|
|
607
570
|
toInitialChainStates,
|
|
608
571
|
committedCheckpointId,
|
|
609
572
|
reorgCheckpoints,
|
package/src/Metrics.res
CHANGED
|
@@ -12,6 +12,8 @@ type chainMetrics = {
|
|
|
12
12
|
startBlock: int,
|
|
13
13
|
endBlock: option<int>,
|
|
14
14
|
numAddresses: int,
|
|
15
|
+
// Per-contract registration counts, in the chain's contract-id order.
|
|
16
|
+
addressesByContract: array<(string, int)>,
|
|
15
17
|
isReady: bool,
|
|
16
18
|
// Raw source height, unlike knownHeight which is clamped to endBlock.
|
|
17
19
|
sourceBlockNumber: int,
|
|
@@ -694,11 +696,23 @@ let renderMetrics = (b: builder, metrics: t) => {
|
|
|
694
696
|
)
|
|
695
697
|
b->series(
|
|
696
698
|
~name="envio_indexing_addresses",
|
|
697
|
-
~help="The number of
|
|
699
|
+
~help="The number of address registrations on chain, static and dynamic. An address shared by N contracts counts N times.",
|
|
698
700
|
~kind="gauge",
|
|
699
701
|
~entries=chains,
|
|
700
702
|
~value=m => m.numAddresses->Int.toFloat,
|
|
701
703
|
)
|
|
704
|
+
b->series(
|
|
705
|
+
~name="envio_indexing_contract_addresses",
|
|
706
|
+
~help="The number of address registrations per contract on chain, static and dynamic. An address shared by N contracts counts N times.",
|
|
707
|
+
~kind="gauge",
|
|
708
|
+
~entries=metrics.chains->Array.flatMap(m =>
|
|
709
|
+
m.addressesByContract->Array.map(((contract, count)) => (
|
|
710
|
+
`{chainId="${m.chainId->ChainId.toString}",contract="${contract->escapeLabelValue}"}`,
|
|
711
|
+
count,
|
|
712
|
+
))
|
|
713
|
+
),
|
|
714
|
+
~value=count => count->Int.toFloat,
|
|
715
|
+
)
|
|
702
716
|
}
|
|
703
717
|
|
|
704
718
|
let contentType = "text/plain; version=0.0.4; charset=utf-8"
|
package/src/Metrics.res.mjs
CHANGED
|
@@ -229,7 +229,11 @@ function renderMetrics(b, metrics) {
|
|
|
229
229
|
series(b, "envio_storage_load_size", "Cumulative number of records loaded from storage during the indexing process.", "counter", storageLoads, s => s.size);
|
|
230
230
|
series(b, "envio_storage_write_seconds", "Cumulative time spent writing batch data to storage.", "counter", storageWrites, s => s.seconds);
|
|
231
231
|
series(b, "envio_storage_write_total", "Cumulative number of successful storage write operations during the indexing process.", "counter", storageWrites, s => s.count);
|
|
232
|
-
series(b, "envio_indexing_addresses", "The number of
|
|
232
|
+
series(b, "envio_indexing_addresses", "The number of address registrations on chain, static and dynamic. An address shared by N contracts counts N times.", "gauge", chains, m => m.numAddresses);
|
|
233
|
+
series(b, "envio_indexing_contract_addresses", "The number of address registrations per contract on chain, static and dynamic. An address shared by N contracts counts N times.", "gauge", metrics.chains.flatMap(m => m.addressesByContract.map(param => [
|
|
234
|
+
`{chainId="` + ChainId.toString(m.chainId) + `",contract="` + escapeLabelValue(param[0]) + `"}`,
|
|
235
|
+
param[1]
|
|
236
|
+
])), count => count);
|
|
233
237
|
}
|
|
234
238
|
|
|
235
239
|
function collect(metrics) {
|
package/src/Persistence.res
CHANGED
|
@@ -27,22 +27,25 @@ type initialChainState = {
|
|
|
27
27
|
numEventsProcessed: float,
|
|
28
28
|
firstEventBlockNumber: option<int>,
|
|
29
29
|
timestampCaughtUpToHeadOrEndblock: option<Date.t>,
|
|
30
|
-
|
|
30
|
+
// Every address the chain indexes, columnar — config-declared and dynamically
|
|
31
|
+
// registered alike. The chain's address store seeds straight from it.
|
|
32
|
+
addressRows: AddressRows.seedRows,
|
|
31
33
|
sourceBlockNumber: int,
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
type initialState = {
|
|
35
37
|
cleanRun: bool,
|
|
38
|
+
// On a resume this is what the database holds, not what the config would
|
|
39
|
+
// derive — the ids must never reshuffle under stored rows.
|
|
40
|
+
contractMapping: ContractMapping.t,
|
|
41
|
+
// Public config snapshot, restored with the address rows. None when
|
|
42
|
+
// envio_info or envio_contracts is missing.
|
|
43
|
+
envioInfo: option<JSON.t>,
|
|
36
44
|
cache: dict<effectCacheRecord>,
|
|
37
45
|
chains: array<initialChainState>,
|
|
38
46
|
checkpointId: Internal.checkpointId,
|
|
39
47
|
// Needed to keep reorg detection logic between restarts
|
|
40
48
|
reorgCheckpoints: array<Internal.reorgCheckpoint>,
|
|
41
|
-
// Public config snapshot read from envio_info, used by `Persistence.init`
|
|
42
|
-
// to compat-check a resume against the running config. None when the
|
|
43
|
-
// schema pre-dates envio_info or the row is missing — `init` treats that
|
|
44
|
-
// as a version mismatch.
|
|
45
|
-
envioInfo: option<JSON.t>,
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
// Carries the already-resolved cache address (`table`) rather than an effect +
|
|
@@ -58,6 +61,9 @@ type updatedEffectCache = {
|
|
|
58
61
|
type rollback = {
|
|
59
62
|
targetCheckpointId: Internal.checkpointId,
|
|
60
63
|
diffCheckpointId: Internal.checkpointId,
|
|
64
|
+
// The address registrations the rollback dropped, as the chains' address
|
|
65
|
+
// stores resolved them. Deleted by primary key in the same transaction.
|
|
66
|
+
rolledBackAddresses: array<AddressRows.key>,
|
|
61
67
|
// Last valid block per chain affected by the rollback. Read by
|
|
62
68
|
// `RollbackCommit.fire` once the diff is durably written.
|
|
63
69
|
progressBlockNumberByChainId: dict<int>,
|
|
@@ -92,6 +98,7 @@ type storage = {
|
|
|
92
98
|
~chainConfigs: array<Config.chain>=?,
|
|
93
99
|
~entities: array<Internal.entityConfig>=?,
|
|
94
100
|
~enums: array<Table.enumConfig<Table.enum>>=?,
|
|
101
|
+
~contractMapping: ContractMapping.t,
|
|
95
102
|
~envioInfo: JSON.t,
|
|
96
103
|
) => promise<initialState>,
|
|
97
104
|
resumeInitialState: unit => promise<initialState>,
|
|
@@ -163,6 +170,8 @@ type storage = {
|
|
|
163
170
|
~allEntities: array<Internal.entityConfig>,
|
|
164
171
|
~updatedEffectsCache: array<updatedEffectCache>,
|
|
165
172
|
~updatedEntities: array<updatedEntity>,
|
|
173
|
+
// Addresses this batch registered, with the checkpoint that covers them.
|
|
174
|
+
~registeredAddresses: array<AddressRows.staged>,
|
|
166
175
|
// Chain metadata stale since the last write, persisted in the same
|
|
167
176
|
// transaction so it never races the batch write.
|
|
168
177
|
~chainMetaData: option<dict<InternalTable.Chains.metaFields>>,
|
|
@@ -196,7 +205,7 @@ let make = (
|
|
|
196
205
|
~allEnums,
|
|
197
206
|
~storage,
|
|
198
207
|
) => {
|
|
199
|
-
let allEntities = userEntities
|
|
208
|
+
let allEntities = userEntities
|
|
200
209
|
let allEnums =
|
|
201
210
|
allEnums->Array.concat([EntityHistory.RowAction.config->Table.fromGenericEnumConfig])
|
|
202
211
|
{
|
|
@@ -209,7 +218,15 @@ let make = (
|
|
|
209
218
|
}
|
|
210
219
|
|
|
211
220
|
let init = {
|
|
212
|
-
async (
|
|
221
|
+
async (
|
|
222
|
+
persistence,
|
|
223
|
+
~chainConfigs,
|
|
224
|
+
~contractMapping,
|
|
225
|
+
~envioInfo,
|
|
226
|
+
~resetCommand,
|
|
227
|
+
~runCommand,
|
|
228
|
+
~reset=false,
|
|
229
|
+
) => {
|
|
213
230
|
try {
|
|
214
231
|
let shouldRun = switch persistence.storageStatus {
|
|
215
232
|
| Unknown => true
|
|
@@ -231,6 +248,7 @@ let init = {
|
|
|
231
248
|
~entities=persistence.allEntities,
|
|
232
249
|
~enums=persistence.allEnums,
|
|
233
250
|
~chainConfigs,
|
|
251
|
+
~contractMapping,
|
|
234
252
|
~envioInfo,
|
|
235
253
|
)
|
|
236
254
|
Logging.info(`The indexer storage is ready. Starting indexing!`)
|
|
@@ -245,17 +263,10 @@ let init = {
|
|
|
245
263
|
) {
|
|
246
264
|
Logging.info(`Found existing indexer storage. Resuming indexing state...`)
|
|
247
265
|
let initialState = await persistence.storage.resumeInitialState()
|
|
248
|
-
// Compat-check the running config against what was stored on the
|
|
249
|
-
// last successful initialize. None means the schema pre-dates
|
|
250
|
-
// envio_info (or the row was wiped out-of-band) and we can't
|
|
251
|
-
// compare — treat it as a version mismatch.
|
|
252
266
|
let changedPaths = switch initialState.envioInfo {
|
|
253
|
-
| None => ["
|
|
267
|
+
| None => ["storage was initialized by an older envio version"]
|
|
254
268
|
| Some(stored) => Config.diffPaths(~stored, ~current=envioInfo)
|
|
255
269
|
}
|
|
256
|
-
// `storage.clickhouse` is serialized as a plain bool by the
|
|
257
|
-
// public config (see Rust `StorageConfig`), so probe for
|
|
258
|
-
// `Boolean(true)`, not an object.
|
|
259
270
|
let hasClickhouse = switch envioInfo {
|
|
260
271
|
| Object(d) =>
|
|
261
272
|
switch d->Dict.get("storage") {
|
|
@@ -269,6 +280,9 @@ let init = {
|
|
|
269
280
|
| _ => false
|
|
270
281
|
}
|
|
271
282
|
Config.throwIfIncompatible(changedPaths, ~resetCommand, ~runCommand, ~hasClickhouse)
|
|
283
|
+
if !(initialState.contractMapping->ContractMapping.isEqual(contractMapping)) {
|
|
284
|
+
Config.throwIfIncompatible(["contracts"], ~resetCommand, ~runCommand, ~hasClickhouse)
|
|
285
|
+
}
|
|
272
286
|
persistence.storageStatus = Ready(initialState)
|
|
273
287
|
let progress = Dict.make()
|
|
274
288
|
initialState.chains->Array.forEach(c => {
|
package/src/Persistence.res.mjs
CHANGED
|
@@ -5,23 +5,23 @@ import * as Logging from "./Logging.res.mjs";
|
|
|
5
5
|
import * as EntityHistory from "./db/EntityHistory.res.mjs";
|
|
6
6
|
import * as ErrorHandling from "./ErrorHandling.res.mjs";
|
|
7
7
|
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
8
|
+
import * as ContractMapping from "./ContractMapping.res.mjs";
|
|
8
9
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
9
10
|
|
|
10
11
|
let StorageError = /* @__PURE__ */Primitive_exceptions.create("Persistence.StorageError");
|
|
11
12
|
|
|
12
13
|
function make(userEntities, allEnums, storage) {
|
|
13
|
-
let allEntities = userEntities.concat([Config.EnvioAddresses.entityConfig]);
|
|
14
14
|
let allEnums$1 = allEnums.concat([EntityHistory.RowAction.config]);
|
|
15
15
|
return {
|
|
16
16
|
userEntities: userEntities,
|
|
17
|
-
allEntities:
|
|
17
|
+
allEntities: userEntities,
|
|
18
18
|
allEnums: allEnums$1,
|
|
19
19
|
storageStatus: "Unknown",
|
|
20
20
|
storage: storage
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
async function init(persistence, chainConfigs, envioInfo, resetCommand, runCommand, resetOpt) {
|
|
24
|
+
async function init(persistence, chainConfigs, contractMapping, envioInfo, resetCommand, runCommand, resetOpt) {
|
|
25
25
|
let reset = resetOpt !== undefined ? resetOpt : false;
|
|
26
26
|
try {
|
|
27
27
|
let promise = persistence.storageStatus;
|
|
@@ -49,7 +49,7 @@ async function init(persistence, chainConfigs, envioInfo, resetCommand, runComma
|
|
|
49
49
|
};
|
|
50
50
|
if (reset || !await persistence.storage.isInitialized()) {
|
|
51
51
|
Logging.info(`Initializing the indexer storage...`);
|
|
52
|
-
let initialState = await persistence.storage.initialize(chainConfigs, persistence.allEntities, persistence.allEnums, envioInfo);
|
|
52
|
+
let initialState = await persistence.storage.initialize(chainConfigs, persistence.allEntities, persistence.allEnums, contractMapping, envioInfo);
|
|
53
53
|
Logging.info(`The indexer storage is ready. Starting indexing!`);
|
|
54
54
|
persistence.storageStatus = {
|
|
55
55
|
TAG: "Ready",
|
|
@@ -63,7 +63,7 @@ async function init(persistence, chainConfigs, envioInfo, resetCommand, runComma
|
|
|
63
63
|
Logging.info(`Found existing indexer storage. Resuming indexing state...`);
|
|
64
64
|
let initialState$1 = await persistence.storage.resumeInitialState();
|
|
65
65
|
let stored = initialState$1.envioInfo;
|
|
66
|
-
let changedPaths = stored !== undefined ? Config.diffPaths(stored, envioInfo) : ["
|
|
66
|
+
let changedPaths = stored !== undefined ? Config.diffPaths(stored, envioInfo) : ["storage was initialized by an older envio version"];
|
|
67
67
|
let hasClickhouse;
|
|
68
68
|
if (typeof envioInfo === "object" && envioInfo !== null && !Array.isArray(envioInfo)) {
|
|
69
69
|
let match$1 = envioInfo["storage"];
|
|
@@ -77,6 +77,9 @@ async function init(persistence, chainConfigs, envioInfo, resetCommand, runComma
|
|
|
77
77
|
hasClickhouse = false;
|
|
78
78
|
}
|
|
79
79
|
Config.throwIfIncompatible(changedPaths, resetCommand, runCommand, hasClickhouse);
|
|
80
|
+
if (!ContractMapping.isEqual(initialState$1.contractMapping, contractMapping)) {
|
|
81
|
+
Config.throwIfIncompatible(["contracts"], resetCommand, runCommand, hasClickhouse);
|
|
82
|
+
}
|
|
80
83
|
persistence.storageStatus = {
|
|
81
84
|
TAG: "Ready",
|
|
82
85
|
_0: initialState$1
|