@subql/node-ethereum 0.3.1-0 → 0.3.1-2
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/README.md +0 -2
- package/dist/.tsbuildinfo +1 -1
- package/dist/configure/SubqueryProject.js +15 -5
- package/dist/configure/SubqueryProject.js.map +1 -1
- package/dist/configure/configure.module.js +2 -2
- package/dist/configure/configure.module.js.map +1 -1
- package/dist/ethereum/api.ethereum.d.ts +1 -0
- package/dist/ethereum/api.ethereum.js +28 -0
- package/dist/ethereum/api.ethereum.js.map +1 -1
- package/dist/ethereum/api.service.ethereum.d.ts +4 -0
- package/dist/ethereum/api.service.ethereum.js +16 -1
- package/dist/ethereum/api.service.ethereum.js.map +1 -1
- package/dist/indexer/blockDispatcher/base-block-dispatcher.d.ts +1 -1
- package/dist/indexer/blockDispatcher/base-block-dispatcher.js +3 -1
- package/dist/indexer/blockDispatcher/base-block-dispatcher.js.map +1 -1
- package/dist/indexer/blockDispatcher/block-dispatcher.service.d.ts +1 -1
- package/dist/indexer/blockDispatcher/block-dispatcher.service.js +10 -5
- package/dist/indexer/blockDispatcher/block-dispatcher.service.js.map +1 -1
- package/dist/indexer/blockDispatcher/worker-block-dispatcher.service.d.ts +1 -1
- package/dist/indexer/blockDispatcher/worker-block-dispatcher.service.js +3 -3
- package/dist/indexer/blockDispatcher/worker-block-dispatcher.service.js.map +1 -1
- package/dist/indexer/dictionary.service.js +7 -2
- package/dist/indexer/dictionary.service.js.map +1 -1
- package/dist/indexer/ds-processor.service.d.ts +1 -1
- package/dist/indexer/ds-processor.service.js +4 -0
- package/dist/indexer/ds-processor.service.js.map +1 -1
- package/dist/indexer/dynamic-ds.service.js +4 -0
- package/dist/indexer/dynamic-ds.service.js.map +1 -1
- package/dist/indexer/fetch.module.js +12 -5
- package/dist/indexer/fetch.module.js.map +1 -1
- package/dist/indexer/fetch.service.d.ts +5 -1
- package/dist/indexer/fetch.service.js +71 -22
- package/dist/indexer/fetch.service.js.map +1 -1
- package/dist/indexer/indexer.manager.d.ts +1 -1
- package/dist/indexer/indexer.manager.js +4 -0
- package/dist/indexer/indexer.manager.js.map +1 -1
- package/dist/indexer/indexer.module.js +4 -6
- package/dist/indexer/indexer.module.js.map +1 -1
- package/dist/indexer/project.service.d.ts +1 -1
- package/dist/indexer/project.service.js +22 -6
- package/dist/indexer/project.service.js.map +1 -1
- package/dist/indexer/sandbox.service.js +4 -0
- package/dist/indexer/sandbox.service.js.map +1 -1
- package/dist/indexer/worker/worker.js +1 -1
- package/dist/indexer/worker/worker.js.map +1 -1
- package/dist/subcommands/forceClean.service.d.ts +3 -1
- package/dist/subcommands/forceClean.service.js +26 -6
- package/dist/subcommands/forceClean.service.js.map +1 -1
- package/dist/subcommands/reindex.module.js.map +1 -1
- package/dist/subcommands/reindex.service.js +6 -1
- package/dist/subcommands/reindex.service.js.map +1 -1
- package/dist/utils/project.d.ts +1 -0
- package/dist/utils/project.js +5 -1
- package/dist/utils/project.js.map +1 -1
- package/dist/yargs.d.ts +1 -7
- package/dist/yargs.js +1 -6
- package/dist/yargs.js.map +1 -1
- package/package.json +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-block-dispatcher.service.js","sourceRoot":"","sources":["../../../src/indexer/blockDispatcher/worker-block-dispatcher.service.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2020-2021 OnFinality Limited authors & contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport assert from 'assert';\nimport path from 'path';\nimport { Injectable, OnApplicationShutdown } from '@nestjs/common';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport { Interval } from '@nestjs/schedule';\nimport {\n getLogger,\n NodeConfig,\n IndexerEvent,\n Worker,\n AutoQueue,\n} from '@subql/node-core';\nimport chalk from 'chalk';\nimport { last } from 'lodash';\nimport { ProjectService } from '../project.service';\nimport {\n FetchBlock,\n ProcessBlock,\n InitWorker,\n NumFetchedBlocks,\n NumFetchingBlocks,\n GetWorkerStatus,\n} from '../worker/worker';\nimport { BaseBlockDispatcher } from './base-block-dispatcher';\n\nconst logger = getLogger('WorkerBlockDispatcherService');\n\ntype IIndexerWorker = {\n processBlock: ProcessBlock;\n fetchBlock: FetchBlock;\n numFetchedBlocks: NumFetchedBlocks;\n numFetchingBlocks: NumFetchingBlocks;\n getStatus: GetWorkerStatus;\n};\n\ntype IInitIndexerWorker = IIndexerWorker & {\n initWorker: InitWorker;\n};\n\ntype IndexerWorker = IIndexerWorker & {\n terminate: () => Promise<number>;\n};\n\nasync function createIndexerWorker(): Promise<IndexerWorker> {\n const indexerWorker = Worker.create<IInitIndexerWorker>(\n path.resolve(__dirname, '../../../dist/indexer/worker/worker.js'),\n [\n 'initWorker',\n 'processBlock',\n 'fetchBlock',\n 'numFetchedBlocks',\n 'numFetchingBlocks',\n 'getStatus',\n ],\n );\n\n await indexerWorker.initWorker();\n\n return indexerWorker;\n}\n\n@Injectable()\nexport class WorkerBlockDispatcherService\n extends BaseBlockDispatcher<AutoQueue<void>>\n implements OnApplicationShutdown\n{\n private workers: IndexerWorker[];\n private numWorkers: number;\n\n private taskCounter = 0;\n private isShutdown = false;\n\n constructor(\n nodeConfig: NodeConfig,\n eventEmitter: EventEmitter2,\n projectService: ProjectService,\n ) {\n const numWorkers = nodeConfig.workers;\n super(\n nodeConfig,\n eventEmitter,\n projectService,\n new AutoQueue(numWorkers * nodeConfig.batchSize * 2),\n );\n this.numWorkers = numWorkers;\n }\n\n async init(\n onDynamicDsCreated: (height: number) => Promise<void>,\n ): Promise<void> {\n if (this.nodeConfig.unfinalizedBlocks) {\n throw new Error(\n 'Sorry, best block feature is not supported with workers yet.',\n );\n }\n\n this.workers = await Promise.all(\n new Array(this.numWorkers).fill(0).map(() => createIndexerWorker()),\n );\n\n this.onDynamicDsCreated = onDynamicDsCreated;\n\n const blockAmount = await this.projectService.getProcessedBlockCount();\n this.setProcessedBlockCount(blockAmount ?? 0);\n }\n\n async onApplicationShutdown(): Promise<void> {\n this.isShutdown = true;\n // Stop processing blocks\n this.queue.abort();\n\n // Stop all workers\n if (this.workers) {\n await Promise.all(this.workers.map((w) => w.terminate()));\n }\n }\n\n enqueueBlocks(heights: number[]): void {\n if (!heights.length) return;\n logger.info(\n `Enqueing blocks [${heights[0]}...${last(heights)}], total ${\n heights.length\n } blocks`,\n );\n\n // eslint-disable-next-line no-constant-condition\n if (true) {\n /*\n * Load balancing:\n * worker1: 1,2,3\n * worker2: 4,5,6\n */\n const workerIdx = this.getNextWorkerIndex();\n heights.map((height) => this.enqueueBlock(height, workerIdx));\n } else {\n /*\n * Load balancing:\n * worker1: 1,3,5\n * worker2: 2,4,6\n */\n heights.map((height) =>\n this.enqueueBlock(height, this.getNextWorkerIndex()),\n );\n }\n\n this.latestBufferedHeight = last(heights);\n }\n\n private enqueueBlock(height: number, workerIdx: number) {\n if (this.isShutdown) return;\n const worker = this.workers[workerIdx];\n\n assert(worker, `Worker ${workerIdx} not found`);\n\n // Used to compare before and after as a way to check if queue was flushed\n const bufferedHeight = this.latestBufferedHeight;\n const pendingBlock = worker.fetchBlock(height);\n\n const processBlock = async () => {\n try {\n const start = new Date();\n const result = await pendingBlock;\n const end = new Date();\n\n if (bufferedHeight > this.latestBufferedHeight) {\n logger.debug(`Queue was reset for new DS, discarding fetched blocks`);\n return;\n }\n\n const waitTime = end.getTime() - start.getTime();\n if (waitTime > 1000) {\n logger.info(\n `Waiting to fetch block ${height}: ${chalk.red(`${waitTime}ms`)}`,\n );\n } else if (waitTime > 200) {\n logger.info(\n `Waiting to fetch block ${height}: ${chalk.yellow(\n `${waitTime}ms`,\n )}`,\n );\n }\n\n // logger.info(\n // `worker ${workerIdx} processing block ${height}, fetched blocks: ${await worker.numFetchedBlocks()}, fetching blocks: ${await worker.numFetchingBlocks()}`,\n // );\n\n this.preProcessBlock(height);\n\n const { dynamicDsCreated, operationHash, reindexBlockHeight } =\n await worker.processBlock(height);\n\n await this.postProcessBlock(height, {\n dynamicDsCreated,\n operationHash: Buffer.from(operationHash, 'base64'),\n reindexBlockHeight,\n });\n } catch (e) {\n logger.error(\n e,\n `failed to index block at height ${height} ${\n e.handler ? `${e.handler}(${e.stack ?? ''})` : ''\n }`,\n );\n throw e;\n }\n };\n\n void this.queue.put(processBlock);\n }\n\n @Interval(15000)\n async sampleWorkerStatus(): Promise<void> {\n for (const worker of this.workers) {\n const status = await worker.getStatus();\n logger.info(JSON.stringify(status));\n }\n }\n\n // Getter doesn't seem to cary from abstract class\n get latestBufferedHeight(): number {\n return this._latestBufferedHeight;\n }\n\n set latestBufferedHeight(height: number) {\n super.latestBufferedHeight = height;\n // There is only a single queue with workers so we treat them as the same\n this.eventEmitter.emit(IndexerEvent.BlockQueueSize, {\n value: this.queueSize,\n });\n }\n\n private getNextWorkerIndex(): number {\n const index = this.taskCounter % this.numWorkers;\n\n this.taskCounter++;\n\n return index;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"worker-block-dispatcher.service.js","sourceRoot":"","sources":["../../../src/indexer/blockDispatcher/worker-block-dispatcher.service.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2020-2021 OnFinality Limited authors & contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport assert from 'assert';\nimport path from 'path';\nimport { Injectable, OnApplicationShutdown } from '@nestjs/common';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport { Interval } from '@nestjs/schedule';\nimport {\n getLogger,\n NodeConfig,\n IndexerEvent,\n Worker,\n AutoQueue,\n} from '@subql/node-core';\nimport chalk from 'chalk';\nimport { last } from 'lodash';\nimport { ProjectService } from '../project.service';\nimport {\n FetchBlock,\n ProcessBlock,\n InitWorker,\n NumFetchedBlocks,\n NumFetchingBlocks,\n GetWorkerStatus,\n} from '../worker/worker';\nimport { BaseBlockDispatcher } from './base-block-dispatcher';\n\nconst logger = getLogger('WorkerBlockDispatcherService');\n\ntype IIndexerWorker = {\n processBlock: ProcessBlock;\n fetchBlock: FetchBlock;\n numFetchedBlocks: NumFetchedBlocks;\n numFetchingBlocks: NumFetchingBlocks;\n getStatus: GetWorkerStatus;\n};\n\ntype IInitIndexerWorker = IIndexerWorker & {\n initWorker: InitWorker;\n};\n\ntype IndexerWorker = IIndexerWorker & {\n terminate: () => Promise<number>;\n};\n\nasync function createIndexerWorker(): Promise<IndexerWorker> {\n const indexerWorker = Worker.create<IInitIndexerWorker>(\n path.resolve(__dirname, '../../../dist/indexer/worker/worker.js'),\n [\n 'initWorker',\n 'processBlock',\n 'fetchBlock',\n 'numFetchedBlocks',\n 'numFetchingBlocks',\n 'getStatus',\n ],\n );\n\n await indexerWorker.initWorker();\n\n return indexerWorker;\n}\n\n@Injectable()\nexport class WorkerBlockDispatcherService\n extends BaseBlockDispatcher<AutoQueue<void>>\n implements OnApplicationShutdown\n{\n private workers: IndexerWorker[];\n private numWorkers: number;\n\n private taskCounter = 0;\n private isShutdown = false;\n\n constructor(\n nodeConfig: NodeConfig,\n eventEmitter: EventEmitter2,\n projectService: ProjectService,\n ) {\n const numWorkers = nodeConfig.workers;\n super(\n nodeConfig,\n eventEmitter,\n projectService,\n new AutoQueue(numWorkers * nodeConfig.batchSize * 2),\n );\n this.numWorkers = numWorkers;\n }\n\n async init(\n onDynamicDsCreated: (height: number) => Promise<void>,\n ): Promise<void> {\n if (this.nodeConfig.unfinalizedBlocks) {\n throw new Error(\n 'Sorry, best block feature is not supported with workers yet.',\n );\n }\n\n this.workers = await Promise.all(\n new Array(this.numWorkers).fill(0).map(() => createIndexerWorker()),\n );\n\n this.onDynamicDsCreated = onDynamicDsCreated;\n\n const blockAmount = await this.projectService.getProcessedBlockCount();\n this.setProcessedBlockCount(blockAmount ?? 0);\n }\n\n async onApplicationShutdown(): Promise<void> {\n this.isShutdown = true;\n // Stop processing blocks\n this.queue.abort();\n\n // Stop all workers\n if (this.workers) {\n await Promise.all(this.workers.map((w) => w.terminate()));\n }\n }\n\n enqueueBlocks(heights: number[], latestBufferHeight?: number): void {\n if (!heights.length) return;\n logger.info(\n `Enqueing blocks [${heights[0]}...${last(heights)}], total ${\n heights.length\n } blocks`,\n );\n\n // eslint-disable-next-line no-constant-condition\n if (true) {\n /*\n * Load balancing:\n * worker1: 1,2,3\n * worker2: 4,5,6\n */\n const workerIdx = this.getNextWorkerIndex();\n heights.map((height) => this.enqueueBlock(height, workerIdx));\n } else {\n /*\n * Load balancing:\n * worker1: 1,3,5\n * worker2: 2,4,6\n */\n heights.map((height) =>\n this.enqueueBlock(height, this.getNextWorkerIndex()),\n );\n }\n\n this.latestBufferedHeight = latestBufferHeight ?? last(heights);\n }\n\n private enqueueBlock(height: number, workerIdx: number) {\n if (this.isShutdown) return;\n const worker = this.workers[workerIdx];\n\n assert(worker, `Worker ${workerIdx} not found`);\n\n // Used to compare before and after as a way to check if queue was flushed\n const bufferedHeight = this.latestBufferedHeight;\n const pendingBlock = worker.fetchBlock(height);\n\n const processBlock = async () => {\n try {\n const start = new Date();\n const result = await pendingBlock;\n const end = new Date();\n\n if (bufferedHeight > this.latestBufferedHeight) {\n logger.debug(`Queue was reset for new DS, discarding fetched blocks`);\n return;\n }\n\n const waitTime = end.getTime() - start.getTime();\n if (waitTime > 1000) {\n logger.info(\n `Waiting to fetch block ${height}: ${chalk.red(`${waitTime}ms`)}`,\n );\n } else if (waitTime > 200) {\n logger.info(\n `Waiting to fetch block ${height}: ${chalk.yellow(\n `${waitTime}ms`,\n )}`,\n );\n }\n\n // logger.info(\n // `worker ${workerIdx} processing block ${height}, fetched blocks: ${await worker.numFetchedBlocks()}, fetching blocks: ${await worker.numFetchingBlocks()}`,\n // );\n\n this.preProcessBlock(height);\n\n const { dynamicDsCreated, operationHash, reindexBlockHeight } =\n await worker.processBlock(height);\n\n await this.postProcessBlock(height, {\n dynamicDsCreated,\n operationHash: Buffer.from(operationHash, 'base64'),\n reindexBlockHeight,\n });\n } catch (e) {\n logger.error(\n e,\n `failed to index block at height ${height} ${\n e.handler ? `${e.handler}(${e.stack ?? ''})` : ''\n }`,\n );\n process.exit(1);\n }\n };\n\n void this.queue.put(processBlock);\n }\n\n @Interval(15000)\n async sampleWorkerStatus(): Promise<void> {\n for (const worker of this.workers) {\n const status = await worker.getStatus();\n logger.info(JSON.stringify(status));\n }\n }\n\n // Getter doesn't seem to cary from abstract class\n get latestBufferedHeight(): number {\n return this._latestBufferedHeight;\n }\n\n set latestBufferedHeight(height: number) {\n super.latestBufferedHeight = height;\n // There is only a single queue with workers so we treat them as the same\n this.eventEmitter.emit(IndexerEvent.BlockQueueSize, {\n value: this.queueSize,\n });\n }\n\n private getNextWorkerIndex(): number {\n const index = this.taskCounter % this.numWorkers;\n\n this.taskCounter++;\n\n return index;\n }\n}\n"]}
|
|
@@ -10,6 +10,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
10
10
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
11
11
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
12
12
|
};
|
|
13
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
14
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
15
|
+
};
|
|
13
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
17
|
exports.DictionaryService = void 0;
|
|
15
18
|
const core_1 = require("@apollo/client/core");
|
|
@@ -19,7 +22,7 @@ const SubqueryProject_1 = require("../configure/SubqueryProject");
|
|
|
19
22
|
const logger = (0, node_core_1.getLogger)('dictionary');
|
|
20
23
|
let DictionaryService = class DictionaryService extends node_core_1.DictionaryService {
|
|
21
24
|
constructor(project, nodeConfig) {
|
|
22
|
-
super(project.network.dictionary, nodeConfig);
|
|
25
|
+
super(project.network.dictionary, project.network.chainId, nodeConfig);
|
|
23
26
|
this.project = project;
|
|
24
27
|
}
|
|
25
28
|
async getEvmChainId() {
|
|
@@ -38,7 +41,9 @@ let DictionaryService = class DictionaryService extends node_core_1.DictionarySe
|
|
|
38
41
|
};
|
|
39
42
|
DictionaryService = __decorate([
|
|
40
43
|
(0, common_1.Injectable)(),
|
|
41
|
-
|
|
44
|
+
__param(0, (0, common_1.Inject)('ISubqueryProject')),
|
|
45
|
+
__metadata("design:paramtypes", [SubqueryProject_1.SubqueryProject,
|
|
46
|
+
node_core_1.NodeConfig])
|
|
42
47
|
], DictionaryService);
|
|
43
48
|
exports.DictionaryService = DictionaryService;
|
|
44
49
|
//# sourceMappingURL=dictionary.service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dictionary.service.js","sourceRoot":"","sources":["../../src/indexer/dictionary.service.ts"],"names":[],"mappings":";AAAA,gEAAgE;AAChE,sCAAsC
|
|
1
|
+
{"version":3,"file":"dictionary.service.js","sourceRoot":"","sources":["../../src/indexer/dictionary.service.ts"],"names":[],"mappings":";AAAA,gEAAgE;AAChE,sCAAsC;;;;;;;;;;;;;;;AAEtC,8CAA0C;AAC1C,2CAA2E;AAC3E,gDAK0B;AAC1B,kEAA+D;AAE/D,MAAM,MAAM,GAAG,IAAA,qBAAS,EAAC,YAAY,CAAC,CAAC;AAGhC,IAAM,iBAAiB,GAAvB,MAAM,iBACX,SAAQ,6BAAqB;IAG7B,YACwC,OAAwB,EAC9D,UAAsB;QAEtB,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QAHjC,YAAO,GAAP,OAAO,CAAiB;IAIhE,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,MAAM,KAAK,GAAG,4CAA4C,CAAC;QAE3D,IAAI;YACF,MAAM,IAAI,GAAG,MAAM,IAAA,mBAAO,EACxB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;gBAChB,KAAK,EAAE,IAAA,UAAG,EAAC,KAAK,CAAC;aAClB,CAAC,EACF,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAClC,CAAC;YACF,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;SACnC;QAAC,OAAO,CAAC,EAAE;YACV,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,6CAA6C,CAAC,CAAC;YAC9D,OAAO,SAAS,CAAC;SAClB;IACH,CAAC;CACF,CAAA;AA3BY,iBAAiB;IAD7B,IAAA,mBAAU,GAAE;IAMR,WAAA,IAAA,eAAM,EAAC,kBAAkB,CAAC,CAAA;qCAAoB,iCAAe;QAClD,sBAAU;GANb,iBAAiB,CA2B7B;AA3BY,8CAAiB","sourcesContent":["// Copyright 2020-2022 OnFinality Limited authors & contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport { gql } from '@apollo/client/core';\nimport { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';\nimport {\n NodeConfig,\n DictionaryService as CoreDictionaryService,\n timeout,\n getLogger,\n} from '@subql/node-core';\nimport { SubqueryProject } from '../configure/SubqueryProject';\n\nconst logger = getLogger('dictionary');\n\n@Injectable()\nexport class DictionaryService\n extends CoreDictionaryService\n implements OnApplicationShutdown\n{\n constructor(\n @Inject('ISubqueryProject') protected project: SubqueryProject,\n nodeConfig: NodeConfig,\n ) {\n super(project.network.dictionary, project.network.chainId, nodeConfig);\n }\n\n async getEvmChainId(): Promise<string> {\n const query = `query{chainAlias(id: \"evmChainId\"){value}}`;\n\n try {\n const resp = await timeout(\n this.client.query({\n query: gql(query),\n }),\n this.nodeConfig.dictionaryTimeout,\n );\n return resp.data.chainAlias.value;\n } catch (e) {\n logger.warn(e, `failed to fetch evm chainId from dictionary`);\n return undefined;\n }\n }\n}\n"]}
|
|
@@ -15,7 +15,7 @@ export declare class DsPluginSandbox extends Sandbox {
|
|
|
15
15
|
getDsPlugin<D extends string>(): SubqlDatasourceProcessor<D, unknown>;
|
|
16
16
|
}
|
|
17
17
|
export declare class DsProcessorService {
|
|
18
|
-
private project;
|
|
18
|
+
private readonly project;
|
|
19
19
|
private readonly nodeConfig;
|
|
20
20
|
private processorCache;
|
|
21
21
|
constructor(project: SubqueryProject, nodeConfig: NodeConfig);
|
|
@@ -10,6 +10,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
10
10
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
11
11
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
12
12
|
};
|
|
13
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
14
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
15
|
+
};
|
|
13
16
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
18
|
};
|
|
@@ -126,6 +129,7 @@ let DsProcessorService = class DsProcessorService {
|
|
|
126
129
|
};
|
|
127
130
|
DsProcessorService = __decorate([
|
|
128
131
|
(0, common_1.Injectable)(),
|
|
132
|
+
__param(0, (0, common_1.Inject)('ISubqueryProject')),
|
|
129
133
|
__metadata("design:paramtypes", [SubqueryProject_1.SubqueryProject,
|
|
130
134
|
node_core_1.NodeConfig])
|
|
131
135
|
], DsProcessorService);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ds-processor.service.js","sourceRoot":"","sources":["../../src/indexer/ds-processor.service.ts"],"names":[],"mappings":";AAAA,gEAAgE;AAChE,sCAAsC;;;;;;;;;;;;;;;AAEtC,4CAAoB;AACpB,gDAAwB;AACxB,2CAA4C;AAC5C,4DAMgC;AAChC,gDAAkE;AAOlE,6BAA+B;AAC/B,kEAA+D;AAQ/D,MAAM,MAAM,GAAG,IAAA,qBAAS,EAAC,YAAY,CAAC,CAAC;AAEvC,SAAgB,mCAAmC,CAMjD,SAEkD;IAElD,4GAA4G;IAC5G,OAAO,SAAS,CAAC,WAAW,KAAK,SAAS,CAAC;AAC7C,CAAC;AAZD,kFAYC;AAED,SAAgB,mCAAmC,CAMjD,SAEkD;IAElD,OAAO,SAAS,CAAC,WAAW,KAAK,OAAO,CAAC;AAC3C,CAAC;AAXD,kFAWC;AAED,SAAgB,mCAAmC,CAMjD,SAEkD;IAElD,IAAI,mCAAmC,CAAC,SAAS,CAAC,EAAE;QAClD,OAAO,SAAS,CAAC;KAClB;IAED,IAAI,CAAC,mCAAmC,CAAC,SAAS,CAAC,EAAE;QACnD,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;KACrD;IAED,uCACK,SAAS,KACZ,WAAW,EAAE,OAAO,EACpB,eAAe,EAAE,CAAC,MAAM,EAAE,EAAE,CAC1B,SAAS,CAAC,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,EACnE,WAAW,EAAE,CAAC,MAAM,EAAE,EAAE,CACtB,SAAS;aACN,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC;aAC/D,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IACzB;AACJ,CAAC;AA5BD,kFA4BC;AAED,MAAa,eAAgB,SAAQ,mBAAO;IAC1C,YAAY,MAA6B,EAAE,UAAsB;QAC/D,KAAK,CACH,MAAM,EACN,IAAI,cAAQ,CACV,6BAA6B,MAAM,CAAC,KAAK,aAAa,EACtD,cAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CACrC,EACD,UAAU,CACX,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAChC,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;CACF;AAhBD,0CAgBC;AAGM,IAAM,kBAAkB,GAAxB,MAAM,kBAAkB;IAI7B,YACU,OAAwB,EACf,UAAsB;QAD/B,YAAO,GAAP,OAAO,CAAiB;QACf,eAAU,GAAV,UAAU,CAAY;QALjC,mBAAc,GAElB,EAAE,CAAC;IAIJ,CAAC;IAEJ,KAAK,CAAC,gBAAgB,CACpB,WAA4C;QAE5C,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE;YAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;YAC1C,oEAAoE;YACpE,IAAI,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,EAAE;gBAC9B,MAAM,IAAI,KAAK,CACb,YAAY,EAAE,CAAC,IAAI,6BAA6B,SAAS,CAAC,IAAI,GAAG,CAClE,CAAC;aACH;YAED,KAAK,MAAM,OAAO,IAAI,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE;gBACzC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC,iBAAiB,CAAC,EAAE;oBAClD,MAAM,IAAI,KAAK,CACb,WAAW,OAAO,CAAC,IAAI,eAAe,MAAM,CAAC,IAAI,CAC/C,SAAS,CAAC,iBAAiB,CAC5B,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACf,CAAC;iBACH;aACF;YAED,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAClC,SAAS,CAAC,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,eAAe,CACvD,OAAO,CAAC,MAAM,CACf,CACF,CAAC;YAEF,8CAA8C;YAC9C,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;SAClD;IACH,CAAC;IAED,KAAK,CAAC,gCAAgC;QACpC,MAAM,IAAI,CAAC,gBAAgB,CACxB,IAAI,CAAC,OAAO,CAAC,WAAyC,CAAC,MAAM,CAC5D,4BAAU,CACX,CACF,CAAC;IACJ,CAAC;IAED,cAAc,CACZ,EAAyC;QAEzC,IAAI,CAAC,IAAA,4BAAU,EAAC,EAAE,CAAC,EAAE;YACnB,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;SAC5D;QACD,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;YAC3C,MAAM,OAAO,GAAG,IAAI,eAAe,CACjC;gBACE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI;gBACvB,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI;gBACxB,MAAM,EACJ,IAAI,CAAC,yDAAyD;aACjE,EACD,IAAI,CAAC,UAAU,CAChB,CAAC;YACF,IAAI;gBACF,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,WAAW,EAAK,CAAC;aACnE;YAAC,OAAO,CAAC,EAAE;gBACV,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC7C,MAAM,CAAC,CAAC;aACT;SACF;QACD,OAAO,IAAI,CAAC,cAAc,CACxB,EAAE,CAAC,SAAS,CAAC,IAAI,CACiC,CAAC;IACvD,CAAC;IAED,4DAA4D;IAC5D,KAAK,CAAC,SAAS,CACb,EAAiC;QAEjC,IAAI,CAAC,IAAA,4BAAU,EAAC,EAAE,CAAC,EAAE;YACnB,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;SAC5D;QAED,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE;YACd,OAAO,EAAE,CAAC;SACX;QAED,MAAM,GAAG,GAA2B,EAAE,CAAC;QAEvC,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE;YACxC,8DAA8D;YAC9D,IAAI;gBACF,GAAG,CAAC,IAAI,CAAC,GAAG,YAAE,CAAC,YAAY,CAAC,IAAI,EAAE;oBAChC,QAAQ,EAAE,MAAM;iBACjB,CAAC,CAAC;aACJ;YAAC,OAAO,CAAC,EAAE;gBACV,MAAM,CAAC,KAAK,CAAC,mCAAmC,IAAI,EAAE,CAAC,CAAC;gBACxD,MAAM,CAAC,CAAC;aACT;SACF;QAED,OAAO,GAAG,CAAC;IACb,CAAC;CACF,CAAA;AA1GY,kBAAkB;IAD9B,IAAA,mBAAU,GAAE;qCAMQ,iCAAe;QACH,sBAAU;GAN9B,kBAAkB,CA0G9B;AA1GY,gDAAkB","sourcesContent":["// Copyright 2020-2022 OnFinality Limited authors & contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport fs from 'fs';\nimport path from 'path';\nimport { Injectable } from '@nestjs/common';\nimport {\n EthereumHandlerKind,\n isCustomDs,\n SubqlEthereumCustomDataSource,\n SubqlEthereumDataSource,\n SubqlDatasourceProcessor,\n} from '@subql/common-ethereum';\nimport { getLogger, NodeConfig, Sandbox } from '@subql/node-core';\nimport {\n SecondLayerHandlerProcessor_0_0_0,\n SecondLayerHandlerProcessor_1_0_0,\n SubqlCustomDatasource,\n} from '@subql/types-ethereum';\n\nimport { VMScript } from 'vm2';\nimport { SubqueryProject } from '../configure/SubqueryProject';\n\nexport interface DsPluginSandboxOption {\n root: string;\n entry: string;\n script: string;\n}\n\nconst logger = getLogger('ds-sandbox');\n\nexport function isSecondLayerHandlerProcessor_0_0_0<\n K extends EthereumHandlerKind,\n F,\n E,\n DS extends SubqlCustomDatasource = SubqlEthereumCustomDataSource,\n>(\n processor:\n | SecondLayerHandlerProcessor_0_0_0<K, F, E, DS>\n | SecondLayerHandlerProcessor_1_0_0<K, F, E, DS>,\n): processor is SecondLayerHandlerProcessor_0_0_0<K, F, E, DS> {\n // Exisiting datasource processors had no concept of specVersion, therefore undefined is equivalent to 0.0.0\n return processor.specVersion === undefined;\n}\n\nexport function isSecondLayerHandlerProcessor_1_0_0<\n K extends EthereumHandlerKind,\n F,\n E,\n DS extends SubqlEthereumCustomDataSource = SubqlEthereumCustomDataSource,\n>(\n processor:\n | SecondLayerHandlerProcessor_0_0_0<K, F, E, DS>\n | SecondLayerHandlerProcessor_1_0_0<K, F, E, DS>,\n): processor is SecondLayerHandlerProcessor_1_0_0<K, F, E, DS> {\n return processor.specVersion === '1.0.0';\n}\n\nexport function asSecondLayerHandlerProcessor_1_0_0<\n K extends EthereumHandlerKind,\n F,\n E,\n DS extends SubqlEthereumCustomDataSource = SubqlEthereumCustomDataSource,\n>(\n processor:\n | SecondLayerHandlerProcessor_0_0_0<K, F, E, DS>\n | SecondLayerHandlerProcessor_1_0_0<K, F, E, DS>,\n): SecondLayerHandlerProcessor_1_0_0<K, F, E, DS> {\n if (isSecondLayerHandlerProcessor_1_0_0(processor)) {\n return processor;\n }\n\n if (!isSecondLayerHandlerProcessor_0_0_0(processor)) {\n throw new Error('Unsupported ds processor version');\n }\n\n return {\n ...processor,\n specVersion: '1.0.0',\n filterProcessor: (params) =>\n processor.filterProcessor(params.filter, params.input, params.ds),\n transformer: (params) =>\n processor\n .transformer(params.input, params.ds, params.api, params.assets)\n .then((res) => [res]),\n };\n}\n\nexport class DsPluginSandbox extends Sandbox {\n constructor(option: DsPluginSandboxOption, nodeConfig: NodeConfig) {\n super(\n option,\n new VMScript(\n `module.exports = require('${option.entry}').default;`,\n path.join(option.root, 'ds_sandbox'),\n ),\n nodeConfig,\n );\n this.freeze(logger, 'logger');\n }\n\n getDsPlugin<D extends string>(): SubqlDatasourceProcessor<D, unknown> {\n return this.run(this.script);\n }\n}\n\n@Injectable()\nexport class DsProcessorService {\n private processorCache: {\n [entry: string]: SubqlDatasourceProcessor<string, unknown>;\n } = {};\n constructor(\n private project: SubqueryProject,\n private readonly nodeConfig: NodeConfig,\n ) {}\n\n async validateCustomDs(\n datasources: SubqlEthereumCustomDataSource[],\n ): Promise<void> {\n for (const ds of datasources) {\n const processor = this.getDsProcessor(ds);\n /* Standard validation applicable to all custom ds and processors */\n if (ds.kind !== processor.kind) {\n throw new Error(\n `ds kind (${ds.kind}) doesnt match processor (${processor.kind})`,\n );\n }\n\n for (const handler of ds.mapping.handlers) {\n if (!(handler.kind in processor.handlerProcessors)) {\n throw new Error(\n `ds kind ${handler.kind} not one of ${Object.keys(\n processor.handlerProcessors,\n ).join(', ')}`,\n );\n }\n }\n\n ds.mapping.handlers.map((handler) =>\n processor.handlerProcessors[handler.kind].filterValidator(\n handler.filter,\n ),\n );\n\n /* Additional processor specific validation */\n processor.validate(ds, await this.getAssets(ds));\n }\n }\n\n async validateProjectCustomDatasources(): Promise<void> {\n await this.validateCustomDs(\n (this.project.dataSources as SubqlEthereumDataSource[]).filter(\n isCustomDs,\n ),\n );\n }\n\n getDsProcessor<D extends string>(\n ds: SubqlEthereumCustomDataSource<string>,\n ): SubqlDatasourceProcessor<D, unknown> {\n if (!isCustomDs(ds)) {\n throw new Error(`data source is not a custom data source`);\n }\n if (!this.processorCache[ds.processor.file]) {\n const sandbox = new DsPluginSandbox(\n {\n root: this.project.root,\n entry: ds.processor.file,\n script:\n null /* TODO get working with Readers, same as with sandbox */,\n },\n this.nodeConfig,\n );\n try {\n this.processorCache[ds.processor.file] = sandbox.getDsPlugin<D>();\n } catch (e) {\n logger.error(`not supported ds @${ds.kind}`);\n throw e;\n }\n }\n return this.processorCache[\n ds.processor.file\n ] as unknown as SubqlDatasourceProcessor<D, unknown>;\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async getAssets(\n ds: SubqlEthereumCustomDataSource,\n ): Promise<Record<string, string>> {\n if (!isCustomDs(ds)) {\n throw new Error(`data source is not a custom data source`);\n }\n\n if (!ds.assets) {\n return {};\n }\n\n const res: Record<string, string> = {};\n\n for (const [name, { file }] of ds.assets) {\n // TODO update with https://github.com/subquery/subql/pull/511\n try {\n res[name] = fs.readFileSync(file, {\n encoding: 'utf8',\n });\n } catch (e) {\n logger.error(`Failed to load datasource asset ${file}`);\n throw e;\n }\n }\n\n return res;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ds-processor.service.js","sourceRoot":"","sources":["../../src/indexer/ds-processor.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 fs from 'fs';\nimport path from 'path';\nimport { Inject, Injectable } from '@nestjs/common';\nimport {\n EthereumHandlerKind,\n isCustomDs,\n SubqlEthereumCustomDataSource,\n SubqlEthereumDataSource,\n SubqlDatasourceProcessor,\n} from '@subql/common-ethereum';\nimport { getLogger, NodeConfig, Sandbox } from '@subql/node-core';\nimport {\n SecondLayerHandlerProcessor_0_0_0,\n SecondLayerHandlerProcessor_1_0_0,\n SubqlCustomDatasource,\n} from '@subql/types-ethereum';\n\nimport { VMScript } from 'vm2';\nimport { SubqueryProject } from '../configure/SubqueryProject';\n\nexport interface DsPluginSandboxOption {\n root: string;\n entry: string;\n script: string;\n}\n\nconst logger = getLogger('ds-sandbox');\n\nexport function isSecondLayerHandlerProcessor_0_0_0<\n K extends EthereumHandlerKind,\n F,\n E,\n DS extends SubqlCustomDatasource = SubqlEthereumCustomDataSource,\n>(\n processor:\n | SecondLayerHandlerProcessor_0_0_0<K, F, E, DS>\n | SecondLayerHandlerProcessor_1_0_0<K, F, E, DS>,\n): processor is SecondLayerHandlerProcessor_0_0_0<K, F, E, DS> {\n // Exisiting datasource processors had no concept of specVersion, therefore undefined is equivalent to 0.0.0\n return processor.specVersion === undefined;\n}\n\nexport function isSecondLayerHandlerProcessor_1_0_0<\n K extends EthereumHandlerKind,\n F,\n E,\n DS extends SubqlEthereumCustomDataSource = SubqlEthereumCustomDataSource,\n>(\n processor:\n | SecondLayerHandlerProcessor_0_0_0<K, F, E, DS>\n | SecondLayerHandlerProcessor_1_0_0<K, F, E, DS>,\n): processor is SecondLayerHandlerProcessor_1_0_0<K, F, E, DS> {\n return processor.specVersion === '1.0.0';\n}\n\nexport function asSecondLayerHandlerProcessor_1_0_0<\n K extends EthereumHandlerKind,\n F,\n E,\n DS extends SubqlEthereumCustomDataSource = SubqlEthereumCustomDataSource,\n>(\n processor:\n | SecondLayerHandlerProcessor_0_0_0<K, F, E, DS>\n | SecondLayerHandlerProcessor_1_0_0<K, F, E, DS>,\n): SecondLayerHandlerProcessor_1_0_0<K, F, E, DS> {\n if (isSecondLayerHandlerProcessor_1_0_0(processor)) {\n return processor;\n }\n\n if (!isSecondLayerHandlerProcessor_0_0_0(processor)) {\n throw new Error('Unsupported ds processor version');\n }\n\n return {\n ...processor,\n specVersion: '1.0.0',\n filterProcessor: (params) =>\n processor.filterProcessor(params.filter, params.input, params.ds),\n transformer: (params) =>\n processor\n .transformer(params.input, params.ds, params.api, params.assets)\n .then((res) => [res]),\n };\n}\n\nexport class DsPluginSandbox extends Sandbox {\n constructor(option: DsPluginSandboxOption, nodeConfig: NodeConfig) {\n super(\n option,\n new VMScript(\n `module.exports = require('${option.entry}').default;`,\n path.join(option.root, 'ds_sandbox'),\n ),\n nodeConfig,\n );\n this.freeze(logger, 'logger');\n }\n\n getDsPlugin<D extends string>(): SubqlDatasourceProcessor<D, unknown> {\n return this.run(this.script);\n }\n}\n\n@Injectable()\nexport class DsProcessorService {\n private processorCache: {\n [entry: string]: SubqlDatasourceProcessor<string, unknown>;\n } = {};\n constructor(\n @Inject('ISubqueryProject') private readonly project: SubqueryProject,\n private readonly nodeConfig: NodeConfig,\n ) {}\n\n async validateCustomDs(\n datasources: SubqlEthereumCustomDataSource[],\n ): Promise<void> {\n for (const ds of datasources) {\n const processor = this.getDsProcessor(ds);\n /* Standard validation applicable to all custom ds and processors */\n if (ds.kind !== processor.kind) {\n throw new Error(\n `ds kind (${ds.kind}) doesnt match processor (${processor.kind})`,\n );\n }\n\n for (const handler of ds.mapping.handlers) {\n if (!(handler.kind in processor.handlerProcessors)) {\n throw new Error(\n `ds kind ${handler.kind} not one of ${Object.keys(\n processor.handlerProcessors,\n ).join(', ')}`,\n );\n }\n }\n\n ds.mapping.handlers.map((handler) =>\n processor.handlerProcessors[handler.kind].filterValidator(\n handler.filter,\n ),\n );\n\n /* Additional processor specific validation */\n processor.validate(ds, await this.getAssets(ds));\n }\n }\n\n async validateProjectCustomDatasources(): Promise<void> {\n await this.validateCustomDs(\n (this.project.dataSources as SubqlEthereumDataSource[]).filter(\n isCustomDs,\n ),\n );\n }\n\n getDsProcessor<D extends string>(\n ds: SubqlEthereumCustomDataSource<string>,\n ): SubqlDatasourceProcessor<D, unknown> {\n if (!isCustomDs(ds)) {\n throw new Error(`data source is not a custom data source`);\n }\n if (!this.processorCache[ds.processor.file]) {\n const sandbox = new DsPluginSandbox(\n {\n root: this.project.root,\n entry: ds.processor.file,\n script:\n null /* TODO get working with Readers, same as with sandbox */,\n },\n this.nodeConfig,\n );\n try {\n this.processorCache[ds.processor.file] = sandbox.getDsPlugin<D>();\n } catch (e) {\n logger.error(`not supported ds @${ds.kind}`);\n throw e;\n }\n }\n return this.processorCache[\n ds.processor.file\n ] as unknown as SubqlDatasourceProcessor<D, unknown>;\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async getAssets(\n ds: SubqlEthereumCustomDataSource,\n ): Promise<Record<string, string>> {\n if (!isCustomDs(ds)) {\n throw new Error(`data source is not a custom data source`);\n }\n\n if (!ds.assets) {\n return {};\n }\n\n const res: Record<string, string> = {};\n\n for (const [name, { file }] of ds.assets) {\n // TODO update with https://github.com/subquery/subql/pull/511\n try {\n res[name] = fs.readFileSync(file, {\n encoding: 'utf8',\n });\n } catch (e) {\n logger.error(`Failed to load datasource asset ${file}`);\n throw e;\n }\n }\n\n return res;\n }\n}\n"]}
|
|
@@ -10,6 +10,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
10
10
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
11
11
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
12
12
|
};
|
|
13
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
14
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
15
|
+
};
|
|
13
16
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
18
|
};
|
|
@@ -124,6 +127,7 @@ let DynamicDsService = class DynamicDsService {
|
|
|
124
127
|
};
|
|
125
128
|
DynamicDsService = __decorate([
|
|
126
129
|
(0, common_1.Injectable)(),
|
|
130
|
+
__param(1, (0, common_1.Inject)('ISubqueryProject')),
|
|
127
131
|
__metadata("design:paramtypes", [ds_processor_service_1.DsProcessorService,
|
|
128
132
|
SubqueryProject_1.SubqueryProject])
|
|
129
133
|
], DynamicDsService);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dynamic-ds.service.js","sourceRoot":"","sources":["../../src/indexer/dynamic-ds.service.ts"],"names":[],"mappings":";AAAA,gEAAgE;AAChE,sCAAsC
|
|
1
|
+
{"version":3,"file":"dynamic-ds.service.js","sourceRoot":"","sources":["../../src/indexer/dynamic-ds.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 assert from 'assert';\nimport { Inject, Injectable } from '@nestjs/common';\nimport { isCustomDs, isRuntimeDs } from '@subql/common-ethereum';\nimport { getLogger, MetadataRepo } from '@subql/node-core';\nimport { cloneDeep, isEqual, unionWith } from 'lodash';\nimport { Transaction } from 'sequelize/types';\nimport { SubqlProjectDs, SubqueryProject } from '../configure/SubqueryProject';\nimport { DsProcessorService } from './ds-processor.service';\n\nconst logger = getLogger('dynamic-ds');\n\nconst METADATA_KEY = 'dynamicDatasources';\nconst TEMP_DS_PREFIX = 'ds_';\n\ninterface DatasourceParams {\n templateName: string;\n args?: Record<string, unknown>;\n startBlock: number;\n}\n\n@Injectable()\nexport class DynamicDsService {\n private metaDataRepo: MetadataRepo;\n private tempDsRecords: Record<string, string>;\n\n constructor(\n private readonly dsProcessorService: DsProcessorService,\n @Inject('ISubqueryProject') private readonly project: SubqueryProject,\n ) {}\n\n init(metaDataRepo: MetadataRepo): void {\n this.metaDataRepo = metaDataRepo;\n }\n\n private _datasources: SubqlProjectDs[];\n\n async resetDynamicDatasource(targetHeight: number, tx: Transaction) {\n const dynamicDs = await this.getDynamicDatasourceParams();\n if (dynamicDs.length !== 0) {\n const filteredDs = dynamicDs.filter(\n (ds) => ds.startBlock <= targetHeight,\n );\n const dsRecords = JSON.stringify(filteredDs);\n await this.metaDataRepo.upsert(\n { key: METADATA_KEY, value: dsRecords },\n { transaction: tx },\n );\n }\n }\n\n async createDynamicDatasource(\n params: DatasourceParams,\n tx: Transaction,\n ): Promise<SubqlProjectDs> {\n try {\n const ds = await this.getDatasource(params);\n\n await this.saveDynamicDatasourceParams(params, tx);\n\n logger.info(\n `Created new dynamic datasource from template: \"${params.templateName}\"`,\n );\n\n if (!this._datasources) this._datasources = [];\n this._datasources.push(ds);\n\n return ds;\n } catch (e) {\n logger.error(e.message);\n process.exit(1);\n }\n }\n\n async getDynamicDatasources(): Promise<SubqlProjectDs[]> {\n if (!this._datasources) {\n try {\n const params = await this.getDynamicDatasourceParams();\n\n this._datasources = await Promise.all(\n params.map((params) => this.getDatasource(params)),\n );\n } catch (e) {\n logger.error(`Unable to get dynamic datasources:\\n${e.message}`);\n process.exit(1);\n }\n }\n\n return this._datasources;\n }\n\n deleteTempDsRecords(blockHeight: number) {\n delete this.tempDsRecords[TEMP_DS_PREFIX + blockHeight];\n }\n\n private async getDynamicDatasourceParams(\n blockHeight?: number,\n ): Promise<DatasourceParams[]> {\n assert(this.metaDataRepo, `Model _metadata does not exist`);\n const record = await this.metaDataRepo.findByPk(METADATA_KEY);\n\n let results: DatasourceParams[] = [];\n\n const metaResults: DatasourceParams[] = JSON.parse(\n (record?.value as string) ?? '[]',\n );\n if (metaResults.length) {\n results = [...metaResults];\n }\n\n if (blockHeight !== undefined) {\n const tempResults: DatasourceParams[] = JSON.parse(\n this.tempDsRecords?.[TEMP_DS_PREFIX + blockHeight] ?? '[]',\n );\n if (tempResults.length) {\n results = unionWith(results, tempResults, isEqual);\n }\n }\n\n return results;\n }\n\n private async saveDynamicDatasourceParams(\n dsParams: DatasourceParams,\n tx: Transaction,\n ): Promise<void> {\n const existing = await this.getDynamicDatasourceParams(dsParams.startBlock);\n\n assert(this.metaDataRepo, `Model _metadata does not exist`);\n const dsRecords = JSON.stringify([...existing, dsParams]);\n await this.metaDataRepo\n .upsert({ key: METADATA_KEY, value: dsRecords }, { transaction: tx })\n .then(() => {\n this.tempDsRecords = {\n ...this.tempDsRecords,\n [TEMP_DS_PREFIX + dsParams.startBlock]: dsRecords,\n };\n });\n }\n\n private async getDatasource(\n params: DatasourceParams,\n ): Promise<SubqlProjectDs> {\n const template = cloneDeep(\n this.project.templates.find((t) => t.name === params.templateName),\n );\n\n if (!template) {\n throw new Error(\n `Unable to find matching template in project for name: \"${params.templateName}\"`,\n );\n }\n\n logger.info(\n `Initialised dynamic datasource from template: \"${params.templateName}\"`,\n );\n\n const dsObj = {\n ...template,\n startBlock: params.startBlock,\n } as SubqlProjectDs;\n delete dsObj.name;\n try {\n if (isCustomDs(dsObj)) {\n dsObj.processor.options = {\n ...dsObj.processor.options,\n ...params.args,\n };\n await this.dsProcessorService.validateCustomDs([dsObj]);\n } else if (isRuntimeDs(dsObj)) {\n // XXX add any modifications to the ds here\n }\n\n return dsObj;\n } catch (e) {\n throw new Error(`Unable to create dynamic datasource.\\n ${e.message}`);\n }\n }\n}\n"]}
|
|
@@ -12,7 +12,6 @@ exports.FetchModule = void 0;
|
|
|
12
12
|
const common_1 = require("@nestjs/common");
|
|
13
13
|
const event_emitter_1 = require("@nestjs/event-emitter");
|
|
14
14
|
const node_core_1 = require("@subql/node-core");
|
|
15
|
-
const SubqueryProject_1 = require("../configure/SubqueryProject");
|
|
16
15
|
const api_service_ethereum_1 = require("../ethereum/api.service.ethereum");
|
|
17
16
|
const blockDispatcher_1 = require("./blockDispatcher");
|
|
18
17
|
const dictionary_service_1 = require("./dictionary.service");
|
|
@@ -31,12 +30,12 @@ FetchModule = __decorate([
|
|
|
31
30
|
node_core_1.StoreService,
|
|
32
31
|
{
|
|
33
32
|
provide: node_core_1.ApiService,
|
|
34
|
-
useFactory: async (project) => {
|
|
35
|
-
const apiService = new api_service_ethereum_1.EthereumApiService(project);
|
|
33
|
+
useFactory: async (project, eventEmitter) => {
|
|
34
|
+
const apiService = new api_service_ethereum_1.EthereumApiService(project, eventEmitter);
|
|
36
35
|
await apiService.init();
|
|
37
36
|
return apiService;
|
|
38
37
|
},
|
|
39
|
-
inject: [
|
|
38
|
+
inject: ['ISubqueryProject', event_emitter_1.EventEmitter2],
|
|
40
39
|
},
|
|
41
40
|
indexer_manager_1.IndexerManager,
|
|
42
41
|
{
|
|
@@ -54,7 +53,15 @@ FetchModule = __decorate([
|
|
|
54
53
|
},
|
|
55
54
|
fetch_service_1.FetchService,
|
|
56
55
|
node_core_1.BenchmarkService,
|
|
57
|
-
|
|
56
|
+
{
|
|
57
|
+
provide: dictionary_service_1.DictionaryService,
|
|
58
|
+
useFactory: async (project, nodeConfig) => {
|
|
59
|
+
const dictionaryService = new dictionary_service_1.DictionaryService(project, nodeConfig);
|
|
60
|
+
await dictionaryService.init();
|
|
61
|
+
return dictionaryService;
|
|
62
|
+
},
|
|
63
|
+
inject: ['ISubqueryProject', node_core_1.NodeConfig],
|
|
64
|
+
},
|
|
58
65
|
sandbox_service_1.SandboxService,
|
|
59
66
|
ds_processor_service_1.DsProcessorService,
|
|
60
67
|
dynamic_ds_service_1.DynamicDsService,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.module.js","sourceRoot":"","sources":["../../src/indexer/fetch.module.ts"],"names":[],"mappings":";AAAA,gEAAgE;AAChE,sCAAsC;;;;;;;;;AAEtC,2CAAwC;AACxC,yDAAsD;AACtD,gDAO0B;
|
|
1
|
+
{"version":3,"file":"fetch.module.js","sourceRoot":"","sources":["../../src/indexer/fetch.module.ts"],"names":[],"mappings":";AAAA,gEAAgE;AAChE,sCAAsC;;;;;;;;;AAEtC,2CAAwC;AACxC,yDAAsD;AACtD,gDAO0B;AAE1B,2EAAsE;AACtE,uDAG2B;AAC3B,6DAAyD;AACzD,iEAA4D;AAC5D,6DAAwD;AACxD,mDAA+C;AAC/C,uDAAmD;AACnD,uDAAmD;AACnD,uDAAmD;AACnD,2EAAuE;AAqEhE,IAAM,WAAW,GAAjB,MAAM,WAAW;CAAG,CAAA;AAAd,WAAW;IAnEvB,IAAA,eAAM,EAAC;QACN,SAAS,EAAE;YACT,wBAAY;YACZ;gBACE,OAAO,EAAE,sBAAU;gBACnB,UAAU,EAAE,KAAK,EACf,OAAwB,EACxB,YAA2B,EAC3B,EAAE;oBACF,MAAM,UAAU,GAAG,IAAI,yCAAkB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;oBACjE,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;oBACxB,OAAO,UAAU,CAAC;gBACpB,CAAC;gBACD,MAAM,EAAE,CAAC,kBAAkB,EAAE,6BAAa,CAAC;aAC5C;YACD,gCAAc;YACd;gBACE,OAAO,EAAE,kBAAkB;gBAC3B,UAAU,EAAE,CACV,UAAsB,EACtB,YAA2B,EAC3B,cAA8B,EAC9B,UAAsB,EACtB,cAA8B,EAC9B,EAAE,CACF,UAAU,CAAC,OAAO,KAAK,SAAS;oBAC9B,CAAC,CAAC,IAAI,8CAA4B,CAC9B,UAAU,EACV,YAAY,EACZ,cAAc,CACf;oBACH,CAAC,CAAC,IAAI,wCAAsB,CACxB,UAAU,EACV,UAAU,EACV,cAAc,EACd,YAAY,EACZ,cAAc,CACf;gBACP,MAAM,EAAE;oBACN,sBAAU;oBACV,6BAAa;oBACb,gCAAc;oBACd,sBAAU;oBACV,gCAAc;iBACf;aACF;YACD,4BAAY;YACZ,4BAAgB;YAChB;gBACE,OAAO,EAAE,sCAAiB;gBAC1B,UAAU,EAAE,KAAK,EAAE,OAAwB,EAAE,UAAsB,EAAE,EAAE;oBACrE,MAAM,iBAAiB,GAAG,IAAI,sCAAiB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;oBACrE,MAAM,iBAAiB,CAAC,IAAI,EAAE,CAAC;oBAC/B,OAAO,iBAAiB,CAAC;gBAC3B,CAAC;gBACD,MAAM,EAAE,CAAC,kBAAkB,EAAE,sBAAU,CAAC;aACzC;YACD,gCAAc;YACd,yCAAkB;YAClB,qCAAgB;YAChB,sBAAU;YACV,sBAAU;YACV,gCAAc;YACd,oDAAwB;SACzB;QACD,OAAO,EAAE,CAAC,wBAAY,EAAE,sBAAU,CAAC;KACpC,CAAC;GACW,WAAW,CAAG;AAAd,kCAAW","sourcesContent":["// Copyright 2020-2022 OnFinality Limited authors & contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Module } from '@nestjs/common';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport {\n BenchmarkService,\n MmrService,\n StoreService,\n PoiService,\n ApiService,\n NodeConfig,\n} from '@subql/node-core';\nimport { SubqueryProject } from '../configure/SubqueryProject';\nimport { EthereumApiService } from '../ethereum/api.service.ethereum';\nimport {\n BlockDispatcherService,\n WorkerBlockDispatcherService,\n} from './blockDispatcher';\nimport { DictionaryService } from './dictionary.service';\nimport { DsProcessorService } from './ds-processor.service';\nimport { DynamicDsService } from './dynamic-ds.service';\nimport { FetchService } from './fetch.service';\nimport { IndexerManager } from './indexer.manager';\nimport { ProjectService } from './project.service';\nimport { SandboxService } from './sandbox.service';\nimport { UnfinalizedBlocksService } from './unfinalizedBlocks.service';\n\n@Module({\n providers: [\n StoreService,\n {\n provide: ApiService,\n useFactory: async (\n project: SubqueryProject,\n eventEmitter: EventEmitter2,\n ) => {\n const apiService = new EthereumApiService(project, eventEmitter);\n await apiService.init();\n return apiService;\n },\n inject: ['ISubqueryProject', EventEmitter2],\n },\n IndexerManager,\n {\n provide: 'IBlockDispatcher',\n useFactory: (\n nodeConfig: NodeConfig,\n eventEmitter: EventEmitter2,\n projectService: ProjectService,\n apiService: ApiService,\n indexerManager: IndexerManager,\n ) =>\n nodeConfig.workers !== undefined\n ? new WorkerBlockDispatcherService(\n nodeConfig,\n eventEmitter,\n projectService,\n )\n : new BlockDispatcherService(\n apiService,\n nodeConfig,\n indexerManager,\n eventEmitter,\n projectService,\n ),\n inject: [\n NodeConfig,\n EventEmitter2,\n ProjectService,\n ApiService,\n IndexerManager,\n ],\n },\n FetchService,\n BenchmarkService,\n {\n provide: DictionaryService,\n useFactory: async (project: SubqueryProject, nodeConfig: NodeConfig) => {\n const dictionaryService = new DictionaryService(project, nodeConfig);\n await dictionaryService.init();\n return dictionaryService;\n },\n inject: ['ISubqueryProject', NodeConfig],\n },\n SandboxService,\n DsProcessorService,\n DynamicDsService,\n PoiService,\n MmrService,\n ProjectService,\n UnfinalizedBlocksService,\n ],\n exports: [StoreService, MmrService],\n})\nexport class FetchModule {}\n"]}
|
|
@@ -21,11 +21,11 @@ export declare class FetchService implements OnApplicationShutdown {
|
|
|
21
21
|
private latestBestHeight;
|
|
22
22
|
private latestFinalizedHeight;
|
|
23
23
|
private isShutdown;
|
|
24
|
-
private dictionaryQueryEntries?;
|
|
25
24
|
private batchSizeScale;
|
|
26
25
|
private templateDynamicDatasouces;
|
|
27
26
|
private dictionaryGenesisMatches;
|
|
28
27
|
private evmChainId;
|
|
28
|
+
private bypassBlocks;
|
|
29
29
|
constructor(apiService: ApiService, nodeConfig: NodeConfig, project: SubqueryProject, blockDispatcher: IBlockDispatcher, dictionaryService: DictionaryService, dynamicDsService: DynamicDsService, unfinalizedBlocksService: UnfinalizedBlocksService, eventEmitter: EventEmitter2, schedulerRegistry: SchedulerRegistry);
|
|
30
30
|
onApplicationShutdown(): void;
|
|
31
31
|
get api(): ApiWrapper;
|
|
@@ -34,6 +34,8 @@ export declare class FetchService implements OnApplicationShutdown {
|
|
|
34
34
|
updateDictionary(): void;
|
|
35
35
|
private get useDictionary();
|
|
36
36
|
init(startHeight: number): Promise<void>;
|
|
37
|
+
getUseDictionary(): boolean;
|
|
38
|
+
getLatestFinalizedHeight(): number;
|
|
37
39
|
checkBatchScale(): void;
|
|
38
40
|
getFinalizedBlockHead(): Promise<void>;
|
|
39
41
|
getBestBlockHead(): Promise<void>;
|
|
@@ -42,6 +44,8 @@ export declare class FetchService implements OnApplicationShutdown {
|
|
|
42
44
|
getModuloBlocks(startHeight: number, endHeight: number): number[];
|
|
43
45
|
getEnqueuedModuloBlocks(startBlockHeight: number): number[];
|
|
44
46
|
fillNextBlockBuffer(initBlockHeight: number): Promise<void>;
|
|
47
|
+
private getLatestBufferHeight;
|
|
48
|
+
private filteredBlockBatch;
|
|
45
49
|
private nextEndBlockHeight;
|
|
46
50
|
private dictionaryValidation;
|
|
47
51
|
resetForNewDs(blockHeight: number): Promise<void>;
|
|
@@ -94,6 +94,7 @@ let FetchService = class FetchService {
|
|
|
94
94
|
this.schedulerRegistry = schedulerRegistry;
|
|
95
95
|
this.isShutdown = false;
|
|
96
96
|
this.dictionaryGenesisMatches = true;
|
|
97
|
+
this.bypassBlocks = [];
|
|
97
98
|
this.batchSizeScale = 1;
|
|
98
99
|
}
|
|
99
100
|
onApplicationShutdown() {
|
|
@@ -164,6 +165,10 @@ let FetchService = class FetchService {
|
|
|
164
165
|
!!this.dictionaryService.getDictionaryQueryEntries((_a = this.blockDispatcher.latestBufferedHeight) !== null && _a !== void 0 ? _a : Math.min(...this.project.dataSources.map((ds) => ds.startBlock))).length);
|
|
165
166
|
}
|
|
166
167
|
async init(startHeight) {
|
|
168
|
+
var _a;
|
|
169
|
+
if (((_a = this.project.network) === null || _a === void 0 ? void 0 : _a.bypassBlocks) !== undefined) {
|
|
170
|
+
this.bypassBlocks = (0, node_core_1.transformBypassBlocks)(this.project.network.bypassBlocks).filter((blk) => blk >= startHeight);
|
|
171
|
+
}
|
|
167
172
|
if (this.api) {
|
|
168
173
|
const CHAIN_INTERVAL = (0, utils_ethereum_1.calcInterval)(this.api) * INTERVAL_PERCENT;
|
|
169
174
|
BLOCK_TIME_VARIANCE = Math.min(BLOCK_TIME_VARIANCE, CHAIN_INTERVAL);
|
|
@@ -179,9 +184,22 @@ let FetchService = class FetchService {
|
|
|
179
184
|
}
|
|
180
185
|
await this.getFinalizedBlockHead();
|
|
181
186
|
await this.getBestBlockHead();
|
|
187
|
+
// Call metadata here, other network should align with this
|
|
188
|
+
// For substrate, we might use the specVersion metadata in future if we have same error handling as in node-core
|
|
189
|
+
const metadata = await this.dictionaryService.getMetadata();
|
|
190
|
+
const validChecker = this.dictionaryValidation(metadata);
|
|
191
|
+
if (validChecker) {
|
|
192
|
+
this.dictionaryService.setDictionaryStartHeight(metadata._metadata.startHeight);
|
|
193
|
+
}
|
|
182
194
|
await this.blockDispatcher.init(this.resetForNewDs.bind(this));
|
|
183
195
|
void this.startLoop(startHeight);
|
|
184
196
|
}
|
|
197
|
+
getUseDictionary() {
|
|
198
|
+
return this.useDictionary;
|
|
199
|
+
}
|
|
200
|
+
getLatestFinalizedHeight() {
|
|
201
|
+
return this.latestFinalizedHeight;
|
|
202
|
+
}
|
|
185
203
|
checkBatchScale() {
|
|
186
204
|
if (this.nodeConfig['scale-batch-size']) {
|
|
187
205
|
const scale = (0, node_core_1.checkMemoryUsage)(this.batchSizeScale, this.nodeConfig);
|
|
@@ -281,6 +299,9 @@ let FetchService = class FetchService {
|
|
|
281
299
|
? this.blockDispatcher.latestBufferedHeight + 1
|
|
282
300
|
: initBlockHeight;
|
|
283
301
|
};
|
|
302
|
+
if (this.dictionaryService.startHeight > getStartBlockHeight()) {
|
|
303
|
+
logger.warn(`Dictionary start height ${this.dictionaryService.startHeight} is beyond indexing height ${getStartBlockHeight()}, skipping dictionary for now`);
|
|
304
|
+
}
|
|
284
305
|
while (!this.isShutdown) {
|
|
285
306
|
startBlockHeight = getStartBlockHeight();
|
|
286
307
|
scaledBatchSize = Math.max(Math.round(this.batchSizeScale * this.nodeConfig.batchSize), Math.min(MINIMUM_BATCH_SIZE, this.nodeConfig.batchSize * 3));
|
|
@@ -292,7 +313,8 @@ let FetchService = class FetchService {
|
|
|
292
313
|
await (0, node_core_1.delay)(1);
|
|
293
314
|
continue;
|
|
294
315
|
}
|
|
295
|
-
if (this.useDictionary
|
|
316
|
+
if (this.useDictionary &&
|
|
317
|
+
startBlockHeight >= this.dictionaryService.startHeight) {
|
|
296
318
|
const queryEndBlock = startBlockHeight + DICTIONARY_MAX_QUERY_SIZE;
|
|
297
319
|
const moduloBlocks = this.getModuloBlocks(startBlockHeight, queryEndBlock);
|
|
298
320
|
try {
|
|
@@ -309,12 +331,13 @@ let FetchService = class FetchService {
|
|
|
309
331
|
.sort((a, b) => a - b);
|
|
310
332
|
if (batchBlocks.length === 0) {
|
|
311
333
|
// There we're no blocks in this query range, we can set a new height we're up to
|
|
312
|
-
this.blockDispatcher.
|
|
334
|
+
this.blockDispatcher.enqueueBlocks([], Math.min(queryEndBlock - 1, dictionary._metadata.lastProcessedHeight));
|
|
313
335
|
}
|
|
314
336
|
else {
|
|
315
337
|
const maxBlockSize = Math.min(batchBlocks.length, this.blockDispatcher.freeSize);
|
|
316
|
-
|
|
317
|
-
this.
|
|
338
|
+
const enqueuingBlocks = batchBlocks.slice(0, maxBlockSize);
|
|
339
|
+
const cleanedBatchBlocks = this.filteredBlockBatch(enqueuingBlocks);
|
|
340
|
+
this.blockDispatcher.enqueueBlocks(cleanedBatchBlocks, this.getLatestBufferHeight(cleanedBatchBlocks, enqueuingBlocks));
|
|
318
341
|
}
|
|
319
342
|
continue; // skip nextBlockRange() way
|
|
320
343
|
}
|
|
@@ -327,13 +350,32 @@ let FetchService = class FetchService {
|
|
|
327
350
|
}
|
|
328
351
|
const endHeight = this.nextEndBlockHeight(startBlockHeight, scaledBatchSize);
|
|
329
352
|
if (handlers.length && this.getModulos().length === handlers.length) {
|
|
330
|
-
this.
|
|
353
|
+
const enqueuingBlocks = this.getEnqueuedModuloBlocks(startBlockHeight);
|
|
354
|
+
const cleanedBatchBlocks = this.filteredBlockBatch(enqueuingBlocks);
|
|
355
|
+
this.blockDispatcher.enqueueBlocks(cleanedBatchBlocks, this.getLatestBufferHeight(cleanedBatchBlocks, enqueuingBlocks));
|
|
331
356
|
}
|
|
332
357
|
else {
|
|
333
|
-
|
|
358
|
+
const enqueuingBlocks = (0, lodash_1.range)(startBlockHeight, endHeight + 1);
|
|
359
|
+
const cleanedBatchBlocks = this.filteredBlockBatch(enqueuingBlocks);
|
|
360
|
+
this.blockDispatcher.enqueueBlocks(cleanedBatchBlocks, this.getLatestBufferHeight(cleanedBatchBlocks, enqueuingBlocks));
|
|
334
361
|
}
|
|
335
362
|
}
|
|
336
363
|
}
|
|
364
|
+
getLatestBufferHeight(cleanedBatchBlocks, rawBatchBlocks) {
|
|
365
|
+
return Math.max(...cleanedBatchBlocks, ...rawBatchBlocks);
|
|
366
|
+
}
|
|
367
|
+
filteredBlockBatch(currentBatchBlocks) {
|
|
368
|
+
if (!this.bypassBlocks.length || !currentBatchBlocks) {
|
|
369
|
+
return currentBatchBlocks;
|
|
370
|
+
}
|
|
371
|
+
const cleanedBatch = (0, node_core_1.cleanedBatchBlocks)(this.bypassBlocks, currentBatchBlocks);
|
|
372
|
+
const pollutedBlocks = this.bypassBlocks.filter((b) => b < Math.max(...currentBatchBlocks));
|
|
373
|
+
if (pollutedBlocks.length) {
|
|
374
|
+
logger.info(`Bypassing blocks: ${pollutedBlocks}`);
|
|
375
|
+
}
|
|
376
|
+
this.bypassBlocks = (0, lodash_1.without)(this.bypassBlocks, ...pollutedBlocks);
|
|
377
|
+
return cleanedBatch;
|
|
378
|
+
}
|
|
337
379
|
nextEndBlockHeight(startBlockHeight, scaledBatchSize) {
|
|
338
380
|
let endBlockHeight = startBlockHeight + scaledBatchSize - 1;
|
|
339
381
|
if (endBlockHeight > this.latestFinalizedHeight) {
|
|
@@ -348,23 +390,29 @@ let FetchService = class FetchService {
|
|
|
348
390
|
}
|
|
349
391
|
return endBlockHeight;
|
|
350
392
|
}
|
|
351
|
-
dictionaryValidation(
|
|
352
|
-
if (
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
393
|
+
dictionaryValidation(dictionary, startBlockHeight) {
|
|
394
|
+
if (dictionary !== undefined) {
|
|
395
|
+
const { _metadata: metaData } = dictionary;
|
|
396
|
+
if (metaData.genesisHash !== this.api.getGenesisHash() &&
|
|
397
|
+
this.evmChainId !== this.api.getChainId().toString()) {
|
|
398
|
+
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');
|
|
399
|
+
this.dictionaryGenesisMatches = false;
|
|
400
|
+
this.eventEmitter.emit(node_core_1.IndexerEvent.UsingDictionary, {
|
|
401
|
+
value: Number(this.useDictionary),
|
|
402
|
+
});
|
|
403
|
+
this.eventEmitter.emit(node_core_1.IndexerEvent.SkipDictionary);
|
|
404
|
+
return false;
|
|
405
|
+
}
|
|
406
|
+
if (startBlockHeight !== undefined) {
|
|
407
|
+
if (metaData.lastProcessedHeight < startBlockHeight) {
|
|
408
|
+
logger.warn(`Dictionary indexed block is behind current indexing block height`);
|
|
409
|
+
this.eventEmitter.emit(node_core_1.IndexerEvent.SkipDictionary);
|
|
410
|
+
return false;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
return true;
|
|
366
414
|
}
|
|
367
|
-
return
|
|
415
|
+
return false;
|
|
368
416
|
}
|
|
369
417
|
async resetForNewDs(blockHeight) {
|
|
370
418
|
await this.syncDynamicDatascourcesFromMeta();
|
|
@@ -398,6 +446,7 @@ __decorate([
|
|
|
398
446
|
], FetchService.prototype, "getBestBlockHead", null);
|
|
399
447
|
FetchService = __decorate([
|
|
400
448
|
(0, common_1.Injectable)(),
|
|
449
|
+
__param(2, (0, common_1.Inject)('ISubqueryProject')),
|
|
401
450
|
__param(3, (0, common_1.Inject)('IBlockDispatcher')),
|
|
402
451
|
__metadata("design:paramtypes", [node_core_1.ApiService,
|
|
403
452
|
node_core_1.NodeConfig,
|