@subql/node-ethereum 0.1.1 → 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/CHANGELOG.md +8 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/indexer/blockDispatcher/base-block-dispatcher.d.ts +40 -0
- package/dist/indexer/blockDispatcher/base-block-dispatcher.js +97 -0
- package/dist/indexer/blockDispatcher/base-block-dispatcher.js.map +1 -0
- package/dist/indexer/blockDispatcher/block-dispatcher.service.d.ts +23 -0
- package/dist/indexer/blockDispatcher/block-dispatcher.service.js +134 -0
- package/dist/indexer/blockDispatcher/block-dispatcher.service.js.map +1 -0
- package/dist/indexer/blockDispatcher/index.d.ts +4 -0
- package/dist/indexer/blockDispatcher/index.js +10 -0
- package/dist/indexer/blockDispatcher/index.js.map +1 -0
- package/dist/indexer/blockDispatcher/worker-block-dispatcher.service.d.ts +20 -0
- package/dist/indexer/blockDispatcher/worker-block-dispatcher.service.js +170 -0
- package/dist/indexer/blockDispatcher/worker-block-dispatcher.service.js.map +1 -0
- package/dist/indexer/dynamic-ds.service.d.ts +1 -0
- package/dist/indexer/dynamic-ds.service.js +19 -12
- package/dist/indexer/dynamic-ds.service.js.map +1 -1
- package/dist/indexer/fetch.module.js +3 -3
- package/dist/indexer/fetch.module.js.map +1 -1
- package/dist/indexer/fetch.service.d.ts +6 -4
- package/dist/indexer/fetch.service.js +45 -16
- package/dist/indexer/fetch.service.js.map +1 -1
- package/dist/indexer/indexer.manager.d.ts +1 -0
- package/dist/indexer/indexer.manager.js +2 -1
- package/dist/indexer/indexer.manager.js.map +1 -1
- package/dist/indexer/project.service.d.ts +3 -0
- package/dist/indexer/project.service.js +18 -0
- package/dist/indexer/project.service.js.map +1 -1
- package/dist/indexer/worker/worker.service.d.ts +1 -0
- package/dist/indexer/worker/worker.service.js.map +1 -1
- package/dist/main.js +3 -0
- package/dist/main.js.map +1 -1
- package/dist/subcommands/reindex.init.js +1 -0
- package/dist/subcommands/reindex.init.js.map +1 -1
- package/dist/subcommands/reindex.module.js +10 -1
- package/dist/subcommands/reindex.module.js.map +1 -1
- package/dist/subcommands/reindex.service.d.ts +4 -3
- package/dist/subcommands/reindex.service.js +21 -42
- package/dist/subcommands/reindex.service.js.map +1 -1
- package/dist/utils/project.js +21 -0
- package/dist/utils/project.js.map +1 -1
- package/dist/utils/reindex.d.ts +5 -0
- package/dist/utils/reindex.js +48 -0
- package/dist/utils/reindex.js.map +1 -0
- package/dist/yargs.d.ts +7 -1
- package/dist/yargs.js +6 -0
- package/dist/yargs.js.map +1 -1
- package/package.json +5 -5
- package/dist/indexer/worker/block-dispatcher.service.d.ts +0 -69
- package/dist/indexer/worker/block-dispatcher.service.js +0 -356
- package/dist/indexer/worker/block-dispatcher.service.js.map +0 -1
package/dist/yargs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yargs.js","sourceRoot":"","sources":["../src/yargs.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2020-2022 OnFinality Limited authors & contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport { initLogger } from '@subql/node-core/logger';\nimport { hideBin } from 'yargs/helpers';\nimport yargs from 'yargs/yargs';\n\nexport const yargsOptions = yargs(hideBin(process.argv))\n .command({\n command: 'force-clean',\n describe:\n 'Clean the database dropping project schemas and tables. Once the command is executed, the application would exit upon completion.',\n builder: {},\n handler: (argv) => {\n initLogger(\n argv.debug as boolean,\n argv.outputFmt as 'json' | 'colored',\n argv.logLevel as string | undefined,\n );\n\n // lazy import to make sure logger is instantiated before all other services\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { forceCleanInit } = require('./subcommands/forceClean.init');\n return forceCleanInit();\n },\n })\n .command({\n command: 'reindex',\n describe:\n 'Reindex to specified block height. Historical must be enabled for the targeted project (--disable-historical=false). Once the command is executed, the application would exit upon completion.',\n builder: (yargs) =>\n yargs.options('targetHeight', {\n type: 'number',\n description: 'set targetHeight',\n require: true,\n }),\n handler: (argv) => {\n initLogger(\n argv.debug as boolean,\n argv.outputFmt as 'json' | 'colored',\n argv.logLevel as string | undefined,\n );\n // lazy import to make sure logger is instantiated before all other services\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { reindexInit } = require('./subcommands/reindex.init');\n return reindexInit(argv.targetHeight);\n },\n })\n .options({\n subquery: {\n alias: 'f',\n demandOption: true,\n default: process.cwd(),\n describe: 'Local path or IPFS cid of the subquery project',\n type: 'string',\n },\n 'subquery-name': {\n deprecated: true,\n demandOption: false,\n describe: 'Name of the subquery project',\n type: 'string',\n },\n config: {\n alias: 'c',\n demandOption: false,\n describe: 'Specify configuration file',\n type: 'string',\n },\n local: {\n deprecated: true,\n type: 'boolean',\n demandOption: false,\n describe: 'Use local mode',\n },\n 'db-schema': {\n demandOption: false,\n describe: 'Db schema name of the project',\n type: 'string',\n },\n unsafe: {\n type: 'boolean',\n demandOption: false,\n describe: 'Allows usage of any built-in module within the sandbox',\n },\n subscription: {\n demandOption: false,\n describe: 'Enable subscription by create notification triggers',\n type: 'boolean',\n default: false,\n },\n 'batch-size': {\n demandOption: false,\n describe: 'Batch size of blocks to fetch in one round',\n type: 'number',\n },\n 'scale-batch-size': {\n type: 'boolean',\n demandOption: false,\n describe: 'scale batch size based on memory usage',\n default: false,\n },\n timeout: {\n demandOption: false,\n describe: 'Timeout for indexer sandbox to execute the mapping functions',\n type: 'number',\n },\n debug: {\n demandOption: false,\n describe:\n 'Show debug information to console output. will forcefully set log level to debug',\n type: 'boolean',\n default: false,\n },\n profiler: {\n demandOption: false,\n describe: 'Show profiler information to console output',\n type: 'boolean',\n default: false,\n },\n 'network-endpoint': {\n demandOption: false,\n type: 'string',\n describe: 'Blockchain network endpoint to connect',\n },\n 'output-fmt': {\n demandOption: false,\n describe: 'Print log as json or plain text',\n type: 'string',\n choices: ['json', 'colored'],\n },\n 'log-level': {\n demandOption: false,\n describe: 'Specify log level to print. Ignored when --debug is used',\n type: 'string',\n choices: ['fatal', 'error', 'warn', 'info', 'debug', 'trace', 'silent'],\n },\n migrate: {\n demandOption: false,\n describe: 'Migrate db schema (for management tables only)',\n type: 'boolean',\n default: false,\n },\n 'timestamp-field': {\n demandOption: false,\n describe: 'Enable/disable created_at and updated_at in schema',\n type: 'boolean',\n default: false,\n },\n 'network-dictionary': {\n alias: 'd',\n demandOption: false,\n describe: 'Specify the dictionary api for this network',\n type: 'string',\n },\n 'dictionary-timeout': {\n demandOption: false,\n describe: 'Max timeout for dictionary query',\n type: 'number',\n },\n 'mmr-path': {\n alias: 'm',\n demandOption: false,\n describe: 'Local path of the merkle mountain range (.mmr) file',\n type: 'string',\n },\n 'proof-of-index': {\n demandOption: false,\n describe: 'Enable/disable proof of index',\n type: 'boolean',\n default: false,\n },\n ipfs: {\n demandOption: false,\n describe: 'IPFS gateway endpoint',\n type: 'string',\n },\n port: {\n alias: 'p',\n demandOption: false,\n describe: 'The port the service will bind to',\n type: 'number',\n },\n 'disable-historical': {\n demandOption: false,\n default: false,\n describe: 'Disable storing historical state entities',\n type: 'boolean',\n },\n workers: {\n alias: 'w',\n demandOption: false,\n describe:\n 'Number of worker threads to use for fetching and processing blocks. Disabled by default.',\n type: 'number',\n },\n 'query-limit': {\n demandOption: false,\n describe:\n 'The limit of items a project can query with store.getByField at once',\n type: 'number',\n default: 100,\n },\n });\n"]}
|
|
1
|
+
{"version":3,"file":"yargs.js","sourceRoot":"","sources":["../src/yargs.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2020-2022 OnFinality Limited authors & contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport { initLogger } from '@subql/node-core/logger';\nimport { hideBin } from 'yargs/helpers';\nimport yargs from 'yargs/yargs';\n\nexport const yargsOptions = yargs(hideBin(process.argv))\n .command({\n command: 'force-clean',\n describe:\n 'Clean the database dropping project schemas and tables. Once the command is executed, the application would exit upon completion.',\n builder: {},\n handler: (argv) => {\n initLogger(\n argv.debug as boolean,\n argv.outputFmt as 'json' | 'colored',\n argv.logLevel as string | undefined,\n );\n\n // lazy import to make sure logger is instantiated before all other services\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { forceCleanInit } = require('./subcommands/forceClean.init');\n return forceCleanInit();\n },\n })\n .command({\n command: 'reindex',\n describe:\n 'Reindex to specified block height. Historical must be enabled for the targeted project (--disable-historical=false). Once the command is executed, the application would exit upon completion.',\n builder: (yargs) =>\n yargs.options('targetHeight', {\n type: 'number',\n description: 'set targetHeight',\n require: true,\n }),\n handler: (argv) => {\n initLogger(\n argv.debug as boolean,\n argv.outputFmt as 'json' | 'colored',\n argv.logLevel as string | undefined,\n );\n // lazy import to make sure logger is instantiated before all other services\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const { reindexInit } = require('./subcommands/reindex.init');\n return reindexInit(argv.targetHeight);\n },\n })\n .options({\n subquery: {\n alias: 'f',\n demandOption: true,\n default: process.cwd(),\n describe: 'Local path or IPFS cid of the subquery project',\n type: 'string',\n },\n 'subquery-name': {\n deprecated: true,\n demandOption: false,\n describe: 'Name of the subquery project',\n type: 'string',\n },\n config: {\n alias: 'c',\n demandOption: false,\n describe: 'Specify configuration file',\n type: 'string',\n },\n local: {\n deprecated: true,\n type: 'boolean',\n demandOption: false,\n describe: 'Use local mode',\n },\n 'db-schema': {\n demandOption: false,\n describe: 'Db schema name of the project',\n type: 'string',\n },\n unsafe: {\n type: 'boolean',\n demandOption: false,\n describe: 'Allows usage of any built-in module within the sandbox',\n },\n subscription: {\n demandOption: false,\n describe: 'Enable subscription by create notification triggers',\n type: 'boolean',\n default: false,\n },\n 'batch-size': {\n demandOption: false,\n describe: 'Batch size of blocks to fetch in one round',\n type: 'number',\n },\n 'scale-batch-size': {\n type: 'boolean',\n demandOption: false,\n describe: 'scale batch size based on memory usage',\n default: false,\n },\n timeout: {\n demandOption: false,\n describe: 'Timeout for indexer sandbox to execute the mapping functions',\n type: 'number',\n },\n debug: {\n demandOption: false,\n describe:\n 'Show debug information to console output. will forcefully set log level to debug',\n type: 'boolean',\n default: false,\n },\n profiler: {\n demandOption: false,\n describe: 'Show profiler information to console output',\n type: 'boolean',\n default: false,\n },\n 'network-endpoint': {\n demandOption: false,\n type: 'string',\n describe: 'Blockchain network endpoint to connect',\n },\n 'output-fmt': {\n demandOption: false,\n describe: 'Print log as json or plain text',\n type: 'string',\n choices: ['json', 'colored'],\n },\n 'log-level': {\n demandOption: false,\n describe: 'Specify log level to print. Ignored when --debug is used',\n type: 'string',\n choices: ['fatal', 'error', 'warn', 'info', 'debug', 'trace', 'silent'],\n },\n migrate: {\n demandOption: false,\n describe: 'Migrate db schema (for management tables only)',\n type: 'boolean',\n default: false,\n },\n 'timestamp-field': {\n demandOption: false,\n describe: 'Enable/disable created_at and updated_at in schema',\n type: 'boolean',\n default: false,\n },\n 'network-dictionary': {\n alias: 'd',\n demandOption: false,\n describe: 'Specify the dictionary api for this network',\n type: 'string',\n },\n 'dictionary-timeout': {\n demandOption: false,\n describe: 'Max timeout for dictionary query',\n type: 'number',\n },\n 'mmr-path': {\n alias: 'm',\n demandOption: false,\n describe: 'Local path of the merkle mountain range (.mmr) file',\n type: 'string',\n },\n 'proof-of-index': {\n demandOption: false,\n describe: 'Enable/disable proof of index',\n type: 'boolean',\n default: false,\n },\n ipfs: {\n demandOption: false,\n describe: 'IPFS gateway endpoint',\n type: 'string',\n },\n port: {\n alias: 'p',\n demandOption: false,\n describe: 'The port the service will bind to',\n type: 'number',\n },\n 'disable-historical': {\n demandOption: false,\n default: false,\n describe: 'Disable storing historical state entities',\n type: 'boolean',\n },\n workers: {\n alias: 'w',\n demandOption: false,\n describe:\n 'Number of worker threads to use for fetching and processing blocks. Disabled by default.',\n type: 'number',\n },\n 'query-limit': {\n demandOption: false,\n describe:\n 'The limit of items a project can query with store.getByField at once',\n type: 'number',\n default: 100,\n },\n 'unfinalized-blocks': {\n demandOption: false,\n default: false,\n describe: 'Enable to fetch and index unfinalized blocks',\n type: 'boolean',\n },\n });\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@subql/node-ethereum",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "Ian He",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"homepage": "https://github.com/subquery/subql",
|
|
16
16
|
"repository": "github:subquery/subql",
|
|
17
17
|
"bin": {
|
|
18
|
-
"subql-node-
|
|
18
|
+
"subql-node-flare": "./bin/run"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@apollo/client": "3.5.8",
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"@nestjs/platform-express": "^8.2.6",
|
|
26
26
|
"@nestjs/schedule": "^1.0.2",
|
|
27
27
|
"@subql/common": "latest",
|
|
28
|
-
"@subql/common-ethereum": "0.1
|
|
29
|
-
"@subql/node-core": "1.
|
|
30
|
-
"@subql/types-ethereum": "0.1
|
|
28
|
+
"@subql/common-ethereum": "0.2.1",
|
|
29
|
+
"@subql/node-core": "1.4.2-0",
|
|
30
|
+
"@subql/types-ethereum": "0.2.1",
|
|
31
31
|
"@subql/utils": "latest",
|
|
32
32
|
"@subql/x-merkle-mountain-range": "2.0.0-0.1.2",
|
|
33
33
|
"@willsoto/nestjs-prometheus": "^4.4.0",
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { OnApplicationShutdown } from '@nestjs/common';
|
|
2
|
-
import { EventEmitter2 } from '@nestjs/event-emitter';
|
|
3
|
-
import { ApiService, NodeConfig } from '@subql/node-core';
|
|
4
|
-
import { IndexerManager } from '../indexer.manager';
|
|
5
|
-
import { ProjectService } from '../project.service';
|
|
6
|
-
export interface IBlockDispatcher {
|
|
7
|
-
init(onDynamicDsCreated: (height: number) => Promise<void>): Promise<void>;
|
|
8
|
-
enqueueBlocks(heights: number[]): void;
|
|
9
|
-
queueSize: number;
|
|
10
|
-
freeSize: number;
|
|
11
|
-
latestBufferedHeight: number | undefined;
|
|
12
|
-
flushQueue(height: number): void;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* @description Intended to behave the same as WorkerBlockDispatcherService but doesn't use worker threads or any parallel processing
|
|
16
|
-
*/
|
|
17
|
-
export declare class BlockDispatcherService implements IBlockDispatcher, OnApplicationShutdown {
|
|
18
|
-
private apiService;
|
|
19
|
-
private nodeConfig;
|
|
20
|
-
private indexerManager;
|
|
21
|
-
private eventEmitter;
|
|
22
|
-
private projectService;
|
|
23
|
-
private fetchQueue;
|
|
24
|
-
private processQueue;
|
|
25
|
-
private fetching;
|
|
26
|
-
private isShutdown;
|
|
27
|
-
private onDynamicDsCreated;
|
|
28
|
-
private _latestBufferedHeight;
|
|
29
|
-
private _processedBlockCount;
|
|
30
|
-
private fetchBlocksBatches;
|
|
31
|
-
private latestProcessedHeight;
|
|
32
|
-
constructor(apiService: ApiService, nodeConfig: NodeConfig, indexerManager: IndexerManager, eventEmitter: EventEmitter2, projectService: ProjectService);
|
|
33
|
-
init(onDynamicDsCreated: (height: number) => Promise<void>): Promise<void>;
|
|
34
|
-
onApplicationShutdown(): void;
|
|
35
|
-
enqueueBlocks(heights: number[]): void;
|
|
36
|
-
flushQueue(height: number): void;
|
|
37
|
-
private setProcessedBlockCount;
|
|
38
|
-
private fetchBlocksFromQueue;
|
|
39
|
-
get queueSize(): number;
|
|
40
|
-
get freeSize(): number;
|
|
41
|
-
get latestBufferedHeight(): number;
|
|
42
|
-
set latestBufferedHeight(height: number);
|
|
43
|
-
}
|
|
44
|
-
export declare class WorkerBlockDispatcherService implements IBlockDispatcher, OnApplicationShutdown {
|
|
45
|
-
private nodeConfig;
|
|
46
|
-
private eventEmitter;
|
|
47
|
-
private projectService;
|
|
48
|
-
private workers;
|
|
49
|
-
private numWorkers;
|
|
50
|
-
private onDynamicDsCreated;
|
|
51
|
-
private taskCounter;
|
|
52
|
-
private isShutdown;
|
|
53
|
-
private queue;
|
|
54
|
-
private _latestBufferedHeight;
|
|
55
|
-
private _processedBlockCount;
|
|
56
|
-
constructor(nodeConfig: NodeConfig, eventEmitter: EventEmitter2, projectService: ProjectService);
|
|
57
|
-
init(onDynamicDsCreated: (height: number) => Promise<void>): Promise<void>;
|
|
58
|
-
private setProcessedBlockCount;
|
|
59
|
-
onApplicationShutdown(): Promise<void>;
|
|
60
|
-
enqueueBlocks(heights: number[]): void;
|
|
61
|
-
flushQueue(height: number): void;
|
|
62
|
-
private enqueueBlock;
|
|
63
|
-
sampleWorkerStatus(): Promise<void>;
|
|
64
|
-
get queueSize(): number;
|
|
65
|
-
get freeSize(): number;
|
|
66
|
-
get latestBufferedHeight(): number;
|
|
67
|
-
set latestBufferedHeight(height: number);
|
|
68
|
-
private getNextWorkerIndex;
|
|
69
|
-
}
|
|
@@ -1,356 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// Copyright 2020-2021 OnFinality Limited authors & contributors
|
|
3
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
5
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
6
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
7
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
8
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
9
|
-
};
|
|
10
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
11
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
12
|
-
};
|
|
13
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.WorkerBlockDispatcherService = exports.BlockDispatcherService = void 0;
|
|
18
|
-
const assert_1 = __importDefault(require("assert"));
|
|
19
|
-
const path_1 = __importDefault(require("path"));
|
|
20
|
-
const common_1 = require("@nestjs/common");
|
|
21
|
-
const event_emitter_1 = require("@nestjs/event-emitter");
|
|
22
|
-
const schedule_1 = require("@nestjs/schedule");
|
|
23
|
-
const util_1 = require("@polkadot/util");
|
|
24
|
-
const node_core_1 = require("@subql/node-core");
|
|
25
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
26
|
-
const lodash_1 = require("lodash");
|
|
27
|
-
const indexer_manager_1 = require("../indexer.manager");
|
|
28
|
-
const project_service_1 = require("../project.service");
|
|
29
|
-
const NULL_MERKEL_ROOT = (0, util_1.hexToU8a)('0x00');
|
|
30
|
-
function isNullMerkelRoot(operationHash) {
|
|
31
|
-
return (0, util_1.u8aEq)(operationHash, NULL_MERKEL_ROOT);
|
|
32
|
-
}
|
|
33
|
-
async function createIndexerWorker() {
|
|
34
|
-
const indexerWorker = node_core_1.Worker.create(path_1.default.resolve(__dirname, '../../../dist/indexer/worker/worker.js'), [
|
|
35
|
-
'initWorker',
|
|
36
|
-
'processBlock',
|
|
37
|
-
'fetchBlock',
|
|
38
|
-
'numFetchedBlocks',
|
|
39
|
-
'numFetchingBlocks',
|
|
40
|
-
'getStatus',
|
|
41
|
-
]);
|
|
42
|
-
await indexerWorker.initWorker();
|
|
43
|
-
return indexerWorker;
|
|
44
|
-
}
|
|
45
|
-
const logger = (0, node_core_1.getLogger)('BlockDispatcherService');
|
|
46
|
-
// TODO move to another file
|
|
47
|
-
/**
|
|
48
|
-
* @description Intended to behave the same as WorkerBlockDispatcherService but doesn't use worker threads or any parallel processing
|
|
49
|
-
*/
|
|
50
|
-
let BlockDispatcherService = class BlockDispatcherService {
|
|
51
|
-
constructor(apiService, nodeConfig, indexerManager, eventEmitter, projectService) {
|
|
52
|
-
this.apiService = apiService;
|
|
53
|
-
this.nodeConfig = nodeConfig;
|
|
54
|
-
this.indexerManager = indexerManager;
|
|
55
|
-
this.eventEmitter = eventEmitter;
|
|
56
|
-
this.projectService = projectService;
|
|
57
|
-
this.fetching = false;
|
|
58
|
-
this.isShutdown = false;
|
|
59
|
-
this.fetchQueue = new node_core_1.Queue(nodeConfig.batchSize * 3);
|
|
60
|
-
this.processQueue = new node_core_1.AutoQueue(nodeConfig.batchSize * 3);
|
|
61
|
-
const fetchBlocks = this.apiService.api.fetchBlocks.bind(this.apiService.api);
|
|
62
|
-
if (this.nodeConfig.profiler) {
|
|
63
|
-
this.fetchBlocksBatches = (0, node_core_1.profilerWrap)(fetchBlocks, 'EthereumUtil', 'fetchBlocksBatches');
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
this.fetchBlocksBatches = fetchBlocks;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
70
|
-
async init(onDynamicDsCreated) {
|
|
71
|
-
this.onDynamicDsCreated = onDynamicDsCreated;
|
|
72
|
-
const blockAmount = await this.projectService.getProcessedBlockCount();
|
|
73
|
-
this.setProcessedBlockCount(blockAmount !== null && blockAmount !== void 0 ? blockAmount : 0);
|
|
74
|
-
}
|
|
75
|
-
onApplicationShutdown() {
|
|
76
|
-
this.isShutdown = true;
|
|
77
|
-
this.processQueue.abort();
|
|
78
|
-
}
|
|
79
|
-
enqueueBlocks(heights) {
|
|
80
|
-
if (!heights.length)
|
|
81
|
-
return;
|
|
82
|
-
logger.info(`Enqueing blocks ${heights[0]}...${(0, lodash_1.last)(heights)}`);
|
|
83
|
-
this.fetchQueue.putMany(heights);
|
|
84
|
-
this.latestBufferedHeight = (0, lodash_1.last)(heights);
|
|
85
|
-
void this.fetchBlocksFromQueue().catch((e) => {
|
|
86
|
-
logger.error(e, 'Failed to fetch blocks from queue');
|
|
87
|
-
if (!this.isShutdown) {
|
|
88
|
-
throw e;
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
flushQueue(height) {
|
|
93
|
-
this.latestBufferedHeight = height;
|
|
94
|
-
this.fetchQueue.flush(); // Empty
|
|
95
|
-
this.processQueue.flush();
|
|
96
|
-
}
|
|
97
|
-
setProcessedBlockCount(processedBlockCount) {
|
|
98
|
-
this._processedBlockCount = processedBlockCount;
|
|
99
|
-
this.eventEmitter.emit(node_core_1.IndexerEvent.BlockProcessedCount, {
|
|
100
|
-
processedBlockCount,
|
|
101
|
-
timestamp: Date.now(),
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
async fetchBlocksFromQueue() {
|
|
105
|
-
if (this.fetching || this.isShutdown)
|
|
106
|
-
return;
|
|
107
|
-
// Process queue is full, no point in fetching more blocks
|
|
108
|
-
// if (this.processQueue.freeSpace < this.nodeConfig.batchSize) return;
|
|
109
|
-
this.fetching = true;
|
|
110
|
-
try {
|
|
111
|
-
while (!this.isShutdown) {
|
|
112
|
-
const blockNums = this.fetchQueue.takeMany(Math.min(this.nodeConfig.batchSize, this.processQueue.freeSpace));
|
|
113
|
-
// Used to compare before and after as a way to check if queue was flushed
|
|
114
|
-
const bufferedHeight = this._latestBufferedHeight;
|
|
115
|
-
// Queue is empty
|
|
116
|
-
if (!blockNums.length) {
|
|
117
|
-
// The process queue might be full so no block nums were taken, wait and try again
|
|
118
|
-
if (this.fetchQueue.size) {
|
|
119
|
-
await (0, node_core_1.delay)(1);
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
break;
|
|
123
|
-
}
|
|
124
|
-
logger.info(`fetch block [${blockNums[0]},${blockNums[blockNums.length - 1]}], total ${blockNums.length} blocks`);
|
|
125
|
-
const blocks = await this.fetchBlocksBatches(blockNums);
|
|
126
|
-
if (bufferedHeight > this._latestBufferedHeight) {
|
|
127
|
-
logger.debug(`Queue was reset for new DS, discarding fetched blocks`);
|
|
128
|
-
continue;
|
|
129
|
-
}
|
|
130
|
-
const blockTasks = blocks.map((block) => async () => {
|
|
131
|
-
var _a;
|
|
132
|
-
const height = block.blockHeight;
|
|
133
|
-
try {
|
|
134
|
-
this.eventEmitter.emit(node_core_1.IndexerEvent.BlockProcessing, {
|
|
135
|
-
height,
|
|
136
|
-
timestamp: Date.now(),
|
|
137
|
-
});
|
|
138
|
-
const { dynamicDsCreated, operationHash } = await this.indexerManager.indexBlock(block);
|
|
139
|
-
// In memory _processedBlockCount increase, db metadata increase BlockCount in indexer.manager
|
|
140
|
-
this.setProcessedBlockCount(this._processedBlockCount + 1);
|
|
141
|
-
if (this.nodeConfig.proofOfIndex &&
|
|
142
|
-
!isNullMerkelRoot(operationHash)) {
|
|
143
|
-
if (!this.projectService.blockOffset) {
|
|
144
|
-
// Which means during project init, it has not found offset and set value
|
|
145
|
-
await this.projectService.upsertMetadataBlockOffset(height - 1);
|
|
146
|
-
}
|
|
147
|
-
void this.projectService.setBlockOffset(height - 1);
|
|
148
|
-
}
|
|
149
|
-
if (dynamicDsCreated) {
|
|
150
|
-
await this.onDynamicDsCreated(height);
|
|
151
|
-
}
|
|
152
|
-
(0, assert_1.default)(!this.latestProcessedHeight ||
|
|
153
|
-
height > this.latestProcessedHeight, `Block processed out of order. Height: ${height}. Latest: ${this.latestProcessedHeight}`);
|
|
154
|
-
this.latestProcessedHeight = height;
|
|
155
|
-
}
|
|
156
|
-
catch (e) {
|
|
157
|
-
if (this.isShutdown) {
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
logger.error(e, `failed to index block at height ${height} ${e.handler ? `${e.handler}(${(_a = e.stack) !== null && _a !== void 0 ? _a : ''})` : ''}`);
|
|
161
|
-
throw e;
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
// There can be enough of a delay after fetching blocks that shutdown could now be true
|
|
165
|
-
if (this.isShutdown)
|
|
166
|
-
break;
|
|
167
|
-
this.processQueue.putMany(blockTasks);
|
|
168
|
-
this.eventEmitter.emit(node_core_1.IndexerEvent.BlockQueueSize, {
|
|
169
|
-
value: this.processQueue.size,
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
finally {
|
|
174
|
-
this.fetching = false;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
get queueSize() {
|
|
178
|
-
return this.fetchQueue.size;
|
|
179
|
-
}
|
|
180
|
-
get freeSize() {
|
|
181
|
-
return this.fetchQueue.freeSpace;
|
|
182
|
-
}
|
|
183
|
-
get latestBufferedHeight() {
|
|
184
|
-
return this._latestBufferedHeight;
|
|
185
|
-
}
|
|
186
|
-
set latestBufferedHeight(height) {
|
|
187
|
-
this.eventEmitter.emit(node_core_1.IndexerEvent.BlocknumberQueueSize, {
|
|
188
|
-
value: this.queueSize,
|
|
189
|
-
});
|
|
190
|
-
this._latestBufferedHeight = height;
|
|
191
|
-
}
|
|
192
|
-
};
|
|
193
|
-
BlockDispatcherService = __decorate([
|
|
194
|
-
(0, common_1.Injectable)(),
|
|
195
|
-
__metadata("design:paramtypes", [node_core_1.ApiService,
|
|
196
|
-
node_core_1.NodeConfig,
|
|
197
|
-
indexer_manager_1.IndexerManager,
|
|
198
|
-
event_emitter_1.EventEmitter2,
|
|
199
|
-
project_service_1.ProjectService])
|
|
200
|
-
], BlockDispatcherService);
|
|
201
|
-
exports.BlockDispatcherService = BlockDispatcherService;
|
|
202
|
-
let WorkerBlockDispatcherService = class WorkerBlockDispatcherService {
|
|
203
|
-
constructor(nodeConfig, eventEmitter, projectService) {
|
|
204
|
-
this.nodeConfig = nodeConfig;
|
|
205
|
-
this.eventEmitter = eventEmitter;
|
|
206
|
-
this.projectService = projectService;
|
|
207
|
-
this.taskCounter = 0;
|
|
208
|
-
this.isShutdown = false;
|
|
209
|
-
this.numWorkers = nodeConfig.workers;
|
|
210
|
-
this.queue = new node_core_1.AutoQueue(this.numWorkers * nodeConfig.batchSize * 2);
|
|
211
|
-
}
|
|
212
|
-
async init(onDynamicDsCreated) {
|
|
213
|
-
this.workers = await Promise.all(new Array(this.numWorkers).fill(0).map(() => createIndexerWorker()));
|
|
214
|
-
this.onDynamicDsCreated = onDynamicDsCreated;
|
|
215
|
-
const blockAmount = await this.projectService.getProcessedBlockCount();
|
|
216
|
-
this.setProcessedBlockCount(blockAmount !== null && blockAmount !== void 0 ? blockAmount : 0);
|
|
217
|
-
}
|
|
218
|
-
setProcessedBlockCount(processedBlockCount) {
|
|
219
|
-
this._processedBlockCount = processedBlockCount;
|
|
220
|
-
this.eventEmitter.emit(node_core_1.IndexerEvent.BlockProcessedCount, {
|
|
221
|
-
processedBlockCount,
|
|
222
|
-
timestamp: Date.now(),
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
async onApplicationShutdown() {
|
|
226
|
-
this.isShutdown = true;
|
|
227
|
-
// Stop processing blocks
|
|
228
|
-
this.queue.abort();
|
|
229
|
-
// Stop all workers
|
|
230
|
-
if (this.workers) {
|
|
231
|
-
await Promise.all(this.workers.map((w) => w.terminate()));
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
enqueueBlocks(heights) {
|
|
235
|
-
if (!heights.length)
|
|
236
|
-
return;
|
|
237
|
-
logger.info(`Enqueing blocks [${heights[0]}...${(0, lodash_1.last)(heights)}], total ${heights.length} blocks`);
|
|
238
|
-
// eslint-disable-next-line no-constant-condition
|
|
239
|
-
if (true) {
|
|
240
|
-
/*
|
|
241
|
-
* Load balancing:
|
|
242
|
-
* worker1: 1,2,3
|
|
243
|
-
* worker2: 4,5,6
|
|
244
|
-
*/
|
|
245
|
-
const workerIdx = this.getNextWorkerIndex();
|
|
246
|
-
heights.map((height) => this.enqueueBlock(height, workerIdx));
|
|
247
|
-
}
|
|
248
|
-
else {
|
|
249
|
-
/*
|
|
250
|
-
* Load balancing:
|
|
251
|
-
* worker1: 1,3,5
|
|
252
|
-
* worker2: 2,4,6
|
|
253
|
-
*/
|
|
254
|
-
heights.map((height) => this.enqueueBlock(height, this.getNextWorkerIndex()));
|
|
255
|
-
}
|
|
256
|
-
this.latestBufferedHeight = (0, lodash_1.last)(heights);
|
|
257
|
-
}
|
|
258
|
-
flushQueue(height) {
|
|
259
|
-
this.latestBufferedHeight = height;
|
|
260
|
-
this.queue.flush();
|
|
261
|
-
}
|
|
262
|
-
enqueueBlock(height, workerIdx) {
|
|
263
|
-
if (this.isShutdown)
|
|
264
|
-
return;
|
|
265
|
-
const worker = this.workers[workerIdx];
|
|
266
|
-
(0, assert_1.default)(worker, `Worker ${workerIdx} not found`);
|
|
267
|
-
// Used to compare before and after as a way to check if queue was flushed
|
|
268
|
-
const bufferedHeight = this._latestBufferedHeight;
|
|
269
|
-
const pendingBlock = worker.fetchBlock(height);
|
|
270
|
-
const processBlock = async () => {
|
|
271
|
-
var _a;
|
|
272
|
-
try {
|
|
273
|
-
const start = new Date();
|
|
274
|
-
const result = await pendingBlock;
|
|
275
|
-
const end = new Date();
|
|
276
|
-
if (bufferedHeight > this._latestBufferedHeight) {
|
|
277
|
-
logger.debug(`Queue was reset for new DS, discarding fetched blocks`);
|
|
278
|
-
return;
|
|
279
|
-
}
|
|
280
|
-
const waitTime = end.getTime() - start.getTime();
|
|
281
|
-
if (waitTime > 1000) {
|
|
282
|
-
logger.info(`Waiting to fetch block ${height}: ${chalk_1.default.red(`${waitTime}ms`)}`);
|
|
283
|
-
}
|
|
284
|
-
else if (waitTime > 200) {
|
|
285
|
-
logger.info(`Waiting to fetch block ${height}: ${chalk_1.default.yellow(`${waitTime}ms`)}`);
|
|
286
|
-
}
|
|
287
|
-
// logger.info(
|
|
288
|
-
// `worker ${workerIdx} processing block ${height}, fetched blocks: ${await worker.numFetchedBlocks()}, fetching blocks: ${await worker.numFetchingBlocks()}`,
|
|
289
|
-
// );
|
|
290
|
-
this.eventEmitter.emit(node_core_1.IndexerEvent.BlockProcessing, {
|
|
291
|
-
height,
|
|
292
|
-
timestamp: Date.now(),
|
|
293
|
-
});
|
|
294
|
-
const { dynamicDsCreated, operationHash } = await worker.processBlock(height);
|
|
295
|
-
// In memory _processedBlockCount increase, db metadata increase BlockCount in indexer.manager
|
|
296
|
-
this.setProcessedBlockCount(this._processedBlockCount + 1);
|
|
297
|
-
if (this.nodeConfig.proofOfIndex &&
|
|
298
|
-
!isNullMerkelRoot(Buffer.from(operationHash, 'base64'))) {
|
|
299
|
-
if (!this.projectService.blockOffset) {
|
|
300
|
-
// Which means during project init, it has not found offset and set value
|
|
301
|
-
await this.projectService.upsertMetadataBlockOffset(height - 1);
|
|
302
|
-
}
|
|
303
|
-
void this.projectService.setBlockOffset(height - 1);
|
|
304
|
-
}
|
|
305
|
-
if (dynamicDsCreated) {
|
|
306
|
-
await this.onDynamicDsCreated(height);
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
catch (e) {
|
|
310
|
-
logger.error(e, `failed to index block at height ${height} ${e.handler ? `${e.handler}(${(_a = e.stack) !== null && _a !== void 0 ? _a : ''})` : ''}`);
|
|
311
|
-
throw e;
|
|
312
|
-
}
|
|
313
|
-
};
|
|
314
|
-
void this.queue.put(processBlock);
|
|
315
|
-
}
|
|
316
|
-
async sampleWorkerStatus() {
|
|
317
|
-
for (const worker of this.workers) {
|
|
318
|
-
const status = await worker.getStatus();
|
|
319
|
-
logger.info(JSON.stringify(status));
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
get queueSize() {
|
|
323
|
-
return this.queue.size;
|
|
324
|
-
}
|
|
325
|
-
get freeSize() {
|
|
326
|
-
return this.queue.freeSpace;
|
|
327
|
-
}
|
|
328
|
-
get latestBufferedHeight() {
|
|
329
|
-
return this._latestBufferedHeight;
|
|
330
|
-
}
|
|
331
|
-
set latestBufferedHeight(height) {
|
|
332
|
-
this.eventEmitter.emit(node_core_1.IndexerEvent.BlocknumberQueueSize, {
|
|
333
|
-
value: this.queueSize,
|
|
334
|
-
});
|
|
335
|
-
this._latestBufferedHeight = height;
|
|
336
|
-
}
|
|
337
|
-
getNextWorkerIndex() {
|
|
338
|
-
const index = this.taskCounter % this.numWorkers;
|
|
339
|
-
this.taskCounter++;
|
|
340
|
-
return index;
|
|
341
|
-
}
|
|
342
|
-
};
|
|
343
|
-
__decorate([
|
|
344
|
-
(0, schedule_1.Interval)(15000),
|
|
345
|
-
__metadata("design:type", Function),
|
|
346
|
-
__metadata("design:paramtypes", []),
|
|
347
|
-
__metadata("design:returntype", Promise)
|
|
348
|
-
], WorkerBlockDispatcherService.prototype, "sampleWorkerStatus", null);
|
|
349
|
-
WorkerBlockDispatcherService = __decorate([
|
|
350
|
-
(0, common_1.Injectable)(),
|
|
351
|
-
__metadata("design:paramtypes", [node_core_1.NodeConfig,
|
|
352
|
-
event_emitter_1.EventEmitter2,
|
|
353
|
-
project_service_1.ProjectService])
|
|
354
|
-
], WorkerBlockDispatcherService);
|
|
355
|
-
exports.WorkerBlockDispatcherService = WorkerBlockDispatcherService;
|
|
356
|
-
//# sourceMappingURL=block-dispatcher.service.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"block-dispatcher.service.js","sourceRoot":"","sources":["../../../src/indexer/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 { hexToU8a, u8aEq } from '@polkadot/util';\nimport {\n ApiService,\n getLogger,\n NodeConfig,\n IndexerEvent,\n AutoQueue,\n Queue,\n Worker,\n delay,\n profilerWrap,\n} from '@subql/node-core';\nimport { EthereumBlockWrapper } from '@subql/types-ethereum';\nimport chalk from 'chalk';\nimport { last } from 'lodash';\nimport { IndexerManager } from '../indexer.manager';\nimport { ProjectService } from '../project.service';\nimport {\n FetchBlock,\n ProcessBlock,\n InitWorker,\n NumFetchedBlocks,\n NumFetchingBlocks,\n GetWorkerStatus,\n} from './worker';\n\nconst NULL_MERKEL_ROOT = hexToU8a('0x00');\n\nfunction isNullMerkelRoot(operationHash: Uint8Array): boolean {\n return u8aEq(operationHash, NULL_MERKEL_ROOT);\n}\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\nexport interface IBlockDispatcher {\n init(onDynamicDsCreated: (height: number) => Promise<void>): Promise<void>;\n\n enqueueBlocks(heights: number[]): void;\n\n queueSize: number;\n freeSize: number;\n latestBufferedHeight: number | undefined;\n\n // Remove all enqueued blocks, used when a dynamic ds is created\n flushQueue(height: number): void;\n}\n\nconst logger = getLogger('BlockDispatcherService');\n\n// TODO move to another file\n/**\n * @description Intended to behave the same as WorkerBlockDispatcherService but doesn't use worker threads or any parallel processing\n */\n@Injectable()\nexport class BlockDispatcherService\n implements IBlockDispatcher, OnApplicationShutdown\n{\n private fetchQueue: Queue<number>;\n private processQueue: AutoQueue<void>;\n\n private fetching = false;\n private isShutdown = false;\n private onDynamicDsCreated: (height: number) => Promise<void>;\n private _latestBufferedHeight: number;\n private _processedBlockCount: number;\n\n private fetchBlocksBatches: ApiService['api']['fetchBlocks'];\n private latestProcessedHeight: number;\n\n constructor(\n private apiService: ApiService,\n private nodeConfig: NodeConfig,\n private indexerManager: IndexerManager,\n private eventEmitter: EventEmitter2,\n private projectService: ProjectService,\n ) {\n this.fetchQueue = new Queue(nodeConfig.batchSize * 3);\n this.processQueue = new AutoQueue(nodeConfig.batchSize * 3);\n\n const fetchBlocks = this.apiService.api.fetchBlocks.bind(\n this.apiService.api,\n );\n if (this.nodeConfig.profiler) {\n this.fetchBlocksBatches = profilerWrap(\n fetchBlocks,\n 'EthereumUtil',\n 'fetchBlocksBatches',\n );\n } else {\n this.fetchBlocksBatches = fetchBlocks;\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async init(\n onDynamicDsCreated: (height: number) => Promise<void>,\n ): Promise<void> {\n this.onDynamicDsCreated = onDynamicDsCreated;\n const blockAmount = await this.projectService.getProcessedBlockCount();\n this.setProcessedBlockCount(blockAmount ?? 0);\n }\n\n onApplicationShutdown(): void {\n this.isShutdown = true;\n this.processQueue.abort();\n }\n\n enqueueBlocks(heights: number[]): void {\n if (!heights.length) return;\n\n logger.info(`Enqueing blocks ${heights[0]}...${last(heights)}`);\n\n this.fetchQueue.putMany(heights);\n this.latestBufferedHeight = last(heights);\n\n void this.fetchBlocksFromQueue().catch((e) => {\n logger.error(e, 'Failed to fetch blocks from queue');\n if (!this.isShutdown) {\n throw e;\n }\n });\n }\n\n flushQueue(height: number): void {\n this.latestBufferedHeight = height;\n this.fetchQueue.flush(); // Empty\n this.processQueue.flush();\n }\n\n private setProcessedBlockCount(processedBlockCount: number) {\n this._processedBlockCount = processedBlockCount;\n this.eventEmitter.emit(IndexerEvent.BlockProcessedCount, {\n processedBlockCount,\n timestamp: Date.now(),\n });\n }\n\n private async fetchBlocksFromQueue(): Promise<void> {\n if (this.fetching || this.isShutdown) return;\n // Process queue is full, no point in fetching more blocks\n // if (this.processQueue.freeSpace < this.nodeConfig.batchSize) return;\n\n this.fetching = true;\n\n try {\n while (!this.isShutdown) {\n const blockNums = this.fetchQueue.takeMany(\n Math.min(this.nodeConfig.batchSize, this.processQueue.freeSpace),\n );\n // Used to compare before and after as a way to check if queue was flushed\n const bufferedHeight = this._latestBufferedHeight;\n\n // Queue is empty\n if (!blockNums.length) {\n // The process queue might be full so no block nums were taken, wait and try again\n if (this.fetchQueue.size) {\n await delay(1);\n continue;\n }\n break;\n }\n\n logger.info(\n `fetch block [${blockNums[0]},${\n blockNums[blockNums.length - 1]\n }], total ${blockNums.length} blocks`,\n );\n\n const blocks = await this.fetchBlocksBatches(blockNums);\n\n if (bufferedHeight > this._latestBufferedHeight) {\n logger.debug(`Queue was reset for new DS, discarding fetched blocks`);\n continue;\n }\n\n const blockTasks = blocks.map((block) => async () => {\n const height = block.blockHeight;\n try {\n this.eventEmitter.emit(IndexerEvent.BlockProcessing, {\n height,\n timestamp: Date.now(),\n });\n\n const { dynamicDsCreated, operationHash } =\n await this.indexerManager.indexBlock(\n block as EthereumBlockWrapper,\n );\n\n // In memory _processedBlockCount increase, db metadata increase BlockCount in indexer.manager\n this.setProcessedBlockCount(this._processedBlockCount + 1);\n if (\n this.nodeConfig.proofOfIndex &&\n !isNullMerkelRoot(operationHash)\n ) {\n if (!this.projectService.blockOffset) {\n // Which means during project init, it has not found offset and set value\n await this.projectService.upsertMetadataBlockOffset(height - 1);\n }\n void this.projectService.setBlockOffset(height - 1);\n }\n\n if (dynamicDsCreated) {\n await this.onDynamicDsCreated(height);\n }\n\n assert(\n !this.latestProcessedHeight ||\n height > this.latestProcessedHeight,\n `Block processed out of order. Height: ${height}. Latest: ${this.latestProcessedHeight}`,\n );\n this.latestProcessedHeight = height;\n } catch (e) {\n if (this.isShutdown) {\n return;\n }\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 // There can be enough of a delay after fetching blocks that shutdown could now be true\n if (this.isShutdown) break;\n\n this.processQueue.putMany(blockTasks);\n\n this.eventEmitter.emit(IndexerEvent.BlockQueueSize, {\n value: this.processQueue.size,\n });\n }\n } finally {\n this.fetching = false;\n }\n }\n\n get queueSize(): number {\n return this.fetchQueue.size;\n }\n\n get freeSize(): number {\n return this.fetchQueue.freeSpace;\n }\n\n get latestBufferedHeight(): number {\n return this._latestBufferedHeight;\n }\n\n set latestBufferedHeight(height: number) {\n this.eventEmitter.emit(IndexerEvent.BlocknumberQueueSize, {\n value: this.queueSize,\n });\n this._latestBufferedHeight = height;\n }\n}\n\n@Injectable()\nexport class WorkerBlockDispatcherService\n implements IBlockDispatcher, OnApplicationShutdown\n{\n private workers: IndexerWorker[];\n private numWorkers: number;\n private onDynamicDsCreated: (height: number) => Promise<void>;\n\n private taskCounter = 0;\n private isShutdown = false;\n private queue: AutoQueue<void>;\n private _latestBufferedHeight: number;\n private _processedBlockCount: number;\n\n constructor(\n private nodeConfig: NodeConfig,\n private eventEmitter: EventEmitter2,\n private projectService: ProjectService,\n ) {\n this.numWorkers = nodeConfig.workers;\n this.queue = new AutoQueue(this.numWorkers * nodeConfig.batchSize * 2);\n }\n\n async init(\n onDynamicDsCreated: (height: number) => Promise<void>,\n ): Promise<void> {\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 private setProcessedBlockCount(processedBlockCount: number) {\n this._processedBlockCount = processedBlockCount;\n this.eventEmitter.emit(IndexerEvent.BlockProcessedCount, {\n processedBlockCount,\n timestamp: Date.now(),\n });\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 flushQueue(height: number): void {\n this.latestBufferedHeight = height;\n this.queue.flush();\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.eventEmitter.emit(IndexerEvent.BlockProcessing, {\n height,\n timestamp: Date.now(),\n });\n\n const { dynamicDsCreated, operationHash } = await worker.processBlock(\n height,\n );\n // In memory _processedBlockCount increase, db metadata increase BlockCount in indexer.manager\n this.setProcessedBlockCount(this._processedBlockCount + 1);\n\n if (\n this.nodeConfig.proofOfIndex &&\n !isNullMerkelRoot(Buffer.from(operationHash, 'base64'))\n ) {\n if (!this.projectService.blockOffset) {\n // Which means during project init, it has not found offset and set value\n await this.projectService.upsertMetadataBlockOffset(height - 1);\n }\n void this.projectService.setBlockOffset(height - 1);\n }\n\n if (dynamicDsCreated) {\n await this.onDynamicDsCreated(height);\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 get queueSize(): number {\n return this.queue.size;\n }\n\n get freeSize(): number {\n return this.queue.freeSpace;\n }\n\n get latestBufferedHeight(): number {\n return this._latestBufferedHeight;\n }\n\n set latestBufferedHeight(height: number) {\n this.eventEmitter.emit(IndexerEvent.BlocknumberQueueSize, {\n value: this.queueSize,\n });\n this._latestBufferedHeight = height;\n }\n\n private getNextWorkerIndex(): number {\n const index = this.taskCounter % this.numWorkers;\n\n this.taskCounter++;\n\n return index;\n }\n}\n"]}
|