envio 3.3.2 → 3.4.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/package.json +6 -6
- package/src/Api.res +1 -8
- package/src/Api.res.mjs +1 -5
- package/src/ChainState.res +6 -1
- package/src/ChainState.res.mjs +4 -3
- package/src/Config.res +33 -4
- package/src/Config.res.mjs +34 -5
- package/src/Core.res +30 -19
- package/src/Core.res.mjs +5 -5
- package/src/EnvioGlobal.res +0 -2
- package/src/EnvioGlobal.res.mjs +0 -1
- package/src/ExitOnCaughtUp.res +6 -2
- package/src/ExitOnCaughtUp.res.mjs +4 -0
- package/src/FetchState.res +3 -3
- package/src/HandlerRegister.res +357 -434
- package/src/HandlerRegister.res.mjs +202 -242
- package/src/HandlerRegister.resi +7 -15
- package/src/IndexerState.res +10 -0
- package/src/IndexerState.res.mjs +9 -3
- package/src/IndexerState.resi +3 -0
- package/src/Internal.res +10 -1
- package/src/Main.res.mjs +4 -4
- package/src/PgStorage.res +16 -1
- package/src/PgStorage.res.mjs +9 -1
- package/src/SimulateItems.res +61 -40
- package/src/SimulateItems.res.mjs +37 -21
- package/src/TestIndexer.res +446 -453
- package/src/TestIndexer.res.mjs +320 -343
- package/src/bindings/ClickHouse.res +68 -2
- package/src/bindings/ClickHouse.res.mjs +47 -2
- package/src/sources/EvmChain.res +1 -1
- package/src/sources/EvmChain.res.mjs +2 -2
- package/src/sources/FuelHyperSync.res +74 -0
- package/src/sources/FuelHyperSync.res.mjs +80 -0
- package/src/sources/FuelHyperSync.resi +22 -0
- package/src/sources/FuelHyperSyncClient.res +120 -0
- package/src/sources/FuelHyperSyncClient.res.mjs +71 -0
- package/src/sources/FuelHyperSyncSource.res +257 -0
- package/src/sources/FuelHyperSyncSource.res.mjs +252 -0
- package/src/sources/HyperSyncClient.res +2 -2
- package/src/sources/HyperSyncClient.res.mjs +1 -1
- package/src/sources/SvmHyperSyncClient.res +139 -102
- package/src/sources/SvmHyperSyncClient.res.mjs +45 -5
- package/src/sources/SvmHyperSyncSource.res +60 -440
- package/src/sources/SvmHyperSyncSource.res.mjs +42 -363
- package/src/TestIndexerProxyStorage.res +0 -196
- package/src/TestIndexerProxyStorage.res.mjs +0 -121
- package/src/TestIndexerWorker.res +0 -4
- package/src/TestIndexerWorker.res.mjs +0 -7
- package/src/sources/EventRouter.res +0 -165
- package/src/sources/EventRouter.res.mjs +0 -153
- package/src/sources/HyperFuel.res +0 -179
- package/src/sources/HyperFuel.res.mjs +0 -146
- package/src/sources/HyperFuel.resi +0 -36
- package/src/sources/HyperFuelClient.res +0 -127
- package/src/sources/HyperFuelClient.res.mjs +0 -20
- package/src/sources/HyperFuelSource.res +0 -502
- package/src/sources/HyperFuelSource.res.mjs +0 -481
- /package/src/sources/{HyperSyncSource.res → EvmHyperSyncSource.res} +0 -0
- /package/src/sources/{HyperSyncSource.res.mjs → EvmHyperSyncSource.res.mjs} +0 -0
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
3
|
import * as Source from "./Source.res.mjs";
|
|
4
|
-
import * as EventRouter from "./EventRouter.res.mjs";
|
|
5
4
|
import * as Performance from "../bindings/Performance.res.mjs";
|
|
6
5
|
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
7
6
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
@@ -9,139 +8,9 @@ import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js
|
|
|
9
8
|
import * as SvmHyperSyncClient from "./SvmHyperSyncClient.res.mjs";
|
|
10
9
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
11
10
|
|
|
12
|
-
function
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (programIdString === "") {
|
|
16
|
-
return [];
|
|
17
|
-
}
|
|
18
|
-
let match = cfg.discriminator;
|
|
19
|
-
let match$1 = cfg.discriminatorByteLen;
|
|
20
|
-
let match$2;
|
|
21
|
-
if (match !== undefined) {
|
|
22
|
-
switch (match$1) {
|
|
23
|
-
case 1 :
|
|
24
|
-
match$2 = [
|
|
25
|
-
[match],
|
|
26
|
-
undefined,
|
|
27
|
-
undefined,
|
|
28
|
-
undefined
|
|
29
|
-
];
|
|
30
|
-
break;
|
|
31
|
-
case 2 :
|
|
32
|
-
match$2 = [
|
|
33
|
-
undefined,
|
|
34
|
-
[match],
|
|
35
|
-
undefined,
|
|
36
|
-
undefined
|
|
37
|
-
];
|
|
38
|
-
break;
|
|
39
|
-
case 4 :
|
|
40
|
-
match$2 = [
|
|
41
|
-
undefined,
|
|
42
|
-
undefined,
|
|
43
|
-
[match],
|
|
44
|
-
undefined
|
|
45
|
-
];
|
|
46
|
-
break;
|
|
47
|
-
case 8 :
|
|
48
|
-
match$2 = [
|
|
49
|
-
undefined,
|
|
50
|
-
undefined,
|
|
51
|
-
undefined,
|
|
52
|
-
[match]
|
|
53
|
-
];
|
|
54
|
-
break;
|
|
55
|
-
default:
|
|
56
|
-
match$2 = [
|
|
57
|
-
undefined,
|
|
58
|
-
undefined,
|
|
59
|
-
undefined,
|
|
60
|
-
undefined
|
|
61
|
-
];
|
|
62
|
-
}
|
|
63
|
-
} else {
|
|
64
|
-
match$2 = [
|
|
65
|
-
undefined,
|
|
66
|
-
undefined,
|
|
67
|
-
undefined,
|
|
68
|
-
undefined
|
|
69
|
-
];
|
|
70
|
-
}
|
|
71
|
-
let d8 = match$2[3];
|
|
72
|
-
let d4 = match$2[2];
|
|
73
|
-
let d2 = match$2[1];
|
|
74
|
-
let d1 = match$2[0];
|
|
75
|
-
let gs = cfg.accountFilters;
|
|
76
|
-
let groups = gs.length !== 0 ? gs : [[]];
|
|
77
|
-
return groups.map(group => {
|
|
78
|
-
let pick = position => Stdlib_Array.filterMap(group, f => {
|
|
79
|
-
if (f.position === position) {
|
|
80
|
-
return f.values;
|
|
81
|
-
}
|
|
82
|
-
})[0];
|
|
83
|
-
return {
|
|
84
|
-
programId: [programIdString],
|
|
85
|
-
d1: d1,
|
|
86
|
-
d2: d2,
|
|
87
|
-
d4: d4,
|
|
88
|
-
d8: d8,
|
|
89
|
-
a0: pick(0),
|
|
90
|
-
a1: pick(1),
|
|
91
|
-
a2: pick(2),
|
|
92
|
-
a3: pick(3),
|
|
93
|
-
a4: pick(4),
|
|
94
|
-
a5: pick(5),
|
|
95
|
-
isInner: cfg.isInner
|
|
96
|
-
};
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
function synthLogIndex(instr) {
|
|
102
|
-
let tx = instr.transactionIndex;
|
|
103
|
-
let addrSum = Stdlib_Array.reduce(instr.instructionAddress, 0, (acc, n) => ((acc << 10) + n | 0) + 1 | 0);
|
|
104
|
-
return (tx << 16) + addrSum | 0;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function serializeInstructionAddress(addr) {
|
|
108
|
-
return addr.map(n => n.toString()).join(",");
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function buildProgramSchemas(eventConfigs) {
|
|
112
|
-
let descriptorsByProgram = {};
|
|
113
|
-
eventConfigs.forEach(ec => {
|
|
114
|
-
let programIdString = ec.programId;
|
|
115
|
-
if (programIdString === "") {
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
let hasSchema = ec.accounts.length !== 0 || ec.args !== null;
|
|
119
|
-
let discriminator = Stdlib_Option.getOr(ec.discriminator, "");
|
|
120
|
-
if (!(hasSchema && discriminator !== "")) {
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
let other = ec.definedTypes;
|
|
124
|
-
let definedTypes;
|
|
125
|
-
definedTypes = other === null ? ({}) : other;
|
|
126
|
-
let existing = descriptorsByProgram[programIdString];
|
|
127
|
-
let descriptor = existing !== undefined ? Primitive_option.valFromOption(existing) : ({
|
|
128
|
-
programId: programIdString,
|
|
129
|
-
definedTypes: definedTypes,
|
|
130
|
-
instructions: []
|
|
131
|
-
});
|
|
132
|
-
let instruction = {
|
|
133
|
-
name: ec.name,
|
|
134
|
-
discriminator: discriminator,
|
|
135
|
-
accounts: ec.accounts,
|
|
136
|
-
args: ec.args
|
|
137
|
-
};
|
|
138
|
-
descriptorsByProgram[programIdString] = {
|
|
139
|
-
programId: descriptor.programId,
|
|
140
|
-
definedTypes: descriptor.definedTypes,
|
|
141
|
-
instructions: descriptor.instructions.concat([instruction])
|
|
142
|
-
};
|
|
143
|
-
});
|
|
144
|
-
return Object.values(descriptorsByProgram).map(descriptor => JSON.stringify(descriptor));
|
|
11
|
+
function synthLogIndex(transactionIndex, instructionAddress) {
|
|
12
|
+
let addrSum = Stdlib_Array.reduce(instructionAddress, 0, (acc, n) => ((acc << 10) + n | 0) + 1 | 0);
|
|
13
|
+
return (transactionIndex << 16) + addrSum | 0;
|
|
145
14
|
}
|
|
146
15
|
|
|
147
16
|
function parseDecoded(d) {
|
|
@@ -165,200 +34,45 @@ function parseDecoded(d) {
|
|
|
165
34
|
};
|
|
166
35
|
}
|
|
167
36
|
|
|
168
|
-
function toSvmInstruction(
|
|
37
|
+
function toSvmInstruction(item, programName, instructionName) {
|
|
169
38
|
return {
|
|
170
39
|
programName: programName,
|
|
171
40
|
instructionName: instructionName,
|
|
172
|
-
programId:
|
|
173
|
-
data:
|
|
174
|
-
accounts:
|
|
175
|
-
instructionAddress:
|
|
176
|
-
isInner:
|
|
177
|
-
d1:
|
|
178
|
-
d2:
|
|
179
|
-
d4:
|
|
180
|
-
d8:
|
|
181
|
-
params: Stdlib_Option.map(
|
|
182
|
-
logs: logs
|
|
41
|
+
programId: item.programId,
|
|
42
|
+
data: item.data,
|
|
43
|
+
accounts: item.accounts,
|
|
44
|
+
instructionAddress: item.instructionAddress,
|
|
45
|
+
isInner: item.isInner,
|
|
46
|
+
d1: item.d1,
|
|
47
|
+
d2: item.d2,
|
|
48
|
+
d4: item.d4,
|
|
49
|
+
d8: item.d8,
|
|
50
|
+
params: Stdlib_Option.map(item.decoded, parseDecoded),
|
|
51
|
+
logs: Stdlib_Option.map(item.logs, logs => logs.map(log => ({
|
|
52
|
+
kind: log.kind,
|
|
53
|
+
message: log.message
|
|
54
|
+
})))
|
|
183
55
|
};
|
|
184
56
|
}
|
|
185
57
|
|
|
186
|
-
function probeRouter(router, programId, instr, byteLengthsDesc, contractAddress, contractNameByAddress) {
|
|
187
|
-
let probe = dN => {
|
|
188
|
-
let tag = EventRouter.getSvmEventId(programId, dN);
|
|
189
|
-
return EventRouter.get(router, tag, contractAddress, contractNameByAddress);
|
|
190
|
-
};
|
|
191
|
-
let result = Stdlib_Array.reduce(byteLengthsDesc, undefined, (acc, len) => {
|
|
192
|
-
if (acc !== undefined) {
|
|
193
|
-
return acc;
|
|
194
|
-
}
|
|
195
|
-
let candidate;
|
|
196
|
-
switch (len) {
|
|
197
|
-
case 1 :
|
|
198
|
-
candidate = instr.d1;
|
|
199
|
-
break;
|
|
200
|
-
case 2 :
|
|
201
|
-
candidate = instr.d2;
|
|
202
|
-
break;
|
|
203
|
-
case 4 :
|
|
204
|
-
candidate = instr.d4;
|
|
205
|
-
break;
|
|
206
|
-
case 8 :
|
|
207
|
-
candidate = instr.d8;
|
|
208
|
-
break;
|
|
209
|
-
default:
|
|
210
|
-
candidate = undefined;
|
|
211
|
-
}
|
|
212
|
-
if (candidate !== undefined) {
|
|
213
|
-
return probe(candidate);
|
|
214
|
-
}
|
|
215
|
-
});
|
|
216
|
-
if (result !== undefined) {
|
|
217
|
-
return result;
|
|
218
|
-
} else {
|
|
219
|
-
return probe(undefined);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
function toQueryTxField(field) {
|
|
224
|
-
switch (field) {
|
|
225
|
-
case "signatures" :
|
|
226
|
-
return "signatures";
|
|
227
|
-
case "feePayer" :
|
|
228
|
-
return "fee_payer";
|
|
229
|
-
case "success" :
|
|
230
|
-
return "success";
|
|
231
|
-
case "err" :
|
|
232
|
-
return "err";
|
|
233
|
-
case "fee" :
|
|
234
|
-
return "fee";
|
|
235
|
-
case "computeUnitsConsumed" :
|
|
236
|
-
return "compute_units_consumed";
|
|
237
|
-
case "accountKeys" :
|
|
238
|
-
return "account_keys";
|
|
239
|
-
case "recentBlockhash" :
|
|
240
|
-
return "recent_blockhash";
|
|
241
|
-
case "version" :
|
|
242
|
-
return "version";
|
|
243
|
-
case "transactionIndex" :
|
|
244
|
-
case "tokenBalances" :
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
function toQueryBlockField(field) {
|
|
250
|
-
switch (field) {
|
|
251
|
-
case "height" :
|
|
252
|
-
return "block_height";
|
|
253
|
-
case "parentSlot" :
|
|
254
|
-
return "parent_slot";
|
|
255
|
-
case "parentHash" :
|
|
256
|
-
return "parent_blockhash";
|
|
257
|
-
default:
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
58
|
function make(param) {
|
|
263
59
|
let onEventRegistrations = param.onEventRegistrations;
|
|
264
60
|
let chain = param.chain;
|
|
265
|
-
let
|
|
266
|
-
let
|
|
267
|
-
let client = SvmHyperSyncClient.make(param.endpointUrl, param.apiToken, param.clientTimeoutMillis, undefined, undefined, undefined, programSchemas.length !== 0 ? programSchemas : undefined);
|
|
268
|
-
let match = EventRouter.fromSvmEventConfigsOrThrow(onEventRegistrations, chain);
|
|
269
|
-
let eventRouter = match[0];
|
|
270
|
-
let orderingByProgram = {};
|
|
271
|
-
match[1].forEach(o => {
|
|
272
|
-
orderingByProgram[o.programId] = o.byteLengthsDesc;
|
|
273
|
-
});
|
|
274
|
-
let needsLogs = eventConfigs.some(cfg => cfg.includeLogs);
|
|
275
|
-
let selectedTxFields = new Set();
|
|
276
|
-
eventConfigs.forEach(cfg => {
|
|
277
|
-
cfg.selectedTransactionFields.forEach(field => {
|
|
278
|
-
selectedTxFields.add(field);
|
|
279
|
-
});
|
|
280
|
-
});
|
|
281
|
-
let needsTokenBalances = selectedTxFields.has("tokenBalances");
|
|
282
|
-
let fields = [
|
|
283
|
-
"slot",
|
|
284
|
-
"transaction_index"
|
|
285
|
-
];
|
|
286
|
-
Array.from(selectedTxFields).forEach(field => {
|
|
287
|
-
let queryField = toQueryTxField(field);
|
|
288
|
-
if (queryField !== undefined) {
|
|
289
|
-
fields.push(queryField);
|
|
290
|
-
return;
|
|
291
|
-
}
|
|
292
|
-
});
|
|
293
|
-
let needsTransactions = Array.from(selectedTxFields).some(field => {
|
|
294
|
-
switch (field) {
|
|
295
|
-
case "transactionIndex" :
|
|
296
|
-
case "tokenBalances" :
|
|
297
|
-
return false;
|
|
298
|
-
default:
|
|
299
|
-
return true;
|
|
300
|
-
}
|
|
301
|
-
});
|
|
302
|
-
let fields$1 = [
|
|
303
|
-
"slot",
|
|
304
|
-
"blockhash",
|
|
305
|
-
"block_time"
|
|
306
|
-
];
|
|
307
|
-
let selected = new Set();
|
|
308
|
-
eventConfigs.forEach(cfg => {
|
|
309
|
-
cfg.selectedBlockFields.forEach(field => {
|
|
310
|
-
selected.add(field);
|
|
311
|
-
});
|
|
312
|
-
});
|
|
313
|
-
selected.forEach(field => {
|
|
314
|
-
let queryField = toQueryBlockField(field);
|
|
315
|
-
if (queryField !== undefined) {
|
|
316
|
-
fields$1.push(queryField);
|
|
317
|
-
return;
|
|
318
|
-
}
|
|
319
|
-
});
|
|
320
|
-
let getItemsOrThrow = async (fromBlock, toBlock, param, contractNameByAddress, knownHeight, param$1, param$2, itemsTarget, retry, logger) => {
|
|
61
|
+
let client = SvmHyperSyncClient.make(param.endpointUrl, param.apiToken, param.clientTimeoutMillis, undefined, undefined, undefined, SvmHyperSyncClient.Registration.fromOnEventRegistrations(onEventRegistrations));
|
|
62
|
+
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, param, knownHeight, param$1, selection, itemsTarget, retry, param$2) => {
|
|
321
63
|
let totalTimeRef = Performance.now();
|
|
322
64
|
let pageFetchRef = Performance.now();
|
|
323
|
-
let
|
|
324
|
-
let fields_block = fields$1;
|
|
325
|
-
let fields_transaction = needsTransactions ? fields : undefined;
|
|
326
|
-
let fields_log = needsLogs ? [
|
|
327
|
-
"slot",
|
|
328
|
-
"transaction_index",
|
|
329
|
-
"instruction_address",
|
|
330
|
-
"kind",
|
|
331
|
-
"message"
|
|
332
|
-
] : undefined;
|
|
333
|
-
let fields_tokenBalance = needsTokenBalances ? [
|
|
334
|
-
"slot",
|
|
335
|
-
"transaction_index",
|
|
336
|
-
"account",
|
|
337
|
-
"mint",
|
|
338
|
-
"owner",
|
|
339
|
-
"pre_amount",
|
|
340
|
-
"post_amount"
|
|
341
|
-
] : undefined;
|
|
342
|
-
let fields$2 = {
|
|
343
|
-
block: fields_block,
|
|
344
|
-
transaction: fields_transaction,
|
|
345
|
-
log: fields_log,
|
|
346
|
-
tokenBalance: fields_tokenBalance
|
|
347
|
-
};
|
|
348
|
-
let query_toSlot = Stdlib_Option.map(toBlock, toBlock => toBlock + 1 | 0);
|
|
349
|
-
let query_instructions = instructionSelections;
|
|
350
|
-
let query_fields = fields$2;
|
|
351
|
-
let query_maxNumInstructions = itemsTarget;
|
|
65
|
+
let query_registrationIndexes = selection.onEventRegistrations.map(reg => reg.index);
|
|
352
66
|
let query = {
|
|
353
67
|
fromSlot: fromBlock,
|
|
354
|
-
toSlot:
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
68
|
+
toSlot: toBlock,
|
|
69
|
+
maxNumInstructions: itemsTarget,
|
|
70
|
+
registrationIndexes: query_registrationIndexes,
|
|
71
|
+
addressesByContractName: addressesByContractName
|
|
358
72
|
};
|
|
359
73
|
let match;
|
|
360
74
|
try {
|
|
361
|
-
match = await client.
|
|
75
|
+
match = await client.getEventItems(query);
|
|
362
76
|
} catch (raw_exn) {
|
|
363
77
|
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
364
78
|
throw {
|
|
@@ -384,60 +98,31 @@ function make(param) {
|
|
|
384
98
|
}];
|
|
385
99
|
let parsingRef = Performance.now();
|
|
386
100
|
let blockTimeBySlot = {};
|
|
387
|
-
resp.
|
|
101
|
+
resp.blocks.forEach(b => {
|
|
388
102
|
let t = b.blockTime;
|
|
389
103
|
if (t !== undefined) {
|
|
390
104
|
blockTimeBySlot[b.slot.toString()] = t;
|
|
391
105
|
return;
|
|
392
106
|
}
|
|
393
107
|
});
|
|
394
|
-
let
|
|
395
|
-
|
|
396
|
-
let
|
|
397
|
-
let
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
existing.push(log);
|
|
408
|
-
} else {
|
|
409
|
-
logsByKey[key] = [log];
|
|
410
|
-
}
|
|
411
|
-
});
|
|
412
|
-
let parsedQueueItems = [];
|
|
413
|
-
resp.data.instructions.forEach(instr => {
|
|
414
|
-
let programId = instr.programId;
|
|
415
|
-
let byteLengths = Stdlib_Option.getOr(orderingByProgram[instr.programId], []);
|
|
416
|
-
let contractAddress = instr.programId;
|
|
417
|
-
let maybeConfig = probeRouter(eventRouter, programId, instr, byteLengths, contractAddress, contractNameByAddress);
|
|
418
|
-
if (maybeConfig !== undefined && instr.isCommitted) {
|
|
419
|
-
let eventConfig = maybeConfig.eventConfig;
|
|
420
|
-
let logKey = instr.slot.toString() + ":" + instr.transactionIndex.toString() + ":" + serializeInstructionAddress(instr.instructionAddress);
|
|
421
|
-
let maybeLogs = Stdlib_Option.map(logsByKey[logKey], logs => logs.map(log => ({
|
|
422
|
-
kind: Stdlib_Option.getOr(log.kind, ""),
|
|
423
|
-
message: Stdlib_Option.getOr(log.message, "")
|
|
424
|
-
})));
|
|
425
|
-
let payload = toSvmInstruction(instr, eventConfig.contractName, eventConfig.name, eventConfig.includeLogs ? maybeLogs : undefined);
|
|
426
|
-
parsedQueueItems.push({
|
|
427
|
-
kind: 0,
|
|
428
|
-
onEventRegistration: maybeConfig,
|
|
429
|
-
chain: chain,
|
|
430
|
-
blockNumber: instr.slot,
|
|
431
|
-
logIndex: synthLogIndex(instr),
|
|
432
|
-
transactionIndex: instr.transactionIndex,
|
|
433
|
-
payload: payload
|
|
434
|
-
});
|
|
435
|
-
}
|
|
108
|
+
let parsedQueueItems = resp.items.map(item => {
|
|
109
|
+
let onEventRegistration = onEventRegistrations[item.onEventRegistrationIndex];
|
|
110
|
+
let eventConfig = onEventRegistration.eventConfig;
|
|
111
|
+
let payload = toSvmInstruction(item, eventConfig.contractName, eventConfig.name);
|
|
112
|
+
return {
|
|
113
|
+
kind: 0,
|
|
114
|
+
onEventRegistration: onEventRegistration,
|
|
115
|
+
chain: chain,
|
|
116
|
+
blockNumber: item.slot,
|
|
117
|
+
logIndex: synthLogIndex(item.transactionIndex, item.instructionAddress),
|
|
118
|
+
transactionIndex: item.transactionIndex,
|
|
119
|
+
payload: payload
|
|
120
|
+
};
|
|
436
121
|
});
|
|
437
122
|
let parsingTimeElapsed = Performance.secondsSince(parsingRef);
|
|
438
123
|
let highestSlot = resp.nextSlot - 1 | 0;
|
|
439
124
|
let latestBlockTime = Stdlib_Option.getOr(blockTimeBySlot[highestSlot.toString()], 0);
|
|
440
|
-
let blockHashes = resp.
|
|
125
|
+
let blockHashes = resp.blocks.map(b => ({
|
|
441
126
|
blockHash: b.blockhash,
|
|
442
127
|
blockNumber: b.slot
|
|
443
128
|
}));
|
|
@@ -578,15 +263,9 @@ function make(param) {
|
|
|
578
263
|
}
|
|
579
264
|
|
|
580
265
|
export {
|
|
581
|
-
buildInstructionSelections,
|
|
582
266
|
synthLogIndex,
|
|
583
|
-
serializeInstructionAddress,
|
|
584
|
-
buildProgramSchemas,
|
|
585
267
|
parseDecoded,
|
|
586
268
|
toSvmInstruction,
|
|
587
|
-
probeRouter,
|
|
588
|
-
toQueryTxField,
|
|
589
|
-
toQueryBlockField,
|
|
590
269
|
make,
|
|
591
270
|
}
|
|
592
|
-
/*
|
|
271
|
+
/* SvmHyperSyncClient Not a pure module */
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
// Message types for communication between worker and main thread
|
|
2
|
-
type requestId = int
|
|
3
|
-
|
|
4
|
-
// Serializable change with entity as JSON (for worker thread messaging)
|
|
5
|
-
@tag("type")
|
|
6
|
-
type serializableChange =
|
|
7
|
-
| @as("SET") Set({entityId: string, entity: JSON.t, checkpointId: bigint})
|
|
8
|
-
| @as("DELETE") Delete({entityId: string, checkpointId: bigint})
|
|
9
|
-
|
|
10
|
-
type serializableUpdatedEntity = {
|
|
11
|
-
entityName: string,
|
|
12
|
-
changes: array<serializableChange>,
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// Worker -> Main thread payloads
|
|
16
|
-
@tag("type")
|
|
17
|
-
type workerPayload =
|
|
18
|
-
| @as("load")
|
|
19
|
-
Load({
|
|
20
|
-
tableName: string,
|
|
21
|
-
// Leaf field values are JSON-serialized with the table's field schemas
|
|
22
|
-
filter: EntityFilter.t,
|
|
23
|
-
})
|
|
24
|
-
| @as("writeBatch")
|
|
25
|
-
WriteBatch({
|
|
26
|
-
updatedEntities: array<serializableUpdatedEntity>,
|
|
27
|
-
checkpointIds: array<bigint>,
|
|
28
|
-
checkpointChainIds: array<int>,
|
|
29
|
-
checkpointBlockNumbers: array<int>,
|
|
30
|
-
checkpointBlockHashes: array<Null.t<string>>,
|
|
31
|
-
checkpointEventsProcessed: array<int>,
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
// Main thread -> Worker payloads
|
|
35
|
-
@tag("type")
|
|
36
|
-
type mainPayload =
|
|
37
|
-
| @as("response") Response({data: JSON.t})
|
|
38
|
-
| @as("error") Error({message: string})
|
|
39
|
-
|
|
40
|
-
// Message wrapper with id
|
|
41
|
-
type message<'payload> = {id: requestId, payload: 'payload}
|
|
42
|
-
type workerMessage = message<workerPayload>
|
|
43
|
-
type mainMessage = message<mainPayload>
|
|
44
|
-
|
|
45
|
-
// Pending request tracker
|
|
46
|
-
type pendingRequest = {
|
|
47
|
-
resolve: JSON.t => unit,
|
|
48
|
-
reject: exn => unit,
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
type t = {
|
|
52
|
-
parentPort: NodeJs.WorkerThreads.messagePort,
|
|
53
|
-
initialState: Persistence.initialState,
|
|
54
|
-
pendingRequests: dict<pendingRequest>,
|
|
55
|
-
mutable requestCounter: int,
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
let make = (~parentPort, ~initialState): t => {
|
|
59
|
-
let proxy = {
|
|
60
|
-
parentPort,
|
|
61
|
-
initialState,
|
|
62
|
-
pendingRequests: Dict.make(),
|
|
63
|
-
requestCounter: 0,
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Set up message listener for responses from main thread
|
|
67
|
-
parentPort->NodeJs.WorkerThreads.onPortMessage((msg: mainMessage) => {
|
|
68
|
-
let idStr = msg.id->Int.toString
|
|
69
|
-
let {resolve, reject} = switch proxy.pendingRequests->Utils.Dict.dangerouslyGetNonOption(
|
|
70
|
-
idStr,
|
|
71
|
-
) {
|
|
72
|
-
| Some(pending) => pending
|
|
73
|
-
| None => JsError.throwWithMessage(`TestIndexer: No pending request found for id ${idStr}`)
|
|
74
|
-
}
|
|
75
|
-
Dict.delete(proxy.pendingRequests->Obj.magic, idStr)
|
|
76
|
-
|
|
77
|
-
switch msg.payload {
|
|
78
|
-
| Response({data}) => resolve(data)
|
|
79
|
-
| Error({message}) => reject(Utils.Error.make(message))
|
|
80
|
-
}
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
proxy
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
let nextRequestId = (proxy: t): requestId => {
|
|
87
|
-
proxy.requestCounter = proxy.requestCounter + 1
|
|
88
|
-
proxy.requestCounter
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
let sendRequest = (proxy: t, ~payload: workerPayload): promise<JSON.t> => {
|
|
92
|
-
Promise.make((resolve, reject) => {
|
|
93
|
-
let id = proxy->nextRequestId
|
|
94
|
-
proxy.pendingRequests->Dict.set(id->Int.toString, {resolve, reject})
|
|
95
|
-
proxy.parentPort->NodeJs.WorkerThreads.postMessage({id, payload})
|
|
96
|
-
})
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
let makeStorage = (proxy: t): Persistence.storage => {
|
|
100
|
-
name: "test-proxy",
|
|
101
|
-
isInitialized: async () => true,
|
|
102
|
-
initialize: async (~chainConfigs as _=?, ~entities as _=?, ~enums as _=?, ~envioInfo as _) => {
|
|
103
|
-
JsError.throwWithMessage(
|
|
104
|
-
"TestIndexer: initialize should not be called. Use resumeInitialState instead.",
|
|
105
|
-
)
|
|
106
|
-
},
|
|
107
|
-
resumeInitialState: async () => proxy.initialState,
|
|
108
|
-
loadOrThrow: async (~filter, ~table: Table.table) => {
|
|
109
|
-
let serializeLeafOrThrow = (~fieldName, ~fieldValue: unknown, ~isArray) => {
|
|
110
|
-
let queryField = switch table->Table.queryFields->Dict.get(fieldName) {
|
|
111
|
-
| Some(queryField) => queryField
|
|
112
|
-
| None =>
|
|
113
|
-
JsError.throwWithMessage(
|
|
114
|
-
`TestIndexer: The table "${table.tableName}" doesn't have the field "${fieldName}"`,
|
|
115
|
-
)
|
|
116
|
-
}
|
|
117
|
-
fieldValue
|
|
118
|
-
->S.reverseConvertToJsonOrThrow(
|
|
119
|
-
isArray ? queryField.arrayFieldSchema : queryField.fieldSchema,
|
|
120
|
-
)
|
|
121
|
-
->(Utils.magic: JSON.t => unknown)
|
|
122
|
-
}
|
|
123
|
-
let response = await proxy->sendRequest(
|
|
124
|
-
~payload=Load({
|
|
125
|
-
tableName: table.tableName,
|
|
126
|
-
// Field values must be JSON-safe to survive the worker thread boundary
|
|
127
|
-
filter: filter->EntityFilter.mapValues(~mapValue=serializeLeafOrThrow),
|
|
128
|
-
}),
|
|
129
|
-
)
|
|
130
|
-
response->S.parseOrThrow(table->Table.rowsSchema)
|
|
131
|
-
},
|
|
132
|
-
writeBatch: async (
|
|
133
|
-
~batch,
|
|
134
|
-
~rollback as _,
|
|
135
|
-
~isInReorgThreshold as _,
|
|
136
|
-
~config as _,
|
|
137
|
-
~allEntities as _,
|
|
138
|
-
~updatedEffectsCache as _,
|
|
139
|
-
~updatedEntities,
|
|
140
|
-
~chainMetaData as _,
|
|
141
|
-
~onWrite as _,
|
|
142
|
-
) => {
|
|
143
|
-
// Encode entities to JSON for serialization across worker boundary
|
|
144
|
-
let serializableEntities = updatedEntities->Array.map((
|
|
145
|
-
{entityConfig, changes}: Persistence.updatedEntity,
|
|
146
|
-
) => {
|
|
147
|
-
let encodeChange = (change: Change.t<Internal.entity>): serializableChange => {
|
|
148
|
-
switch change {
|
|
149
|
-
| Set({entityId, entity, checkpointId}) =>
|
|
150
|
-
Set({
|
|
151
|
-
entityId,
|
|
152
|
-
entity: entity->S.reverseConvertToJsonOrThrow(entityConfig.schema),
|
|
153
|
-
checkpointId,
|
|
154
|
-
})
|
|
155
|
-
| Delete({entityId, checkpointId}) => Delete({entityId, checkpointId})
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
{
|
|
159
|
-
entityName: entityConfig.name,
|
|
160
|
-
changes: changes->Array.map(encodeChange),
|
|
161
|
-
}
|
|
162
|
-
})
|
|
163
|
-
let _ = await proxy->sendRequest(
|
|
164
|
-
~payload=WriteBatch({
|
|
165
|
-
updatedEntities: serializableEntities,
|
|
166
|
-
checkpointIds: batch.checkpointIds,
|
|
167
|
-
checkpointChainIds: batch.checkpointChainIds,
|
|
168
|
-
checkpointBlockNumbers: batch.checkpointBlockNumbers,
|
|
169
|
-
checkpointBlockHashes: batch.checkpointBlockHashes,
|
|
170
|
-
checkpointEventsProcessed: batch.checkpointEventsProcessed,
|
|
171
|
-
}),
|
|
172
|
-
)
|
|
173
|
-
},
|
|
174
|
-
dumpEffectCache: async () => (),
|
|
175
|
-
reset: async () => (),
|
|
176
|
-
setChainMeta: async _ => Obj.magic(),
|
|
177
|
-
pruneStaleCheckpoints: async (~safeCheckpointId as _) => (),
|
|
178
|
-
pruneStaleEntityHistory: async (~entityName as _, ~entityIndex as _, ~safeCheckpointId as _) =>
|
|
179
|
-
(),
|
|
180
|
-
getRollbackTargetCheckpoint: async (~reorgChainId as _, ~lastKnownValidBlockNumber as _) => {
|
|
181
|
-
JsError.throwWithMessage(
|
|
182
|
-
"TestIndexer: Rollback is not supported. Set rollbackOnReorg to false in config.",
|
|
183
|
-
)
|
|
184
|
-
},
|
|
185
|
-
getRollbackProgressDiff: async (~rollbackTargetCheckpointId as _) => {
|
|
186
|
-
JsError.throwWithMessage(
|
|
187
|
-
"TestIndexer: Rollback is not supported. Set rollbackOnReorg to false in config.",
|
|
188
|
-
)
|
|
189
|
-
},
|
|
190
|
-
getRollbackData: async (~entityConfig as _, ~rollbackTargetCheckpointId as _) => {
|
|
191
|
-
JsError.throwWithMessage(
|
|
192
|
-
"TestIndexer: Rollback is not supported. Set rollbackOnReorg to false in config.",
|
|
193
|
-
)
|
|
194
|
-
},
|
|
195
|
-
close: async () => (),
|
|
196
|
-
}
|