@subql/node-ethereum 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/LICENSE +201 -0
- package/README.md +76 -0
- package/bin/run +4 -0
- package/bin/run.cmd +3 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/app.module.d.ts +2 -0
- package/dist/app.module.js +35 -0
- package/dist/app.module.js.map +1 -0
- package/dist/configure/SubqueryProject.d.ts +38 -0
- package/dist/configure/SubqueryProject.js +133 -0
- package/dist/configure/SubqueryProject.js.map +1 -0
- package/dist/configure/configure.module.d.ts +7 -0
- package/dist/configure/configure.module.js +172 -0
- package/dist/configure/configure.module.js.map +1 -0
- package/dist/configure/configure.module.spec.d.ts +1 -0
- package/dist/configure/configure.module.spec.js +26 -0
- package/dist/configure/configure.module.spec.js.map +1 -0
- package/dist/ethereum/api.ethereum.d.ts +24 -0
- package/dist/ethereum/api.ethereum.js +177 -0
- package/dist/ethereum/api.ethereum.js.map +1 -0
- package/dist/ethereum/api.service.ethereum.d.ts +8 -0
- package/dist/ethereum/api.service.ethereum.js +57 -0
- package/dist/ethereum/api.service.ethereum.js.map +1 -0
- package/dist/ethereum/block.ethereum.d.ts +15 -0
- package/dist/ethereum/block.ethereum.js +87 -0
- package/dist/ethereum/block.ethereum.js.map +1 -0
- package/dist/ethereum/index.d.ts +2 -0
- package/dist/ethereum/index.js +21 -0
- package/dist/ethereum/index.js.map +1 -0
- package/dist/ethereum/utils.ethereum.d.ts +6 -0
- package/dist/ethereum/utils.ethereum.js +131 -0
- package/dist/ethereum/utils.ethereum.js.map +1 -0
- package/dist/indexer/dictionary.service.d.ts +7 -0
- package/dist/indexer/dictionary.service.js +29 -0
- package/dist/indexer/dictionary.service.js.map +1 -0
- package/dist/indexer/ds-processor.service.d.ts +26 -0
- package/dist/indexer/ds-processor.service.js +133 -0
- package/dist/indexer/ds-processor.service.js.map +1 -0
- package/dist/indexer/dynamic-ds.service.d.ts +25 -0
- package/dist/indexer/dynamic-ds.service.js +124 -0
- package/dist/indexer/dynamic-ds.service.js.map +1 -0
- package/dist/indexer/fetch.module.d.ts +2 -0
- package/dist/indexer/fetch.module.js +68 -0
- package/dist/indexer/fetch.module.js.map +1 -0
- package/dist/indexer/fetch.service.d.ts +44 -0
- package/dist/indexer/fetch.service.js +369 -0
- package/dist/indexer/fetch.service.js.map +1 -0
- package/dist/indexer/indexer.manager.d.ts +36 -0
- package/dist/indexer/indexer.manager.js +266 -0
- package/dist/indexer/indexer.manager.js.map +1 -0
- package/dist/indexer/indexer.module.d.ts +2 -0
- package/dist/indexer/indexer.module.js +52 -0
- package/dist/indexer/indexer.module.js.map +1 -0
- package/dist/indexer/project.service.d.ts +40 -0
- package/dist/indexer/project.service.js +259 -0
- package/dist/indexer/project.service.js.map +1 -0
- package/dist/indexer/sandbox.service.d.ts +12 -0
- package/dist/indexer/sandbox.service.js +58 -0
- package/dist/indexer/sandbox.service.js.map +1 -0
- package/dist/indexer/types.d.ts +10 -0
- package/dist/indexer/types.js +11 -0
- package/dist/indexer/types.js.map +1 -0
- package/dist/indexer/worker/block-dispatcher.service.d.ts +69 -0
- package/dist/indexer/worker/block-dispatcher.service.js +356 -0
- package/dist/indexer/worker/block-dispatcher.service.js.map +1 -0
- package/dist/indexer/worker/worker.d.ts +14 -0
- package/dist/indexer/worker/worker.js +85 -0
- package/dist/indexer/worker/worker.js.map +1 -0
- package/dist/indexer/worker/worker.module.d.ts +2 -0
- package/dist/indexer/worker/worker.module.js +33 -0
- package/dist/indexer/worker/worker.module.js.map +1 -0
- package/dist/indexer/worker/worker.service.d.ts +28 -0
- package/dist/indexer/worker/worker.service.js +79 -0
- package/dist/indexer/worker/worker.service.js.map +1 -0
- package/dist/init.d.ts +1 -0
- package/dist/init.js +54 -0
- package/dist/init.js.map +1 -0
- package/dist/main.d.ts +1 -0
- package/dist/main.js +14 -0
- package/dist/main.js.map +1 -0
- package/dist/meta/meta.controller.d.ts +23 -0
- package/dist/meta/meta.controller.js +36 -0
- package/dist/meta/meta.controller.js.map +1 -0
- package/dist/meta/meta.module.d.ts +2 -0
- package/dist/meta/meta.module.js +77 -0
- package/dist/meta/meta.module.js.map +1 -0
- package/dist/meta/meta.service.d.ts +42 -0
- package/dist/meta/meta.service.js +110 -0
- package/dist/meta/meta.service.js.map +1 -0
- package/dist/subcommands/forceClean.init.d.ts +1 -0
- package/dist/subcommands/forceClean.init.js +25 -0
- package/dist/subcommands/forceClean.init.js.map +1 -0
- package/dist/subcommands/forceClean.module.d.ts +4 -0
- package/dist/subcommands/forceClean.module.js +38 -0
- package/dist/subcommands/forceClean.module.js.map +1 -0
- package/dist/subcommands/forceClean.service.d.ts +8 -0
- package/dist/subcommands/forceClean.service.js +65 -0
- package/dist/subcommands/forceClean.service.js.map +1 -0
- package/dist/subcommands/reindex.init.d.ts +1 -0
- package/dist/subcommands/reindex.init.js +25 -0
- package/dist/subcommands/reindex.init.js.map +1 -0
- package/dist/subcommands/reindex.module.d.ts +4 -0
- package/dist/subcommands/reindex.module.js +39 -0
- package/dist/subcommands/reindex.module.js.map +1 -0
- package/dist/subcommands/reindex.service.d.ts +24 -0
- package/dist/subcommands/reindex.service.js +114 -0
- package/dist/subcommands/reindex.service.js.map +1 -0
- package/dist/utils/project.d.ts +13 -0
- package/dist/utils/project.js +191 -0
- package/dist/utils/project.js.map +1 -0
- package/dist/utils/string.d.ts +4 -0
- package/dist/utils/string.js +32 -0
- package/dist/utils/string.js.map +1 -0
- package/dist/yargs.d.ts +154 -0
- package/dist/yargs.js +193 -0
- package/dist/yargs.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { EthereumHandlerKind, SubqlEthereumCustomDataSource, SubqlDatasourceProcessor } from '@subql/common-ethereum';
|
|
2
|
+
import { NodeConfig, Sandbox } from '@subql/node-core';
|
|
3
|
+
import { SecondLayerHandlerProcessor_0_0_0, SecondLayerHandlerProcessor_1_0_0, SubqlCustomDatasource } from '@subql/types-ethereum';
|
|
4
|
+
import { SubqueryProject } from '../configure/SubqueryProject';
|
|
5
|
+
export interface DsPluginSandboxOption {
|
|
6
|
+
root: string;
|
|
7
|
+
entry: string;
|
|
8
|
+
script: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function isSecondLayerHandlerProcessor_0_0_0<K extends EthereumHandlerKind, F, E, DS extends SubqlCustomDatasource = SubqlEthereumCustomDataSource>(processor: SecondLayerHandlerProcessor_0_0_0<K, F, E, DS> | SecondLayerHandlerProcessor_1_0_0<K, F, E, DS>): processor is SecondLayerHandlerProcessor_0_0_0<K, F, E, DS>;
|
|
11
|
+
export declare function isSecondLayerHandlerProcessor_1_0_0<K extends EthereumHandlerKind, F, E, DS extends SubqlEthereumCustomDataSource = SubqlEthereumCustomDataSource>(processor: SecondLayerHandlerProcessor_0_0_0<K, F, E, DS> | SecondLayerHandlerProcessor_1_0_0<K, F, E, DS>): processor is SecondLayerHandlerProcessor_1_0_0<K, F, E, DS>;
|
|
12
|
+
export declare function asSecondLayerHandlerProcessor_1_0_0<K extends EthereumHandlerKind, F, E, DS extends SubqlEthereumCustomDataSource = SubqlEthereumCustomDataSource>(processor: SecondLayerHandlerProcessor_0_0_0<K, F, E, DS> | SecondLayerHandlerProcessor_1_0_0<K, F, E, DS>): SecondLayerHandlerProcessor_1_0_0<K, F, E, DS>;
|
|
13
|
+
export declare class DsPluginSandbox extends Sandbox {
|
|
14
|
+
constructor(option: DsPluginSandboxOption, nodeConfig: NodeConfig);
|
|
15
|
+
getDsPlugin<D extends string>(): SubqlDatasourceProcessor<D, unknown>;
|
|
16
|
+
}
|
|
17
|
+
export declare class DsProcessorService {
|
|
18
|
+
private project;
|
|
19
|
+
private readonly nodeConfig;
|
|
20
|
+
private processorCache;
|
|
21
|
+
constructor(project: SubqueryProject, nodeConfig: NodeConfig);
|
|
22
|
+
validateCustomDs(datasources: SubqlEthereumCustomDataSource[]): Promise<void>;
|
|
23
|
+
validateProjectCustomDatasources(): Promise<void>;
|
|
24
|
+
getDsProcessor<D extends string>(ds: SubqlEthereumCustomDataSource<string>): SubqlDatasourceProcessor<D, unknown>;
|
|
25
|
+
getAssets(ds: SubqlEthereumCustomDataSource): Promise<Record<string, string>>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2020-2022 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.DsProcessorService = exports.DsPluginSandbox = exports.asSecondLayerHandlerProcessor_1_0_0 = exports.isSecondLayerHandlerProcessor_1_0_0 = exports.isSecondLayerHandlerProcessor_0_0_0 = void 0;
|
|
18
|
+
const fs_1 = __importDefault(require("fs"));
|
|
19
|
+
const path_1 = __importDefault(require("path"));
|
|
20
|
+
const common_1 = require("@nestjs/common");
|
|
21
|
+
const common_ethereum_1 = require("@subql/common-ethereum");
|
|
22
|
+
const node_core_1 = require("@subql/node-core");
|
|
23
|
+
const vm2_1 = require("vm2");
|
|
24
|
+
const SubqueryProject_1 = require("../configure/SubqueryProject");
|
|
25
|
+
const logger = (0, node_core_1.getLogger)('ds-sandbox');
|
|
26
|
+
function isSecondLayerHandlerProcessor_0_0_0(processor) {
|
|
27
|
+
// Exisiting datasource processors had no concept of specVersion, therefore undefined is equivalent to 0.0.0
|
|
28
|
+
return processor.specVersion === undefined;
|
|
29
|
+
}
|
|
30
|
+
exports.isSecondLayerHandlerProcessor_0_0_0 = isSecondLayerHandlerProcessor_0_0_0;
|
|
31
|
+
function isSecondLayerHandlerProcessor_1_0_0(processor) {
|
|
32
|
+
return processor.specVersion === '1.0.0';
|
|
33
|
+
}
|
|
34
|
+
exports.isSecondLayerHandlerProcessor_1_0_0 = isSecondLayerHandlerProcessor_1_0_0;
|
|
35
|
+
function asSecondLayerHandlerProcessor_1_0_0(processor) {
|
|
36
|
+
if (isSecondLayerHandlerProcessor_1_0_0(processor)) {
|
|
37
|
+
return processor;
|
|
38
|
+
}
|
|
39
|
+
if (!isSecondLayerHandlerProcessor_0_0_0(processor)) {
|
|
40
|
+
throw new Error('Unsupported ds processor version');
|
|
41
|
+
}
|
|
42
|
+
return Object.assign(Object.assign({}, processor), { specVersion: '1.0.0', filterProcessor: (params) => processor.filterProcessor(params.filter, params.input, params.ds), transformer: (params) => processor
|
|
43
|
+
.transformer(params.input, params.ds, params.api, params.assets)
|
|
44
|
+
.then((res) => [res]) });
|
|
45
|
+
}
|
|
46
|
+
exports.asSecondLayerHandlerProcessor_1_0_0 = asSecondLayerHandlerProcessor_1_0_0;
|
|
47
|
+
class DsPluginSandbox extends node_core_1.Sandbox {
|
|
48
|
+
constructor(option, nodeConfig) {
|
|
49
|
+
super(option, new vm2_1.VMScript(`module.exports = require('${option.entry}').default;`, path_1.default.join(option.root, 'ds_sandbox')), nodeConfig);
|
|
50
|
+
this.freeze(logger, 'logger');
|
|
51
|
+
}
|
|
52
|
+
getDsPlugin() {
|
|
53
|
+
return this.run(this.script);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.DsPluginSandbox = DsPluginSandbox;
|
|
57
|
+
let DsProcessorService = class DsProcessorService {
|
|
58
|
+
constructor(project, nodeConfig) {
|
|
59
|
+
this.project = project;
|
|
60
|
+
this.nodeConfig = nodeConfig;
|
|
61
|
+
this.processorCache = {};
|
|
62
|
+
}
|
|
63
|
+
async validateCustomDs(datasources) {
|
|
64
|
+
for (const ds of datasources) {
|
|
65
|
+
const processor = this.getDsProcessor(ds);
|
|
66
|
+
/* Standard validation applicable to all custom ds and processors */
|
|
67
|
+
if (ds.kind !== processor.kind) {
|
|
68
|
+
throw new Error(`ds kind (${ds.kind}) doesnt match processor (${processor.kind})`);
|
|
69
|
+
}
|
|
70
|
+
for (const handler of ds.mapping.handlers) {
|
|
71
|
+
if (!(handler.kind in processor.handlerProcessors)) {
|
|
72
|
+
throw new Error(`ds kind ${handler.kind} not one of ${Object.keys(processor.handlerProcessors).join(', ')}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
ds.mapping.handlers.map((handler) => processor.handlerProcessors[handler.kind].filterValidator(handler.filter));
|
|
76
|
+
/* Additional processor specific validation */
|
|
77
|
+
processor.validate(ds, await this.getAssets(ds));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async validateProjectCustomDatasources() {
|
|
81
|
+
await this.validateCustomDs(this.project.dataSources.filter(common_ethereum_1.isCustomDs));
|
|
82
|
+
}
|
|
83
|
+
getDsProcessor(ds) {
|
|
84
|
+
if (!(0, common_ethereum_1.isCustomDs)(ds)) {
|
|
85
|
+
throw new Error(`data source is not a custom data source`);
|
|
86
|
+
}
|
|
87
|
+
if (!this.processorCache[ds.processor.file]) {
|
|
88
|
+
const sandbox = new DsPluginSandbox({
|
|
89
|
+
root: this.project.root,
|
|
90
|
+
entry: ds.processor.file,
|
|
91
|
+
script: null /* TODO get working with Readers, same as with sandbox */,
|
|
92
|
+
}, this.nodeConfig);
|
|
93
|
+
try {
|
|
94
|
+
this.processorCache[ds.processor.file] = sandbox.getDsPlugin();
|
|
95
|
+
}
|
|
96
|
+
catch (e) {
|
|
97
|
+
logger.error(`not supported ds @${ds.kind}`);
|
|
98
|
+
throw e;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return this.processorCache[ds.processor.file];
|
|
102
|
+
}
|
|
103
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
104
|
+
async getAssets(ds) {
|
|
105
|
+
if (!(0, common_ethereum_1.isCustomDs)(ds)) {
|
|
106
|
+
throw new Error(`data source is not a custom data source`);
|
|
107
|
+
}
|
|
108
|
+
if (!ds.assets) {
|
|
109
|
+
return {};
|
|
110
|
+
}
|
|
111
|
+
const res = {};
|
|
112
|
+
for (const [name, { file }] of ds.assets) {
|
|
113
|
+
// TODO update with https://github.com/subquery/subql/pull/511
|
|
114
|
+
try {
|
|
115
|
+
res[name] = fs_1.default.readFileSync(file, {
|
|
116
|
+
encoding: 'utf8',
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
catch (e) {
|
|
120
|
+
logger.error(`Failed to load datasource asset ${file}`);
|
|
121
|
+
throw e;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return res;
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
DsProcessorService = __decorate([
|
|
128
|
+
(0, common_1.Injectable)(),
|
|
129
|
+
__metadata("design:paramtypes", [SubqueryProject_1.SubqueryProject,
|
|
130
|
+
node_core_1.NodeConfig])
|
|
131
|
+
], DsProcessorService);
|
|
132
|
+
exports.DsProcessorService = DsProcessorService;
|
|
133
|
+
//# sourceMappingURL=ds-processor.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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 { 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"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { MetadataRepo } from '@subql/node-core';
|
|
2
|
+
import { Transaction } from 'sequelize/types';
|
|
3
|
+
import { SubqlProjectDs, SubqueryProject } from '../configure/SubqueryProject';
|
|
4
|
+
import { DsProcessorService } from './ds-processor.service';
|
|
5
|
+
interface DatasourceParams {
|
|
6
|
+
templateName: string;
|
|
7
|
+
args?: Record<string, unknown>;
|
|
8
|
+
startBlock: number;
|
|
9
|
+
}
|
|
10
|
+
export declare class DynamicDsService {
|
|
11
|
+
private readonly dsProcessorService;
|
|
12
|
+
private readonly project;
|
|
13
|
+
private metaDataRepo;
|
|
14
|
+
private tempDsRecords;
|
|
15
|
+
constructor(dsProcessorService: DsProcessorService, project: SubqueryProject);
|
|
16
|
+
init(metaDataRepo: MetadataRepo): void;
|
|
17
|
+
private _datasources;
|
|
18
|
+
createDynamicDatasource(params: DatasourceParams, tx: Transaction): Promise<SubqlProjectDs>;
|
|
19
|
+
getDynamicDatasources(): Promise<SubqlProjectDs[]>;
|
|
20
|
+
deleteTempDsRecords(blockHeight: number): void;
|
|
21
|
+
private getDynamicDatasourceParams;
|
|
22
|
+
private saveDynamicDatasourceParams;
|
|
23
|
+
private getDatasource;
|
|
24
|
+
}
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2020-2022 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.DynamicDsService = void 0;
|
|
18
|
+
const assert_1 = __importDefault(require("assert"));
|
|
19
|
+
const common_1 = require("@nestjs/common");
|
|
20
|
+
const common_ethereum_1 = require("@subql/common-ethereum");
|
|
21
|
+
const node_core_1 = require("@subql/node-core");
|
|
22
|
+
const lodash_1 = require("lodash");
|
|
23
|
+
const SubqueryProject_1 = require("../configure/SubqueryProject");
|
|
24
|
+
const ds_processor_service_1 = require("./ds-processor.service");
|
|
25
|
+
const logger = (0, node_core_1.getLogger)('dynamic-ds');
|
|
26
|
+
const METADATA_KEY = 'dynamicDatasources';
|
|
27
|
+
const TEMP_DS_PREFIX = 'ds_';
|
|
28
|
+
let DynamicDsService = class DynamicDsService {
|
|
29
|
+
constructor(dsProcessorService, project) {
|
|
30
|
+
this.dsProcessorService = dsProcessorService;
|
|
31
|
+
this.project = project;
|
|
32
|
+
}
|
|
33
|
+
init(metaDataRepo) {
|
|
34
|
+
this.metaDataRepo = metaDataRepo;
|
|
35
|
+
}
|
|
36
|
+
async createDynamicDatasource(params, tx) {
|
|
37
|
+
try {
|
|
38
|
+
const ds = await this.getDatasource(params);
|
|
39
|
+
await this.saveDynamicDatasourceParams(params, tx);
|
|
40
|
+
logger.info(`Created new dynamic datasource from template: "${params.templateName}"`);
|
|
41
|
+
if (!this._datasources)
|
|
42
|
+
this._datasources = [];
|
|
43
|
+
this._datasources.push(ds);
|
|
44
|
+
return ds;
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
logger.error(e.message);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async getDynamicDatasources() {
|
|
52
|
+
if (!this._datasources) {
|
|
53
|
+
try {
|
|
54
|
+
const params = await this.getDynamicDatasourceParams();
|
|
55
|
+
this._datasources = await Promise.all(params.map((params) => this.getDatasource(params)));
|
|
56
|
+
}
|
|
57
|
+
catch (e) {
|
|
58
|
+
logger.error(`Unable to get dynamic datasources:\n${e.message}`);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return this._datasources;
|
|
63
|
+
}
|
|
64
|
+
deleteTempDsRecords(blockHeight) {
|
|
65
|
+
delete this.tempDsRecords[TEMP_DS_PREFIX + blockHeight];
|
|
66
|
+
}
|
|
67
|
+
async getDynamicDatasourceParams(blockHeight) {
|
|
68
|
+
var _a;
|
|
69
|
+
(0, assert_1.default)(this.metaDataRepo, `Model _metadata does not exist`);
|
|
70
|
+
const record = await this.metaDataRepo.findByPk(METADATA_KEY);
|
|
71
|
+
let results = record === null || record === void 0 ? void 0 : record.value;
|
|
72
|
+
if (!results || typeof results !== 'string') {
|
|
73
|
+
if (blockHeight !== undefined) {
|
|
74
|
+
results = (_a = this.tempDsRecords) === null || _a === void 0 ? void 0 : _a[TEMP_DS_PREFIX + blockHeight];
|
|
75
|
+
if (!results || typeof results !== 'string') {
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return JSON.parse(results);
|
|
84
|
+
}
|
|
85
|
+
async saveDynamicDatasourceParams(dsParams, tx) {
|
|
86
|
+
const existing = await this.getDynamicDatasourceParams(dsParams.startBlock);
|
|
87
|
+
(0, assert_1.default)(this.metaDataRepo, `Model _metadata does not exist`);
|
|
88
|
+
const dsRecords = JSON.stringify([...existing, dsParams]);
|
|
89
|
+
await this.metaDataRepo
|
|
90
|
+
.upsert({ key: METADATA_KEY, value: dsRecords }, { transaction: tx })
|
|
91
|
+
.then(() => {
|
|
92
|
+
this.tempDsRecords = Object.assign(Object.assign({}, this.tempDsRecords), { [TEMP_DS_PREFIX + dsParams.startBlock]: dsRecords });
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
async getDatasource(params) {
|
|
96
|
+
const template = (0, lodash_1.cloneDeep)(this.project.templates.find((t) => t.name === params.templateName));
|
|
97
|
+
if (!template) {
|
|
98
|
+
throw new Error(`Unable to find matching template in project for name: "${params.templateName}"`);
|
|
99
|
+
}
|
|
100
|
+
logger.info(`Initialised dynamic datasource from template: "${params.templateName}"`);
|
|
101
|
+
const dsObj = Object.assign(Object.assign({}, template), { startBlock: params.startBlock });
|
|
102
|
+
delete dsObj.name;
|
|
103
|
+
try {
|
|
104
|
+
if ((0, common_ethereum_1.isCustomDs)(dsObj)) {
|
|
105
|
+
dsObj.processor.options = Object.assign(Object.assign({}, dsObj.processor.options), params.args);
|
|
106
|
+
await this.dsProcessorService.validateCustomDs([dsObj]);
|
|
107
|
+
}
|
|
108
|
+
else if ((0, common_ethereum_1.isRuntimeDs)(dsObj)) {
|
|
109
|
+
// XXX add any modifications to the ds here
|
|
110
|
+
}
|
|
111
|
+
return dsObj;
|
|
112
|
+
}
|
|
113
|
+
catch (e) {
|
|
114
|
+
throw new Error(`Unable to create dynamic datasource.\n ${e.message}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
DynamicDsService = __decorate([
|
|
119
|
+
(0, common_1.Injectable)(),
|
|
120
|
+
__metadata("design:paramtypes", [ds_processor_service_1.DsProcessorService,
|
|
121
|
+
SubqueryProject_1.SubqueryProject])
|
|
122
|
+
], DynamicDsService);
|
|
123
|
+
exports.DynamicDsService = DynamicDsService;
|
|
124
|
+
//# sourceMappingURL=dynamic-ds.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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 { Injectable } from '@nestjs/common';\nimport { isCustomDs, isRuntimeDs } from '@subql/common-ethereum';\nimport { getLogger, MetadataRepo } from '@subql/node-core';\nimport { cloneDeep } 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 private readonly project: SubqueryProject,\n ) {}\n\n init(metaDataRepo: MetadataRepo): void {\n this.metaDataRepo = metaDataRepo;\n }\n\n private _datasources: SubqlProjectDs[];\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 let results = record?.value;\n\n if (!results || typeof results !== 'string') {\n if (blockHeight !== undefined) {\n results = this.tempDsRecords?.[TEMP_DS_PREFIX + blockHeight];\n if (!results || typeof results !== 'string') {\n return [];\n }\n } else {\n return [];\n }\n }\n\n return JSON.parse(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"]}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2020-2022 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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.FetchModule = void 0;
|
|
12
|
+
const common_1 = require("@nestjs/common");
|
|
13
|
+
const event_emitter_1 = require("@nestjs/event-emitter");
|
|
14
|
+
const node_core_1 = require("@subql/node-core");
|
|
15
|
+
const SubqueryProject_1 = require("../configure/SubqueryProject");
|
|
16
|
+
const api_service_ethereum_1 = require("../ethereum/api.service.ethereum");
|
|
17
|
+
const dictionary_service_1 = require("./dictionary.service");
|
|
18
|
+
const ds_processor_service_1 = require("./ds-processor.service");
|
|
19
|
+
const dynamic_ds_service_1 = require("./dynamic-ds.service");
|
|
20
|
+
const fetch_service_1 = require("./fetch.service");
|
|
21
|
+
const indexer_manager_1 = require("./indexer.manager");
|
|
22
|
+
const project_service_1 = require("./project.service");
|
|
23
|
+
const sandbox_service_1 = require("./sandbox.service");
|
|
24
|
+
const block_dispatcher_service_1 = require("./worker/block-dispatcher.service");
|
|
25
|
+
let FetchModule = class FetchModule {
|
|
26
|
+
};
|
|
27
|
+
FetchModule = __decorate([
|
|
28
|
+
(0, common_1.Module)({
|
|
29
|
+
providers: [
|
|
30
|
+
node_core_1.StoreService,
|
|
31
|
+
{
|
|
32
|
+
provide: node_core_1.ApiService,
|
|
33
|
+
useFactory: async (project) => {
|
|
34
|
+
const apiService = new api_service_ethereum_1.EthereumApiService(project);
|
|
35
|
+
await apiService.init();
|
|
36
|
+
return apiService;
|
|
37
|
+
},
|
|
38
|
+
inject: [SubqueryProject_1.SubqueryProject],
|
|
39
|
+
},
|
|
40
|
+
indexer_manager_1.IndexerManager,
|
|
41
|
+
{
|
|
42
|
+
provide: 'IBlockDispatcher',
|
|
43
|
+
useFactory: (nodeConfig, eventEmitter, projectService, apiService, indexerManager) => nodeConfig.workers !== undefined
|
|
44
|
+
? new block_dispatcher_service_1.WorkerBlockDispatcherService(nodeConfig, eventEmitter, projectService)
|
|
45
|
+
: new block_dispatcher_service_1.BlockDispatcherService(apiService, nodeConfig, indexerManager, eventEmitter, projectService),
|
|
46
|
+
inject: [
|
|
47
|
+
node_core_1.NodeConfig,
|
|
48
|
+
event_emitter_1.EventEmitter2,
|
|
49
|
+
project_service_1.ProjectService,
|
|
50
|
+
node_core_1.ApiService,
|
|
51
|
+
indexer_manager_1.IndexerManager,
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
fetch_service_1.FetchService,
|
|
55
|
+
node_core_1.BenchmarkService,
|
|
56
|
+
dictionary_service_1.DictionaryService,
|
|
57
|
+
sandbox_service_1.SandboxService,
|
|
58
|
+
ds_processor_service_1.DsProcessorService,
|
|
59
|
+
dynamic_ds_service_1.DynamicDsService,
|
|
60
|
+
node_core_1.PoiService,
|
|
61
|
+
node_core_1.MmrService,
|
|
62
|
+
project_service_1.ProjectService,
|
|
63
|
+
],
|
|
64
|
+
exports: [node_core_1.StoreService, node_core_1.MmrService],
|
|
65
|
+
})
|
|
66
|
+
], FetchModule);
|
|
67
|
+
exports.FetchModule = FetchModule;
|
|
68
|
+
//# sourceMappingURL=fetch.module.js.map
|
|
@@ -0,0 +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;AAC1B,kEAA+D;AAC/D,2EAAsE;AACtE,6DAAyD;AACzD,iEAA4D;AAC5D,6DAAwD;AACxD,mDAA+C;AAC/C,uDAAmD;AACnD,uDAAmD;AACnD,uDAAmD;AACnD,gFAG2C;AA0DpC,IAAM,WAAW,GAAjB,MAAM,WAAW;CAAG,CAAA;AAAd,WAAW;IAxDvB,IAAA,eAAM,EAAC;QACN,SAAS,EAAE;YACT,wBAAY;YACZ;gBACE,OAAO,EAAE,sBAAU;gBACnB,UAAU,EAAE,KAAK,EAAE,OAAwB,EAAE,EAAE;oBAC7C,MAAM,UAAU,GAAG,IAAI,yCAAkB,CAAC,OAAO,CAAC,CAAC;oBAEnD,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;oBACxB,OAAO,UAAU,CAAC;gBACpB,CAAC;gBACD,MAAM,EAAE,CAAC,iCAAe,CAAC;aAC1B;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,uDAA4B,CAC9B,UAAU,EACV,YAAY,EACZ,cAAc,CACf;oBACH,CAAC,CAAC,IAAI,iDAAsB,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,sCAAiB;YACjB,gCAAc;YACd,yCAAkB;YAClB,qCAAgB;YAChB,sBAAU;YACV,sBAAU;YACV,gCAAc;SACf;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 { 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 {\n BlockDispatcherService,\n WorkerBlockDispatcherService,\n} from './worker/block-dispatcher.service';\n\n@Module({\n providers: [\n StoreService,\n {\n provide: ApiService,\n useFactory: async (project: SubqueryProject) => {\n const apiService = new EthereumApiService(project);\n\n await apiService.init();\n return apiService;\n },\n inject: [SubqueryProject],\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 DictionaryService,\n SandboxService,\n DsProcessorService,\n DynamicDsService,\n PoiService,\n MmrService,\n ProjectService,\n ],\n exports: [StoreService, MmrService],\n})\nexport class FetchModule {}\n"]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { OnApplicationShutdown } from '@nestjs/common';
|
|
2
|
+
import { EventEmitter2 } from '@nestjs/event-emitter';
|
|
3
|
+
import { SchedulerRegistry } from '@nestjs/schedule';
|
|
4
|
+
import { ApiService, NodeConfig } from '@subql/node-core';
|
|
5
|
+
import { DictionaryQueryEntry, ApiWrapper } from '@subql/types-ethereum';
|
|
6
|
+
import { SubqueryProject } from '../configure/SubqueryProject';
|
|
7
|
+
import { DictionaryService } from './dictionary.service';
|
|
8
|
+
import { DynamicDsService } from './dynamic-ds.service';
|
|
9
|
+
import { IBlockDispatcher } from './worker/block-dispatcher.service';
|
|
10
|
+
export declare class FetchService implements OnApplicationShutdown {
|
|
11
|
+
private apiService;
|
|
12
|
+
private nodeConfig;
|
|
13
|
+
private project;
|
|
14
|
+
private blockDispatcher;
|
|
15
|
+
private dictionaryService;
|
|
16
|
+
private dynamicDsService;
|
|
17
|
+
private eventEmitter;
|
|
18
|
+
private schedulerRegistry;
|
|
19
|
+
private latestBestHeight;
|
|
20
|
+
private latestFinalizedHeight;
|
|
21
|
+
private isShutdown;
|
|
22
|
+
private useDictionary;
|
|
23
|
+
private dictionaryQueryEntries?;
|
|
24
|
+
private batchSizeScale;
|
|
25
|
+
private templateDynamicDatasouces;
|
|
26
|
+
constructor(apiService: ApiService, nodeConfig: NodeConfig, project: SubqueryProject, blockDispatcher: IBlockDispatcher, dictionaryService: DictionaryService, dynamicDsService: DynamicDsService, eventEmitter: EventEmitter2, schedulerRegistry: SchedulerRegistry);
|
|
27
|
+
onApplicationShutdown(): void;
|
|
28
|
+
get api(): ApiWrapper;
|
|
29
|
+
syncDynamicDatascourcesFromMeta(): Promise<void>;
|
|
30
|
+
getDictionaryQueryEntries(): DictionaryQueryEntry[];
|
|
31
|
+
updateDictionary(): void;
|
|
32
|
+
init(startHeight: number): Promise<void>;
|
|
33
|
+
checkBatchScale(): void;
|
|
34
|
+
getFinalizedBlockHead(): Promise<void>;
|
|
35
|
+
getBestBlockHead(): Promise<void>;
|
|
36
|
+
startLoop(initBlockHeight: number): Promise<void>;
|
|
37
|
+
getModulos(): number[];
|
|
38
|
+
getModuloBlocks(startHeight: number, endHeight: number): number[];
|
|
39
|
+
getEnqueuedModuloBlocks(startBlockHeight: number): number[];
|
|
40
|
+
fillNextBlockBuffer(initBlockHeight: number): Promise<void>;
|
|
41
|
+
private nextEndBlockHeight;
|
|
42
|
+
private dictionaryValidation;
|
|
43
|
+
resetForNewDs(blockHeight: number): Promise<void>;
|
|
44
|
+
}
|