@subql/node-ethereum 2.0.2-0 → 2.0.2-1
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/dist/.tsbuildinfo +1 -1
- package/dist/configure/SubqueryProject.d.ts +2 -4
- package/dist/configure/SubqueryProject.js +17 -17
- package/dist/configure/SubqueryProject.js.map +1 -1
- package/dist/configure/configure.module.d.ts +1 -4
- package/dist/configure/configure.module.js +24 -71
- package/dist/configure/configure.module.js.map +1 -1
- package/dist/ethereum/api.ethereum.d.ts +8 -6
- package/dist/ethereum/api.ethereum.js +13 -6
- package/dist/ethereum/api.ethereum.js.map +1 -1
- package/dist/indexer/blockDispatcher/worker-block-dispatcher.service.js +1 -0
- package/dist/indexer/blockDispatcher/worker-block-dispatcher.service.js.map +1 -1
- package/dist/indexer/dictionary.service.js +1 -1
- package/dist/indexer/dictionary.service.js.map +1 -1
- package/dist/indexer/ds-processor.service.d.ts +4 -21
- package/dist/indexer/ds-processor.service.js +6 -97
- package/dist/indexer/ds-processor.service.js.map +1 -1
- package/dist/indexer/dynamic-ds.service.js +1 -1
- package/dist/indexer/dynamic-ds.service.js.map +1 -1
- package/dist/indexer/fetch.module.js +8 -1
- package/dist/indexer/fetch.module.js.map +1 -1
- package/dist/indexer/fetch.service.d.ts +18 -43
- package/dist/indexer/fetch.service.js +28 -286
- package/dist/indexer/fetch.service.js.map +1 -1
- package/dist/indexer/indexer.manager.d.ts +33 -18
- package/dist/indexer/indexer.manager.js +29 -164
- package/dist/indexer/indexer.manager.js.map +1 -1
- package/dist/indexer/indexer.module.js +0 -1
- package/dist/indexer/indexer.module.js.map +1 -1
- package/dist/indexer/project.service.d.ts +5 -35
- package/dist/indexer/project.service.js +6 -203
- package/dist/indexer/project.service.js.map +1 -1
- package/dist/indexer/sandbox.service.d.ts +6 -5
- package/dist/indexer/sandbox.service.js +14 -18
- package/dist/indexer/sandbox.service.js.map +1 -1
- package/dist/indexer/unfinalizedBlocks.service.d.ts +10 -33
- package/dist/indexer/unfinalizedBlocks.service.js +23 -166
- package/dist/indexer/unfinalizedBlocks.service.js.map +1 -1
- package/dist/indexer/worker/worker.d.ts +2 -1
- package/dist/indexer/worker/worker.js.map +1 -1
- package/dist/indexer/worker/worker.service.d.ts +2 -8
- package/dist/indexer/worker/worker.service.js +1 -3
- package/dist/indexer/worker/worker.service.js.map +1 -1
- package/dist/indexer/worker/worker.unfinalizedBlocks.service.d.ts +8 -5
- package/dist/indexer/worker/worker.unfinalizedBlocks.service.js +10 -0
- package/dist/indexer/worker/worker.unfinalizedBlocks.service.js.map +1 -1
- package/dist/main.js +4 -1
- package/dist/main.js.map +1 -1
- package/dist/meta/meta.controller.d.ts +4 -6
- package/dist/meta/meta.module.js +1 -52
- package/dist/meta/meta.module.js.map +1 -1
- package/dist/meta/meta.service.d.ts +7 -40
- package/dist/meta/meta.service.js +9 -83
- package/dist/meta/meta.service.js.map +1 -1
- package/dist/subcommands/forceClean.init.js +1 -2
- package/dist/subcommands/forceClean.init.js.map +1 -1
- package/dist/subcommands/forceClean.module.js +2 -2
- package/dist/subcommands/forceClean.module.js.map +1 -1
- package/dist/subcommands/mmrMigrate.init.d.ts +2 -0
- package/dist/subcommands/mmrMigrate.init.js +28 -0
- package/dist/subcommands/mmrMigrate.init.js.map +1 -0
- package/dist/subcommands/mmrMigrate.module.d.ts +4 -0
- package/dist/subcommands/mmrMigrate.module.js +48 -0
- package/dist/subcommands/mmrMigrate.module.js.map +1 -0
- package/dist/subcommands/mmrRegenerate.init.d.ts +1 -0
- package/dist/subcommands/mmrRegenerate.init.js +27 -0
- package/dist/subcommands/mmrRegenerate.init.js.map +1 -0
- package/dist/subcommands/mmrRegenerate.module.d.ts +4 -0
- package/dist/subcommands/mmrRegenerate.module.js +46 -0
- package/dist/subcommands/mmrRegenerate.module.js.map +1 -0
- package/dist/subcommands/reindex.module.js +3 -2
- package/dist/subcommands/reindex.module.js.map +1 -1
- package/dist/subcommands/reindex.service.d.ts +1 -2
- package/dist/subcommands/reindex.service.js +5 -10
- package/dist/subcommands/reindex.service.js.map +1 -1
- package/dist/subcommands/testing.init.js.map +1 -1
- package/dist/subcommands/testing.module.js +1 -0
- package/dist/subcommands/testing.module.js.map +1 -1
- package/dist/subcommands/testing.service.d.ts +1 -1
- package/dist/subcommands/testing.service.js +0 -1
- package/dist/subcommands/testing.service.js.map +1 -1
- package/dist/utils/project.d.ts +4 -11
- package/dist/utils/project.js +9 -138
- package/dist/utils/project.js.map +1 -1
- package/dist/yargs.d.ts +90 -2
- package/dist/yargs.js +113 -0
- package/dist/yargs.js.map +1 -1
- package/package.json +10 -19
- package/dist/configure/configure.module.spec.d.ts +0 -1
- package/dist/configure/configure.module.spec.js +0 -26
- package/dist/configure/configure.module.spec.js.map +0 -1
- package/dist/indexer/unfinalizedBlocks.spec.d.ts +0 -1
- package/dist/indexer/unfinalizedBlocks.spec.js +0 -195
- package/dist/indexer/unfinalizedBlocks.spec.js.map +0 -1
- package/dist/subcommands/forceClean.service.d.ts +0 -10
- package/dist/subcommands/forceClean.service.js +0 -89
- package/dist/subcommands/forceClean.service.js.map +0 -1
- package/dist/utils/reindex.d.ts +0 -6
- package/dist/utils/reindex.js +0 -48
- package/dist/utils/reindex.js.map +0 -1
|
@@ -25,13 +25,10 @@ const SubqueryProject_1 = require("../configure/SubqueryProject");
|
|
|
25
25
|
const utils_ethereum_1 = require("../ethereum/utils.ethereum");
|
|
26
26
|
const string_1 = require("../utils/string");
|
|
27
27
|
const dictionary_service_1 = require("./dictionary.service");
|
|
28
|
+
const ds_processor_service_1 = require("./ds-processor.service");
|
|
28
29
|
const dynamic_ds_service_1 = require("./dynamic-ds.service");
|
|
29
30
|
const unfinalizedBlocks_service_1 = require("./unfinalizedBlocks.service");
|
|
30
|
-
const
|
|
31
|
-
let BLOCK_TIME_VARIANCE = 5000;
|
|
32
|
-
const DICTIONARY_MAX_QUERY_SIZE = 10000;
|
|
33
|
-
const CHECK_MEMORY_INTERVAL = 60000;
|
|
34
|
-
const MINIMUM_BATCH_SIZE = 5;
|
|
31
|
+
const BLOCK_TIME_VARIANCE = 5000;
|
|
35
32
|
const INTERVAL_PERCENT = 0.9;
|
|
36
33
|
const QUERY_ADDRESS_LIMIT = 50;
|
|
37
34
|
function eventFilterToQueryEntry(filter, dsOptions) {
|
|
@@ -100,32 +97,14 @@ function callFilterToQueryEntry(filter) {
|
|
|
100
97
|
conditions,
|
|
101
98
|
};
|
|
102
99
|
}
|
|
103
|
-
let FetchService = class FetchService {
|
|
104
|
-
constructor(apiService, nodeConfig, project, blockDispatcher, dictionaryService, dynamicDsService, unfinalizedBlocksService, eventEmitter, schedulerRegistry) {
|
|
105
|
-
|
|
106
|
-
this.nodeConfig = nodeConfig;
|
|
107
|
-
this.project = project;
|
|
108
|
-
this.blockDispatcher = blockDispatcher;
|
|
109
|
-
this.dictionaryService = dictionaryService;
|
|
110
|
-
this.dynamicDsService = dynamicDsService;
|
|
100
|
+
let FetchService = class FetchService extends node_core_1.BaseFetchService {
|
|
101
|
+
constructor(apiService, nodeConfig, project, blockDispatcher, dictionaryService, dsProcessorService, dynamicDsService, unfinalizedBlocksService, eventEmitter, schedulerRegistry) {
|
|
102
|
+
super(apiService, nodeConfig, project, blockDispatcher, dictionaryService, dsProcessorService, dynamicDsService, eventEmitter, schedulerRegistry);
|
|
111
103
|
this.unfinalizedBlocksService = unfinalizedBlocksService;
|
|
112
|
-
this.eventEmitter = eventEmitter;
|
|
113
|
-
this.schedulerRegistry = schedulerRegistry;
|
|
114
|
-
this.isShutdown = false;
|
|
115
|
-
this.dictionaryMetaValid = false;
|
|
116
|
-
this.bypassBlocks = [];
|
|
117
|
-
this.batchSizeScale = 1;
|
|
118
|
-
}
|
|
119
|
-
onApplicationShutdown() {
|
|
120
|
-
this.isShutdown = true;
|
|
121
104
|
}
|
|
122
105
|
get api() {
|
|
123
106
|
return this.apiService.api;
|
|
124
107
|
}
|
|
125
|
-
async syncDynamicDatascourcesFromMeta() {
|
|
126
|
-
this.templateDynamicDatasouces =
|
|
127
|
-
await this.dynamicDsService.getDynamicDatasources();
|
|
128
|
-
}
|
|
129
108
|
buildDictionaryQueryEntries(startBlock) {
|
|
130
109
|
var _a;
|
|
131
110
|
const queryEntries = [];
|
|
@@ -179,103 +158,22 @@ let FetchService = class FetchService {
|
|
|
179
158
|
}
|
|
180
159
|
return (0, lodash_1.uniqBy)(queryEntries, (item) => `${item.entity}|${JSON.stringify((0, lodash_1.sortBy)(item.conditions, (c) => c.field))}`);
|
|
181
160
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
return (!!this.project.network.dictionary &&
|
|
188
|
-
this.dictionaryMetaValid &&
|
|
189
|
-
!!this.dictionaryService.getDictionaryQueryEntries((_a = this.blockDispatcher.latestBufferedHeight) !== null && _a !== void 0 ? _a : Math.min(...this.project.dataSources.map((ds) => ds.startBlock))).length);
|
|
190
|
-
}
|
|
191
|
-
async init(startHeight) {
|
|
192
|
-
var _a;
|
|
193
|
-
if (((_a = this.project.network) === null || _a === void 0 ? void 0 : _a.bypassBlocks) !== undefined) {
|
|
194
|
-
this.bypassBlocks = (0, node_core_1.transformBypassBlocks)(this.project.network.bypassBlocks).filter((blk) => blk >= startHeight);
|
|
195
|
-
}
|
|
196
|
-
if (this.api) {
|
|
197
|
-
const CHAIN_INTERVAL = (0, utils_ethereum_1.calcInterval)(this.api) * INTERVAL_PERCENT;
|
|
198
|
-
BLOCK_TIME_VARIANCE = Math.min(BLOCK_TIME_VARIANCE, CHAIN_INTERVAL);
|
|
199
|
-
this.schedulerRegistry.addInterval('getLatestBlockHead', setInterval(() => void this.getBestBlockHead(), BLOCK_TIME_VARIANCE));
|
|
200
|
-
}
|
|
201
|
-
await this.syncDynamicDatascourcesFromMeta();
|
|
202
|
-
if (this.project.network.dictionary) {
|
|
203
|
-
this.updateDictionary();
|
|
204
|
-
// Call metadata here, other network should align with this
|
|
205
|
-
// For substrate, we might use the specVersion metadata in future if we have same error handling as in node-core
|
|
206
|
-
const metadata = await this.dictionaryService.getMetadata();
|
|
207
|
-
this.evmChainId = await this.dictionaryService.getEvmChainId();
|
|
208
|
-
this.dictionaryValidation(metadata);
|
|
209
|
-
}
|
|
210
|
-
await Promise.all([this.getFinalizedBlockHead(), this.getBestBlockHead()]);
|
|
211
|
-
await this.blockDispatcher.init(this.resetForNewDs.bind(this));
|
|
212
|
-
void this.startLoop(startHeight);
|
|
213
|
-
}
|
|
214
|
-
getUseDictionary() {
|
|
215
|
-
return this.useDictionary;
|
|
216
|
-
}
|
|
217
|
-
getLatestFinalizedHeight() {
|
|
218
|
-
return this.latestFinalizedHeight;
|
|
219
|
-
}
|
|
220
|
-
checkBatchScale() {
|
|
221
|
-
if (this.nodeConfig['scale-batch-size']) {
|
|
222
|
-
const scale = (0, node_core_1.checkMemoryUsage)(this.batchSizeScale, this.nodeConfig);
|
|
223
|
-
if (this.batchSizeScale !== scale) {
|
|
224
|
-
this.batchSizeScale = scale;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
161
|
+
async getFinalizedHeight() {
|
|
162
|
+
const block = await this.api.getFinalizedBlock();
|
|
163
|
+
const header = (0, unfinalizedBlocks_service_1.blockToHeader)(block);
|
|
164
|
+
this.unfinalizedBlocksService.registerFinalizedBlock(header);
|
|
165
|
+
return header.blockHeight;
|
|
227
166
|
}
|
|
228
|
-
async
|
|
229
|
-
|
|
230
|
-
logger.debug(`Skip fetch finalized block until API is ready`);
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
try {
|
|
234
|
-
const currentFinalizedHeight = await this.api.getFinalizedBlockHeight();
|
|
235
|
-
logger.debug(`finalized:${currentFinalizedHeight.toString()}`);
|
|
236
|
-
const finalizedHeader = await this.api.getBlockByHeightOrHash(currentFinalizedHeight);
|
|
237
|
-
if (this.latestFinalizedHeight !== currentFinalizedHeight) {
|
|
238
|
-
this.latestFinalizedHeight = currentFinalizedHeight;
|
|
239
|
-
this.unfinalizedBlocksService.registerFinalizedBlock(finalizedHeader);
|
|
240
|
-
if (!this.nodeConfig.unfinalizedBlocks) {
|
|
241
|
-
if (!this.nodeConfig.unfinalizedBlocks) {
|
|
242
|
-
this.eventEmitter.emit(node_core_1.IndexerEvent.BlockTarget, {
|
|
243
|
-
height: this.latestFinalizedHeight,
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
catch (e) {
|
|
250
|
-
logger.warn(e, `Having a problem when get finalized block`);
|
|
251
|
-
}
|
|
167
|
+
async getBestHeight() {
|
|
168
|
+
return this.api.getBestBlockHeight();
|
|
252
169
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
}
|
|
258
|
-
try {
|
|
259
|
-
const currentBestHeight = await this.api.getBestBlockHeight();
|
|
260
|
-
logger.debug(`best:${currentBestHeight.toString()}`);
|
|
261
|
-
if (this.latestBestHeight !== currentBestHeight) {
|
|
262
|
-
this.latestBestHeight = currentBestHeight;
|
|
263
|
-
this.eventEmitter.emit(node_core_1.IndexerEvent.BlockBest, {
|
|
264
|
-
height: this.latestBestHeight,
|
|
265
|
-
});
|
|
266
|
-
if (this.nodeConfig.unfinalizedBlocks) {
|
|
267
|
-
this.eventEmitter.emit(node_core_1.IndexerEvent.BlockTarget, {
|
|
268
|
-
height: this.latestBestHeight,
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
catch (e) {
|
|
274
|
-
logger.warn(e, `Having a problem when get best block`);
|
|
275
|
-
}
|
|
170
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
171
|
+
async getChainInterval() {
|
|
172
|
+
const CHAIN_INTERVAL = (0, utils_ethereum_1.calcInterval)(this.api) * INTERVAL_PERCENT;
|
|
173
|
+
return Math.min(BLOCK_TIME_VARIANCE, CHAIN_INTERVAL);
|
|
276
174
|
}
|
|
277
|
-
async
|
|
278
|
-
|
|
175
|
+
async getChainId() {
|
|
176
|
+
return Promise.resolve(this.api.getChainId().toString());
|
|
279
177
|
}
|
|
280
178
|
getModulos() {
|
|
281
179
|
const modulos = [];
|
|
@@ -293,176 +191,19 @@ let FetchService = class FetchService {
|
|
|
293
191
|
}
|
|
294
192
|
return modulos;
|
|
295
193
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
const moduloBlocks = [];
|
|
299
|
-
for (let i = startHeight; i < endHeight; i++) {
|
|
300
|
-
if (modulos.find((m) => i % m === 0)) {
|
|
301
|
-
moduloBlocks.push(i);
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
return moduloBlocks;
|
|
305
|
-
}
|
|
306
|
-
getEnqueuedModuloBlocks(startBlockHeight) {
|
|
307
|
-
return this.getModuloBlocks(startBlockHeight, this.nodeConfig.batchSize * Math.max(...this.getModulos()) +
|
|
308
|
-
startBlockHeight).slice(0, this.nodeConfig.batchSize);
|
|
309
|
-
}
|
|
310
|
-
async fillNextBlockBuffer(initBlockHeight) {
|
|
311
|
-
let startBlockHeight;
|
|
312
|
-
let scaledBatchSize;
|
|
313
|
-
const handlers = [].concat(...this.project.dataSources.map((ds) => ds.mapping.handlers));
|
|
314
|
-
const getStartBlockHeight = () => {
|
|
315
|
-
return this.blockDispatcher.latestBufferedHeight
|
|
316
|
-
? this.blockDispatcher.latestBufferedHeight + 1
|
|
317
|
-
: initBlockHeight;
|
|
318
|
-
};
|
|
319
|
-
if (this.useDictionary &&
|
|
320
|
-
this.dictionaryService.startHeight > getStartBlockHeight()) {
|
|
321
|
-
logger.warn(`Dictionary start height ${this.dictionaryService.startHeight} is beyond indexing height ${getStartBlockHeight()}, skipping dictionary for now`);
|
|
322
|
-
}
|
|
323
|
-
while (!this.isShutdown) {
|
|
324
|
-
startBlockHeight = getStartBlockHeight();
|
|
325
|
-
scaledBatchSize = this.blockDispatcher.smartBatchSize;
|
|
326
|
-
if (scaledBatchSize === 0) {
|
|
327
|
-
await (0, node_core_1.waitForBatchSize)(this.blockDispatcher.minimumHeapLimit);
|
|
328
|
-
continue;
|
|
329
|
-
}
|
|
330
|
-
const latestHeight = this.nodeConfig.unfinalizedBlocks
|
|
331
|
-
? this.latestBestHeight
|
|
332
|
-
: this.latestFinalizedHeight;
|
|
333
|
-
if (this.blockDispatcher.freeSize < scaledBatchSize ||
|
|
334
|
-
startBlockHeight > latestHeight) {
|
|
335
|
-
await (0, node_core_1.delay)(1);
|
|
336
|
-
continue;
|
|
337
|
-
}
|
|
338
|
-
if (this.useDictionary &&
|
|
339
|
-
startBlockHeight >= this.dictionaryService.startHeight) {
|
|
340
|
-
const queryEndBlock = startBlockHeight + DICTIONARY_MAX_QUERY_SIZE;
|
|
341
|
-
const moduloBlocks = this.getModuloBlocks(startBlockHeight, queryEndBlock);
|
|
342
|
-
try {
|
|
343
|
-
const dictionary = await this.dictionaryService.scopedDictionaryEntries(startBlockHeight, queryEndBlock, scaledBatchSize);
|
|
344
|
-
if (startBlockHeight !== getStartBlockHeight()) {
|
|
345
|
-
logger.debug(`Queue was reset for new DS, discarding dictionary query result`);
|
|
346
|
-
continue;
|
|
347
|
-
}
|
|
348
|
-
if (dictionary &&
|
|
349
|
-
this.dictionaryValidation(dictionary, startBlockHeight)) {
|
|
350
|
-
let { batchBlocks } = dictionary;
|
|
351
|
-
batchBlocks = batchBlocks
|
|
352
|
-
.concat(moduloBlocks)
|
|
353
|
-
.sort((a, b) => a - b);
|
|
354
|
-
if (batchBlocks.length === 0) {
|
|
355
|
-
// There we're no blocks in this query range, we can set a new height we're up to
|
|
356
|
-
await this.blockDispatcher.enqueueBlocks([], Math.min(queryEndBlock - 1, dictionary._metadata.lastProcessedHeight));
|
|
357
|
-
}
|
|
358
|
-
else {
|
|
359
|
-
const maxBlockSize = Math.min(batchBlocks.length, this.blockDispatcher.freeSize);
|
|
360
|
-
const enqueuingBlocks = batchBlocks.slice(0, maxBlockSize);
|
|
361
|
-
const cleanedBatchBlocks = this.filteredBlockBatch(enqueuingBlocks);
|
|
362
|
-
await this.blockDispatcher.enqueueBlocks(cleanedBatchBlocks, this.getLatestBufferHeight(cleanedBatchBlocks, enqueuingBlocks));
|
|
363
|
-
}
|
|
364
|
-
continue; // skip nextBlockRange() way
|
|
365
|
-
}
|
|
366
|
-
// else use this.nextBlockRange()
|
|
367
|
-
}
|
|
368
|
-
catch (e) {
|
|
369
|
-
logger.debug(`Fetch dictionary stopped: ${e.message}`);
|
|
370
|
-
this.eventEmitter.emit(node_core_1.IndexerEvent.SkipDictionary);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
const endHeight = this.nextEndBlockHeight(startBlockHeight, scaledBatchSize);
|
|
374
|
-
const enqueuingBlocks = handlers.length && this.getModulos().length === handlers.length
|
|
375
|
-
? this.getEnqueuedModuloBlocks(startBlockHeight)
|
|
376
|
-
: (0, lodash_1.range)(startBlockHeight, endHeight + 1);
|
|
377
|
-
const cleanedBatchBlocks = this.filteredBlockBatch(enqueuingBlocks);
|
|
378
|
-
await this.blockDispatcher.enqueueBlocks(cleanedBatchBlocks, this.getLatestBufferHeight(cleanedBatchBlocks, enqueuingBlocks));
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
getLatestBufferHeight(cleanedBatchBlocks, rawBatchBlocks) {
|
|
382
|
-
return Math.max(...cleanedBatchBlocks, ...rawBatchBlocks);
|
|
383
|
-
}
|
|
384
|
-
filteredBlockBatch(currentBatchBlocks) {
|
|
385
|
-
if (!this.bypassBlocks.length || !currentBatchBlocks) {
|
|
386
|
-
return currentBatchBlocks;
|
|
387
|
-
}
|
|
388
|
-
const cleanedBatch = (0, node_core_1.cleanedBatchBlocks)(this.bypassBlocks, currentBatchBlocks);
|
|
389
|
-
const pollutedBlocks = this.bypassBlocks.filter((b) => b < Math.max(...currentBatchBlocks));
|
|
390
|
-
if (pollutedBlocks.length) {
|
|
391
|
-
logger.info(`Bypassing blocks: ${pollutedBlocks}`);
|
|
392
|
-
}
|
|
393
|
-
this.bypassBlocks = (0, lodash_1.without)(this.bypassBlocks, ...pollutedBlocks);
|
|
394
|
-
return cleanedBatch;
|
|
395
|
-
}
|
|
396
|
-
nextEndBlockHeight(startBlockHeight, scaledBatchSize) {
|
|
397
|
-
let endBlockHeight = startBlockHeight + scaledBatchSize - 1;
|
|
398
|
-
if (endBlockHeight > this.latestFinalizedHeight) {
|
|
399
|
-
if (this.nodeConfig.unfinalizedBlocks) {
|
|
400
|
-
if (endBlockHeight >= this.latestBestHeight) {
|
|
401
|
-
endBlockHeight = this.latestBestHeight;
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
else {
|
|
405
|
-
endBlockHeight = this.latestFinalizedHeight;
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
return endBlockHeight;
|
|
409
|
-
}
|
|
410
|
-
dictionaryValidation(dictionary, startBlockHeight) {
|
|
411
|
-
const validate = () => {
|
|
412
|
-
if (dictionary !== undefined) {
|
|
413
|
-
const { _metadata: metaData } = dictionary;
|
|
414
|
-
if (metaData.genesisHash !== this.api.getGenesisHash() &&
|
|
415
|
-
this.evmChainId !== this.api.getChainId().toString()) {
|
|
416
|
-
logger.error('The dictionary that you have specified does not match the chain you are indexing, it will be ignored. Please update your project manifest to reference the correct dictionary');
|
|
417
|
-
return false;
|
|
418
|
-
}
|
|
419
|
-
if (startBlockHeight !== undefined &&
|
|
420
|
-
metaData.lastProcessedHeight < startBlockHeight) {
|
|
421
|
-
logger.warn(`Dictionary indexed block is behind current indexing block height`);
|
|
422
|
-
return false;
|
|
423
|
-
}
|
|
424
|
-
return true;
|
|
425
|
-
}
|
|
426
|
-
return false;
|
|
427
|
-
};
|
|
428
|
-
const valid = validate();
|
|
429
|
-
this.dictionaryMetaValid = valid;
|
|
430
|
-
this.eventEmitter.emit(node_core_1.IndexerEvent.UsingDictionary, {
|
|
431
|
-
value: Number(this.useDictionary),
|
|
432
|
-
});
|
|
433
|
-
this.eventEmitter.emit(node_core_1.IndexerEvent.SkipDictionary);
|
|
434
|
-
return valid;
|
|
194
|
+
async initBlockDispatcher() {
|
|
195
|
+
await this.blockDispatcher.init(this.resetForNewDs.bind(this));
|
|
435
196
|
}
|
|
436
|
-
async
|
|
437
|
-
await this.
|
|
438
|
-
this.
|
|
439
|
-
|
|
440
|
-
this.blockDispatcher.flushQueue(blockHeight);
|
|
197
|
+
async validatateDictionaryMeta(metaData) {
|
|
198
|
+
const evmChainId = await this.dictionaryService.getEvmChainId();
|
|
199
|
+
return (metaData.genesisHash !== this.api.getGenesisHash() &&
|
|
200
|
+
evmChainId !== this.api.getChainId().toString());
|
|
441
201
|
}
|
|
442
|
-
async
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
this.blockDispatcher.flushQueue(blockHeight);
|
|
202
|
+
async preLoopHook() {
|
|
203
|
+
// Ethereum doesn't need to do anything here
|
|
204
|
+
return Promise.resolve();
|
|
446
205
|
}
|
|
447
206
|
};
|
|
448
|
-
__decorate([
|
|
449
|
-
(0, schedule_1.Interval)(CHECK_MEMORY_INTERVAL),
|
|
450
|
-
__metadata("design:type", Function),
|
|
451
|
-
__metadata("design:paramtypes", []),
|
|
452
|
-
__metadata("design:returntype", void 0)
|
|
453
|
-
], FetchService.prototype, "checkBatchScale", null);
|
|
454
|
-
__decorate([
|
|
455
|
-
(0, schedule_1.Interval)(BLOCK_TIME_VARIANCE),
|
|
456
|
-
__metadata("design:type", Function),
|
|
457
|
-
__metadata("design:paramtypes", []),
|
|
458
|
-
__metadata("design:returntype", Promise)
|
|
459
|
-
], FetchService.prototype, "getFinalizedBlockHead", null);
|
|
460
|
-
__decorate([
|
|
461
|
-
(0, schedule_1.Interval)(BLOCK_TIME_VARIANCE),
|
|
462
|
-
__metadata("design:type", Function),
|
|
463
|
-
__metadata("design:paramtypes", []),
|
|
464
|
-
__metadata("design:returntype", Promise)
|
|
465
|
-
], FetchService.prototype, "getBestBlockHead", null);
|
|
466
207
|
FetchService = __decorate([
|
|
467
208
|
(0, common_1.Injectable)(),
|
|
468
209
|
__param(2, (0, common_1.Inject)('ISubqueryProject')),
|
|
@@ -470,6 +211,7 @@ FetchService = __decorate([
|
|
|
470
211
|
__metadata("design:paramtypes", [node_core_1.ApiService,
|
|
471
212
|
node_core_1.NodeConfig,
|
|
472
213
|
SubqueryProject_1.SubqueryProject, Object, dictionary_service_1.DictionaryService,
|
|
214
|
+
ds_processor_service_1.DsProcessorService,
|
|
473
215
|
dynamic_ds_service_1.DynamicDsService,
|
|
474
216
|
unfinalizedBlocks_service_1.UnfinalizedBlocksService,
|
|
475
217
|
event_emitter_1.EventEmitter2,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.service.js","sourceRoot":"","sources":["../../src/indexer/fetch.service.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2020-2022 OnFinality Limited authors & contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport { Interval, SchedulerRegistry } from '@nestjs/schedule';\n\nimport {\n isCustomDs,\n EthereumHandlerKind,\n EthereumLogFilter,\n SubqlEthereumProcessorOptions,\n EthereumTransactionFilter,\n} from '@subql/common-ethereum';\nimport {\n ApiService,\n cleanedBatchBlocks,\n checkMemoryUsage,\n delay,\n getLogger,\n IndexerEvent,\n NodeConfig,\n transformBypassBlocks,\n waitForBatchSize,\n} from '@subql/node-core';\nimport {\n ApiWrapper,\n DictionaryQueryCondition,\n DictionaryQueryEntry,\n} from '@subql/types-ethereum';\nimport { MetaData } from '@subql/utils';\nimport { groupBy, range, sortBy, uniqBy, without } from 'lodash';\nimport { SubqlProjectDs, SubqueryProject } from '../configure/SubqueryProject';\nimport { calcInterval } from '../ethereum/utils.ethereum';\nimport { eventToTopic, functionToSighash } from '../utils/string';\nimport { IEthereumBlockDispatcher } from './blockDispatcher';\nimport { DictionaryService } from './dictionary.service';\nimport { DynamicDsService } from './dynamic-ds.service';\nimport { UnfinalizedBlocksService } from './unfinalizedBlocks.service';\n\nconst logger = getLogger('fetch');\nlet BLOCK_TIME_VARIANCE = 5000;\nconst DICTIONARY_MAX_QUERY_SIZE = 10000;\nconst CHECK_MEMORY_INTERVAL = 60000;\nconst MINIMUM_BATCH_SIZE = 5;\nconst INTERVAL_PERCENT = 0.9;\nconst QUERY_ADDRESS_LIMIT = 50;\n\nfunction eventFilterToQueryEntry(\n filter: EthereumLogFilter,\n dsOptions: SubqlEthereumProcessorOptions | SubqlEthereumProcessorOptions[],\n): DictionaryQueryEntry {\n const conditions: DictionaryQueryCondition[] = [];\n\n if (Array.isArray(dsOptions)) {\n const addresses = dsOptions.map((option) => option.address).filter(Boolean);\n\n if (addresses.length !== 0 && addresses.length <= QUERY_ADDRESS_LIMIT) {\n conditions.push({\n field: 'address',\n value: addresses,\n matcher: 'inInsensitive',\n });\n }\n } else {\n if (dsOptions?.address) {\n conditions.push({\n field: 'address',\n value: dsOptions.address.toLowerCase(),\n // matcher: 'equals',\n });\n }\n }\n if (filter.topics) {\n for (let i = 0; i < Math.min(filter.topics.length, 4); i++) {\n const topic = filter.topics[i];\n if (!topic) {\n continue;\n }\n const field = `topics${i}`;\n conditions.push({\n field,\n value: eventToTopic(topic),\n matcher: 'equalTo',\n });\n }\n }\n return {\n entity: 'evmLogs',\n conditions,\n };\n}\n\nfunction callFilterToQueryEntry(\n filter: EthereumTransactionFilter,\n): DictionaryQueryEntry {\n const conditions: DictionaryQueryCondition[] = [];\n if (filter.from) {\n conditions.push({\n field: 'from',\n value: filter.from.toLowerCase(),\n });\n }\n if (filter.to) {\n conditions.push({\n field: 'to',\n value: filter.to.toLowerCase(),\n });\n }\n if (filter.function) {\n conditions.push({\n field: 'func',\n value: functionToSighash(filter.function),\n matcher: 'equalTo',\n });\n }\n return {\n entity: 'evmTransactions',\n conditions,\n };\n}\n\n@Injectable()\nexport class FetchService implements OnApplicationShutdown {\n private latestBestHeight: number;\n private latestFinalizedHeight: number;\n private isShutdown = false;\n private batchSizeScale: number;\n private templateDynamicDatasouces: SubqlProjectDs[];\n private dictionaryMetaValid = false;\n private evmChainId: string;\n private bypassBlocks: number[] = [];\n\n constructor(\n private apiService: ApiService,\n private nodeConfig: NodeConfig,\n @Inject('ISubqueryProject') private project: SubqueryProject,\n @Inject('IBlockDispatcher')\n private blockDispatcher: IEthereumBlockDispatcher,\n private dictionaryService: DictionaryService,\n private dynamicDsService: DynamicDsService,\n private unfinalizedBlocksService: UnfinalizedBlocksService,\n private eventEmitter: EventEmitter2,\n private schedulerRegistry: SchedulerRegistry,\n ) {\n this.batchSizeScale = 1;\n }\n\n onApplicationShutdown(): void {\n this.isShutdown = true;\n }\n\n get api(): ApiWrapper {\n return this.apiService.api;\n }\n\n async syncDynamicDatascourcesFromMeta(): Promise<void> {\n this.templateDynamicDatasouces =\n await this.dynamicDsService.getDynamicDatasources();\n }\n\n buildDictionaryQueryEntries(startBlock: number): DictionaryQueryEntry[] {\n const queryEntries: DictionaryQueryEntry[] = [];\n\n type GroupedSubqlProjectDs = SubqlProjectDs & {\n groupedOptions?: SubqlEthereumProcessorOptions[];\n };\n\n const groupdDynamicDs: GroupedSubqlProjectDs[] = Object.values(\n groupBy(this.templateDynamicDatasouces, (ds) => ds.name),\n ).map((grouped: SubqlProjectDs[]) => {\n const options = grouped.map((ds) => ds.options);\n const ref = grouped[0];\n\n return {\n ...ref,\n groupedOptions: options,\n };\n });\n\n // Only run the ds that is equal or less than startBlock\n // sort array from lowest ds.startBlock to highest\n const filteredDs: GroupedSubqlProjectDs[] = this.project.dataSources\n .concat(groupdDynamicDs)\n .filter((ds) => ds.startBlock <= startBlock)\n .sort((a, b) => a.startBlock - b.startBlock);\n\n for (const ds of filteredDs) {\n for (const handler of ds.mapping.handlers) {\n // No filters, cant use dictionary\n if (!handler.filter) return [];\n\n switch (handler.kind) {\n case EthereumHandlerKind.Block:\n return [];\n case EthereumHandlerKind.Call: {\n const filter = handler.filter as EthereumTransactionFilter;\n if (\n filter.from !== undefined ||\n filter.to !== undefined ||\n filter.function\n ) {\n queryEntries.push(callFilterToQueryEntry(filter));\n } else {\n return [];\n }\n break;\n }\n case EthereumHandlerKind.Event: {\n const filter = handler.filter as EthereumLogFilter;\n if (ds.groupedOptions) {\n queryEntries.push(\n eventFilterToQueryEntry(filter, ds.groupedOptions),\n );\n } else if (ds.options?.address || filter.topics) {\n queryEntries.push(eventFilterToQueryEntry(filter, ds.options));\n } else {\n return [];\n }\n break;\n }\n default:\n }\n }\n }\n\n return uniqBy(\n queryEntries,\n (item) =>\n `${item.entity}|${JSON.stringify(\n sortBy(item.conditions, (c) => c.field),\n )}`,\n );\n }\n\n updateDictionary(): void {\n this.dictionaryService.buildDictionaryEntryMap<SubqlProjectDs>(\n this.project.dataSources.concat(this.templateDynamicDatasouces),\n this.buildDictionaryQueryEntries.bind(this),\n );\n }\n\n private get useDictionary(): boolean {\n return (\n !!this.project.network.dictionary &&\n this.dictionaryMetaValid &&\n !!this.dictionaryService.getDictionaryQueryEntries(\n this.blockDispatcher.latestBufferedHeight ??\n Math.min(...this.project.dataSources.map((ds) => ds.startBlock)),\n ).length\n );\n }\n\n async init(startHeight: number): Promise<void> {\n if (this.project.network?.bypassBlocks !== undefined) {\n this.bypassBlocks = transformBypassBlocks(\n this.project.network.bypassBlocks,\n ).filter((blk) => blk >= startHeight);\n }\n if (this.api) {\n const CHAIN_INTERVAL = calcInterval(this.api) * INTERVAL_PERCENT;\n\n BLOCK_TIME_VARIANCE = Math.min(BLOCK_TIME_VARIANCE, CHAIN_INTERVAL);\n\n this.schedulerRegistry.addInterval(\n 'getLatestBlockHead',\n setInterval(() => void this.getBestBlockHead(), BLOCK_TIME_VARIANCE),\n );\n }\n await this.syncDynamicDatascourcesFromMeta();\n\n if (this.project.network.dictionary) {\n this.updateDictionary();\n // Call metadata here, other network should align with this\n // For substrate, we might use the specVersion metadata in future if we have same error handling as in node-core\n const metadata = await this.dictionaryService.getMetadata();\n this.evmChainId = await this.dictionaryService.getEvmChainId();\n this.dictionaryValidation(metadata);\n }\n\n await Promise.all([this.getFinalizedBlockHead(), this.getBestBlockHead()]);\n\n await this.blockDispatcher.init(this.resetForNewDs.bind(this));\n void this.startLoop(startHeight);\n }\n\n getUseDictionary(): boolean {\n return this.useDictionary;\n }\n\n getLatestFinalizedHeight(): number {\n return this.latestFinalizedHeight;\n }\n\n @Interval(CHECK_MEMORY_INTERVAL)\n checkBatchScale(): void {\n if (this.nodeConfig['scale-batch-size']) {\n const scale = checkMemoryUsage(this.batchSizeScale, this.nodeConfig);\n\n if (this.batchSizeScale !== scale) {\n this.batchSizeScale = scale;\n }\n }\n }\n\n @Interval(BLOCK_TIME_VARIANCE)\n async getFinalizedBlockHead(): Promise<void> {\n if (!this.api) {\n logger.debug(`Skip fetch finalized block until API is ready`);\n return;\n }\n try {\n const currentFinalizedHeight = await this.api.getFinalizedBlockHeight();\n logger.debug(`finalized:${currentFinalizedHeight.toString()}`);\n const finalizedHeader = await this.api.getBlockByHeightOrHash(\n currentFinalizedHeight,\n );\n if (this.latestFinalizedHeight !== currentFinalizedHeight) {\n this.latestFinalizedHeight = currentFinalizedHeight;\n this.unfinalizedBlocksService.registerFinalizedBlock(finalizedHeader);\n if (!this.nodeConfig.unfinalizedBlocks) {\n if (!this.nodeConfig.unfinalizedBlocks) {\n this.eventEmitter.emit(IndexerEvent.BlockTarget, {\n height: this.latestFinalizedHeight,\n });\n }\n }\n }\n } catch (e) {\n logger.warn(e, `Having a problem when get finalized block`);\n }\n }\n\n @Interval(BLOCK_TIME_VARIANCE)\n async getBestBlockHead(): Promise<void> {\n if (!this.api) {\n logger.debug(`Skip fetch best block until API is ready`);\n return;\n }\n try {\n const currentBestHeight = await this.api.getBestBlockHeight();\n logger.debug(`best:${currentBestHeight.toString()}`);\n if (this.latestBestHeight !== currentBestHeight) {\n this.latestBestHeight = currentBestHeight;\n this.eventEmitter.emit(IndexerEvent.BlockBest, {\n height: this.latestBestHeight,\n });\n\n if (this.nodeConfig.unfinalizedBlocks) {\n this.eventEmitter.emit(IndexerEvent.BlockTarget, {\n height: this.latestBestHeight,\n });\n }\n }\n } catch (e) {\n logger.warn(e, `Having a problem when get best block`);\n }\n }\n private async startLoop(initBlockHeight: number): Promise<void> {\n await this.fillNextBlockBuffer(initBlockHeight);\n }\n\n getModulos(): number[] {\n const modulos: number[] = [];\n for (const ds of this.project.dataSources) {\n if (isCustomDs(ds)) {\n continue;\n }\n for (const handler of ds.mapping.handlers) {\n if (\n handler.kind === EthereumHandlerKind.Block &&\n handler.filter &&\n handler.filter.modulo\n ) {\n modulos.push(handler.filter.modulo);\n }\n }\n }\n return modulos;\n }\n\n getModuloBlocks(startHeight: number, endHeight: number): number[] {\n const modulos = this.getModulos();\n const moduloBlocks: number[] = [];\n for (let i = startHeight; i < endHeight; i++) {\n if (modulos.find((m) => i % m === 0)) {\n moduloBlocks.push(i);\n }\n }\n return moduloBlocks;\n }\n\n getEnqueuedModuloBlocks(startBlockHeight: number): number[] {\n return this.getModuloBlocks(\n startBlockHeight,\n this.nodeConfig.batchSize * Math.max(...this.getModulos()) +\n startBlockHeight,\n ).slice(0, this.nodeConfig.batchSize);\n }\n\n async fillNextBlockBuffer(initBlockHeight: number): Promise<void> {\n let startBlockHeight: number;\n let scaledBatchSize: number;\n const handlers = [].concat(\n ...this.project.dataSources.map((ds) => ds.mapping.handlers),\n );\n\n const getStartBlockHeight = (): number => {\n return this.blockDispatcher.latestBufferedHeight\n ? this.blockDispatcher.latestBufferedHeight + 1\n : initBlockHeight;\n };\n\n if (\n this.useDictionary &&\n this.dictionaryService.startHeight > getStartBlockHeight()\n ) {\n logger.warn(\n `Dictionary start height ${\n this.dictionaryService.startHeight\n } is beyond indexing height ${getStartBlockHeight()}, skipping dictionary for now`,\n );\n }\n\n while (!this.isShutdown) {\n startBlockHeight = getStartBlockHeight();\n\n scaledBatchSize = this.blockDispatcher.smartBatchSize;\n\n if (scaledBatchSize === 0) {\n await waitForBatchSize(this.blockDispatcher.minimumHeapLimit);\n continue;\n }\n\n const latestHeight = this.nodeConfig.unfinalizedBlocks\n ? this.latestBestHeight\n : this.latestFinalizedHeight;\n\n if (\n this.blockDispatcher.freeSize < scaledBatchSize ||\n startBlockHeight > latestHeight\n ) {\n await delay(1);\n continue;\n }\n\n if (\n this.useDictionary &&\n startBlockHeight >= this.dictionaryService.startHeight\n ) {\n const queryEndBlock = startBlockHeight + DICTIONARY_MAX_QUERY_SIZE;\n const moduloBlocks = this.getModuloBlocks(\n startBlockHeight,\n queryEndBlock,\n );\n\n try {\n const dictionary =\n await this.dictionaryService.scopedDictionaryEntries(\n startBlockHeight,\n queryEndBlock,\n scaledBatchSize,\n );\n\n if (startBlockHeight !== getStartBlockHeight()) {\n logger.debug(\n `Queue was reset for new DS, discarding dictionary query result`,\n );\n continue;\n }\n\n if (\n dictionary &&\n this.dictionaryValidation(dictionary, startBlockHeight)\n ) {\n let { batchBlocks } = dictionary;\n\n batchBlocks = batchBlocks\n .concat(moduloBlocks)\n .sort((a, b) => a - b);\n if (batchBlocks.length === 0) {\n // There we're no blocks in this query range, we can set a new height we're up to\n await this.blockDispatcher.enqueueBlocks(\n [],\n Math.min(\n queryEndBlock - 1,\n dictionary._metadata.lastProcessedHeight,\n ),\n );\n } else {\n const maxBlockSize = Math.min(\n batchBlocks.length,\n this.blockDispatcher.freeSize,\n );\n const enqueuingBlocks = batchBlocks.slice(0, maxBlockSize);\n const cleanedBatchBlocks =\n this.filteredBlockBatch(enqueuingBlocks);\n await this.blockDispatcher.enqueueBlocks(\n cleanedBatchBlocks,\n this.getLatestBufferHeight(cleanedBatchBlocks, enqueuingBlocks),\n );\n }\n continue; // skip nextBlockRange() way\n }\n // else use this.nextBlockRange()\n } catch (e) {\n logger.debug(`Fetch dictionary stopped: ${e.message}`);\n this.eventEmitter.emit(IndexerEvent.SkipDictionary);\n }\n }\n\n const endHeight = this.nextEndBlockHeight(\n startBlockHeight,\n scaledBatchSize,\n );\n\n const enqueuingBlocks =\n handlers.length && this.getModulos().length === handlers.length\n ? this.getEnqueuedModuloBlocks(startBlockHeight)\n : range(startBlockHeight, endHeight + 1);\n\n const cleanedBatchBlocks = this.filteredBlockBatch(enqueuingBlocks);\n await this.blockDispatcher.enqueueBlocks(\n cleanedBatchBlocks,\n this.getLatestBufferHeight(cleanedBatchBlocks, enqueuingBlocks),\n );\n }\n }\n\n private getLatestBufferHeight(\n cleanedBatchBlocks: number[],\n rawBatchBlocks: number[],\n ): number {\n return Math.max(...cleanedBatchBlocks, ...rawBatchBlocks);\n }\n private filteredBlockBatch(currentBatchBlocks: number[]): number[] {\n if (!this.bypassBlocks.length || !currentBatchBlocks) {\n return currentBatchBlocks;\n }\n\n const cleanedBatch = cleanedBatchBlocks(\n this.bypassBlocks,\n currentBatchBlocks,\n );\n\n const pollutedBlocks = this.bypassBlocks.filter(\n (b) => b < Math.max(...currentBatchBlocks),\n );\n if (pollutedBlocks.length) {\n logger.info(`Bypassing blocks: ${pollutedBlocks}`);\n }\n this.bypassBlocks = without(this.bypassBlocks, ...pollutedBlocks);\n return cleanedBatch;\n }\n\n private nextEndBlockHeight(\n startBlockHeight: number,\n scaledBatchSize: number,\n ): number {\n let endBlockHeight = startBlockHeight + scaledBatchSize - 1;\n\n if (endBlockHeight > this.latestFinalizedHeight) {\n if (this.nodeConfig.unfinalizedBlocks) {\n if (endBlockHeight >= this.latestBestHeight) {\n endBlockHeight = this.latestBestHeight;\n }\n } else {\n endBlockHeight = this.latestFinalizedHeight;\n }\n }\n return endBlockHeight;\n }\n\n private dictionaryValidation(\n dictionary: { _metadata: MetaData },\n startBlockHeight?: number,\n ): boolean {\n const validate = (): boolean => {\n if (dictionary !== undefined) {\n const { _metadata: metaData } = dictionary;\n\n if (\n metaData.genesisHash !== this.api.getGenesisHash() &&\n this.evmChainId !== this.api.getChainId().toString()\n ) {\n logger.error(\n 'The dictionary that you have specified does not match the chain you are indexing, it will be ignored. Please update your project manifest to reference the correct dictionary',\n );\n return false;\n }\n\n if (\n startBlockHeight !== undefined &&\n metaData.lastProcessedHeight < startBlockHeight\n ) {\n logger.warn(\n `Dictionary indexed block is behind current indexing block height`,\n );\n return false;\n }\n return true;\n }\n return false;\n };\n\n const valid = validate();\n\n this.dictionaryMetaValid = valid;\n this.eventEmitter.emit(IndexerEvent.UsingDictionary, {\n value: Number(this.useDictionary),\n });\n this.eventEmitter.emit(IndexerEvent.SkipDictionary);\n\n return valid;\n }\n\n async resetForNewDs(blockHeight: number): Promise<void> {\n await this.syncDynamicDatascourcesFromMeta();\n this.dynamicDsService.deleteTempDsRecords(blockHeight);\n this.updateDictionary();\n this.blockDispatcher.flushQueue(blockHeight);\n }\n async resetForIncorrectBestBlock(blockHeight: number): Promise<void> {\n await this.syncDynamicDatascourcesFromMeta();\n this.updateDictionary();\n this.blockDispatcher.flushQueue(blockHeight);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"fetch.service.js","sourceRoot":"","sources":["../../src/indexer/fetch.service.ts"],"names":[],"mappings":";AAAA,gEAAgE;AAChE,sCAAsC;;;;;;;;;;;;;;;AAEtC,2CAAoD;AACpD,yDAAsD;AACtD,+CAAqD;AAErD,4DAMgC;AAChC,gDAA4E;AAQ5E,mCAAiD;AACjD,kEAA+E;AAE/E,+DAA0D;AAC1D,4CAAkE;AAElE,6DAAyD;AACzD,iEAA4D;AAC5D,6DAAwD;AACxD,2EAGqC;AAErC,MAAM,mBAAmB,GAAG,IAAI,CAAC;AAEjC,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAC7B,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAE/B,SAAS,uBAAuB,CAC9B,MAAyB,EACzB,SAA0E;IAE1E,MAAM,UAAU,GAA+B,EAAE,CAAC;IAElD,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;QAC5B,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAE5E,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,CAAC,MAAM,IAAI,mBAAmB,EAAE;YACrE,UAAU,CAAC,IAAI,CAAC;gBACd,KAAK,EAAE,SAAS;gBAChB,KAAK,EAAE,SAAS;gBAChB,OAAO,EAAE,eAAe;aACzB,CAAC,CAAC;SACJ;KACF;SAAM;QACL,IAAI,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,OAAO,EAAE;YACtB,UAAU,CAAC,IAAI,CAAC;gBACd,KAAK,EAAE,SAAS;gBAChB,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,WAAW,EAAE;gBACtC,qBAAqB;aACtB,CAAC,CAAC;SACJ;KACF;IACD,IAAI,MAAM,CAAC,MAAM,EAAE;QACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YAC1D,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC/B,IAAI,CAAC,KAAK,EAAE;gBACV,SAAS;aACV;YACD,MAAM,KAAK,GAAG,SAAS,CAAC,EAAE,CAAC;YAC3B,UAAU,CAAC,IAAI,CAAC;gBACd,KAAK;gBACL,KAAK,EAAE,IAAA,qBAAY,EAAC,KAAK,CAAC;gBAC1B,OAAO,EAAE,SAAS;aACnB,CAAC,CAAC;SACJ;KACF;IACD,OAAO;QACL,MAAM,EAAE,SAAS;QACjB,UAAU;KACX,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAC7B,MAAiC;IAEjC,MAAM,UAAU,GAA+B,EAAE,CAAC;IAClD,IAAI,MAAM,CAAC,IAAI,EAAE;QACf,UAAU,CAAC,IAAI,CAAC;YACd,KAAK,EAAE,MAAM;YACb,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE;SACjC,CAAC,CAAC;KACJ;IACD,IAAI,MAAM,CAAC,EAAE,EAAE;QACb,UAAU,CAAC,IAAI,CAAC;YACd,KAAK,EAAE,IAAI;YACX,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE;SAC/B,CAAC,CAAC;KACJ;IACD,IAAI,MAAM,CAAC,QAAQ,EAAE;QACnB,UAAU,CAAC,IAAI,CAAC;YACd,KAAK,EAAE,MAAM;YACb,KAAK,EAAE,IAAA,0BAAiB,EAAC,MAAM,CAAC,QAAQ,CAAC;YACzC,OAAO,EAAE,SAAS;SACnB,CAAC,CAAC;KACJ;IACD,OAAO;QACL,MAAM,EAAE,iBAAiB;QACzB,UAAU;KACX,CAAC;AACJ,CAAC;AAGM,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,4BAIjC;IAGC,YACE,UAAsB,EACtB,UAAsB,EACM,OAAwB,EAEpD,eAAyC,EACzC,iBAAoC,EACpC,kBAAsC,EACtC,gBAAkC,EAC1B,wBAAkD,EAC1D,YAA2B,EAC3B,iBAAoC;QAEpC,KAAK,CACH,UAAU,EACV,UAAU,EACV,OAAO,EACP,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,CAClB,CAAC;QAdM,6BAAwB,GAAxB,wBAAwB,CAA0B;IAe5D,CAAC;IAED,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;IAC7B,CAAC;IAED,2BAA2B,CAAC,UAAkB;;QAC5C,MAAM,YAAY,GAA2B,EAAE,CAAC;QAMhD,MAAM,eAAe,GAA4B,MAAM,CAAC,MAAM,CAC5D,IAAA,gBAAO,EAAC,IAAI,CAAC,yBAAyB,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CACzD,CAAC,GAAG,CAAC,CAAC,OAAyB,EAAE,EAAE;YAClC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;YAChD,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAEvB,uCACK,GAAG,KACN,cAAc,EAAE,OAAO,IACvB;QACJ,CAAC,CAAC,CAAC;QAEH,wDAAwD;QACxD,kDAAkD;QAClD,MAAM,UAAU,GAA4B,IAAI,CAAC,OAAO,CAAC,WAAW;aACjE,MAAM,CAAC,eAAe,CAAC;aACvB,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,IAAI,UAAU,CAAC;aAC3C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;QAE/C,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE;YAC3B,KAAK,MAAM,OAAO,IAAI,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE;gBACzC,kCAAkC;gBAClC,IAAI,CAAC,OAAO,CAAC,MAAM;oBAAE,OAAO,EAAE,CAAC;gBAE/B,QAAQ,OAAO,CAAC,IAAI,EAAE;oBACpB,KAAK,qCAAmB,CAAC,KAAK;wBAC5B,OAAO,EAAE,CAAC;oBACZ,KAAK,qCAAmB,CAAC,IAAI,CAAC,CAAC;wBAC7B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAmC,CAAC;wBAC3D,IACE,MAAM,CAAC,IAAI,KAAK,SAAS;4BACzB,MAAM,CAAC,EAAE,KAAK,SAAS;4BACvB,MAAM,CAAC,QAAQ,EACf;4BACA,YAAY,CAAC,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,CAAC;yBACnD;6BAAM;4BACL,OAAO,EAAE,CAAC;yBACX;wBACD,MAAM;qBACP;oBACD,KAAK,qCAAmB,CAAC,KAAK,CAAC,CAAC;wBAC9B,MAAM,MAAM,GAAG,OAAO,CAAC,MAA2B,CAAC;wBACnD,IAAI,EAAE,CAAC,cAAc,EAAE;4BACrB,YAAY,CAAC,IAAI,CACf,uBAAuB,CAAC,MAAM,EAAE,EAAE,CAAC,cAAc,CAAC,CACnD,CAAC;yBACH;6BAAM,IAAI,CAAA,MAAA,EAAE,CAAC,OAAO,0CAAE,OAAO,KAAI,MAAM,CAAC,MAAM,EAAE;4BAC/C,YAAY,CAAC,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;yBAChE;6BAAM;4BACL,OAAO,EAAE,CAAC;yBACX;wBACD,MAAM;qBACP;oBACD,QAAQ;iBACT;aACF;SACF;QAED,OAAO,IAAA,eAAM,EACX,YAAY,EACZ,CAAC,IAAI,EAAE,EAAE,CACP,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS,CAC9B,IAAA,eAAM,EAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CACxC,EAAE,CACN,CAAC;IACJ,CAAC;IAES,KAAK,CAAC,kBAAkB;QAChC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAEjD,MAAM,MAAM,GAAG,IAAA,yCAAa,EAAC,KAAK,CAAC,CAAC;QAEpC,IAAI,CAAC,wBAAwB,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC;QAC7D,OAAO,MAAM,CAAC,WAAW,CAAC;IAC5B,CAAC;IAES,KAAK,CAAC,aAAa;QAC3B,OAAO,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC;IACvC,CAAC;IAED,4DAA4D;IAClD,KAAK,CAAC,gBAAgB;QAC9B,MAAM,cAAc,GAAG,IAAA,6BAAY,EAAC,IAAI,CAAC,GAAG,CAAC,GAAG,gBAAgB,CAAC;QAEjE,OAAO,IAAI,CAAC,GAAG,CAAC,mBAAmB,EAAE,cAAc,CAAC,CAAC;IACvD,CAAC;IAES,KAAK,CAAC,UAAU;QACxB,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC3D,CAAC;IAES,UAAU;QAClB,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE;YACzC,IAAI,IAAA,4BAAU,EAAC,EAAE,CAAC,EAAE;gBAClB,SAAS;aACV;YACD,KAAK,MAAM,OAAO,IAAI,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE;gBACzC,IACE,OAAO,CAAC,IAAI,KAAK,qCAAmB,CAAC,KAAK;oBAC1C,OAAO,CAAC,MAAM;oBACd,OAAO,CAAC,MAAM,CAAC,MAAM,EACrB;oBACA,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;iBACrC;aACF;SACF;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAES,KAAK,CAAC,mBAAmB;QACjC,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACjE,CAAC;IAES,KAAK,CAAC,wBAAwB,CACtC,QAAkB;QAElB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,aAAa,EAAE,CAAC;QAEhE,OAAO,CACL,QAAQ,CAAC,WAAW,KAAK,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE;YAClD,UAAU,KAAK,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,CAChD,CAAC;IACJ,CAAC;IAES,KAAK,CAAC,WAAW;QACzB,4CAA4C;QAC5C,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;CACF,CAAA;AA7KY,YAAY;IADxB,IAAA,mBAAU,GAAE;IAWR,WAAA,IAAA,eAAM,EAAC,kBAAkB,CAAC,CAAA;IAC1B,WAAA,IAAA,eAAM,EAAC,kBAAkB,CAAC,CAAA;qCAHf,sBAAU;QACV,sBAAU;QACe,iCAAe,UAGjC,sCAAiB;QAChB,yCAAkB;QACpB,qCAAgB;QACA,oDAAwB;QAC5C,6BAAa;QACR,4BAAiB;GAlB3B,YAAY,CA6KxB;AA7KY,oCAAY","sourcesContent":["// Copyright 2020-2022 OnFinality Limited authors & contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Inject, Injectable } from '@nestjs/common';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport { SchedulerRegistry } from '@nestjs/schedule';\n\nimport {\n isCustomDs,\n EthereumHandlerKind,\n EthereumLogFilter,\n SubqlEthereumProcessorOptions,\n EthereumTransactionFilter,\n} from '@subql/common-ethereum';\nimport { ApiService, NodeConfig, BaseFetchService } from '@subql/node-core';\nimport { DictionaryQueryCondition, DictionaryQueryEntry } from '@subql/types';\nimport {\n // DictionaryQueryCondition,\n // DictionaryQueryEntry,\n SubqlDatasource,\n} from '@subql/types-ethereum';\nimport { MetaData } from '@subql/utils';\nimport { groupBy, sortBy, uniqBy } from 'lodash';\nimport { SubqlProjectDs, SubqueryProject } from '../configure/SubqueryProject';\nimport { EthereumApi } from '../ethereum';\nimport { calcInterval } from '../ethereum/utils.ethereum';\nimport { eventToTopic, functionToSighash } from '../utils/string';\nimport { IEthereumBlockDispatcher } from './blockDispatcher';\nimport { DictionaryService } from './dictionary.service';\nimport { DsProcessorService } from './ds-processor.service';\nimport { DynamicDsService } from './dynamic-ds.service';\nimport {\n blockToHeader,\n UnfinalizedBlocksService,\n} from './unfinalizedBlocks.service';\n\nconst BLOCK_TIME_VARIANCE = 5000;\n\nconst INTERVAL_PERCENT = 0.9;\nconst QUERY_ADDRESS_LIMIT = 50;\n\nfunction eventFilterToQueryEntry(\n filter: EthereumLogFilter,\n dsOptions: SubqlEthereumProcessorOptions | SubqlEthereumProcessorOptions[],\n): DictionaryQueryEntry {\n const conditions: DictionaryQueryCondition[] = [];\n\n if (Array.isArray(dsOptions)) {\n const addresses = dsOptions.map((option) => option.address).filter(Boolean);\n\n if (addresses.length !== 0 && addresses.length <= QUERY_ADDRESS_LIMIT) {\n conditions.push({\n field: 'address',\n value: addresses,\n matcher: 'inInsensitive',\n });\n }\n } else {\n if (dsOptions?.address) {\n conditions.push({\n field: 'address',\n value: dsOptions.address.toLowerCase(),\n // matcher: 'equals',\n });\n }\n }\n if (filter.topics) {\n for (let i = 0; i < Math.min(filter.topics.length, 4); i++) {\n const topic = filter.topics[i];\n if (!topic) {\n continue;\n }\n const field = `topics${i}`;\n conditions.push({\n field,\n value: eventToTopic(topic),\n matcher: 'equalTo',\n });\n }\n }\n return {\n entity: 'evmLogs',\n conditions,\n };\n}\n\nfunction callFilterToQueryEntry(\n filter: EthereumTransactionFilter,\n): DictionaryQueryEntry {\n const conditions: DictionaryQueryCondition[] = [];\n if (filter.from) {\n conditions.push({\n field: 'from',\n value: filter.from.toLowerCase(),\n });\n }\n if (filter.to) {\n conditions.push({\n field: 'to',\n value: filter.to.toLowerCase(),\n });\n }\n if (filter.function) {\n conditions.push({\n field: 'func',\n value: functionToSighash(filter.function),\n matcher: 'equalTo',\n });\n }\n return {\n entity: 'evmTransactions',\n conditions,\n };\n}\n\n@Injectable()\nexport class FetchService extends BaseFetchService<\n SubqlDatasource,\n IEthereumBlockDispatcher,\n DictionaryService\n> {\n private evmChainId?: string;\n\n constructor(\n apiService: ApiService,\n nodeConfig: NodeConfig,\n @Inject('ISubqueryProject') project: SubqueryProject,\n @Inject('IBlockDispatcher')\n blockDispatcher: IEthereumBlockDispatcher,\n dictionaryService: DictionaryService,\n dsProcessorService: DsProcessorService,\n dynamicDsService: DynamicDsService,\n private unfinalizedBlocksService: UnfinalizedBlocksService,\n eventEmitter: EventEmitter2,\n schedulerRegistry: SchedulerRegistry,\n ) {\n super(\n apiService,\n nodeConfig,\n project,\n blockDispatcher,\n dictionaryService,\n dsProcessorService,\n dynamicDsService,\n eventEmitter,\n schedulerRegistry,\n );\n }\n\n get api(): EthereumApi {\n return this.apiService.api;\n }\n\n buildDictionaryQueryEntries(startBlock: number): DictionaryQueryEntry[] {\n const queryEntries: DictionaryQueryEntry[] = [];\n\n type GroupedSubqlProjectDs = SubqlDatasource & {\n groupedOptions?: SubqlEthereumProcessorOptions[];\n };\n\n const groupdDynamicDs: GroupedSubqlProjectDs[] = Object.values(\n groupBy(this.templateDynamicDatasouces, (ds) => ds.name),\n ).map((grouped: SubqlProjectDs[]) => {\n const options = grouped.map((ds) => ds.options);\n const ref = grouped[0];\n\n return {\n ...ref,\n groupedOptions: options,\n };\n });\n\n // Only run the ds that is equal or less than startBlock\n // sort array from lowest ds.startBlock to highest\n const filteredDs: GroupedSubqlProjectDs[] = this.project.dataSources\n .concat(groupdDynamicDs)\n .filter((ds) => ds.startBlock <= startBlock)\n .sort((a, b) => a.startBlock - b.startBlock);\n\n for (const ds of filteredDs) {\n for (const handler of ds.mapping.handlers) {\n // No filters, cant use dictionary\n if (!handler.filter) return [];\n\n switch (handler.kind) {\n case EthereumHandlerKind.Block:\n return [];\n case EthereumHandlerKind.Call: {\n const filter = handler.filter as EthereumTransactionFilter;\n if (\n filter.from !== undefined ||\n filter.to !== undefined ||\n filter.function\n ) {\n queryEntries.push(callFilterToQueryEntry(filter));\n } else {\n return [];\n }\n break;\n }\n case EthereumHandlerKind.Event: {\n const filter = handler.filter as EthereumLogFilter;\n if (ds.groupedOptions) {\n queryEntries.push(\n eventFilterToQueryEntry(filter, ds.groupedOptions),\n );\n } else if (ds.options?.address || filter.topics) {\n queryEntries.push(eventFilterToQueryEntry(filter, ds.options));\n } else {\n return [];\n }\n break;\n }\n default:\n }\n }\n }\n\n return uniqBy(\n queryEntries,\n (item) =>\n `${item.entity}|${JSON.stringify(\n sortBy(item.conditions, (c) => c.field),\n )}`,\n );\n }\n\n protected async getFinalizedHeight(): Promise<number> {\n const block = await this.api.getFinalizedBlock();\n\n const header = blockToHeader(block);\n\n this.unfinalizedBlocksService.registerFinalizedBlock(header);\n return header.blockHeight;\n }\n\n protected async getBestHeight(): Promise<number> {\n return this.api.getBestBlockHeight();\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n protected async getChainInterval(): Promise<number> {\n const CHAIN_INTERVAL = calcInterval(this.api) * INTERVAL_PERCENT;\n\n return Math.min(BLOCK_TIME_VARIANCE, CHAIN_INTERVAL);\n }\n\n protected async getChainId(): Promise<string> {\n return Promise.resolve(this.api.getChainId().toString());\n }\n\n protected getModulos(): number[] {\n const modulos: number[] = [];\n for (const ds of this.project.dataSources) {\n if (isCustomDs(ds)) {\n continue;\n }\n for (const handler of ds.mapping.handlers) {\n if (\n handler.kind === EthereumHandlerKind.Block &&\n handler.filter &&\n handler.filter.modulo\n ) {\n modulos.push(handler.filter.modulo);\n }\n }\n }\n return modulos;\n }\n\n protected async initBlockDispatcher(): Promise<void> {\n await this.blockDispatcher.init(this.resetForNewDs.bind(this));\n }\n\n protected async validatateDictionaryMeta(\n metaData: MetaData,\n ): Promise<boolean> {\n const evmChainId = await this.dictionaryService.getEvmChainId();\n\n return (\n metaData.genesisHash !== this.api.getGenesisHash() &&\n evmChainId !== this.api.getChainId().toString()\n );\n }\n\n protected async preLoopHook(): Promise<void> {\n // Ethereum doesn't need to do anything here\n return Promise.resolve();\n }\n}\n"]}
|
|
@@ -1,30 +1,45 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { isBlockHandlerProcessor, isCallHandlerProcessor, isEventHandlerProcessor, isCustomDs, isRuntimeDs, SubqlEthereumCustomDataSource, EthereumHandlerKind, EthereumRuntimeHandlerInputMap, SubqlEthereumDataSource } from '@subql/common-ethereum';
|
|
2
|
+
import { NodeConfig, IndexerSandbox, ProcessBlockResponse, BaseIndexerManager, ApiService } from '@subql/node-core';
|
|
3
|
+
import { EthereumBlockWrapper, SubqlRuntimeDatasource } from '@subql/types-ethereum';
|
|
3
4
|
import { SubqlProjectDs } from '../configure/SubqueryProject';
|
|
4
|
-
import {
|
|
5
|
+
import { EthereumBlockWrapped } from '../ethereum/block.ethereum';
|
|
6
|
+
import SafeEthProvider from '../ethereum/safe-api';
|
|
7
|
+
import { asSecondLayerHandlerProcessor_1_0_0, DsProcessorService } from './ds-processor.service';
|
|
5
8
|
import { DynamicDsService } from './dynamic-ds.service';
|
|
6
9
|
import { ProjectService } from './project.service';
|
|
7
10
|
import { SandboxService } from './sandbox.service';
|
|
8
11
|
import { UnfinalizedBlocksService } from './unfinalizedBlocks.service';
|
|
9
|
-
export declare class IndexerManager
|
|
10
|
-
private apiService;
|
|
11
|
-
private nodeConfig;
|
|
12
|
-
private sandboxService;
|
|
13
|
-
private dsProcessorService;
|
|
14
|
-
private dynamicDsService;
|
|
15
|
-
private unfinalizedBlocksService;
|
|
12
|
+
export declare class IndexerManager extends BaseIndexerManager<ApiService, SafeEthProvider, EthereumBlockWrapper, SubqlEthereumDataSource, SubqlEthereumCustomDataSource, typeof FilterTypeMap, typeof ProcessorTypeMap, EthereumRuntimeHandlerInputMap> {
|
|
16
13
|
private projectService;
|
|
14
|
+
protected isRuntimeDs: typeof isRuntimeDs;
|
|
15
|
+
protected isCustomDs: typeof isCustomDs;
|
|
16
|
+
protected updateCustomProcessor: typeof asSecondLayerHandlerProcessor_1_0_0;
|
|
17
17
|
constructor(apiService: ApiService, nodeConfig: NodeConfig, sandboxService: SandboxService, dsProcessorService: DsProcessorService, dynamicDsService: DynamicDsService, unfinalizedBlocksService: UnfinalizedBlocksService, projectService: ProjectService);
|
|
18
|
-
indexBlock(blockContent: EthereumBlockWrapper, dataSources: SubqlProjectDs[]): Promise<ProcessBlockResponse>;
|
|
19
18
|
start(): Promise<void>;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
private
|
|
19
|
+
indexBlock(block: EthereumBlockWrapper, dataSources: SubqlEthereumDataSource[]): Promise<ProcessBlockResponse>;
|
|
20
|
+
getBlockHeight(block: EthereumBlockWrapper): number;
|
|
21
|
+
getBlockHash(block: EthereumBlockWrapper): string;
|
|
22
|
+
private getApi;
|
|
23
|
+
protected indexBlockData({ block, transactions }: EthereumBlockWrapper, dataSources: SubqlProjectDs[], getVM: (d: SubqlProjectDs) => Promise<IndexerSandbox>): Promise<void>;
|
|
24
24
|
private indexBlockContent;
|
|
25
25
|
private indexTransaction;
|
|
26
26
|
private indexEvent;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
private transformAndExecuteCustomDs;
|
|
27
|
+
protected prepareFilteredData(kind: EthereumHandlerKind, data: any, ds: SubqlRuntimeDatasource): Promise<any>;
|
|
28
|
+
protected baseCustomHandlerFilter(kind: EthereumHandlerKind, data: any, baseFilter: any): boolean;
|
|
30
29
|
}
|
|
30
|
+
type ProcessorTypeMap = {
|
|
31
|
+
[EthereumHandlerKind.Block]: typeof isBlockHandlerProcessor;
|
|
32
|
+
[EthereumHandlerKind.Event]: typeof isEventHandlerProcessor;
|
|
33
|
+
[EthereumHandlerKind.Call]: typeof isCallHandlerProcessor;
|
|
34
|
+
};
|
|
35
|
+
declare const ProcessorTypeMap: {
|
|
36
|
+
"ethereum/BlockHandler": typeof isBlockHandlerProcessor;
|
|
37
|
+
"ethereum/LogHandler": typeof isEventHandlerProcessor;
|
|
38
|
+
"ethereum/TransactionHandler": typeof isCallHandlerProcessor;
|
|
39
|
+
};
|
|
40
|
+
declare const FilterTypeMap: {
|
|
41
|
+
"ethereum/BlockHandler": typeof EthereumBlockWrapped.filterBlocksProcessor;
|
|
42
|
+
"ethereum/LogHandler": typeof EthereumBlockWrapped.filterLogsProcessor;
|
|
43
|
+
"ethereum/TransactionHandler": typeof EthereumBlockWrapped.filterTransactionsProcessor;
|
|
44
|
+
};
|
|
45
|
+
export {};
|