envio 3.9.0 → 3.10.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/evm.schema.json +26 -0
- package/fuel.schema.json +26 -0
- package/index.d.ts +35 -3
- 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 +52 -44
- package/src/Config.res.mjs +51 -17
- package/src/Core.res +4 -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/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/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/svm.schema.json +1 -75
- 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/Rollback.res
CHANGED
|
@@ -127,86 +127,105 @@ and executeRollback = async (
|
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
// The diff computed here replaces a pending one rather than merging with it,
|
|
131
|
+
// so its deletes have to cover everything that one would have deleted. The
|
|
132
|
+
// flush above leaves a diff pending only when no batch has come along to
|
|
133
|
+
// carry it.
|
|
134
|
+
let floors = {
|
|
135
|
+
let next = if state->IndexerState.config->Config.isIsolatedMultichain {
|
|
136
|
+
RollbackFloors.isolated(
|
|
137
|
+
~chainId=reorgChain,
|
|
138
|
+
~floorCheckpointId=rollbackTargetCheckpointId,
|
|
139
|
+
~forkBlockNumber=rollbackTargetBlockNumber,
|
|
140
|
+
)
|
|
141
|
+
} else {
|
|
142
|
+
RollbackFloors.global(
|
|
143
|
+
~floorCheckpointId=rollbackTargetCheckpointId,
|
|
144
|
+
~reorgChainId=reorgChain,
|
|
145
|
+
~forkBlockNumber=rollbackTargetBlockNumber,
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
switch state->IndexerState.pendingRollback {
|
|
149
|
+
| None => next
|
|
150
|
+
| Some({floors: pending}) => RollbackFloors.merge(pending, next)
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
let progressDiffByChain: dict<ChainState.progressDiff> = Dict.make()
|
|
132
155
|
let rollbackedProcessedEvents = ref(0.)
|
|
133
156
|
|
|
134
157
|
{
|
|
135
158
|
let rollbackProgressDiff = await (
|
|
136
159
|
state->IndexerState.persistence
|
|
137
|
-
).storage.getRollbackProgressDiff(~
|
|
160
|
+
).storage.getRollbackProgressDiff(~floors)
|
|
138
161
|
for idx in 0 to rollbackProgressDiff->Array.length - 1 {
|
|
139
162
|
let diff = rollbackProgressDiff->Array.getUnsafe(idx)
|
|
140
|
-
|
|
141
|
-
|
|
163
|
+
let chainId = diff["chain_id"]
|
|
164
|
+
let eventsProcessed = Float.fromString(diff["events_processed_diff"])->Option.getOrThrow
|
|
165
|
+
rollbackedProcessedEvents := rollbackedProcessedEvents.contents +. eventsProcessed
|
|
166
|
+
progressDiffByChain->ChainId.Dict.set(
|
|
167
|
+
chainId,
|
|
142
168
|
{
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
rollbackedProcessedEvents := rollbackedProcessedEvents.contents +. eventsProcessedDiff
|
|
146
|
-
eventsProcessedDiff
|
|
147
|
-
},
|
|
148
|
-
)
|
|
149
|
-
newProgressBlockNumberPerChain->ChainId.Dict.set(
|
|
150
|
-
diff["chain_id"],
|
|
151
|
-
if rollbackTargetCheckpointId === 0n && diff["chain_id"] === reorgChain {
|
|
152
|
-
Pervasives.min(diff["new_progress_block_number"], rollbackTargetBlockNumber)
|
|
153
|
-
} else {
|
|
154
|
-
diff["new_progress_block_number"]
|
|
169
|
+
blockNumber: diff["new_progress_block_number"],
|
|
170
|
+
eventsProcessed,
|
|
155
171
|
},
|
|
156
172
|
)
|
|
157
173
|
}
|
|
158
174
|
}
|
|
159
175
|
|
|
160
|
-
|
|
176
|
+
// Where the rollback leaves each chain it moved, written with the diff: the
|
|
177
|
+
// batch that carries it may belong to a chain the rollback never touched.
|
|
178
|
+
let rolledBackChains: array<InternalTable.Chains.progressedChain> = []
|
|
161
179
|
let rolledBackAddresses = []
|
|
162
180
|
state
|
|
163
181
|
->IndexerState.chainStates
|
|
164
182
|
->Utils.Dict.forEach(cs => {
|
|
165
183
|
let chainId = (cs->ChainState.chainConfig).id
|
|
166
184
|
let fromBlock = cs->ChainState.committedProgressBlockNumber
|
|
167
|
-
let
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
185
|
+
let progressDiff = progressDiffByChain->ChainId.Dict.dangerouslyGetNonOption(chainId)
|
|
186
|
+
let killedAddresses = cs->ChainState.rollback(
|
|
187
|
+
~rolledBackTo=switch (progressDiff, floors->RollbackFloors.forkBlockNumber(chainId)) {
|
|
188
|
+
| (Some(progressDiff), forkBlockNumber) =>
|
|
189
|
+
RecomputedProgress({
|
|
190
|
+
...progressDiff,
|
|
191
|
+
blockNumber: forkBlockNumber->Option.mapOr(progressDiff.blockNumber, forkBlockNumber =>
|
|
192
|
+
Pervasives.min(progressDiff.blockNumber, forkBlockNumber)
|
|
193
|
+
),
|
|
194
|
+
})
|
|
195
|
+
// Nothing of this chain's is above its floor, so there are no checkpoints
|
|
196
|
+
// to recompute from.
|
|
197
|
+
| (None, Some(forkBlockNumber)) => ForkBlock(forkBlockNumber)
|
|
198
|
+
| (None, None) => Untouched
|
|
199
|
+
},
|
|
200
|
+
)
|
|
178
201
|
rolledBackAddresses->Array.pushMany(killedAddresses)->ignore
|
|
179
202
|
let toBlock = cs->ChainState.committedProgressBlockNumber
|
|
180
203
|
if fromBlock !== toBlock {
|
|
181
204
|
rolledBackChains
|
|
182
205
|
->Array.push({
|
|
206
|
+
chainId,
|
|
207
|
+
progressBlockNumber: toBlock,
|
|
208
|
+
sourceBlockNumber: cs->ChainState.knownHeight,
|
|
209
|
+
totalEventsProcessed: cs->ChainState.numEventsProcessed,
|
|
210
|
+
})
|
|
211
|
+
->ignore
|
|
212
|
+
logger->Logging.childInfo({
|
|
213
|
+
"msg": "Rollbacked",
|
|
183
214
|
"chainId": chainId,
|
|
184
215
|
"fromBlock": fromBlock,
|
|
185
216
|
"toBlock": toBlock,
|
|
186
|
-
"rollbackedEvents":
|
|
187
|
-
->ChainId.Dict.dangerouslyGetNonOption(chainId)
|
|
188
|
-
->Option.getOr(0.),
|
|
217
|
+
"rollbackedEvents": progressDiff->Option.mapOr(0., diff => diff.eventsProcessed),
|
|
189
218
|
})
|
|
190
|
-
->ignore
|
|
191
219
|
}
|
|
192
220
|
})
|
|
193
221
|
|
|
194
222
|
let diff = await state->InMemoryStore.prepareRollbackDiff(
|
|
195
|
-
~
|
|
223
|
+
~floors,
|
|
196
224
|
~rollbackDiffCheckpointId=state->IndexerState.committedCheckpointId->BigInt.add(1n),
|
|
197
|
-
~
|
|
225
|
+
~progressedChains=rolledBackChains,
|
|
198
226
|
~rolledBackAddresses,
|
|
199
227
|
)
|
|
200
228
|
|
|
201
|
-
rolledBackChains->Array.forEach(rolledBack => {
|
|
202
|
-
logger->Logging.childInfo({
|
|
203
|
-
"msg": "Rollbacked",
|
|
204
|
-
"chainId": rolledBack["chainId"],
|
|
205
|
-
"fromBlock": rolledBack["fromBlock"],
|
|
206
|
-
"toBlock": rolledBack["toBlock"],
|
|
207
|
-
"rollbackedEvents": rolledBack["rollbackedEvents"],
|
|
208
|
-
})
|
|
209
|
-
})
|
|
210
229
|
logger->Logging.childTrace({
|
|
211
230
|
"msg": "Rollback entity changes",
|
|
212
231
|
"deleted": diff["deletedEntities"],
|
|
@@ -217,7 +236,11 @@ and executeRollback = async (
|
|
|
217
236
|
~rollbackedProcessedEvents=rollbackedProcessedEvents.contents,
|
|
218
237
|
)
|
|
219
238
|
|
|
220
|
-
state->IndexerState.completeRollback(
|
|
239
|
+
state->IndexerState.completeRollback(
|
|
240
|
+
~eventsProcessedDiffByChain=progressDiffByChain->Utils.Dict.mapValues(diff =>
|
|
241
|
+
diff.eventsProcessed
|
|
242
|
+
),
|
|
243
|
+
)
|
|
221
244
|
scheduleFetch()
|
|
222
245
|
scheduleProcessing()
|
|
223
246
|
}
|
package/src/Rollback.res.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
3
|
import * as Utils from "./Utils.res.mjs";
|
|
4
|
+
import * as Config from "./Config.res.mjs";
|
|
4
5
|
import * as Logging from "./Logging.res.mjs";
|
|
5
6
|
import * as Writing from "./Writing.res.mjs";
|
|
6
7
|
import * as ChainState from "./ChainState.res.mjs";
|
|
@@ -12,6 +13,7 @@ import * as InMemoryStore from "./InMemoryStore.res.mjs";
|
|
|
12
13
|
import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
|
|
13
14
|
import * as SourceManager from "./sources/SourceManager.res.mjs";
|
|
14
15
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
16
|
+
import * as RollbackFloors from "./db/RollbackFloors.res.mjs";
|
|
15
17
|
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
16
18
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
17
19
|
|
|
@@ -42,50 +44,67 @@ async function executeRollback(state, reorgChain, rollbackTargetBlockNumber, sch
|
|
|
42
44
|
await Writing.flush(state);
|
|
43
45
|
let checkpointId = await IndexerState.persistence(state).storage.getRollbackTargetCheckpoint(reorgChain, rollbackTargetBlockNumber);
|
|
44
46
|
let rollbackTargetCheckpointId = checkpointId !== undefined ? checkpointId : 0n;
|
|
45
|
-
let
|
|
46
|
-
let
|
|
47
|
+
let next = Config.isIsolatedMultichain(IndexerState.config(state)) ? RollbackFloors.isolated(reorgChain, rollbackTargetCheckpointId, rollbackTargetBlockNumber) : RollbackFloors.global(rollbackTargetCheckpointId, reorgChain, rollbackTargetBlockNumber);
|
|
48
|
+
let match = IndexerState.pendingRollback(state);
|
|
49
|
+
let floors = match !== undefined ? RollbackFloors.merge(match.floors, next) : next;
|
|
50
|
+
let progressDiffByChain = {};
|
|
47
51
|
let rollbackedProcessedEvents = 0;
|
|
48
|
-
let rollbackProgressDiff = await IndexerState.persistence(state).storage.getRollbackProgressDiff(
|
|
52
|
+
let rollbackProgressDiff = await IndexerState.persistence(state).storage.getRollbackProgressDiff(floors);
|
|
49
53
|
for (let idx = 0, idx_finish = rollbackProgressDiff.length; idx < idx_finish; ++idx) {
|
|
50
54
|
let diff = rollbackProgressDiff[idx];
|
|
51
|
-
let
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
+
let chainId = diff.chain_id;
|
|
56
|
+
let eventsProcessed = Stdlib_Option.getOrThrow(Stdlib_Float.fromString(diff.events_processed_diff), undefined);
|
|
57
|
+
rollbackedProcessedEvents = rollbackedProcessedEvents + eventsProcessed;
|
|
58
|
+
progressDiffByChain[chainId] = {
|
|
59
|
+
blockNumber: diff.new_progress_block_number,
|
|
60
|
+
eventsProcessed: eventsProcessed
|
|
61
|
+
};
|
|
55
62
|
}
|
|
56
63
|
let rolledBackChains = [];
|
|
57
64
|
let rolledBackAddresses = [];
|
|
58
65
|
Utils.Dict.forEach(IndexerState.chainStates(state), cs => {
|
|
59
66
|
let chainId = ChainState.chainConfig(cs).id;
|
|
60
67
|
let fromBlock = ChainState.committedProgressBlockNumber(cs);
|
|
61
|
-
let
|
|
68
|
+
let progressDiff = progressDiffByChain[chainId];
|
|
69
|
+
let match = RollbackFloors.forkBlockNumber(floors, chainId);
|
|
70
|
+
let killedAddresses = ChainState.rollback(cs, progressDiff !== undefined ? ({
|
|
71
|
+
TAG: "RecomputedProgress",
|
|
72
|
+
_0: {
|
|
73
|
+
blockNumber: Stdlib_Option.mapOr(match, progressDiff.blockNumber, forkBlockNumber => Primitive_int.min(progressDiff.blockNumber, forkBlockNumber)),
|
|
74
|
+
eventsProcessed: progressDiff.eventsProcessed
|
|
75
|
+
}
|
|
76
|
+
}) : (
|
|
77
|
+
match !== undefined ? ({
|
|
78
|
+
TAG: "ForkBlock",
|
|
79
|
+
_0: match
|
|
80
|
+
}) : "Untouched"
|
|
81
|
+
));
|
|
62
82
|
rolledBackAddresses.push(...killedAddresses);
|
|
63
83
|
let toBlock = ChainState.committedProgressBlockNumber(cs);
|
|
64
84
|
if (fromBlock !== toBlock) {
|
|
65
85
|
rolledBackChains.push({
|
|
86
|
+
chainId: chainId,
|
|
87
|
+
progressBlockNumber: toBlock,
|
|
88
|
+
sourceBlockNumber: ChainState.knownHeight(cs),
|
|
89
|
+
totalEventsProcessed: ChainState.numEventsProcessed(cs)
|
|
90
|
+
});
|
|
91
|
+
return Logging.childInfo(logger, {
|
|
92
|
+
msg: "Rollbacked",
|
|
66
93
|
chainId: chainId,
|
|
67
94
|
fromBlock: fromBlock,
|
|
68
95
|
toBlock: toBlock,
|
|
69
|
-
rollbackedEvents: Stdlib_Option.
|
|
96
|
+
rollbackedEvents: Stdlib_Option.mapOr(progressDiff, 0, diff => diff.eventsProcessed)
|
|
70
97
|
});
|
|
71
|
-
return;
|
|
72
98
|
}
|
|
73
99
|
});
|
|
74
|
-
let diff$1 = await InMemoryStore.prepareRollbackDiff(state,
|
|
75
|
-
rolledBackChains.forEach(rolledBack => Logging.childInfo(logger, {
|
|
76
|
-
msg: "Rollbacked",
|
|
77
|
-
chainId: rolledBack.chainId,
|
|
78
|
-
fromBlock: rolledBack.fromBlock,
|
|
79
|
-
toBlock: rolledBack.toBlock,
|
|
80
|
-
rollbackedEvents: rolledBack.rollbackedEvents
|
|
81
|
-
}));
|
|
100
|
+
let diff$1 = await InMemoryStore.prepareRollbackDiff(state, floors, IndexerState.committedCheckpointId(state) + 1n, rolledBackChains, rolledBackAddresses);
|
|
82
101
|
Logging.childTrace(logger, {
|
|
83
102
|
msg: "Rollback entity changes",
|
|
84
103
|
deleted: diff$1.deletedEntities,
|
|
85
104
|
upserted: diff$1.setEntities
|
|
86
105
|
});
|
|
87
106
|
IndexerState.recordRollbackSuccess(state, Performance.secondsSince(startTime), rollbackedProcessedEvents);
|
|
88
|
-
IndexerState.completeRollback(state,
|
|
107
|
+
IndexerState.completeRollback(state, Utils.Dict.mapValues(progressDiffByChain, diff => diff.eventsProcessed));
|
|
89
108
|
scheduleFetch();
|
|
90
109
|
return scheduleProcessing();
|
|
91
110
|
}
|
package/src/RollbackCommit.res
CHANGED
|
@@ -20,15 +20,13 @@ let register = (callback: callback) => {
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
// Fired after a rollback diff is durably written, once per affected chain
|
|
24
|
-
//
|
|
25
|
-
// the
|
|
26
|
-
|
|
27
|
-
let
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
->Array.flatMap(((chainIdKey, rollbackToBlock)) => {
|
|
31
|
-
let args = {chainId: chainIdKey->ChainId.normalizeOrThrow, rollbackToBlock}
|
|
23
|
+
// Fired after a rollback diff is durably written, once per affected chain, with
|
|
24
|
+
// the last valid block the rollback left that chain at. A throwing callback
|
|
25
|
+
// bubbles to the write loop's onError, crashing the indexer like a failed write.
|
|
26
|
+
let fire = async (~progressedChains: array<InternalTable.Chains.progressedChain>) => {
|
|
27
|
+
let _ = await progressedChains
|
|
28
|
+
->Array.flatMap(({chainId, progressBlockNumber}) => {
|
|
29
|
+
let args = {chainId, rollbackToBlock: progressBlockNumber}
|
|
32
30
|
callbacks->Array.map(callback => callback(args))
|
|
33
31
|
})
|
|
34
32
|
->Promise.all
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
-
import * as ChainId from "./ChainId.res.mjs";
|
|
4
3
|
import * as EnvioGlobal from "./EnvioGlobal.res.mjs";
|
|
5
4
|
|
|
6
5
|
let callbacks = EnvioGlobal.value.rollbackCommitCallbacks;
|
|
@@ -16,10 +15,10 @@ function register(callback) {
|
|
|
16
15
|
};
|
|
17
16
|
}
|
|
18
17
|
|
|
19
|
-
async function fire(
|
|
20
|
-
await Promise.all(
|
|
21
|
-
let args_chainId =
|
|
22
|
-
let args_rollbackToBlock = param
|
|
18
|
+
async function fire(progressedChains) {
|
|
19
|
+
await Promise.all(progressedChains.flatMap(param => {
|
|
20
|
+
let args_chainId = param.chainId;
|
|
21
|
+
let args_rollbackToBlock = param.progressBlockNumber;
|
|
23
22
|
let args = {
|
|
24
23
|
chainId: args_chainId,
|
|
25
24
|
rollbackToBlock: args_rollbackToBlock
|
|
@@ -33,4 +32,4 @@ export {
|
|
|
33
32
|
register,
|
|
34
33
|
fire,
|
|
35
34
|
}
|
|
36
|
-
/*
|
|
35
|
+
/* EnvioGlobal Not a pure module */
|
|
@@ -33,15 +33,15 @@ let make = (
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
let getSafeCheckpointId = (safeCheckpointTracking: t, ~sourceBlockNumber: int)
|
|
36
|
+
let getSafeCheckpointId = (safeCheckpointTracking: t, ~sourceBlockNumber: int): option<
|
|
37
|
+
Internal.checkpointId,
|
|
38
|
+
> => {
|
|
37
39
|
let safeBlockNumber = sourceBlockNumber - safeCheckpointTracking.maxReorgDepth
|
|
38
40
|
|
|
39
41
|
switch safeCheckpointTracking.checkpointIds {
|
|
40
|
-
| [] =>
|
|
41
|
-
| _
|
|
42
|
-
|
|
43
|
-
safeBlockNumber => 0n
|
|
44
|
-
| [checkpointId] => checkpointId
|
|
42
|
+
| [] => None
|
|
43
|
+
| _ if safeCheckpointTracking.checkpointBlockNumbers->Array.getUnsafe(0) > safeBlockNumber => None
|
|
44
|
+
| [checkpointId] => Some(checkpointId)
|
|
45
45
|
| _ => {
|
|
46
46
|
let trackingCheckpointsCount = safeCheckpointTracking.checkpointIds->Array.length
|
|
47
47
|
let result = ref(None)
|
|
@@ -52,16 +52,15 @@ let getSafeCheckpointId = (safeCheckpointTracking: t, ~sourceBlockNumber: int) =
|
|
|
52
52
|
safeCheckpointTracking.checkpointBlockNumbers->Array.getUnsafe(idx.contents) >
|
|
53
53
|
safeBlockNumber
|
|
54
54
|
) {
|
|
55
|
-
result :=
|
|
56
|
-
Some(safeCheckpointTracking.checkpointIds->Array.getUnsafe(idx.contents - 1))
|
|
55
|
+
result := Some(safeCheckpointTracking.checkpointIds->Array.getUnsafe(idx.contents - 1))
|
|
57
56
|
}
|
|
58
57
|
idx := idx.contents + 1
|
|
59
58
|
}
|
|
60
59
|
|
|
61
60
|
switch result.contents {
|
|
62
|
-
| Some(
|
|
61
|
+
| Some(_) => result.contents
|
|
63
62
|
| None =>
|
|
64
|
-
safeCheckpointTracking.checkpointIds->Array.getUnsafe(trackingCheckpointsCount - 1)
|
|
63
|
+
Some(safeCheckpointTracking.checkpointIds->Array.getUnsafe(trackingCheckpointsCount - 1))
|
|
65
64
|
}
|
|
66
65
|
}
|
|
67
66
|
}
|
|
@@ -75,7 +74,8 @@ let updateOnNewBatch = (
|
|
|
75
74
|
~batchCheckpointBlockNumbers: array<int>,
|
|
76
75
|
~batchCheckpointChainIds: array<ChainId.t>,
|
|
77
76
|
) => {
|
|
78
|
-
let safeCheckpointId =
|
|
77
|
+
let safeCheckpointId =
|
|
78
|
+
getSafeCheckpointId(safeCheckpointTracking, ~sourceBlockNumber)->Option.getOr(0n)
|
|
79
79
|
|
|
80
80
|
let mutCheckpointIds = []
|
|
81
81
|
let mutCheckpointBlockNumbers = []
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
3
4
|
|
|
4
5
|
function make(maxReorgDepth, shouldRollbackOnReorg, chainReorgCheckpoints) {
|
|
5
6
|
if (!(maxReorgDepth > 0 && shouldRollbackOnReorg)) {
|
|
@@ -22,10 +23,10 @@ function getSafeCheckpointId(safeCheckpointTracking, sourceBlockNumber) {
|
|
|
22
23
|
let safeBlockNumber = sourceBlockNumber - safeCheckpointTracking.maxReorgDepth | 0;
|
|
23
24
|
let match = safeCheckpointTracking.checkpointIds;
|
|
24
25
|
if (match.length === 0) {
|
|
25
|
-
return
|
|
26
|
+
return;
|
|
26
27
|
}
|
|
27
28
|
if (safeCheckpointTracking.checkpointBlockNumbers[0] > safeBlockNumber) {
|
|
28
|
-
return
|
|
29
|
+
return;
|
|
29
30
|
}
|
|
30
31
|
if (match.length === 1) {
|
|
31
32
|
return match[0];
|
|
@@ -39,16 +40,16 @@ function getSafeCheckpointId(safeCheckpointTracking, sourceBlockNumber) {
|
|
|
39
40
|
}
|
|
40
41
|
idx = idx + 1 | 0;
|
|
41
42
|
};
|
|
42
|
-
let
|
|
43
|
-
if (
|
|
44
|
-
return
|
|
43
|
+
let match$1 = result;
|
|
44
|
+
if (match$1 !== undefined) {
|
|
45
|
+
return result;
|
|
45
46
|
} else {
|
|
46
47
|
return safeCheckpointTracking.checkpointIds[trackingCheckpointsCount - 1 | 0];
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
function updateOnNewBatch(safeCheckpointTracking, sourceBlockNumber, chainId, batchCheckpointIds, batchCheckpointBlockNumbers, batchCheckpointChainIds) {
|
|
51
|
-
let safeCheckpointId = getSafeCheckpointId(safeCheckpointTracking, sourceBlockNumber);
|
|
52
|
+
let safeCheckpointId = Stdlib_Option.getOr(getSafeCheckpointId(safeCheckpointTracking, sourceBlockNumber), 0n);
|
|
52
53
|
let mutCheckpointIds = [];
|
|
53
54
|
let mutCheckpointBlockNumbers = [];
|
|
54
55
|
for (let idx = 0, idx_finish = safeCheckpointTracking.checkpointIds.length; idx < idx_finish; ++idx) {
|
package/src/SimulateItems.res
CHANGED
|
@@ -338,11 +338,12 @@ let parse = (
|
|
|
338
338
|
| None =>
|
|
339
339
|
switch blockJson {
|
|
340
340
|
| Some(bj) =>
|
|
341
|
-
switch
|
|
341
|
+
switch bj->(Utils.magic: JSON.t => dict<JSON.t>)->Dict.get("slot") {
|
|
342
342
|
| Some(v) =>
|
|
343
|
-
v
|
|
344
|
-
|
|
345
|
-
|
|
343
|
+
v
|
|
344
|
+
->(Utils.magic: JSON.t => Nullable.t<int>)
|
|
345
|
+
->Nullable.toOption
|
|
346
|
+
->Option.getOr(currentBlock.contents)
|
|
346
347
|
| None => currentBlock.contents
|
|
347
348
|
}
|
|
348
349
|
| None => currentBlock.contents
|
|
@@ -371,13 +372,23 @@ let parse = (
|
|
|
371
372
|
| None => []
|
|
372
373
|
}
|
|
373
374
|
}
|
|
374
|
-
let data = item.data
|
|
375
|
-
|
|
375
|
+
let data = switch (item.data, svmEventConfig.discriminator) {
|
|
376
|
+
| (Some(data), _) => data
|
|
377
|
+
| (None, Some(discriminator)) =>
|
|
378
|
+
discriminator
|
|
379
|
+
->String.replace("0x", "")
|
|
380
|
+
->NodeJs.Buffer.fromHex
|
|
381
|
+
->Uint8Array.fromArrayLikeOrIterable
|
|
382
|
+
| (None, None) => Uint8Array.fromLength(0)
|
|
383
|
+
}
|
|
384
|
+
let args = item.args->Option.getOr(Dict.make()->(Utils.magic: dict<unknown> => unknown))
|
|
376
385
|
let logs = item.logs->Option.map(logs =>
|
|
377
|
-
logs->Array.map(
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
386
|
+
logs->Array.map(
|
|
387
|
+
(log): SvmHyperSyncClient.EventItems.log => {
|
|
388
|
+
kind: log.kind->Null.fromOption,
|
|
389
|
+
message: log.message->Null.fromOption,
|
|
390
|
+
},
|
|
391
|
+
)
|
|
381
392
|
)
|
|
382
393
|
|
|
383
394
|
let liveRegistrations = liveRegistrationsFor(~config, ~chainId, ~eventConfig)
|
|
@@ -414,13 +425,13 @@ let parse = (
|
|
|
414
425
|
accountIndex: ?activity.transactionAccountIndex,
|
|
415
426
|
isSigner: ?activity.isSigner,
|
|
416
427
|
isWritable: ?activity.isWritable,
|
|
417
|
-
preBalance: ?activity.lamports->Option.flatMap(l => l.pre),
|
|
418
|
-
postBalance: ?activity.lamports->Option.flatMap(l => l.post),
|
|
419
|
-
mint: ?activity.token->Option.flatMap(t => t.mint),
|
|
420
|
-
owner: ?activity.token->Option.flatMap(t => t.owner),
|
|
421
|
-
decimals: ?activity.token->Option.flatMap(t => t.decimals),
|
|
422
|
-
preAmount: ?activity.token->Option.flatMap(t => t.preAmount),
|
|
423
|
-
postAmount: ?activity.token->Option.flatMap(t => t.postAmount),
|
|
428
|
+
preBalance: ?(activity.lamports->Option.flatMap(l => l.pre)),
|
|
429
|
+
postBalance: ?(activity.lamports->Option.flatMap(l => l.post)),
|
|
430
|
+
mint: ?(activity.token->Option.flatMap(t => t.mint)),
|
|
431
|
+
owner: ?(activity.token->Option.flatMap(t => t.owner)),
|
|
432
|
+
decimals: ?(activity.token->Option.flatMap(t => t.decimals)),
|
|
433
|
+
preAmount: ?(activity.token->Option.flatMap(t => t.preAmount)),
|
|
434
|
+
postAmount: ?(activity.token->Option.flatMap(t => t.postAmount)),
|
|
424
435
|
})
|
|
425
436
|
->ignore
|
|
426
437
|
)
|
|
@@ -456,7 +467,11 @@ let parse = (
|
|
|
456
467
|
accounts: accountArguments,
|
|
457
468
|
data,
|
|
458
469
|
isInner: item.isInner->Option.getOr(false),
|
|
459
|
-
|
|
470
|
+
// As the Rust client does: present exactly when this registration
|
|
471
|
+
// selected `args`.
|
|
472
|
+
args: onEventRegistration.fieldSelection.instructionFields->Utils.Set.has("args")
|
|
473
|
+
? Null.make(args)
|
|
474
|
+
: Null.null,
|
|
460
475
|
logs: logs->Null.fromOption,
|
|
461
476
|
},
|
|
462
477
|
~programName,
|
|
@@ -245,8 +245,12 @@ function parse(simulateItems, config, chainConfig, onEventRegistrations) {
|
|
|
245
245
|
}
|
|
246
246
|
}) : [];
|
|
247
247
|
}
|
|
248
|
-
let
|
|
249
|
-
let
|
|
248
|
+
let match$3 = rawJson.data;
|
|
249
|
+
let match$4 = eventConfig.discriminator;
|
|
250
|
+
let data = match$3 !== undefined ? match$3 : (
|
|
251
|
+
match$4 !== undefined ? Uint8Array.from(Buffer.from(match$4.replace("0x", ""), "hex")) : new Uint8Array(0)
|
|
252
|
+
);
|
|
253
|
+
let args$1 = Stdlib_Option.getOr(rawJson.args, {});
|
|
250
254
|
let logs = Stdlib_Option.map(rawJson.logs, logs => logs.map(log => ({
|
|
251
255
|
kind: Stdlib_Null.fromOption(log.kind),
|
|
252
256
|
message: Stdlib_Null.fromOption(log.message)
|
|
@@ -312,7 +316,7 @@ function parse(simulateItems, config, chainConfig, onEventRegistrations) {
|
|
|
312
316
|
accounts: accountArguments,
|
|
313
317
|
data: data,
|
|
314
318
|
isInner: Stdlib_Option.getOr(rawJson.isInner, false),
|
|
315
|
-
|
|
319
|
+
args: newrecord.fieldSelection.instructionFields.has("args") ? args$1 : null,
|
|
316
320
|
logs: Stdlib_Null.fromOption(logs)
|
|
317
321
|
}, match$1, match$2, eventConfig, newrecord.fieldSelection);
|
|
318
322
|
payload["srcAddress"] = programId;
|
|
@@ -329,14 +333,14 @@ function parse(simulateItems, config, chainConfig, onEventRegistrations) {
|
|
|
329
333
|
});
|
|
330
334
|
return;
|
|
331
335
|
}
|
|
332
|
-
let match$
|
|
333
|
-
let match$
|
|
334
|
-
let match$
|
|
335
|
-
match$
|
|
336
|
-
match$
|
|
336
|
+
let match$5 = rawJson.contract;
|
|
337
|
+
let match$6 = rawJson.event;
|
|
338
|
+
let match$7 = match$5 !== undefined && match$6 !== undefined ? [
|
|
339
|
+
match$5,
|
|
340
|
+
match$6
|
|
337
341
|
] : Stdlib_JsError.throwWithMessage(`simulate: Invalid item. Each item must have "contract" and "event" fields.`);
|
|
338
|
-
let eventName = match$
|
|
339
|
-
let contractName = match$
|
|
342
|
+
let eventName = match$7[1];
|
|
343
|
+
let contractName = match$7[0];
|
|
340
344
|
let ec$1 = findEventConfig(config, contractName, eventName);
|
|
341
345
|
let eventConfig$1 = ec$1 !== undefined ? ec$1 : Stdlib_JsError.throwWithMessage(`simulate: Event "` + eventName + `" not found on contract "` + contractName + `". Check that the contract and event names match your config.yaml.`);
|
|
342
346
|
let json = rawJson.params;
|
|
@@ -359,32 +363,32 @@ function parse(simulateItems, config, chainConfig, onEventRegistrations) {
|
|
|
359
363
|
let blockJson$2 = (blockJson$1 == null) ? undefined : Primitive_option.some(blockJson$1);
|
|
360
364
|
let transactionJson = rawJson.transaction;
|
|
361
365
|
let transactionJson$1 = (transactionJson == null) ? undefined : Primitive_option.some(transactionJson);
|
|
362
|
-
let match$
|
|
363
|
-
let match$
|
|
364
|
-
switch (match$
|
|
366
|
+
let match$8 = config.ecosystem.name;
|
|
367
|
+
let match$9;
|
|
368
|
+
switch (match$8) {
|
|
365
369
|
case "evm" :
|
|
366
370
|
let block$2 = parseEvmSimulateBlock(currentBlock.contents, blockJson$2);
|
|
367
|
-
match$
|
|
371
|
+
match$9 = [
|
|
368
372
|
block$2,
|
|
369
373
|
block$2.number
|
|
370
374
|
];
|
|
371
375
|
break;
|
|
372
376
|
case "fuel" :
|
|
373
377
|
let block$3 = parseFuelSimulateBlock(currentBlock.contents, blockJson$2);
|
|
374
|
-
match$
|
|
378
|
+
match$9 = [
|
|
375
379
|
block$3,
|
|
376
380
|
block$3.height
|
|
377
381
|
];
|
|
378
382
|
break;
|
|
379
383
|
case "svm" :
|
|
380
|
-
match$
|
|
384
|
+
match$9 = Stdlib_JsError.throwWithMessage("simulate is not supported for SVM ecosystem");
|
|
381
385
|
break;
|
|
382
386
|
}
|
|
383
|
-
let blockNumber = match$
|
|
384
|
-
let block$4 = match$
|
|
385
|
-
let match$
|
|
387
|
+
let blockNumber = match$9[1];
|
|
388
|
+
let block$4 = match$9[0];
|
|
389
|
+
let match$10 = config.ecosystem.name;
|
|
386
390
|
let transaction$1;
|
|
387
|
-
switch (match$
|
|
391
|
+
switch (match$10) {
|
|
388
392
|
case "evm" :
|
|
389
393
|
transaction$1 = parseEvmSimulateTransaction(transactionJson$1);
|
|
390
394
|
break;
|
|
@@ -411,9 +415,9 @@ function parse(simulateItems, config, chainConfig, onEventRegistrations) {
|
|
|
411
415
|
}
|
|
412
416
|
});
|
|
413
417
|
if (Utils.$$Array.isEmpty(liveRegistrations$1)) {
|
|
414
|
-
let match$
|
|
418
|
+
let match$11 = ChainMap.values(config.chainMap).length;
|
|
415
419
|
Stdlib_JsError.throwWithMessage(`simulate: no handler runs for event "` + eventName + `" on contract "` + contractName + `"` + (
|
|
416
|
-
match$
|
|
420
|
+
match$11 !== 1 ? ` on chain ` + ChainId.toString(chainId) : ""
|
|
417
421
|
) + `. Register a handler with indexer.onEvent (and check any \`where\` filter isn't excluding this chain) before simulating it.`);
|
|
418
422
|
}
|
|
419
423
|
liveRegistrations$1.forEach(reg => {
|