envio 3.3.0-alpha.3 → 3.3.0-alpha.4
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/Bin.res +3 -0
- package/src/Bin.res.mjs +4 -0
- package/src/ChainFetching.res +1 -3
- package/src/ChainFetching.res.mjs +3 -3
- package/src/ChainState.res +3 -12
- package/src/ChainState.res.mjs +6 -8
- package/src/ChainState.resi +0 -2
- package/src/Ecosystem.res +0 -4
- package/src/EventConfigBuilder.res +3 -0
- package/src/EventConfigBuilder.res.mjs +7 -1
- package/src/FetchState.res +10 -27
- package/src/FetchState.res.mjs +13 -56
- package/src/Internal.res +5 -0
- package/src/Main.res +17 -9
- package/src/Main.res.mjs +15 -6
- package/src/SimulateItems.res +4 -0
- package/src/TestIndexer.res +43 -17
- package/src/TestIndexer.res.mjs +16 -9
- package/src/sources/Evm.res +10 -3
- package/src/sources/Evm.res.mjs +5 -5
- package/src/sources/Fuel.res +0 -2
- package/src/sources/Fuel.res.mjs +0 -1
- package/src/sources/SourceManager.res +1 -1
- package/src/sources/SourceManager.res.mjs +1 -1
- package/src/sources/Svm.res +3 -2
- package/src/sources/Svm.res.mjs +3 -4
- package/src/sources/TransactionStore.res +84 -74
- package/src/sources/TransactionStore.res.mjs +39 -33
package/src/FetchState.res.mjs
CHANGED
|
@@ -14,7 +14,7 @@ function deriveEffectiveStartBlock(registrationBlock, contractStartBlock) {
|
|
|
14
14
|
return Primitive_int.max(Primitive_int.max(registrationBlock, 0), Stdlib_Option.getOr(contractStartBlock, 0));
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
let deriveContractNameByAddress = Utils.$$WeakMap.memoize(addressesByContractName => {
|
|
18
18
|
let result = {};
|
|
19
19
|
Utils.Dict.forEachWithKey(addressesByContractName, (addresses, contractName) => {
|
|
20
20
|
for (let i = 0, i_finish = addresses.length; i < i_finish; ++i) {
|
|
@@ -22,7 +22,7 @@ function deriveContractNameByAddress(addressesByContractName) {
|
|
|
22
22
|
}
|
|
23
23
|
});
|
|
24
24
|
return result;
|
|
25
|
-
}
|
|
25
|
+
});
|
|
26
26
|
|
|
27
27
|
function calculateEstResponseSize(p, fromBlock, toBlock, maxQueryBlockNumber) {
|
|
28
28
|
if (p.prevQueryRange <= 0) {
|
|
@@ -82,7 +82,6 @@ function mergePartitionsAtBlock(p1, p2, potentialMergeBlock, contractName, maxAd
|
|
|
82
82
|
latestFetchedBlock: p1.latestFetchedBlock,
|
|
83
83
|
selection: p1.selection,
|
|
84
84
|
addressesByContractName: p1.addressesByContractName,
|
|
85
|
-
contractNameByAddress: p1.contractNameByAddress,
|
|
86
85
|
mergeBlock: potentialMergeBlock,
|
|
87
86
|
dynamicContract: p1.dynamicContract,
|
|
88
87
|
mutPendingQueries: p1.mutPendingQueries,
|
|
@@ -96,7 +95,6 @@ function mergePartitionsAtBlock(p1, p2, potentialMergeBlock, contractName, maxAd
|
|
|
96
95
|
latestFetchedBlock: p2.latestFetchedBlock,
|
|
97
96
|
selection: p2.selection,
|
|
98
97
|
addressesByContractName: p2.addressesByContractName,
|
|
99
|
-
contractNameByAddress: p2.contractNameByAddress,
|
|
100
98
|
mergeBlock: potentialMergeBlock,
|
|
101
99
|
dynamicContract: p2.dynamicContract,
|
|
102
100
|
mutPendingQueries: p2.mutPendingQueries,
|
|
@@ -119,7 +117,6 @@ function mergePartitionsAtBlock(p1, p2, potentialMergeBlock, contractName, maxAd
|
|
|
119
117
|
},
|
|
120
118
|
selection: p1.selection,
|
|
121
119
|
addressesByContractName: {},
|
|
122
|
-
contractNameByAddress: {},
|
|
123
120
|
mergeBlock: undefined,
|
|
124
121
|
dynamicContract: contractName,
|
|
125
122
|
mutPendingQueries: [],
|
|
@@ -134,7 +131,6 @@ function mergePartitionsAtBlock(p1, p2, potentialMergeBlock, contractName, maxAd
|
|
|
134
131
|
latestFetchedBlock: p1.latestFetchedBlock,
|
|
135
132
|
selection: p1.selection,
|
|
136
133
|
addressesByContractName: p1.addressesByContractName,
|
|
137
|
-
contractNameByAddress: p1.contractNameByAddress,
|
|
138
134
|
mergeBlock: potentialMergeBlock,
|
|
139
135
|
dynamicContract: p1.dynamicContract,
|
|
140
136
|
mutPendingQueries: p1.mutPendingQueries,
|
|
@@ -151,7 +147,6 @@ function mergePartitionsAtBlock(p1, p2, potentialMergeBlock, contractName, maxAd
|
|
|
151
147
|
latestFetchedBlock: p2.latestFetchedBlock,
|
|
152
148
|
selection: p2.selection,
|
|
153
149
|
addressesByContractName: p2.addressesByContractName,
|
|
154
|
-
contractNameByAddress: p2.contractNameByAddress,
|
|
155
150
|
mergeBlock: potentialMergeBlock,
|
|
156
151
|
dynamicContract: p2.dynamicContract,
|
|
157
152
|
mutPendingQueries: p2.mutPendingQueries,
|
|
@@ -176,7 +171,6 @@ function mergePartitionsAtBlock(p1, p2, potentialMergeBlock, contractName, maxAd
|
|
|
176
171
|
latestFetchedBlock: continuingBase.latestFetchedBlock,
|
|
177
172
|
selection: continuingBase.selection,
|
|
178
173
|
addressesByContractName: abcFull,
|
|
179
|
-
contractNameByAddress: continuingBase.contractNameByAddress,
|
|
180
174
|
mergeBlock: continuingBase.mergeBlock,
|
|
181
175
|
dynamicContract: continuingBase.dynamicContract,
|
|
182
176
|
mutPendingQueries: continuingBase.mutPendingQueries,
|
|
@@ -192,7 +186,6 @@ function mergePartitionsAtBlock(p1, p2, potentialMergeBlock, contractName, maxAd
|
|
|
192
186
|
latestFetchedBlock: continuingBase.latestFetchedBlock,
|
|
193
187
|
selection: continuingBase.selection,
|
|
194
188
|
addressesByContractName: abcRest,
|
|
195
|
-
contractNameByAddress: continuingBase.contractNameByAddress,
|
|
196
189
|
mergeBlock: continuingBase.mergeBlock,
|
|
197
190
|
dynamicContract: continuingBase.dynamicContract,
|
|
198
191
|
mutPendingQueries: [],
|
|
@@ -210,7 +203,6 @@ function mergePartitionsAtBlock(p1, p2, potentialMergeBlock, contractName, maxAd
|
|
|
210
203
|
latestFetchedBlock: continuingBase.latestFetchedBlock,
|
|
211
204
|
selection: continuingBase.selection,
|
|
212
205
|
addressesByContractName: abc,
|
|
213
|
-
contractNameByAddress: continuingBase.contractNameByAddress,
|
|
214
206
|
mergeBlock: continuingBase.mergeBlock,
|
|
215
207
|
dynamicContract: continuingBase.dynamicContract,
|
|
216
208
|
mutPendingQueries: continuingBase.mutPendingQueries,
|
|
@@ -309,20 +301,7 @@ function make(partitions, maxAddrInPartition, nextPartitionIndex, dynamicContrac
|
|
|
309
301
|
for (let idx$2 = 0; idx$2 < partitionsCount; ++idx$2) {
|
|
310
302
|
let p$1 = newPartitions[idx$2];
|
|
311
303
|
idsInAscOrder[idx$2] = p$1.id;
|
|
312
|
-
entities[p$1.id] =
|
|
313
|
-
id: p$1.id,
|
|
314
|
-
latestFetchedBlock: p$1.latestFetchedBlock,
|
|
315
|
-
selection: p$1.selection,
|
|
316
|
-
addressesByContractName: p$1.addressesByContractName,
|
|
317
|
-
contractNameByAddress: deriveContractNameByAddress(p$1.addressesByContractName),
|
|
318
|
-
mergeBlock: p$1.mergeBlock,
|
|
319
|
-
dynamicContract: p$1.dynamicContract,
|
|
320
|
-
mutPendingQueries: p$1.mutPendingQueries,
|
|
321
|
-
prevQueryRange: p$1.prevQueryRange,
|
|
322
|
-
prevPrevQueryRange: p$1.prevPrevQueryRange,
|
|
323
|
-
prevRangeSize: p$1.prevRangeSize,
|
|
324
|
-
latestBlockRangeUpdateBlock: p$1.latestBlockRangeUpdateBlock
|
|
325
|
-
};
|
|
304
|
+
entities[p$1.id] = p$1;
|
|
326
305
|
}
|
|
327
306
|
return {
|
|
328
307
|
idsInAscOrder: idsInAscOrder,
|
|
@@ -416,7 +395,6 @@ function handleQueryResponse(optimizedPartitions, query, knownHeight, itemsCount
|
|
|
416
395
|
let updatedMainPartition_id = p$1.id;
|
|
417
396
|
let updatedMainPartition_selection = p$1.selection;
|
|
418
397
|
let updatedMainPartition_addressesByContractName = p$1.addressesByContractName;
|
|
419
|
-
let updatedMainPartition_contractNameByAddress = p$1.contractNameByAddress;
|
|
420
398
|
let updatedMainPartition_mergeBlock = p$1.mergeBlock;
|
|
421
399
|
let updatedMainPartition_dynamicContract = p$1.dynamicContract;
|
|
422
400
|
let updatedMainPartition_mutPendingQueries = p$1.mutPendingQueries;
|
|
@@ -426,7 +404,6 @@ function handleQueryResponse(optimizedPartitions, query, knownHeight, itemsCount
|
|
|
426
404
|
latestFetchedBlock: updatedLatestFetchedBlock,
|
|
427
405
|
selection: updatedMainPartition_selection,
|
|
428
406
|
addressesByContractName: updatedMainPartition_addressesByContractName,
|
|
429
|
-
contractNameByAddress: updatedMainPartition_contractNameByAddress,
|
|
430
407
|
mergeBlock: updatedMainPartition_mergeBlock,
|
|
431
408
|
dynamicContract: updatedMainPartition_dynamicContract,
|
|
432
409
|
mutPendingQueries: updatedMainPartition_mutPendingQueries,
|
|
@@ -674,7 +651,6 @@ function createPartitionsFromIndexingAddresses(registeringContractsByContract, d
|
|
|
674
651
|
latestFetchedBlock: latestFetchedBlock,
|
|
675
652
|
selection: normalSelection,
|
|
676
653
|
addressesByContractName: addressesByContractName,
|
|
677
|
-
contractNameByAddress: {},
|
|
678
654
|
mergeBlock: undefined,
|
|
679
655
|
dynamicContract: isDynamic ? contractName : undefined,
|
|
680
656
|
mutPendingQueries: [],
|
|
@@ -726,7 +702,6 @@ function createPartitionsFromIndexingAddresses(registeringContractsByContract, d
|
|
|
726
702
|
latestFetchedBlock: currentP.latestFetchedBlock,
|
|
727
703
|
selection: currentP.selection,
|
|
728
704
|
addressesByContractName: currentP.addressesByContractName,
|
|
729
|
-
contractNameByAddress: currentP.contractNameByAddress,
|
|
730
705
|
mergeBlock: currentPBlock < nextPBlock ? nextPBlock : undefined,
|
|
731
706
|
dynamicContract: currentP.dynamicContract,
|
|
732
707
|
mutPendingQueries: currentP.mutPendingQueries,
|
|
@@ -740,7 +715,6 @@ function createPartitionsFromIndexingAddresses(registeringContractsByContract, d
|
|
|
740
715
|
latestFetchedBlock: nextP.latestFetchedBlock,
|
|
741
716
|
selection: nextP.selection,
|
|
742
717
|
addressesByContractName: mergedAddresses,
|
|
743
|
-
contractNameByAddress: nextP.contractNameByAddress,
|
|
744
718
|
mergeBlock: nextP.mergeBlock,
|
|
745
719
|
dynamicContract: nextP.dynamicContract,
|
|
746
720
|
mutPendingQueries: nextP.mutPendingQueries,
|
|
@@ -755,7 +729,6 @@ function createPartitionsFromIndexingAddresses(registeringContractsByContract, d
|
|
|
755
729
|
latestFetchedBlock: currentP.latestFetchedBlock,
|
|
756
730
|
selection: currentP.selection,
|
|
757
731
|
addressesByContractName: mergedAddresses,
|
|
758
|
-
contractNameByAddress: currentP.contractNameByAddress,
|
|
759
732
|
mergeBlock: currentP.mergeBlock,
|
|
760
733
|
dynamicContract: currentP.dynamicContract,
|
|
761
734
|
mutPendingQueries: currentP.mutPendingQueries,
|
|
@@ -901,7 +874,6 @@ function registerDynamicContracts(fetchState, items) {
|
|
|
901
874
|
latestFetchedBlock: p.latestFetchedBlock,
|
|
902
875
|
selection: p.selection,
|
|
903
876
|
addressesByContractName: restAddressesByContractName,
|
|
904
|
-
contractNameByAddress: p.contractNameByAddress,
|
|
905
877
|
mergeBlock: p.mergeBlock,
|
|
906
878
|
dynamicContract: p.dynamicContract,
|
|
907
879
|
mutPendingQueries: p.mutPendingQueries,
|
|
@@ -917,7 +889,6 @@ function registerDynamicContracts(fetchState, items) {
|
|
|
917
889
|
latestFetchedBlock: p.latestFetchedBlock,
|
|
918
890
|
selection: fetchState.normalSelection,
|
|
919
891
|
addressesByContractName: addressesByContractName,
|
|
920
|
-
contractNameByAddress: {},
|
|
921
892
|
mergeBlock: undefined,
|
|
922
893
|
dynamicContract: contractName,
|
|
923
894
|
mutPendingQueries: p.mutPendingQueries,
|
|
@@ -933,7 +904,6 @@ function registerDynamicContracts(fetchState, items) {
|
|
|
933
904
|
latestFetchedBlock: p.latestFetchedBlock,
|
|
934
905
|
selection: p.selection,
|
|
935
906
|
addressesByContractName: p.addressesByContractName,
|
|
936
|
-
contractNameByAddress: p.contractNameByAddress,
|
|
937
907
|
mergeBlock: p.mergeBlock,
|
|
938
908
|
dynamicContract: contractName,
|
|
939
909
|
mutPendingQueries: p.mutPendingQueries,
|
|
@@ -1029,8 +999,7 @@ function pushQueriesForRange(queries, partitionId, rangeFromBlock, rangeEndBlock
|
|
|
1029
999
|
chainId: 0,
|
|
1030
1000
|
progress: 0,
|
|
1031
1001
|
selection: selection,
|
|
1032
|
-
addressesByContractName: addressesByContractName
|
|
1033
|
-
contractNameByAddress: partition.contractNameByAddress
|
|
1002
|
+
addressesByContractName: addressesByContractName
|
|
1034
1003
|
});
|
|
1035
1004
|
chunkFromBlock = chunkToBlock + 1 | 0;
|
|
1036
1005
|
chunkIdx = chunkIdx + 1 | 0;
|
|
@@ -1046,8 +1015,7 @@ function pushQueriesForRange(queries, partitionId, rangeFromBlock, rangeEndBlock
|
|
|
1046
1015
|
chainId: 0,
|
|
1047
1016
|
progress: 0,
|
|
1048
1017
|
selection: selection,
|
|
1049
|
-
addressesByContractName: addressesByContractName
|
|
1050
|
-
contractNameByAddress: partition.contractNameByAddress
|
|
1018
|
+
addressesByContractName: addressesByContractName
|
|
1051
1019
|
});
|
|
1052
1020
|
return;
|
|
1053
1021
|
}
|
|
@@ -1060,8 +1028,7 @@ function pushQueriesForRange(queries, partitionId, rangeFromBlock, rangeEndBlock
|
|
|
1060
1028
|
chainId: 0,
|
|
1061
1029
|
progress: 0,
|
|
1062
1030
|
selection: selection,
|
|
1063
|
-
addressesByContractName: addressesByContractName
|
|
1064
|
-
contractNameByAddress: partition.contractNameByAddress
|
|
1031
|
+
addressesByContractName: addressesByContractName
|
|
1065
1032
|
});
|
|
1066
1033
|
}
|
|
1067
1034
|
|
|
@@ -1140,8 +1107,7 @@ function getNextQuery(fetchState, budget, chainPendingBudget) {
|
|
|
1140
1107
|
chainId: 0,
|
|
1141
1108
|
progress: 0,
|
|
1142
1109
|
selection: selection,
|
|
1143
|
-
addressesByContractName: addressesByContractName
|
|
1144
|
-
contractNameByAddress: p.contractNameByAddress
|
|
1110
|
+
addressesByContractName: addressesByContractName
|
|
1145
1111
|
});
|
|
1146
1112
|
chunkFromBlock = chunkToBlock + 1 | 0;
|
|
1147
1113
|
chunkIdx = chunkIdx + 1 | 0;
|
|
@@ -1156,8 +1122,7 @@ function getNextQuery(fetchState, budget, chainPendingBudget) {
|
|
|
1156
1122
|
chainId: 0,
|
|
1157
1123
|
progress: 0,
|
|
1158
1124
|
selection: selection,
|
|
1159
|
-
addressesByContractName: addressesByContractName
|
|
1160
|
-
contractNameByAddress: p.contractNameByAddress
|
|
1125
|
+
addressesByContractName: addressesByContractName
|
|
1161
1126
|
});
|
|
1162
1127
|
}
|
|
1163
1128
|
} else {
|
|
@@ -1170,8 +1135,7 @@ function getNextQuery(fetchState, budget, chainPendingBudget) {
|
|
|
1170
1135
|
chainId: 0,
|
|
1171
1136
|
progress: 0,
|
|
1172
1137
|
selection: selection,
|
|
1173
|
-
addressesByContractName: addressesByContractName
|
|
1174
|
-
contractNameByAddress: p.contractNameByAddress
|
|
1138
|
+
addressesByContractName: addressesByContractName
|
|
1175
1139
|
});
|
|
1176
1140
|
}
|
|
1177
1141
|
}
|
|
@@ -1219,8 +1183,7 @@ function getNextQuery(fetchState, budget, chainPendingBudget) {
|
|
|
1219
1183
|
chainId: 0,
|
|
1220
1184
|
progress: 0,
|
|
1221
1185
|
selection: selection$1,
|
|
1222
|
-
addressesByContractName: addressesByContractName$1
|
|
1223
|
-
contractNameByAddress: p.contractNameByAddress
|
|
1186
|
+
addressesByContractName: addressesByContractName$1
|
|
1224
1187
|
});
|
|
1225
1188
|
chunkFromBlock$1 = chunkToBlock$1 + 1 | 0;
|
|
1226
1189
|
chunkIdx$1 = chunkIdx$1 + 1 | 0;
|
|
@@ -1235,8 +1198,7 @@ function getNextQuery(fetchState, budget, chainPendingBudget) {
|
|
|
1235
1198
|
chainId: 0,
|
|
1236
1199
|
progress: 0,
|
|
1237
1200
|
selection: selection$1,
|
|
1238
|
-
addressesByContractName: addressesByContractName$1
|
|
1239
|
-
contractNameByAddress: p.contractNameByAddress
|
|
1201
|
+
addressesByContractName: addressesByContractName$1
|
|
1240
1202
|
});
|
|
1241
1203
|
}
|
|
1242
1204
|
} else {
|
|
@@ -1249,8 +1211,7 @@ function getNextQuery(fetchState, budget, chainPendingBudget) {
|
|
|
1249
1211
|
chainId: 0,
|
|
1250
1212
|
progress: 0,
|
|
1251
1213
|
selection: selection$1,
|
|
1252
|
-
addressesByContractName: addressesByContractName$1
|
|
1253
|
-
contractNameByAddress: p.contractNameByAddress
|
|
1214
|
+
addressesByContractName: addressesByContractName$1
|
|
1254
1215
|
});
|
|
1255
1216
|
}
|
|
1256
1217
|
}
|
|
@@ -1352,7 +1313,6 @@ function make$1(startBlock, endBlock, eventConfigs, addresses, maxAddrInPartitio
|
|
|
1352
1313
|
dependsOnAddresses: false
|
|
1353
1314
|
},
|
|
1354
1315
|
addressesByContractName: {},
|
|
1355
|
-
contractNameByAddress: {},
|
|
1356
1316
|
mergeBlock: undefined,
|
|
1357
1317
|
dynamicContract: undefined,
|
|
1358
1318
|
mutPendingQueries: [],
|
|
@@ -1529,7 +1489,6 @@ function rollback(fetchState, targetBlockNumber) {
|
|
|
1529
1489
|
latestFetchedBlock: p.latestFetchedBlock,
|
|
1530
1490
|
selection: p.selection,
|
|
1531
1491
|
addressesByContractName: rollbackedAddressesByContractName,
|
|
1532
|
-
contractNameByAddress: p.contractNameByAddress,
|
|
1533
1492
|
mergeBlock: mergeBlock$1,
|
|
1534
1493
|
dynamicContract: p.dynamicContract,
|
|
1535
1494
|
mutPendingQueries: rollbackPendingQueries(p.mutPendingQueries, targetBlockNumber),
|
|
@@ -1551,7 +1510,6 @@ function rollback(fetchState, targetBlockNumber) {
|
|
|
1551
1510
|
}) : p.latestFetchedBlock,
|
|
1552
1511
|
selection: p.selection,
|
|
1553
1512
|
addressesByContractName: p.addressesByContractName,
|
|
1554
|
-
contractNameByAddress: p.contractNameByAddress,
|
|
1555
1513
|
mergeBlock: p.mergeBlock,
|
|
1556
1514
|
dynamicContract: p.dynamicContract,
|
|
1557
1515
|
mutPendingQueries: rollbackPendingQueries(p.mutPendingQueries, targetBlockNumber),
|
|
@@ -1597,7 +1555,6 @@ function resetPendingQueries(fetchState) {
|
|
|
1597
1555
|
latestFetchedBlock: partition.latestFetchedBlock,
|
|
1598
1556
|
selection: partition.selection,
|
|
1599
1557
|
addressesByContractName: partition.addressesByContractName,
|
|
1600
|
-
contractNameByAddress: partition.contractNameByAddress,
|
|
1601
1558
|
mergeBlock: partition.mergeBlock,
|
|
1602
1559
|
dynamicContract: partition.dynamicContract,
|
|
1603
1560
|
mutPendingQueries: kept,
|
|
@@ -1804,4 +1761,4 @@ export {
|
|
|
1804
1761
|
getProgressBlockNumberAt,
|
|
1805
1762
|
updateKnownHeight,
|
|
1806
1763
|
}
|
|
1807
|
-
/*
|
|
1764
|
+
/* deriveContractNameByAddress Not a pure module */
|
package/src/Internal.res
CHANGED
|
@@ -420,6 +420,11 @@ type eventConfig = private {
|
|
|
420
420
|
// string set so the shared mask logic is ecosystem-agnostic; sources recover
|
|
421
421
|
// the typed view where they need it.
|
|
422
422
|
selectedTransactionFields: Utils.Set.t<string>,
|
|
423
|
+
// `selectedTransactionFields` precompiled to the transaction-store selection
|
|
424
|
+
// bitmask (bit per ecosystem field code). Materialisation reads this per item
|
|
425
|
+
// so each transaction decodes only the fields its event selected. `0.` when
|
|
426
|
+
// nothing is selected or the ecosystem carries the transaction inline (Fuel).
|
|
427
|
+
transactionFieldMask: float,
|
|
423
428
|
}
|
|
424
429
|
|
|
425
430
|
type fuelEventKind =
|
package/src/Main.res
CHANGED
|
@@ -687,6 +687,10 @@ let dropSchema = async () => {
|
|
|
687
687
|
await persistence.storage.close()
|
|
688
688
|
}
|
|
689
689
|
|
|
690
|
+
// Rejection carried by `onError`: the failure is already logged with full
|
|
691
|
+
// context, so callers should act on it (exit / re-throw) without logging again.
|
|
692
|
+
exception FatalError(exn)
|
|
693
|
+
|
|
690
694
|
let start = async (
|
|
691
695
|
~persistence: option<Persistence.t>=?,
|
|
692
696
|
~reset=false,
|
|
@@ -742,17 +746,20 @@ let start = async (
|
|
|
742
746
|
| None => config
|
|
743
747
|
}
|
|
744
748
|
// The single fatal-error handler, invoked once via IndexerState.errorExit.
|
|
749
|
+
// It logs the failure once (with chain context) and rejects the run wrapped in
|
|
750
|
+
// `FatalError` so callers know it's already logged — `Bin.res` just exits, the
|
|
751
|
+
// test worker unwraps and re-throws it to the parent thread. `runUntilFatalError`
|
|
752
|
+
// only ever rejects: on a clean run it stays pending and the process exits via
|
|
753
|
+
// ExitOnCaughtUp / when the indexer loop drains.
|
|
754
|
+
let onErrorReject = ref(None)
|
|
755
|
+
let runUntilFatalError: promise<unit> = Promise.make((_resolve, reject) =>
|
|
756
|
+
onErrorReject := Some(reject)
|
|
757
|
+
)
|
|
758
|
+
// `onErrorReject` is filled synchronously by `Promise.make` above, before the
|
|
759
|
+
// indexer can run and call `onError`, so it's always present here.
|
|
745
760
|
let onError = (errHandler: ErrorHandling.t) => {
|
|
746
761
|
errHandler->ErrorHandling.log
|
|
747
|
-
|
|
748
|
-
// The TestIndexer runs the indexer in a worker thread and reads the
|
|
749
|
-
// failure off the worker 'error' event. Re-throw the original error
|
|
750
|
-
// outside the promise chain on the next tick so the test sees its real
|
|
751
|
-
// message instead of a generic non-zero exit code.
|
|
752
|
-
NodeJs.setImmediate(() => errHandler->ErrorHandling.raiseExn)
|
|
753
|
-
} else {
|
|
754
|
-
NodeJs.process->NodeJs.exitWithCode(Failure)
|
|
755
|
-
}
|
|
762
|
+
(onErrorReject.contents->Option.getUnsafe)(FatalError(errHandler.exn->Utils.prettifyExn))
|
|
756
763
|
}
|
|
757
764
|
let envioVersion = Utils.EnvioPackage.value.version
|
|
758
765
|
Prometheus.Info.set(~version=envioVersion)
|
|
@@ -793,4 +800,5 @@ let start = async (
|
|
|
793
800
|
}
|
|
794
801
|
indexerStateRef := Some(state)
|
|
795
802
|
state->IndexerLoop.start
|
|
803
|
+
await runUntilFatalError
|
|
796
804
|
}
|
package/src/Main.res.mjs
CHANGED
|
@@ -522,6 +522,8 @@ async function dropSchema() {
|
|
|
522
522
|
return await persistence.storage.close();
|
|
523
523
|
}
|
|
524
524
|
|
|
525
|
+
let FatalError = /* @__PURE__ */Primitive_exceptions.create("Main.FatalError");
|
|
526
|
+
|
|
525
527
|
async function start(persistence, resetOpt, isTestOpt, exitAfterFirstEventBlockOpt, patchConfig) {
|
|
526
528
|
let reset = resetOpt !== undefined ? resetOpt : false;
|
|
527
529
|
let isTest = isTestOpt !== undefined ? isTestOpt : false;
|
|
@@ -562,13 +564,18 @@ async function start(persistence, resetOpt, isTestOpt, exitAfterFirstEventBlockO
|
|
|
562
564
|
allEnums: config.allEnums
|
|
563
565
|
}) : config;
|
|
564
566
|
let config$2 = patchConfig !== undefined ? patchConfig(config$1, registrations) : config$1;
|
|
567
|
+
let onErrorReject = {
|
|
568
|
+
contents: undefined
|
|
569
|
+
};
|
|
570
|
+
let runUntilFatalError = new Promise((_resolve, reject) => {
|
|
571
|
+
onErrorReject.contents = reject;
|
|
572
|
+
});
|
|
565
573
|
let onError = errHandler => {
|
|
566
574
|
ErrorHandling.log(errHandler);
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
}
|
|
575
|
+
onErrorReject.contents({
|
|
576
|
+
RE_EXN_ID: FatalError,
|
|
577
|
+
_1: Utils.prettifyExn(errHandler.exn)
|
|
578
|
+
});
|
|
572
579
|
};
|
|
573
580
|
let envioVersion = Utils.EnvioPackage.value.version;
|
|
574
581
|
Prometheus.Info.set(envioVersion);
|
|
@@ -599,7 +606,8 @@ async function start(persistence, resetOpt, isTestOpt, exitAfterFirstEventBlockO
|
|
|
599
606
|
Tui.start(() => state);
|
|
600
607
|
}
|
|
601
608
|
indexerStateRef.contents = Primitive_option.some(state);
|
|
602
|
-
|
|
609
|
+
IndexerLoop.start(state);
|
|
610
|
+
return await runUntilFatalError;
|
|
603
611
|
}
|
|
604
612
|
|
|
605
613
|
export {
|
|
@@ -616,6 +624,7 @@ export {
|
|
|
616
624
|
getEnvioInfo,
|
|
617
625
|
migrate,
|
|
618
626
|
dropSchema,
|
|
627
|
+
FatalError,
|
|
619
628
|
start,
|
|
620
629
|
}
|
|
621
630
|
/* chainDataSchema Not a pure module */
|
package/src/SimulateItems.res
CHANGED
|
@@ -234,6 +234,10 @@ let deriveSrcAddress = (
|
|
|
234
234
|
// A non-wildcard event is gated by `clientAddressFilter` on srcAddress ownership,
|
|
235
235
|
// so a simulate item whose srcAddress isn't indexed on this chain would be
|
|
236
236
|
// silently dropped (handler never runs). Fail loudly instead.
|
|
237
|
+
//
|
|
238
|
+
// `config` must already have handler registrations applied, otherwise an event
|
|
239
|
+
// made wildcard purely through `indexer.onEvent({ wildcard: true })` reads back
|
|
240
|
+
// as non-wildcard and gets wrongly rejected.
|
|
237
241
|
let validateSrcAddresses = (
|
|
238
242
|
~simulateItems: array<JSON.t>,
|
|
239
243
|
~config: Config.t,
|
package/src/TestIndexer.res
CHANGED
|
@@ -667,8 +667,11 @@ let makeCreateTestIndexer = (~config: Config.t, ~workerPath: string): (
|
|
|
667
667
|
Int.compare(aId, bId)
|
|
668
668
|
})
|
|
669
669
|
|
|
670
|
-
// Parse and validate
|
|
671
|
-
|
|
670
|
+
// Parse and validate the block ranges upfront before starting any
|
|
671
|
+
// workers. srcAddress validation can't run here: it depends on which
|
|
672
|
+
// events are wildcard, and `config` reflects config.yaml only —
|
|
673
|
+
// handler-level `wildcard: true` takes effect only once registrations
|
|
674
|
+
// are applied.
|
|
672
675
|
let chainEntries = sortedChainKeys->Array.map(chainIdStr => {
|
|
673
676
|
let rawChainConfig = rawChains->Dict.getUnsafe(chainIdStr)
|
|
674
677
|
let chainId = switch chainIdStr->Int.fromString {
|
|
@@ -684,19 +687,6 @@ let makeCreateTestIndexer = (~config: Config.t, ~workerPath: string): (
|
|
|
684
687
|
~rawChainConfig,
|
|
685
688
|
~progressBlock=state.progressBlockByChain->Dict.get(chainIdStr),
|
|
686
689
|
)
|
|
687
|
-
switch rawChainConfig.simulate {
|
|
688
|
-
| Some(simulateItems) =>
|
|
689
|
-
let chainConfig = config.chainMap->ChainMap.get(ChainMap.Chain.makeUnsafe(~chainId))
|
|
690
|
-
SimulateItems.validateSrcAddresses(
|
|
691
|
-
~simulateItems,
|
|
692
|
-
~config,
|
|
693
|
-
~chainConfig,
|
|
694
|
-
~indexingAddresses=preflightAddressesByChain
|
|
695
|
-
->Dict.get(chainIdStr)
|
|
696
|
-
->Option.getOr([]),
|
|
697
|
-
)
|
|
698
|
-
| None => ()
|
|
699
|
-
}
|
|
700
690
|
(chainIdStr, chainId, rawChainConfig, processChainConfig)
|
|
701
691
|
})
|
|
702
692
|
|
|
@@ -877,7 +867,27 @@ let initTestWorker = () => {
|
|
|
877
867
|
| Some(_) => ()
|
|
878
868
|
}
|
|
879
869
|
|
|
880
|
-
let patchConfig = (config, _registrations) => {
|
|
870
|
+
let patchConfig = (config: Config.t, _registrations) => {
|
|
871
|
+
// `config` here has handler registrations applied, so `isWildcard`
|
|
872
|
+
// reflects `indexer.onEvent({ wildcard: true })` — which the main thread
|
|
873
|
+
// can't see. Validate srcAddresses against it before patching in the
|
|
874
|
+
// simulate source.
|
|
875
|
+
switch simulate {
|
|
876
|
+
| Some(simulateItems) =>
|
|
877
|
+
let chainConfig = config.chainMap->ChainMap.get(ChainMap.Chain.makeUnsafe(~chainId))
|
|
878
|
+
let indexingAddresses =
|
|
879
|
+
initialState.chains
|
|
880
|
+
->Array.find(c => c.id == chainId)
|
|
881
|
+
->Option.mapOr([], c => c.indexingAddresses)
|
|
882
|
+
SimulateItems.validateSrcAddresses(
|
|
883
|
+
~simulateItems,
|
|
884
|
+
~config,
|
|
885
|
+
~chainConfig,
|
|
886
|
+
~indexingAddresses,
|
|
887
|
+
)
|
|
888
|
+
| None => ()
|
|
889
|
+
}
|
|
890
|
+
|
|
881
891
|
let config = SimulateItems.patchConfig(~config, ~processConfig)
|
|
882
892
|
|
|
883
893
|
// In auto-exit mode, set batchSize=1 to process one block checkpoint at a time
|
|
@@ -887,7 +897,23 @@ let initTestWorker = () => {
|
|
|
887
897
|
config
|
|
888
898
|
}
|
|
889
899
|
}
|
|
890
|
-
Main.start(~persistence, ~isTest=true, ~patchConfig, ~exitAfterFirstEventBlock)
|
|
900
|
+
Main.start(~persistence, ~isTest=true, ~patchConfig, ~exitAfterFirstEventBlock)
|
|
901
|
+
->Promise.catch(exn => {
|
|
902
|
+
// `Main.start` rejects on any fatal error: a runtime failure arrives wrapped
|
|
903
|
+
// in `Main.FatalError` (already logged), a setup throw (e.g. patchConfig's
|
|
904
|
+
// srcAddress validation) arrives raw. The parent only learns of failures
|
|
905
|
+
// through the worker `error` event, which fires on an *uncaught* exception.
|
|
906
|
+
// Throwing synchronously in this catch would just reject the catch's own
|
|
907
|
+
// promise (swallowed by `ignore`); `setImmediate` re-throws outside the
|
|
908
|
+
// promise chain so it becomes uncaught and reaches the parent.
|
|
909
|
+
let toThrow = switch exn {
|
|
910
|
+
| Main.FatalError(inner) => inner
|
|
911
|
+
| _ => exn->Utils.prettifyExn
|
|
912
|
+
}
|
|
913
|
+
NodeJs.setImmediate(() => throw(toThrow))
|
|
914
|
+
Promise.resolve()
|
|
915
|
+
})
|
|
916
|
+
->ignore
|
|
891
917
|
| None =>
|
|
892
918
|
Logging.error("TestIndexerWorker: No worker data provided")
|
|
893
919
|
NodeJs.process->NodeJs.exitWithCode(Failure)
|
package/src/TestIndexer.res.mjs
CHANGED
|
@@ -481,17 +481,11 @@ function makeCreateTestIndexer(config, workerPath) {
|
|
|
481
481
|
let bId = Stdlib_Option.getOr(Stdlib_Int.fromString(b, undefined), 0);
|
|
482
482
|
return Primitive_int.compare(aId, bId);
|
|
483
483
|
});
|
|
484
|
-
let preflightAddressesByChain = getIndexingAddressesByChain(state);
|
|
485
484
|
let chainEntries = sortedChainKeys.map(chainIdStr => {
|
|
486
485
|
let rawChainConfig = rawChains[chainIdStr];
|
|
487
486
|
let id = Stdlib_Int.fromString(chainIdStr, undefined);
|
|
488
487
|
let chainId = id !== undefined ? id : Stdlib_JsError.throwWithMessage(`Invalid chain ID "` + chainIdStr + `": expected a numeric chain ID`);
|
|
489
488
|
let processChainConfig = parseBlockRange(chainIdStr, config, rawChainConfig, state.progressBlockByChain[chainIdStr]);
|
|
490
|
-
let simulateItems = rawChainConfig.simulate;
|
|
491
|
-
if (simulateItems !== undefined) {
|
|
492
|
-
let chainConfig = ChainMap.get(config.chainMap, ChainMap.Chain.makeUnsafe(chainId));
|
|
493
|
-
SimulateItems.validateSrcAddresses(simulateItems, config, chainConfig, Stdlib_Option.getOr(preflightAddressesByChain[chainIdStr], []));
|
|
494
|
-
}
|
|
495
489
|
return [
|
|
496
490
|
chainIdStr,
|
|
497
491
|
chainId,
|
|
@@ -592,9 +586,11 @@ function initTestWorker() {
|
|
|
592
586
|
Process.exit(1);
|
|
593
587
|
return;
|
|
594
588
|
}
|
|
589
|
+
let initialState = workerData.initialState;
|
|
595
590
|
let simulate = workerData.simulate;
|
|
596
591
|
let endBlock = workerData.endBlock;
|
|
597
|
-
let
|
|
592
|
+
let chainId = workerData.chainId;
|
|
593
|
+
let chainIdStr = chainId.toString();
|
|
598
594
|
let exitAfterFirstEventBlock = Stdlib_Option.isNone(endBlock);
|
|
599
595
|
let resolvedChainDict = {};
|
|
600
596
|
resolvedChainDict["startBlock"] = workerData.startBlock;
|
|
@@ -609,7 +605,7 @@ function initTestWorker() {
|
|
|
609
605
|
let processConfig = {
|
|
610
606
|
chains: resolvedChainsDict
|
|
611
607
|
};
|
|
612
|
-
let proxy = TestIndexerProxyStorage.make(parentPort,
|
|
608
|
+
let proxy = TestIndexerProxyStorage.make(parentPort, initialState);
|
|
613
609
|
let storage = TestIndexerProxyStorage.makeStorage(proxy);
|
|
614
610
|
let config = Config.loadWithoutRegistrations();
|
|
615
611
|
let persistence = Persistence.make(config.userEntities, config.allEnums, storage);
|
|
@@ -619,6 +615,11 @@ function initTestWorker() {
|
|
|
619
615
|
Logging.setLogLevel("silent");
|
|
620
616
|
}
|
|
621
617
|
let patchConfig = (config, _registrations) => {
|
|
618
|
+
if (simulate !== undefined) {
|
|
619
|
+
let chainConfig = ChainMap.get(config.chainMap, ChainMap.Chain.makeUnsafe(chainId));
|
|
620
|
+
let indexingAddresses = Stdlib_Option.mapOr(initialState.chains.find(c => c.id === chainId), [], c => c.indexingAddresses);
|
|
621
|
+
SimulateItems.validateSrcAddresses(simulate, config, chainConfig, indexingAddresses);
|
|
622
|
+
}
|
|
622
623
|
let config$1 = SimulateItems.patchConfig(config, processConfig);
|
|
623
624
|
if (exitAfterFirstEventBlock) {
|
|
624
625
|
return {
|
|
@@ -646,7 +647,13 @@ function initTestWorker() {
|
|
|
646
647
|
return config$1;
|
|
647
648
|
}
|
|
648
649
|
};
|
|
649
|
-
Main.start(persistence, undefined, true, exitAfterFirstEventBlock, patchConfig)
|
|
650
|
+
Stdlib_Promise.$$catch(Main.start(persistence, undefined, true, exitAfterFirstEventBlock, patchConfig), exn => {
|
|
651
|
+
let toThrow = exn.RE_EXN_ID === Main.FatalError ? exn._1 : Utils.prettifyExn(exn);
|
|
652
|
+
setImmediate(() => {
|
|
653
|
+
throw toThrow;
|
|
654
|
+
});
|
|
655
|
+
return Promise.resolve();
|
|
656
|
+
});
|
|
650
657
|
}
|
|
651
658
|
|
|
652
659
|
export {
|
package/src/sources/Evm.res
CHANGED
|
@@ -52,7 +52,9 @@ let transactionFields = [
|
|
|
52
52
|
"authorizationList",
|
|
53
53
|
]
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
// One event's selected transaction fields → store selection bitmask. Computed
|
|
56
|
+
// per event at config build and cached on the event config.
|
|
57
|
+
let eventTransactionFieldMask = TransactionStore.makeMaskFn(transactionFields)
|
|
56
58
|
|
|
57
59
|
let cleanUpRawEventFieldsInPlace: JSON.t => unit = %raw(`fields => {
|
|
58
60
|
delete fields.hash
|
|
@@ -83,7 +85,6 @@ let make = (~logger: Pino.t): Ecosystem.t => {
|
|
|
83
85
|
s.field("block", S.option(S.object(s2 => s2.field("number", S.unknown))))
|
|
84
86
|
),
|
|
85
87
|
logger,
|
|
86
|
-
transactionFieldMask,
|
|
87
88
|
// The payload carries `transaction` by batch prep (HyperSync) or inline
|
|
88
89
|
// (RPC/simulate), so the event is the payload as-is.
|
|
89
90
|
toEvent: eventItem => eventItem.payload->(Utils.magic: Internal.eventPayload => Internal.event),
|
|
@@ -101,10 +102,16 @@ let make = (~logger: Pino.t): Ecosystem.t => {
|
|
|
101
102
|
),
|
|
102
103
|
toRawEvent: eventItem => {
|
|
103
104
|
let payload = eventItem.payload->toPayload
|
|
105
|
+
let eventConfig =
|
|
106
|
+
eventItem.eventConfig->(Utils.magic: Internal.eventConfig => Internal.evmEventConfig)
|
|
104
107
|
eventItem->RawEvent.make(
|
|
105
108
|
~block=payload.block,
|
|
106
109
|
~transaction=payload.transaction,
|
|
107
|
-
|
|
110
|
+
// The decoder emits `{}` for zero-parameter events, which the params
|
|
111
|
+
// schema rejects; pass unit so it serializes to the "null" sentinel.
|
|
112
|
+
~params=eventConfig.paramsMetadata->Array.length == 0
|
|
113
|
+
? ()->(Utils.magic: unit => Internal.eventParams)
|
|
114
|
+
: payload.params,
|
|
108
115
|
~srcAddress=payload.srcAddress,
|
|
109
116
|
~cleanUpRawEventFieldsInPlace,
|
|
110
117
|
)
|
package/src/sources/Evm.res.mjs
CHANGED
|
@@ -40,7 +40,7 @@ let transactionFields = [
|
|
|
40
40
|
"authorizationList"
|
|
41
41
|
];
|
|
42
42
|
|
|
43
|
-
let
|
|
43
|
+
let eventTransactionFieldMask = TransactionStore.makeMaskFn(transactionFields);
|
|
44
44
|
|
|
45
45
|
let cleanUpRawEventFieldsInPlace = (fields => {
|
|
46
46
|
delete fields.hash
|
|
@@ -60,7 +60,6 @@ function make(logger) {
|
|
|
60
60
|
onEventBlockFilterSchema: S$RescriptSchema.object(s => s.f("block", S$RescriptSchema.option(S$RescriptSchema.object(s2 => s2.f("number", S$RescriptSchema.unknown))))),
|
|
61
61
|
logger: logger,
|
|
62
62
|
toEvent: eventItem => eventItem.payload,
|
|
63
|
-
transactionFieldMask: transactionFieldMask,
|
|
64
63
|
toEventLogger: eventItem => Logging.createChildFrom(logger, {
|
|
65
64
|
contract: eventItem.eventConfig.contractName,
|
|
66
65
|
event: eventItem.eventConfig.name,
|
|
@@ -71,15 +70,16 @@ function make(logger) {
|
|
|
71
70
|
}),
|
|
72
71
|
toRawEvent: eventItem => {
|
|
73
72
|
let payload = eventItem.payload;
|
|
74
|
-
|
|
73
|
+
let eventConfig = eventItem.eventConfig;
|
|
74
|
+
return RawEvent.make(eventItem, payload.block, payload.transaction, eventConfig.paramsMetadata.length === 0 ? undefined : payload.params, payload.srcAddress, cleanUpRawEventFieldsInPlace);
|
|
75
75
|
}
|
|
76
76
|
};
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
export {
|
|
80
80
|
transactionFields,
|
|
81
|
-
|
|
81
|
+
eventTransactionFieldMask,
|
|
82
82
|
cleanUpRawEventFieldsInPlace,
|
|
83
83
|
make,
|
|
84
84
|
}
|
|
85
|
-
/*
|
|
85
|
+
/* eventTransactionFieldMask Not a pure module */
|
package/src/sources/Fuel.res
CHANGED
|
@@ -39,8 +39,6 @@ let make = (~logger: Pino.t): Ecosystem.t => {
|
|
|
39
39
|
s.field("block", S.option(S.object(s2 => s2.field("height", S.unknown))))
|
|
40
40
|
),
|
|
41
41
|
logger,
|
|
42
|
-
// Fuel carries the transaction inline on the payload.
|
|
43
|
-
transactionFieldMask: _ => 0.,
|
|
44
42
|
toEvent: eventItem => eventItem.payload->(Utils.magic: Internal.eventPayload => Internal.event),
|
|
45
43
|
toEventLogger: eventItem =>
|
|
46
44
|
Logging.createChildFrom(
|
package/src/sources/Fuel.res.mjs
CHANGED
|
@@ -22,7 +22,6 @@ function make(logger) {
|
|
|
22
22
|
onEventBlockFilterSchema: S$RescriptSchema.object(s => s.f("block", S$RescriptSchema.option(S$RescriptSchema.object(s2 => s2.f("height", S$RescriptSchema.unknown))))),
|
|
23
23
|
logger: logger,
|
|
24
24
|
toEvent: eventItem => eventItem.payload,
|
|
25
|
-
transactionFieldMask: param => 0,
|
|
26
25
|
toEventLogger: eventItem => Logging.createChildFrom(logger, {
|
|
27
26
|
contract: eventItem.eventConfig.contractName,
|
|
28
27
|
event: eventItem.eventConfig.name,
|
|
@@ -676,7 +676,7 @@ let executeQuery = async (
|
|
|
676
676
|
~fromBlock=query.fromBlock,
|
|
677
677
|
~toBlock,
|
|
678
678
|
~addressesByContractName=query.addressesByContractName,
|
|
679
|
-
~contractNameByAddress=query.
|
|
679
|
+
~contractNameByAddress=query.addressesByContractName->FetchState.deriveContractNameByAddress,
|
|
680
680
|
~partitionId=query.partitionId,
|
|
681
681
|
~knownHeight,
|
|
682
682
|
~selection=query.selection,
|