envio 3.9.0 → 3.10.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/evm.schema.json +26 -0
- package/fuel.schema.json +26 -0
- package/index.d.ts +41 -8
- package/package.json +6 -7
- package/src/Batch.res +9 -0
- package/src/ChainState.res +35 -39
- package/src/ChainState.res.mjs +14 -11
- package/src/ChainState.resi +15 -7
- package/src/Config.res +61 -44
- package/src/Config.res.mjs +56 -19
- package/src/Core.res +19 -0
- package/src/Core.res.mjs +11 -0
- package/src/CrossChainState.res +15 -23
- package/src/CrossChainState.res.mjs +10 -18
- package/src/CrossChainState.resi +4 -1
- package/src/Ecosystem.res +7 -2
- package/src/Envio.res +6 -4
- package/src/EventConfigBuilder.res +169 -26
- package/src/EventConfigBuilder.res.mjs +124 -15
- package/src/EventProcessing.res +6 -6
- package/src/EventProcessing.res.mjs +8 -6
- package/src/HandlerLoader.res +20 -8
- package/src/HandlerLoader.res.mjs +11 -2
- package/src/HandlerRegister.res +21 -4
- package/src/HandlerRegister.res.mjs +24 -5
- package/src/InMemoryStore.res +9 -7
- package/src/InMemoryStore.res.mjs +3 -3
- package/src/IndexerState.res +43 -6
- package/src/IndexerState.res.mjs +36 -7
- package/src/IndexerState.resi +4 -4
- package/src/Internal.res +16 -17
- package/src/Metrics.res +72 -6
- package/src/Metrics.res.mjs +30 -2
- package/src/Persistence.res +36 -30
- package/src/Persistence.res.mjs +1 -20
- package/src/PgStorage.res +104 -56
- package/src/PgStorage.res.mjs +57 -35
- package/src/PruneStaleHistory.res +85 -52
- package/src/PruneStaleHistory.res.mjs +63 -37
- package/src/Rollback.res +68 -45
- package/src/Rollback.res.mjs +38 -19
- package/src/RollbackCommit.res +7 -9
- package/src/RollbackCommit.res.mjs +5 -6
- package/src/SafeCheckpointTracking.res +11 -11
- package/src/SafeCheckpointTracking.res.mjs +7 -6
- package/src/SimulateItems.res +33 -18
- package/src/SimulateItems.res.mjs +26 -22
- package/src/Sink.res +38 -26
- package/src/Sink.res.mjs +21 -16
- package/src/TestIndexer.res +5 -5
- package/src/TestIndexer.res.mjs +1 -1
- package/src/UserContext.res +358 -51
- package/src/UserContext.res.mjs +271 -35
- package/src/Utils.res +170 -0
- package/src/Utils.res.mjs +153 -0
- package/src/Writing.res +2 -2
- package/src/Writing.res.mjs +1 -1
- package/src/bindings/ClickHouse.res +366 -698
- package/src/bindings/ClickHouse.res.mjs +371 -421
- package/src/bindings/ClickHouseSink.res +337 -0
- package/src/bindings/ClickHouseSink.res.mjs +246 -0
- package/src/bindings/EventSource.res +8 -2
- package/src/bindings/NodeJs.res +6 -0
- package/src/bindings/Vitest.res +23 -0
- package/src/bindings/Vitest.res.mjs +3 -0
- package/src/bindings/WebSocket.res +9 -10
- package/src/db/CheckpointBounds.res +53 -0
- package/src/db/CheckpointBounds.res.mjs +44 -0
- package/src/db/EntityFilter.res +36 -17
- package/src/db/EntityFilter.res.mjs +25 -14
- package/src/db/EntityHistory.res +47 -22
- package/src/db/EntityHistory.res.mjs +19 -12
- package/src/db/InternalTable.res +84 -35
- package/src/db/InternalTable.res.mjs +56 -23
- package/src/db/RollbackFloors.res +55 -0
- package/src/db/RollbackFloors.res.mjs +92 -0
- package/src/db/Table.res +22 -4
- package/src/db/Table.res.mjs +30 -9
- package/src/sources/Evm.res +2 -0
- package/src/sources/Evm.res.mjs +2 -0
- package/src/sources/EvmHyperSyncSource.res +3 -3
- package/src/sources/EvmHyperSyncSource.res.mjs +3 -3
- package/src/sources/EvmRpcWs.res +124 -0
- package/src/sources/EvmRpcWs.res.mjs +117 -0
- package/src/sources/Fuel.res +2 -0
- package/src/sources/Fuel.res.mjs +2 -0
- package/src/sources/FuelHyperSyncSource.res +1 -1
- package/src/sources/FuelHyperSyncSource.res.mjs +2 -1
- package/src/sources/HeightFeed.res +568 -0
- package/src/sources/HeightFeed.res.mjs +452 -0
- package/src/sources/HeightStream.res +257 -0
- package/src/sources/HeightStream.res.mjs +194 -0
- package/src/sources/HyperSync.res +5 -0
- package/src/sources/HyperSync.res.mjs +3 -0
- package/src/sources/HyperSync.resi +4 -0
- package/src/sources/HyperSyncSSE.res +49 -0
- package/src/sources/HyperSyncSSE.res.mjs +79 -0
- package/src/sources/RpcSource.res +1 -1
- package/src/sources/RpcSource.res.mjs +2 -2
- package/src/sources/Source.res +54 -1
- package/src/sources/Source.res.mjs +25 -0
- package/src/sources/SourceManager.res +220 -227
- package/src/sources/SourceManager.res.mjs +139 -164
- package/src/sources/SourceManager.resi +8 -0
- package/src/sources/Svm.res +2 -0
- package/src/sources/Svm.res.mjs +2 -0
- package/src/sources/SvmHyperSyncClient.res +70 -127
- package/src/sources/SvmHyperSyncClient.res.mjs +51 -25
- package/src/sources/SvmHyperSyncSource.res +18 -15
- package/src/sources/SvmHyperSyncSource.res.mjs +5 -4
- package/src/subgraph/blocks.ts +176 -0
- package/src/subgraph/calls.ts +217 -0
- package/src/subgraph/conformance.ts +102 -0
- package/src/subgraph/division.ts +133 -0
- package/src/subgraph/errors.ts +90 -0
- package/src/subgraph/graph-ts-types/VERSION +2 -0
- package/src/subgraph/graph-ts-types/chain/arweave.d.ts +70 -0
- package/src/subgraph/graph-ts-types/chain/cosmos.d.ts +327 -0
- package/src/subgraph/graph-ts-types/chain/ethereum.d.ts +233 -0
- package/src/subgraph/graph-ts-types/chain/near.d.ts +253 -0
- package/src/subgraph/graph-ts-types/chain/starknet.d.ts +32 -0
- package/src/subgraph/graph-ts-types/common/collections.d.ts +136 -0
- package/src/subgraph/graph-ts-types/common/conversion.d.ts +11 -0
- package/src/subgraph/graph-ts-types/common/datasource.d.ts +30 -0
- package/src/subgraph/graph-ts-types/common/eager-offset.d.ts +0 -0
- package/src/subgraph/graph-ts-types/common/json.d.ts +17 -0
- package/src/subgraph/graph-ts-types/common/numbers.d.ts +120 -0
- package/src/subgraph/graph-ts-types/common/value.d.ts +120 -0
- package/src/subgraph/graph-ts-types/common/yaml.d.ts +90 -0
- package/src/subgraph/graph-ts-types/global/global.d.ts +194 -0
- package/src/subgraph/graph-ts-types/helper-functions.d.ts +22 -0
- package/src/subgraph/graph-ts-types/index.d.ts +102 -0
- package/src/subgraph/graph-ts.ts +1948 -0
- package/src/subgraph/hosts.ts +148 -0
- package/src/subgraph/runtime.ts +863 -0
- package/src/subgraph/scope.ts +66 -0
- package/svm.schema.json +6 -81
- package/src/MemoryStorage.res +0 -729
- package/src/MemoryStorage.res.mjs +0 -586
- package/src/sources/HyperSyncHeightStream.res +0 -129
- package/src/sources/HyperSyncHeightStream.res.mjs +0 -110
- package/src/sources/RpcWebSocketHeightStream.res +0 -175
- package/src/sources/RpcWebSocketHeightStream.res.mjs +0 -180
package/src/IndexerState.res
CHANGED
|
@@ -355,7 +355,10 @@ let getChainState = (state: t, ~chainId: ChainId.t): ChainState.t =>
|
|
|
355
355
|
)
|
|
356
356
|
}
|
|
357
357
|
|
|
358
|
-
let
|
|
358
|
+
let getSafeCheckpointIdByChain = (state: t) =>
|
|
359
|
+
state.crossChainState->CrossChainState.getSafeCheckpointIdByChain(
|
|
360
|
+
~committedCheckpointId=state.committedCheckpointId,
|
|
361
|
+
)
|
|
359
362
|
|
|
360
363
|
let createBatch = (
|
|
361
364
|
state: t,
|
|
@@ -452,7 +455,14 @@ let entities = (state: t) => state.entities
|
|
|
452
455
|
// Every in-memory entity table across all scopes, cross-chain first. The size,
|
|
453
456
|
// drop and flush passes walk the whole store this way instead of assuming a
|
|
454
457
|
// single partition.
|
|
455
|
-
let eachEntityTable = (
|
|
458
|
+
let eachEntityTable = (
|
|
459
|
+
state: t,
|
|
460
|
+
fn: (
|
|
461
|
+
~entityConfig: Internal.entityConfig,
|
|
462
|
+
~scope: Internal.chainScope,
|
|
463
|
+
~table: InMemoryTable.Entity.t,
|
|
464
|
+
) => unit,
|
|
465
|
+
) => {
|
|
456
466
|
let chainStates = state.crossChainState->CrossChainState.chainStates
|
|
457
467
|
state.allEntities->Array.forEach(entityConfig =>
|
|
458
468
|
if entityConfig.crossChain {
|
|
@@ -516,6 +526,7 @@ let toMetrics = (state: t): Metrics.t => {
|
|
|
516
526
|
let chainStates = state.crossChainState->CrossChainState.chainStates
|
|
517
527
|
let sourceRequests = []
|
|
518
528
|
let sourceHeights = []
|
|
529
|
+
let sourceHeightStreams = []
|
|
519
530
|
chainStates->Utils.Dict.forEach(cs => {
|
|
520
531
|
let sourceManager = cs->ChainState.sourceManager
|
|
521
532
|
sourceManager
|
|
@@ -538,6 +549,16 @@ let toMetrics = (state: t): Metrics.t => {
|
|
|
538
549
|
height: s.height,
|
|
539
550
|
})
|
|
540
551
|
)
|
|
552
|
+
sourceManager
|
|
553
|
+
->SourceManager.getHeightStreamSamples
|
|
554
|
+
->Array.forEach(s =>
|
|
555
|
+
sourceHeightStreams->Array.push({
|
|
556
|
+
Metrics.source: s.sourceName,
|
|
557
|
+
chainId: s.chainId,
|
|
558
|
+
connectCount: s.stream.connectCount,
|
|
559
|
+
disconnectsByReason: s.stream.disconnectsByReason,
|
|
560
|
+
})
|
|
561
|
+
)
|
|
541
562
|
})
|
|
542
563
|
let historyPrunes = []
|
|
543
564
|
state.historyPruneStats->Utils.Dict.forEachWithKey((s, entityName) =>
|
|
@@ -600,6 +621,7 @@ let toMetrics = (state: t): Metrics.t => {
|
|
|
600
621
|
historyPrunes,
|
|
601
622
|
sourceRequests,
|
|
602
623
|
sourceHeights,
|
|
624
|
+
sourceHeightStreams,
|
|
603
625
|
}
|
|
604
626
|
}
|
|
605
627
|
|
|
@@ -793,6 +815,8 @@ let drainBatchRun = (state: t): Batch.t => {
|
|
|
793
815
|
}
|
|
794
816
|
}
|
|
795
817
|
|
|
818
|
+
let pendingRollback = (state: t): option<Persistence.rollback> => state.rollback
|
|
819
|
+
|
|
796
820
|
// Take the pending rollback diff to write, clearing it from the store.
|
|
797
821
|
let takeRollback = (state: t): option<Persistence.rollback> => {
|
|
798
822
|
let rollback = state.rollback
|
|
@@ -812,9 +836,9 @@ let markCommitted = (state: t, ~upToCheckpointId) => {
|
|
|
812
836
|
// Reset the in-memory tables and arm the rollback diff that the next write commits.
|
|
813
837
|
let beginRollbackDiff = (
|
|
814
838
|
state: t,
|
|
815
|
-
~targetCheckpointId,
|
|
816
839
|
~diffCheckpointId,
|
|
817
|
-
~
|
|
840
|
+
~floors,
|
|
841
|
+
~progressedChains: array<InternalTable.Chains.progressedChain>,
|
|
818
842
|
~rolledBackAddresses,
|
|
819
843
|
) => {
|
|
820
844
|
let perChainEntities = state.allEntities->EntityTables.perChain
|
|
@@ -829,10 +853,23 @@ let beginRollbackDiff = (
|
|
|
829
853
|
| Some({rolledBackAddresses: pending}) => pending->Array.concat(rolledBackAddresses)
|
|
830
854
|
| None => rolledBackAddresses
|
|
831
855
|
}
|
|
856
|
+
// Same for the chains: this rollback recomputes progress from the checkpoints,
|
|
857
|
+
// so a chain the pending diff already moved can land on exactly the block it
|
|
858
|
+
// is now at and go unreported here. Its stored progress still needs
|
|
859
|
+
// correcting, so the pending rows carry over — this rollback's row for a
|
|
860
|
+
// chain wins, being the later reading of the same chain state.
|
|
861
|
+
let progressedChains = switch state.rollback {
|
|
862
|
+
| Some({progressedChains: pending}) =>
|
|
863
|
+
let byChainId = Dict.make()
|
|
864
|
+
pending->Array.forEach(chain => byChainId->ChainId.Dict.set(chain.chainId, chain))
|
|
865
|
+
progressedChains->Array.forEach(chain => byChainId->ChainId.Dict.set(chain.chainId, chain))
|
|
866
|
+
byChainId->Dict.valuesToArray
|
|
867
|
+
| None => progressedChains
|
|
868
|
+
}
|
|
832
869
|
state.rollback = Some({
|
|
833
|
-
targetCheckpointId,
|
|
834
870
|
diffCheckpointId,
|
|
835
|
-
|
|
871
|
+
floors,
|
|
872
|
+
progressedChains,
|
|
836
873
|
rolledBackAddresses,
|
|
837
874
|
})
|
|
838
875
|
}
|
package/src/IndexerState.res.mjs
CHANGED
|
@@ -159,8 +159,8 @@ function getChainState(state, chainId) {
|
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
-
function
|
|
163
|
-
return CrossChainState.
|
|
162
|
+
function getSafeCheckpointIdByChain(state) {
|
|
163
|
+
return CrossChainState.getSafeCheckpointIdByChain(state.crossChainState, state.committedCheckpointId);
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
function createBatch(state, processedCheckpointId, batchSizeTarget, isRollback) {
|
|
@@ -392,6 +392,7 @@ function toMetrics(state) {
|
|
|
392
392
|
let chainStates = CrossChainState.chainStates(state.crossChainState);
|
|
393
393
|
let sourceRequests = [];
|
|
394
394
|
let sourceHeights = [];
|
|
395
|
+
let sourceHeightStreams = [];
|
|
395
396
|
Utils.Dict.forEach(chainStates, cs => {
|
|
396
397
|
let sourceManager = ChainState.sourceManager(cs);
|
|
397
398
|
SourceManager.getRequestStatSamples(sourceManager).forEach(s => {
|
|
@@ -410,6 +411,14 @@ function toMetrics(state) {
|
|
|
410
411
|
height: s.height
|
|
411
412
|
});
|
|
412
413
|
});
|
|
414
|
+
SourceManager.getHeightStreamSamples(sourceManager).forEach(s => {
|
|
415
|
+
sourceHeightStreams.push({
|
|
416
|
+
source: s.sourceName,
|
|
417
|
+
chainId: s.chainId,
|
|
418
|
+
connectCount: s.stream.connectCount,
|
|
419
|
+
disconnectsByReason: s.stream.disconnectsByReason
|
|
420
|
+
});
|
|
421
|
+
});
|
|
413
422
|
});
|
|
414
423
|
let historyPrunes = [];
|
|
415
424
|
Utils.Dict.forEachWithKey(state.historyPruneStats, (s, entityName) => {
|
|
@@ -464,7 +473,8 @@ function toMetrics(state) {
|
|
|
464
473
|
})),
|
|
465
474
|
historyPrunes: historyPrunes,
|
|
466
475
|
sourceRequests: sourceRequests,
|
|
467
|
-
sourceHeights: sourceHeights
|
|
476
|
+
sourceHeights: sourceHeights,
|
|
477
|
+
sourceHeightStreams: sourceHeightStreams
|
|
468
478
|
};
|
|
469
479
|
}
|
|
470
480
|
|
|
@@ -658,6 +668,10 @@ function drainBatchRun(state) {
|
|
|
658
668
|
};
|
|
659
669
|
}
|
|
660
670
|
|
|
671
|
+
function pendingRollback(state) {
|
|
672
|
+
return state.rollback;
|
|
673
|
+
}
|
|
674
|
+
|
|
661
675
|
function takeRollback(state) {
|
|
662
676
|
let rollback = state.rollback;
|
|
663
677
|
state.rollback = undefined;
|
|
@@ -668,18 +682,32 @@ function markCommitted(state, upToCheckpointId) {
|
|
|
668
682
|
state.committedCheckpointId = upToCheckpointId;
|
|
669
683
|
}
|
|
670
684
|
|
|
671
|
-
function beginRollbackDiff(state,
|
|
685
|
+
function beginRollbackDiff(state, diffCheckpointId, floors, progressedChains, rolledBackAddresses) {
|
|
672
686
|
let perChainEntities = EntityTables.perChain(state.allEntities);
|
|
673
687
|
state.entities = EntityTables.make(EntityTables.crossChain(state.allEntities));
|
|
674
688
|
Utils.Dict.forEach(CrossChainState.chainStates(state.crossChainState), cs => ChainState.resetEntities(cs, perChainEntities));
|
|
675
689
|
EffectState.resetForRollback(state.effectState);
|
|
676
690
|
let match = state.rollback;
|
|
677
691
|
let rolledBackAddresses$1 = match !== undefined ? match.rolledBackAddresses.concat(rolledBackAddresses) : rolledBackAddresses;
|
|
692
|
+
let match$1 = state.rollback;
|
|
693
|
+
let progressedChains$1;
|
|
694
|
+
if (match$1 !== undefined) {
|
|
695
|
+
let byChainId = {};
|
|
696
|
+
match$1.progressedChains.forEach(chain => {
|
|
697
|
+
byChainId[chain.chainId] = chain;
|
|
698
|
+
});
|
|
699
|
+
progressedChains.forEach(chain => {
|
|
700
|
+
byChainId[chain.chainId] = chain;
|
|
701
|
+
});
|
|
702
|
+
progressedChains$1 = Object.values(byChainId);
|
|
703
|
+
} else {
|
|
704
|
+
progressedChains$1 = progressedChains;
|
|
705
|
+
}
|
|
678
706
|
state.rollback = {
|
|
679
|
-
targetCheckpointId: targetCheckpointId,
|
|
680
707
|
diffCheckpointId: diffCheckpointId,
|
|
708
|
+
floors: floors,
|
|
681
709
|
rolledBackAddresses: rolledBackAddresses$1,
|
|
682
|
-
|
|
710
|
+
progressedChains: progressedChains$1
|
|
683
711
|
};
|
|
684
712
|
}
|
|
685
713
|
|
|
@@ -766,7 +794,7 @@ export {
|
|
|
766
794
|
markProcessingStalledOnFetch,
|
|
767
795
|
recordProcessedBatch,
|
|
768
796
|
createBatch,
|
|
769
|
-
|
|
797
|
+
getSafeCheckpointIdByChain,
|
|
770
798
|
config,
|
|
771
799
|
persistence,
|
|
772
800
|
allEntities,
|
|
@@ -812,6 +840,7 @@ export {
|
|
|
812
840
|
recordRollbackSuccess,
|
|
813
841
|
queueProcessedBatch,
|
|
814
842
|
drainBatchRun,
|
|
843
|
+
pendingRollback,
|
|
815
844
|
takeRollback,
|
|
816
845
|
markCommitted,
|
|
817
846
|
beginRollbackDiff,
|
package/src/IndexerState.resi
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// The indexer state. `t` is opaque: other modules read it through the accessors
|
|
2
2
|
// and change it only through the transitions and setters exposed here.
|
|
3
3
|
|
|
4
|
-
|
|
5
4
|
type rollbackState =
|
|
6
5
|
| NoRollback
|
|
7
6
|
| ReorgDetected({chainId: ChainId.t, blockNumber: int})
|
|
@@ -67,7 +66,7 @@ let createBatch: (
|
|
|
67
66
|
~batchSizeTarget: int,
|
|
68
67
|
~isRollback: bool,
|
|
69
68
|
) => Batch.t
|
|
70
|
-
let
|
|
69
|
+
let getSafeCheckpointIdByChain: t => array<(ChainId.t, option<Internal.checkpointId>)>
|
|
71
70
|
|
|
72
71
|
// Accessors.
|
|
73
72
|
let config: t => Config.t
|
|
@@ -136,13 +135,14 @@ let recordRollbackSuccess: (t, ~timeSeconds: float, ~rollbackedProcessedEvents:
|
|
|
136
135
|
// Store domain operations.
|
|
137
136
|
let queueProcessedBatch: (t, ~batch: Batch.t) => unit
|
|
138
137
|
let drainBatchRun: t => Batch.t
|
|
138
|
+
let pendingRollback: t => option<Persistence.rollback>
|
|
139
139
|
let takeRollback: t => option<Persistence.rollback>
|
|
140
140
|
let markCommitted: (t, ~upToCheckpointId: Internal.checkpointId) => unit
|
|
141
141
|
let beginRollbackDiff: (
|
|
142
142
|
t,
|
|
143
|
-
~targetCheckpointId: Internal.checkpointId,
|
|
144
143
|
~diffCheckpointId: Internal.checkpointId,
|
|
145
|
-
~
|
|
144
|
+
~floors: RollbackFloors.t,
|
|
145
|
+
~progressedChains: array<InternalTable.Chains.progressedChain>,
|
|
146
146
|
~rolledBackAddresses: array<AddressRows.key>,
|
|
147
147
|
) => unit
|
|
148
148
|
let recordWriteFailure: (t, exn) => unit
|
package/src/Internal.res
CHANGED
|
@@ -573,15 +573,6 @@ type svmInstructionEventConfig = {
|
|
|
573
573
|
programId: SvmTypes.Pubkey.t,
|
|
574
574
|
/** Hex-encoded discriminator. `None` matches every instruction in the program. */
|
|
575
575
|
discriminator: option<string>,
|
|
576
|
-
/** Length of the discriminator in bytes (0 / 1 / 2 / 4 / 8). Drives the
|
|
577
|
-
`dN` selector at query time and the dispatch-key precomputation in the
|
|
578
|
-
router. */
|
|
579
|
-
discriminatorByteLen: int,
|
|
580
|
-
/** Disjunctive normal form: outer array is OR of AND-groups, inner array is
|
|
581
|
-
AND across positions. Empty outer array means "no account filter". */
|
|
582
|
-
accountFilters: array<svmAccountFilterGroup>,
|
|
583
|
-
/** `None` matches both outer and inner (CPI-invoked) instructions. */
|
|
584
|
-
isInner: option<bool>,
|
|
585
576
|
/** Positional account names from the Borsh schema, in declared order.
|
|
586
577
|
`[]` means no schema is attached for this instruction. */
|
|
587
578
|
accounts: array<string>,
|
|
@@ -597,10 +588,11 @@ type svmInstructionEventConfig = {
|
|
|
597
588
|
// Per-(event, chain) registration produced when user handler code registers an
|
|
598
589
|
// event (`onEvent`) or a dynamic contract registers. References its definition
|
|
599
590
|
// by value as `.eventConfig` and adds the handler binding plus the
|
|
600
|
-
// registration/`where`-derived fetch state. Not `private`: Fuel
|
|
601
|
-
//
|
|
602
|
-
//
|
|
603
|
-
//
|
|
591
|
+
// registration/`where`-derived fetch state. Not `private`: Fuel registrations
|
|
592
|
+
// add no ecosystem-specific fields (so the alias must stay directly
|
|
593
|
+
// constructable), and the ecosystem→base casts in sources are sound by
|
|
594
|
+
// ecosystem homogeneity — an EVM chain only ever holds
|
|
595
|
+
// `evmOnEventRegistration`s.
|
|
604
596
|
type onEventRegistration = {
|
|
605
597
|
// Chain-scoped sequential index — the registration's position in the
|
|
606
598
|
// chain's onEventRegistrations array, assigned when registration finishes
|
|
@@ -639,11 +631,18 @@ type evmOnEventRegistration = {
|
|
|
639
631
|
resolvedWhere: resolvedWhere,
|
|
640
632
|
}
|
|
641
633
|
|
|
642
|
-
// Fuel
|
|
643
|
-
//
|
|
644
|
-
// aliases of the base registration.
|
|
634
|
+
// Fuel registrations add no ecosystem-specific fetch state, so it's a bare
|
|
635
|
+
// alias of the base registration.
|
|
645
636
|
type fuelOnEventRegistration = onEventRegistration
|
|
646
|
-
|
|
637
|
+
|
|
638
|
+
type svmOnEventRegistration = {
|
|
639
|
+
...onEventRegistration,
|
|
640
|
+
/** Disjunctive normal form: outer array is OR of AND-groups, inner array is
|
|
641
|
+
AND across positions. Empty outer array means "no account filter". */
|
|
642
|
+
accountFilters: array<svmAccountFilterGroup>,
|
|
643
|
+
/** `None` matches both outer and inner (CPI-invoked) instructions. */
|
|
644
|
+
isInner: option<bool>,
|
|
645
|
+
}
|
|
647
646
|
|
|
648
647
|
type svmProgramConfig = {
|
|
649
648
|
name: string,
|
package/src/Metrics.res
CHANGED
|
@@ -98,6 +98,13 @@ type sourceHeightMetrics = {
|
|
|
98
98
|
height: int,
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
type sourceHeightStreamMetrics = {
|
|
102
|
+
source: string,
|
|
103
|
+
chainId: ChainId.t,
|
|
104
|
+
connectCount: int,
|
|
105
|
+
disconnectsByReason: array<(string, int)>,
|
|
106
|
+
}
|
|
107
|
+
|
|
101
108
|
type t = {
|
|
102
109
|
startTime: Date.t,
|
|
103
110
|
// Wall clock when this snapshot was built, so a scrape can be dated.
|
|
@@ -124,6 +131,7 @@ type t = {
|
|
|
124
131
|
historyPrunes: array<historyPruneMetrics>,
|
|
125
132
|
sourceRequests: array<sourceRequestMetrics>,
|
|
126
133
|
sourceHeights: array<sourceHeightMetrics>,
|
|
134
|
+
sourceHeightStreams: array<sourceHeightStreamMetrics>,
|
|
127
135
|
}
|
|
128
136
|
|
|
129
137
|
// Prometheus floats keep at most 3 decimals; integral values render without a
|
|
@@ -220,13 +228,23 @@ let renderMetrics = (b: builder, metrics: t) => {
|
|
|
220
228
|
metrics.storageWrites->Array.map(s => (`{storage="${s.storage->escapeLabelValue}"}`, s))
|
|
221
229
|
let historyPrunes =
|
|
222
230
|
metrics.historyPrunes->Array.map(s => (`{entity="${s.entity->escapeLabelValue}"}`, s))
|
|
231
|
+
// Every per-source series shares this label set: a scrape whose labels
|
|
232
|
+
// disagree between two of them is one nothing can join on.
|
|
233
|
+
let sourceLabels = (~source, ~chainId, ~extra: option<(string, string)>=?) => {
|
|
234
|
+
let pair = `{source="${source->escapeLabelValue}",chainId="${chainId->ChainId.toString}"`
|
|
235
|
+
switch extra {
|
|
236
|
+
| Some((name, value)) => `${pair},${name}="${value->escapeLabelValue}"}`
|
|
237
|
+
| None => pair ++ "}"
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
223
241
|
// Two sources can share a name (e.g. primary and fallback RPC urls on the
|
|
224
242
|
// same host), so aggregate by label set — duplicate samples would make
|
|
225
243
|
// Prometheus reject the scrape.
|
|
226
244
|
let sourceRequests = {
|
|
227
245
|
let byLabels: dict<sourceRequestMetrics> = Dict.make()
|
|
228
246
|
metrics.sourceRequests->Array.forEach(s => {
|
|
229
|
-
let labels =
|
|
247
|
+
let labels = sourceLabels(~source=s.source, ~chainId=s.chainId, ~extra=("method", s.method))
|
|
230
248
|
switch byLabels->Utils.Dict.dangerouslyGetNonOption(labels) {
|
|
231
249
|
| Some(existing) =>
|
|
232
250
|
byLabels->Dict.set(
|
|
@@ -241,7 +259,7 @@ let renderMetrics = (b: builder, metrics: t) => {
|
|
|
241
259
|
let sources = {
|
|
242
260
|
let byLabels: dict<int> = Dict.make()
|
|
243
261
|
metrics.sourceHeights->Array.forEach(s => {
|
|
244
|
-
let labels =
|
|
262
|
+
let labels = sourceLabels(~source=s.source, ~chainId=s.chainId)
|
|
245
263
|
switch byLabels->Utils.Dict.dangerouslyGetNonOption(labels) {
|
|
246
264
|
| Some(existing) if existing >= s.height => ()
|
|
247
265
|
| _ => byLabels->Dict.set(labels, s.height)
|
|
@@ -250,6 +268,34 @@ let renderMetrics = (b: builder, metrics: t) => {
|
|
|
250
268
|
byLabels->Dict.toArray
|
|
251
269
|
}
|
|
252
270
|
|
|
271
|
+
// Zero connects is the one count worth rendering flat: it is a stream that
|
|
272
|
+
// has never come up, which the disconnects say nothing about — retries at a
|
|
273
|
+
// connection that never opened are not disconnections — and which is
|
|
274
|
+
// otherwise indistinguishable from a chain that was never configured to
|
|
275
|
+
// stream at all.
|
|
276
|
+
let heightStreamConnects = {
|
|
277
|
+
let byLabels: dict<int> = Dict.make()
|
|
278
|
+
metrics.sourceHeightStreams->Array.forEach(s =>
|
|
279
|
+
byLabels->Utils.Dict.incrementBy(
|
|
280
|
+
sourceLabels(~source=s.source, ~chainId=s.chainId),
|
|
281
|
+
s.connectCount,
|
|
282
|
+
)
|
|
283
|
+
)
|
|
284
|
+
byLabels->Dict.toArray
|
|
285
|
+
}
|
|
286
|
+
let heightStreamDisconnects = {
|
|
287
|
+
let byLabels: dict<int> = Dict.make()
|
|
288
|
+
metrics.sourceHeightStreams->Array.forEach(s =>
|
|
289
|
+
s.disconnectsByReason->Array.forEach(((reason, count)) =>
|
|
290
|
+
byLabels->Utils.Dict.incrementBy(
|
|
291
|
+
sourceLabels(~source=s.source, ~chainId=s.chainId, ~extra=("reason", reason)),
|
|
292
|
+
count,
|
|
293
|
+
)
|
|
294
|
+
)
|
|
295
|
+
)
|
|
296
|
+
byLabels->Dict.toArray
|
|
297
|
+
}
|
|
298
|
+
|
|
253
299
|
b->single(
|
|
254
300
|
~name="envio_process_start_time_seconds",
|
|
255
301
|
~help="Start time of the process since unix epoch in seconds.",
|
|
@@ -463,6 +509,24 @@ let renderMetrics = (b: builder, metrics: t) => {
|
|
|
463
509
|
~entries=sourceRequests,
|
|
464
510
|
~value=s => s.seconds !== 0. ? Some(s.seconds) : None,
|
|
465
511
|
)
|
|
512
|
+
if heightStreamConnects->Array.length > 0 {
|
|
513
|
+
b->series(
|
|
514
|
+
~name="envio_source_height_stream_connects_total",
|
|
515
|
+
~help="The number of times a source's height subscription connected. Compare against the disconnects total, which is absent until the first disconnect and counts as zero while it is: one more connect than disconnects means the stream is up, and equal counts mean it is down and the indexer is polling instead. Zero connects means the stream has not come up, which is the normal reading for a chain that is still backfilling: subscriptions are only opened once a chain reaches the head.",
|
|
516
|
+
~kind="counter",
|
|
517
|
+
~entries=heightStreamConnects,
|
|
518
|
+
~value=count => count->Int.toFloat,
|
|
519
|
+
)
|
|
520
|
+
}
|
|
521
|
+
if heightStreamDisconnects->Array.length > 0 {
|
|
522
|
+
b->series(
|
|
523
|
+
~name="envio_source_height_stream_disconnects_total",
|
|
524
|
+
~help="The number of times a source's height subscription lost a connection, by reason. Failed retries are not counted, so this is outages rather than their length. A rotated disconnect is a connection that served its time; unsubscribed is the source being benched; every other reason ended a connection early.",
|
|
525
|
+
~kind="counter",
|
|
526
|
+
~entries=heightStreamDisconnects,
|
|
527
|
+
~value=count => count->Int.toFloat,
|
|
528
|
+
)
|
|
529
|
+
}
|
|
466
530
|
b->series(
|
|
467
531
|
~name="envio_source_known_height",
|
|
468
532
|
~help="The latest known block number reported by the source. This value may lag behind the actual chain height, as it is updated only when queried.",
|
|
@@ -706,10 +770,12 @@ let renderMetrics = (b: builder, metrics: t) => {
|
|
|
706
770
|
~help="The number of address registrations per contract on chain, static and dynamic. An address shared by N contracts counts N times.",
|
|
707
771
|
~kind="gauge",
|
|
708
772
|
~entries=metrics.chains->Array.flatMap(m =>
|
|
709
|
-
m.addressesByContract->Array.map(
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
773
|
+
m.addressesByContract->Array.map(
|
|
774
|
+
((contract, count)) => (
|
|
775
|
+
`{chainId="${m.chainId->ChainId.toString}",contract="${contract->escapeLabelValue}"}`,
|
|
776
|
+
count,
|
|
777
|
+
),
|
|
778
|
+
)
|
|
713
779
|
),
|
|
714
780
|
~value=count => count->Int.toFloat,
|
|
715
781
|
)
|
package/src/Metrics.res.mjs
CHANGED
|
@@ -80,9 +80,20 @@ function renderMetrics(b, metrics) {
|
|
|
80
80
|
`{entity="` + escapeLabelValue(s.entity) + `"}`,
|
|
81
81
|
s
|
|
82
82
|
]);
|
|
83
|
+
let sourceLabels = (source, chainId, extra) => {
|
|
84
|
+
let pair = `{source="` + escapeLabelValue(source) + `",chainId="` + ChainId.toString(chainId) + `"`;
|
|
85
|
+
if (extra !== undefined) {
|
|
86
|
+
return pair + `,` + extra[0] + `="` + escapeLabelValue(extra[1]) + `"}`;
|
|
87
|
+
} else {
|
|
88
|
+
return pair + "}";
|
|
89
|
+
}
|
|
90
|
+
};
|
|
83
91
|
let byLabels = {};
|
|
84
92
|
metrics.sourceRequests.forEach(s => {
|
|
85
|
-
let labels =
|
|
93
|
+
let labels = sourceLabels(s.source, s.chainId, [
|
|
94
|
+
"method",
|
|
95
|
+
s.method
|
|
96
|
+
]);
|
|
86
97
|
let existing = byLabels[labels];
|
|
87
98
|
if (existing !== undefined) {
|
|
88
99
|
byLabels[labels] = {
|
|
@@ -99,7 +110,7 @@ function renderMetrics(b, metrics) {
|
|
|
99
110
|
let sourceRequests = Object.entries(byLabels);
|
|
100
111
|
let byLabels$1 = {};
|
|
101
112
|
metrics.sourceHeights.forEach(s => {
|
|
102
|
-
let labels =
|
|
113
|
+
let labels = sourceLabels(s.source, s.chainId, undefined);
|
|
103
114
|
let existing = byLabels$1[labels];
|
|
104
115
|
if (existing !== undefined && existing >= s.height) {
|
|
105
116
|
return;
|
|
@@ -109,6 +120,17 @@ function renderMetrics(b, metrics) {
|
|
|
109
120
|
}
|
|
110
121
|
});
|
|
111
122
|
let sources = Object.entries(byLabels$1);
|
|
123
|
+
let byLabels$2 = {};
|
|
124
|
+
metrics.sourceHeightStreams.forEach(s => Utils.Dict.incrementBy(byLabels$2, sourceLabels(s.source, s.chainId, undefined), s.connectCount));
|
|
125
|
+
let heightStreamConnects = Object.entries(byLabels$2);
|
|
126
|
+
let byLabels$3 = {};
|
|
127
|
+
metrics.sourceHeightStreams.forEach(s => {
|
|
128
|
+
s.disconnectsByReason.forEach(param => Utils.Dict.incrementBy(byLabels$3, sourceLabels(s.source, s.chainId, [
|
|
129
|
+
"reason",
|
|
130
|
+
param[0]
|
|
131
|
+
]), param[1]));
|
|
132
|
+
});
|
|
133
|
+
let heightStreamDisconnects = Object.entries(byLabels$3);
|
|
112
134
|
single(b, "envio_process_start_time_seconds", "Start time of the process since unix epoch in seconds.", "gauge", metrics.startTime.getTime() / 1000);
|
|
113
135
|
single(b, "envio_process_metric_time_seconds", "The time these metrics were collected. Use it to tell how fresh a snapshot is, or to measure rates between two snapshots.", "gauge", metrics.metricTime.getTime() / 1000);
|
|
114
136
|
single(b, "envio_process_elapsed_seconds", "How long the indexer has been running. Divide a cumulative seconds metric by this to get the share of the run it took, eg envio_processing_seconds for time spent in event handlers.", "gauge", metrics.elapsedSeconds);
|
|
@@ -154,6 +176,12 @@ function renderMetrics(b, metrics) {
|
|
|
154
176
|
return s.seconds;
|
|
155
177
|
}
|
|
156
178
|
});
|
|
179
|
+
if (heightStreamConnects.length !== 0) {
|
|
180
|
+
series(b, "envio_source_height_stream_connects_total", "The number of times a source's height subscription connected. Compare against the disconnects total, which is absent until the first disconnect and counts as zero while it is: one more connect than disconnects means the stream is up, and equal counts mean it is down and the indexer is polling instead. Zero connects means the stream has not come up, which is the normal reading for a chain that is still backfilling: subscriptions are only opened once a chain reaches the head.", "counter", heightStreamConnects, count => count);
|
|
181
|
+
}
|
|
182
|
+
if (heightStreamDisconnects.length !== 0) {
|
|
183
|
+
series(b, "envio_source_height_stream_disconnects_total", "The number of times a source's height subscription lost a connection, by reason. Failed retries are not counted, so this is outages rather than their length. A rotated disconnect is a connection that served its time; unsubscribed is the source being benched; every other reason ended a connection early.", "counter", heightStreamDisconnects, count => count);
|
|
184
|
+
}
|
|
157
185
|
series(b, "envio_source_known_height", "The latest known block number reported by the source. This value may lag behind the actual chain height, as it is updated only when queried.", "gauge", sources, height => height);
|
|
158
186
|
seriesOpt(b, "envio_reorg_detected_total", "Total number of reorgs detected", "counter", chains, m => {
|
|
159
187
|
if (m.reorgCount > 0) {
|
package/src/Persistence.res
CHANGED
|
@@ -59,14 +59,20 @@ type updatedEffectCache = {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
type rollback = {
|
|
62
|
-
targetCheckpointId: Internal.checkpointId,
|
|
63
62
|
diffCheckpointId: Internal.checkpointId,
|
|
63
|
+
// How far back the deletes reach on each chain, travelling with the diff so
|
|
64
|
+
// the write leaves an untouched sibling's rows alone.
|
|
65
|
+
floors: RollbackFloors.t,
|
|
64
66
|
// The address registrations the rollback dropped, as the chains' address
|
|
65
67
|
// stores resolved them. Deleted by primary key in the same transaction.
|
|
66
68
|
rolledBackAddresses: array<AddressRows.key>,
|
|
67
|
-
//
|
|
68
|
-
//
|
|
69
|
-
|
|
69
|
+
// Where the rollback left every chain it moved. Written with the diff rather
|
|
70
|
+
// than waiting for a batch of those chains' own: the batch that carries the
|
|
71
|
+
// diff can belong to a chain the rollback never touched, and a chain whose
|
|
72
|
+
// stored progress outlived the checkpoints backing it would resume past
|
|
73
|
+
// blocks it never re-indexed. Also what `RollbackCommit.fire` reports once
|
|
74
|
+
// the diff is durably written.
|
|
75
|
+
progressedChains: array<InternalTable.Chains.progressedChain>,
|
|
70
76
|
}
|
|
71
77
|
|
|
72
78
|
// One flush group: the changes an entity accumulated within a single chain
|
|
@@ -101,7 +107,16 @@ type storage = {
|
|
|
101
107
|
~contractMapping: ContractMapping.t,
|
|
102
108
|
~envioInfo: JSON.t,
|
|
103
109
|
) => promise<initialState>,
|
|
104
|
-
|
|
110
|
+
// `throwIfIncompatible` gets what the storage holds before any sink is
|
|
111
|
+
// resumed, so a config the stored one rules out is reported as such rather
|
|
112
|
+
// than as the sink tripping over tables it never created.
|
|
113
|
+
resumeInitialState: (
|
|
114
|
+
~entities: array<Internal.entityConfig>,
|
|
115
|
+
~throwIfIncompatible: (
|
|
116
|
+
~storedEnvioInfo: option<JSON.t>,
|
|
117
|
+
~storedContractMapping: ContractMapping.t,
|
|
118
|
+
) => unit,
|
|
119
|
+
) => promise<initialState>,
|
|
105
120
|
// Returns rows matching the filter.
|
|
106
121
|
// Field values are serialized and rows parsed with the table's field schemas.
|
|
107
122
|
@raises("StorageError")
|
|
@@ -131,13 +146,13 @@ type storage = {
|
|
|
131
146
|
// Update chain metadata
|
|
132
147
|
setChainMeta: dict<InternalTable.Chains.metaFields> => promise<unknown>,
|
|
133
148
|
// Prune old checkpoints
|
|
134
|
-
pruneStaleCheckpoints: (~
|
|
149
|
+
pruneStaleCheckpoints: (~safeCheckpoints: CheckpointBounds.t) => promise<unit>,
|
|
135
150
|
// Prune stale entity history
|
|
136
151
|
pruneStaleEntityHistory: (
|
|
137
152
|
~entityName: string,
|
|
138
153
|
~entityIndex: int,
|
|
139
154
|
~chainIdColumn: option<string>,
|
|
140
|
-
~
|
|
155
|
+
~safeCheckpoints: CheckpointBounds.t,
|
|
141
156
|
) => promise<unit>,
|
|
142
157
|
// Get rollback target checkpoint
|
|
143
158
|
getRollbackTargetCheckpoint: (
|
|
@@ -146,7 +161,7 @@ type storage = {
|
|
|
146
161
|
) => promise<option<Internal.checkpointId>>,
|
|
147
162
|
// Get rollback progress diff
|
|
148
163
|
getRollbackProgressDiff: (
|
|
149
|
-
~
|
|
164
|
+
~floors: RollbackFloors.t,
|
|
150
165
|
) => promise<
|
|
151
166
|
array<{
|
|
152
167
|
"chain_id": ChainId.t,
|
|
@@ -159,7 +174,7 @@ type storage = {
|
|
|
159
174
|
// before handing them back.
|
|
160
175
|
getRollbackData: (
|
|
161
176
|
~entityConfig: Internal.entityConfig,
|
|
162
|
-
~
|
|
177
|
+
~floors: RollbackFloors.t,
|
|
163
178
|
) => promise<(array<rollbackRemoval>, array<Internal.entity>)>,
|
|
164
179
|
// Write batch to storage
|
|
165
180
|
writeBatch: (
|
|
@@ -262,27 +277,18 @@ let init = {
|
|
|
262
277
|
}
|
|
263
278
|
) {
|
|
264
279
|
Logging.info(`Found existing indexer storage. Resuming indexing state...`)
|
|
265
|
-
let initialState = await persistence.storage.resumeInitialState(
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
}
|
|
278
|
-
| _ => false
|
|
279
|
-
}
|
|
280
|
-
| _ => false
|
|
281
|
-
}
|
|
282
|
-
Config.throwIfIncompatible(changedPaths, ~resetCommand, ~runCommand, ~hasClickhouse)
|
|
283
|
-
if !(initialState.contractMapping->ContractMapping.isEqual(contractMapping)) {
|
|
284
|
-
Config.throwIfIncompatible(["contracts"], ~resetCommand, ~runCommand, ~hasClickhouse)
|
|
285
|
-
}
|
|
280
|
+
let initialState = await persistence.storage.resumeInitialState(
|
|
281
|
+
~entities=persistence.allEntities,
|
|
282
|
+
~throwIfIncompatible=(~storedEnvioInfo, ~storedContractMapping) =>
|
|
283
|
+
Config.throwIfResumeIncompatible(
|
|
284
|
+
~storedEnvioInfo,
|
|
285
|
+
~storedContractMapping,
|
|
286
|
+
~envioInfo,
|
|
287
|
+
~contractMapping,
|
|
288
|
+
~resetCommand,
|
|
289
|
+
~runCommand,
|
|
290
|
+
),
|
|
291
|
+
)
|
|
286
292
|
persistence.storageStatus = Ready(initialState)
|
|
287
293
|
let progress = Dict.make()
|
|
288
294
|
initialState.chains->Array.forEach(c => {
|
package/src/Persistence.res.mjs
CHANGED
|
@@ -5,7 +5,6 @@ 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";
|
|
9
8
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
10
9
|
|
|
11
10
|
let StorageError = /* @__PURE__ */Primitive_exceptions.create("Persistence.StorageError");
|
|
@@ -61,25 +60,7 @@ async function init(persistence, chainConfigs, contractMapping, envioInfo, reset
|
|
|
61
60
|
tmp = typeof match !== "object" ? false : match.TAG === "Initializing";
|
|
62
61
|
if (tmp) {
|
|
63
62
|
Logging.info(`Found existing indexer storage. Resuming indexing state...`);
|
|
64
|
-
let initialState$1 = await persistence.storage.resumeInitialState();
|
|
65
|
-
let stored = initialState$1.envioInfo;
|
|
66
|
-
let changedPaths = stored !== undefined ? Config.diffPaths(stored, envioInfo) : ["storage was initialized by an older envio version"];
|
|
67
|
-
let hasClickhouse;
|
|
68
|
-
if (typeof envioInfo === "object" && envioInfo !== null && !Array.isArray(envioInfo)) {
|
|
69
|
-
let match$1 = envioInfo["storage"];
|
|
70
|
-
if (typeof match$1 === "object" && match$1 !== null && !Array.isArray(match$1)) {
|
|
71
|
-
let match$2 = match$1["clickhouse"];
|
|
72
|
-
hasClickhouse = match$2 === true;
|
|
73
|
-
} else {
|
|
74
|
-
hasClickhouse = false;
|
|
75
|
-
}
|
|
76
|
-
} else {
|
|
77
|
-
hasClickhouse = false;
|
|
78
|
-
}
|
|
79
|
-
Config.throwIfIncompatible(changedPaths, resetCommand, runCommand, hasClickhouse);
|
|
80
|
-
if (!ContractMapping.isEqual(initialState$1.contractMapping, contractMapping)) {
|
|
81
|
-
Config.throwIfIncompatible(["contracts"], resetCommand, runCommand, hasClickhouse);
|
|
82
|
-
}
|
|
63
|
+
let initialState$1 = await persistence.storage.resumeInitialState(persistence.allEntities, (storedEnvioInfo, storedContractMapping) => Config.throwIfResumeIncompatible(storedEnvioInfo, storedContractMapping, envioInfo, contractMapping, resetCommand, runCommand));
|
|
83
64
|
persistence.storageStatus = {
|
|
84
65
|
TAG: "Ready",
|
|
85
66
|
_0: initialState$1
|