@subql/node-ethereum 1.10.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.
Files changed (118) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +201 -0
  3. package/README.md +76 -0
  4. package/bin/run +4 -0
  5. package/bin/run.cmd +3 -0
  6. package/dist/.tsbuildinfo +1 -0
  7. package/dist/app.module.d.ts +2 -0
  8. package/dist/app.module.js +35 -0
  9. package/dist/app.module.js.map +1 -0
  10. package/dist/configure/SubqueryProject.d.ts +29 -0
  11. package/dist/configure/SubqueryProject.js +82 -0
  12. package/dist/configure/SubqueryProject.js.map +1 -0
  13. package/dist/configure/configure.module.d.ts +7 -0
  14. package/dist/configure/configure.module.js +172 -0
  15. package/dist/configure/configure.module.js.map +1 -0
  16. package/dist/configure/configure.module.spec.d.ts +1 -0
  17. package/dist/configure/configure.module.spec.js +26 -0
  18. package/dist/configure/configure.module.spec.js.map +1 -0
  19. package/dist/ethereum/api.ethereum.d.ts +21 -0
  20. package/dist/ethereum/api.ethereum.js +190 -0
  21. package/dist/ethereum/api.ethereum.js.map +1 -0
  22. package/dist/ethereum/api.service.ethereum.d.ts +8 -0
  23. package/dist/ethereum/api.service.ethereum.js +57 -0
  24. package/dist/ethereum/api.service.ethereum.js.map +1 -0
  25. package/dist/ethereum/block.ethereum.d.ts +15 -0
  26. package/dist/ethereum/block.ethereum.js +87 -0
  27. package/dist/ethereum/block.ethereum.js.map +1 -0
  28. package/dist/ethereum/index.d.ts +2 -0
  29. package/dist/ethereum/index.js +21 -0
  30. package/dist/ethereum/index.js.map +1 -0
  31. package/dist/ethereum/utils.ethereum.d.ts +6 -0
  32. package/dist/ethereum/utils.ethereum.js +131 -0
  33. package/dist/ethereum/utils.ethereum.js.map +1 -0
  34. package/dist/indexer/dictionary.service.d.ts +7 -0
  35. package/dist/indexer/dictionary.service.js +29 -0
  36. package/dist/indexer/dictionary.service.js.map +1 -0
  37. package/dist/indexer/ds-processor.service.d.ts +26 -0
  38. package/dist/indexer/ds-processor.service.js +133 -0
  39. package/dist/indexer/ds-processor.service.js.map +1 -0
  40. package/dist/indexer/dynamic-ds.service.d.ts +23 -0
  41. package/dist/indexer/dynamic-ds.service.js +105 -0
  42. package/dist/indexer/dynamic-ds.service.js.map +1 -0
  43. package/dist/indexer/fetch.module.d.ts +2 -0
  44. package/dist/indexer/fetch.module.js +68 -0
  45. package/dist/indexer/fetch.module.js.map +1 -0
  46. package/dist/indexer/fetch.service.d.ts +43 -0
  47. package/dist/indexer/fetch.service.js +359 -0
  48. package/dist/indexer/fetch.service.js.map +1 -0
  49. package/dist/indexer/indexer.manager.d.ts +36 -0
  50. package/dist/indexer/indexer.manager.js +256 -0
  51. package/dist/indexer/indexer.manager.js.map +1 -0
  52. package/dist/indexer/indexer.module.d.ts +2 -0
  53. package/dist/indexer/indexer.module.js +52 -0
  54. package/dist/indexer/indexer.module.js.map +1 -0
  55. package/dist/indexer/project.service.d.ts +39 -0
  56. package/dist/indexer/project.service.js +255 -0
  57. package/dist/indexer/project.service.js.map +1 -0
  58. package/dist/indexer/sandbox.service.d.ts +12 -0
  59. package/dist/indexer/sandbox.service.js +58 -0
  60. package/dist/indexer/sandbox.service.js.map +1 -0
  61. package/dist/indexer/types.d.ts +10 -0
  62. package/dist/indexer/types.js +11 -0
  63. package/dist/indexer/types.js.map +1 -0
  64. package/dist/indexer/worker/block-dispatcher.service.d.ts +69 -0
  65. package/dist/indexer/worker/block-dispatcher.service.js +356 -0
  66. package/dist/indexer/worker/block-dispatcher.service.js.map +1 -0
  67. package/dist/indexer/worker/worker.d.ts +14 -0
  68. package/dist/indexer/worker/worker.js +85 -0
  69. package/dist/indexer/worker/worker.js.map +1 -0
  70. package/dist/indexer/worker/worker.module.d.ts +2 -0
  71. package/dist/indexer/worker/worker.module.js +33 -0
  72. package/dist/indexer/worker/worker.module.js.map +1 -0
  73. package/dist/indexer/worker/worker.service.d.ts +28 -0
  74. package/dist/indexer/worker/worker.service.js +79 -0
  75. package/dist/indexer/worker/worker.service.js.map +1 -0
  76. package/dist/init.d.ts +1 -0
  77. package/dist/init.js +54 -0
  78. package/dist/init.js.map +1 -0
  79. package/dist/main.d.ts +1 -0
  80. package/dist/main.js +14 -0
  81. package/dist/main.js.map +1 -0
  82. package/dist/meta/meta.controller.d.ts +23 -0
  83. package/dist/meta/meta.controller.js +36 -0
  84. package/dist/meta/meta.controller.js.map +1 -0
  85. package/dist/meta/meta.module.d.ts +2 -0
  86. package/dist/meta/meta.module.js +77 -0
  87. package/dist/meta/meta.module.js.map +1 -0
  88. package/dist/meta/meta.service.d.ts +42 -0
  89. package/dist/meta/meta.service.js +110 -0
  90. package/dist/meta/meta.service.js.map +1 -0
  91. package/dist/subcommands/forceClean.init.d.ts +1 -0
  92. package/dist/subcommands/forceClean.init.js +25 -0
  93. package/dist/subcommands/forceClean.init.js.map +1 -0
  94. package/dist/subcommands/forceClean.module.d.ts +4 -0
  95. package/dist/subcommands/forceClean.module.js +38 -0
  96. package/dist/subcommands/forceClean.module.js.map +1 -0
  97. package/dist/subcommands/forceClean.service.d.ts +8 -0
  98. package/dist/subcommands/forceClean.service.js +65 -0
  99. package/dist/subcommands/forceClean.service.js.map +1 -0
  100. package/dist/subcommands/reindex.init.d.ts +1 -0
  101. package/dist/subcommands/reindex.init.js +25 -0
  102. package/dist/subcommands/reindex.init.js.map +1 -0
  103. package/dist/subcommands/reindex.module.d.ts +4 -0
  104. package/dist/subcommands/reindex.module.js +39 -0
  105. package/dist/subcommands/reindex.module.js.map +1 -0
  106. package/dist/subcommands/reindex.service.d.ts +24 -0
  107. package/dist/subcommands/reindex.service.js +114 -0
  108. package/dist/subcommands/reindex.service.js.map +1 -0
  109. package/dist/utils/project.d.ts +13 -0
  110. package/dist/utils/project.js +191 -0
  111. package/dist/utils/project.js.map +1 -0
  112. package/dist/utils/string.d.ts +4 -0
  113. package/dist/utils/string.js +32 -0
  114. package/dist/utils/string.js.map +1 -0
  115. package/dist/yargs.d.ts +154 -0
  116. package/dist/yargs.js +193 -0
  117. package/dist/yargs.js.map +1 -0
  118. package/package.json +77 -0
@@ -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,23 @@
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
+ constructor(dsProcessorService: DsProcessorService, project: SubqueryProject);
15
+ init(metaDataRepo: MetadataRepo): void;
16
+ private _datasources;
17
+ createDynamicDatasource(params: DatasourceParams, tx: Transaction): Promise<SubqlProjectDs>;
18
+ getDynamicDatasources(): Promise<SubqlProjectDs[]>;
19
+ private getDynamicDatasourceParams;
20
+ private saveDynamicDatasourceParams;
21
+ private getDatasource;
22
+ }
23
+ export {};
@@ -0,0 +1,105 @@
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 SubqueryProject_1 = require("../configure/SubqueryProject");
23
+ const ds_processor_service_1 = require("./ds-processor.service");
24
+ const logger = (0, node_core_1.getLogger)('dynamic-ds');
25
+ const METADATA_KEY = 'dynamicDatasources';
26
+ let DynamicDsService = class DynamicDsService {
27
+ constructor(dsProcessorService, project) {
28
+ this.dsProcessorService = dsProcessorService;
29
+ this.project = project;
30
+ }
31
+ init(metaDataRepo) {
32
+ this.metaDataRepo = metaDataRepo;
33
+ }
34
+ async createDynamicDatasource(params, tx) {
35
+ try {
36
+ const ds = await this.getDatasource(params);
37
+ await this.saveDynamicDatasourceParams(params, tx);
38
+ logger.info(`Created new dynamic datasource from template: "${params.templateName}"`);
39
+ if (!this._datasources)
40
+ this._datasources = [];
41
+ this._datasources.push(ds);
42
+ return ds;
43
+ }
44
+ catch (e) {
45
+ logger.error(e.message);
46
+ process.exit(1);
47
+ }
48
+ }
49
+ async getDynamicDatasources() {
50
+ if (!this._datasources) {
51
+ try {
52
+ const params = await this.getDynamicDatasourceParams();
53
+ this._datasources = await Promise.all(params.map((params) => this.getDatasource(params)));
54
+ }
55
+ catch (e) {
56
+ logger.error(`Unable to get dynamic datasources:\n${e.message}`);
57
+ process.exit(1);
58
+ }
59
+ }
60
+ return this._datasources;
61
+ }
62
+ async getDynamicDatasourceParams() {
63
+ (0, assert_1.default)(this.metaDataRepo, `Model _metadata does not exist`);
64
+ const record = await this.metaDataRepo.findByPk(METADATA_KEY);
65
+ const results = record === null || record === void 0 ? void 0 : record.value;
66
+ if (!results || typeof results !== 'string') {
67
+ return [];
68
+ }
69
+ return JSON.parse(results);
70
+ }
71
+ async saveDynamicDatasourceParams(dsParams, tx) {
72
+ const existing = await this.getDynamicDatasourceParams();
73
+ (0, assert_1.default)(this.metaDataRepo, `Model _metadata does not exist`);
74
+ await this.metaDataRepo.upsert({ key: METADATA_KEY, value: JSON.stringify([...existing, dsParams]) }, { transaction: tx });
75
+ }
76
+ async getDatasource(params) {
77
+ const template = this.project.templates.find((t) => t.name === params.templateName);
78
+ if (!template) {
79
+ throw new Error(`Unable to find matching template in project for name: "${params.templateName}"`);
80
+ }
81
+ logger.info(`Initialised dynamic datasource from template: "${params.templateName}"`);
82
+ const dsObj = Object.assign(Object.assign({}, template), { startBlock: params.startBlock });
83
+ delete dsObj.name;
84
+ try {
85
+ if ((0, common_ethereum_1.isCustomDs)(dsObj)) {
86
+ dsObj.processor.options = Object.assign(Object.assign({}, dsObj.processor.options), params.args);
87
+ await this.dsProcessorService.validateCustomDs([dsObj]);
88
+ }
89
+ else if ((0, common_ethereum_1.isRuntimeDs)(dsObj)) {
90
+ // XXX add any modifications to the ds here
91
+ }
92
+ return dsObj;
93
+ }
94
+ catch (e) {
95
+ throw new Error(`Unable to create dynamic datasource.\n ${e.message}`);
96
+ }
97
+ }
98
+ };
99
+ DynamicDsService = __decorate([
100
+ (0, common_1.Injectable)(),
101
+ __metadata("design:paramtypes", [ds_processor_service_1.DsProcessorService,
102
+ SubqueryProject_1.SubqueryProject])
103
+ ], DynamicDsService);
104
+ exports.DynamicDsService = DynamicDsService;
105
+ //# 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":";AAAA,gEAAgE;AAChE,sCAAsC;;;;;;;;;;;;;;;AAEtC,oDAA4B;AAC5B,2CAA4C;AAC5C,4DAAiE;AACjE,gDAA2D;AAE3D,kEAA+E;AAC/E,iEAA4D;AAE5D,MAAM,MAAM,GAAG,IAAA,qBAAS,EAAC,YAAY,CAAC,CAAC;AAEvC,MAAM,YAAY,GAAG,oBAAoB,CAAC;AASnC,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;IAG3B,YACmB,kBAAsC,EACtC,OAAwB;QADxB,uBAAkB,GAAlB,kBAAkB,CAAoB;QACtC,YAAO,GAAP,OAAO,CAAiB;IACxC,CAAC;IAEJ,IAAI,CAAC,YAA0B;QAC7B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;IAID,KAAK,CAAC,uBAAuB,CAC3B,MAAwB,EACxB,EAAe;QAEf,IAAI;YACF,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAE5C,MAAM,IAAI,CAAC,2BAA2B,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAEnD,MAAM,CAAC,IAAI,CACT,kDAAkD,MAAM,CAAC,YAAY,GAAG,CACzE,CAAC;YAEF,IAAI,CAAC,IAAI,CAAC,YAAY;gBAAE,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;YAC/C,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAE3B,OAAO,EAAE,CAAC;SACX;QAAC,OAAO,CAAC,EAAE;YACV,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;SACjB;IACH,CAAC;IAED,KAAK,CAAC,qBAAqB;QACzB,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;YACtB,IAAI;gBACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,0BAA0B,EAAE,CAAC;gBAEvD,IAAI,CAAC,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CACnC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CACnD,CAAC;aACH;YAAC,OAAO,CAAC,EAAE;gBACV,MAAM,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;gBACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aACjB;SACF;QAED,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAEO,KAAK,CAAC,0BAA0B;QACtC,IAAA,gBAAM,EAAC,IAAI,CAAC,YAAY,EAAE,gCAAgC,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAC9D,MAAM,OAAO,GAAG,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,CAAC;QAE9B,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE;YAC3C,OAAO,EAAE,CAAC;SACX;QAED,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAEO,KAAK,CAAC,2BAA2B,CACvC,QAA0B,EAC1B,EAAe;QAEf,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,0BAA0B,EAAE,CAAC;QAEzD,IAAA,gBAAM,EAAC,IAAI,CAAC,YAAY,EAAE,gCAAgC,CAAC,CAAC;QAC5D,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,CAC5B,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAE,EACrE,EAAE,WAAW,EAAE,EAAE,EAAE,CACpB,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,aAAa,CACzB,MAAwB;QAExB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAC1C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,YAAY,CACtC,CAAC;QAEF,IAAI,CAAC,QAAQ,EAAE;YACb,MAAM,IAAI,KAAK,CACb,0DAA0D,MAAM,CAAC,YAAY,GAAG,CACjF,CAAC;SACH;QAED,MAAM,CAAC,IAAI,CACT,kDAAkD,MAAM,CAAC,YAAY,GAAG,CACzE,CAAC;QAEF,MAAM,KAAK,GAAG,gCACT,QAAQ,KACX,UAAU,EAAE,MAAM,CAAC,UAAU,GACZ,CAAC;QACpB,OAAO,KAAK,CAAC,IAAI,CAAC;QAClB,IAAI;YACF,IAAI,IAAA,4BAAU,EAAC,KAAK,CAAC,EAAE;gBACrB,KAAK,CAAC,SAAS,CAAC,OAAO,mCAClB,KAAK,CAAC,SAAS,CAAC,OAAO,GACvB,MAAM,CAAC,IAAI,CACf,CAAC;gBACF,MAAM,IAAI,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;aACzD;iBAAM,IAAI,IAAA,6BAAW,EAAC,KAAK,CAAC,EAAE;gBAC7B,2CAA2C;aAC5C;YAED,OAAO,KAAK,CAAC;SACd;QAAC,OAAO,CAAC,EAAE;YACV,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;SACxE;IACH,CAAC;CACF,CAAA;AArHY,gBAAgB;IAD5B,IAAA,mBAAU,GAAE;qCAK4B,yCAAkB;QAC7B,iCAAe;GALhC,gBAAgB,CAqH5B;AArHY,4CAAgB","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 { 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';\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\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 private async getDynamicDatasourceParams(): Promise<DatasourceParams[]> {\n assert(this.metaDataRepo, `Model _metadata does not exist`);\n const record = await this.metaDataRepo.findByPk(METADATA_KEY);\n const results = record?.value;\n\n if (!results || typeof results !== 'string') {\n return [];\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();\n\n assert(this.metaDataRepo, `Model _metadata does not exist`);\n await this.metaDataRepo.upsert(\n { key: METADATA_KEY, value: JSON.stringify([...existing, dsParams]) },\n { transaction: tx },\n );\n }\n\n private async getDatasource(\n params: DatasourceParams,\n ): Promise<SubqlProjectDs> {\n const template = this.project.templates.find(\n (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,2 @@
1
+ export declare class FetchModule {
2
+ }
@@ -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,43 @@
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
+ fillNextBlockBuffer(initBlockHeight: number): Promise<void>;
40
+ private nextEndBlockHeight;
41
+ private dictionaryValidation;
42
+ resetForNewDs(blockHeight: number): Promise<void>;
43
+ }
@@ -0,0 +1,359 @@
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 __param = (this && this.__param) || function (paramIndex, decorator) {
14
+ return function (target, key) { decorator(target, key, paramIndex); }
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.FetchService = void 0;
18
+ const common_1 = require("@nestjs/common");
19
+ const event_emitter_1 = require("@nestjs/event-emitter");
20
+ const schedule_1 = require("@nestjs/schedule");
21
+ const common_ethereum_1 = require("@subql/common-ethereum");
22
+ const node_core_1 = require("@subql/node-core");
23
+ const lodash_1 = require("lodash");
24
+ const SubqueryProject_1 = require("../configure/SubqueryProject");
25
+ const utils_ethereum_1 = require("../ethereum/utils.ethereum");
26
+ const string_1 = require("../utils/string");
27
+ const dictionary_service_1 = require("./dictionary.service");
28
+ const dynamic_ds_service_1 = require("./dynamic-ds.service");
29
+ const logger = (0, node_core_1.getLogger)('fetch');
30
+ let BLOCK_TIME_VARIANCE = 5000;
31
+ const DICTIONARY_MAX_QUERY_SIZE = 10000;
32
+ const CHECK_MEMORY_INTERVAL = 60000;
33
+ const MINIMUM_BATCH_SIZE = 5;
34
+ const INTERVAL_PERCENT = 0.9;
35
+ function eventFilterToQueryEntry(filter) {
36
+ const conditions = [];
37
+ if (filter.address) {
38
+ conditions.push({
39
+ field: 'address',
40
+ value: filter.address.toLowerCase(),
41
+ });
42
+ }
43
+ if (filter.topics) {
44
+ for (let i = 0; i < Math.min(filter.topics.length, 4); i++) {
45
+ const topic = filter.topics[i];
46
+ if (!topic) {
47
+ continue;
48
+ }
49
+ const field = `topics${i}`;
50
+ conditions.push({ field, value: (0, string_1.eventToTopic)(topic) });
51
+ }
52
+ }
53
+ return {
54
+ entity: 'evmLogs',
55
+ conditions,
56
+ };
57
+ }
58
+ function callFilterToQueryEntry(filter) {
59
+ const conditions = [];
60
+ if (filter.from) {
61
+ conditions.push({
62
+ field: 'from',
63
+ value: filter.from.toLowerCase(),
64
+ });
65
+ }
66
+ if (filter.to) {
67
+ conditions.push({
68
+ field: 'to',
69
+ value: filter.to.toLowerCase(),
70
+ });
71
+ }
72
+ if (filter.function) {
73
+ conditions.push({
74
+ field: 'func',
75
+ value: (0, string_1.functionToSighash)(filter.function),
76
+ });
77
+ }
78
+ return {
79
+ entity: 'evmTransactions',
80
+ conditions,
81
+ };
82
+ }
83
+ let FetchService = class FetchService {
84
+ constructor(apiService, nodeConfig, project, blockDispatcher, dictionaryService, dynamicDsService, eventEmitter, schedulerRegistry) {
85
+ this.apiService = apiService;
86
+ this.nodeConfig = nodeConfig;
87
+ this.project = project;
88
+ this.blockDispatcher = blockDispatcher;
89
+ this.dictionaryService = dictionaryService;
90
+ this.dynamicDsService = dynamicDsService;
91
+ this.eventEmitter = eventEmitter;
92
+ this.schedulerRegistry = schedulerRegistry;
93
+ this.isShutdown = false;
94
+ this.batchSizeScale = 1;
95
+ }
96
+ onApplicationShutdown() {
97
+ this.isShutdown = true;
98
+ }
99
+ get api() {
100
+ return this.apiService.api;
101
+ }
102
+ async syncDynamicDatascourcesFromMeta() {
103
+ this.templateDynamicDatasouces =
104
+ await this.dynamicDsService.getDynamicDatasources();
105
+ }
106
+ // TODO: if custom ds doesn't support dictionary, use baseFilter, if yes, let
107
+ getDictionaryQueryEntries() {
108
+ const queryEntries = [];
109
+ const dataSources = this.project.dataSources;
110
+ for (const ds of dataSources.concat(this.templateDynamicDatasouces)) {
111
+ for (const handler of ds.mapping.handlers) {
112
+ let filterList;
113
+ filterList = [handler.filter];
114
+ filterList = filterList.filter((f) => f);
115
+ if (!filterList.length)
116
+ return [];
117
+ switch (handler.kind) {
118
+ case common_ethereum_1.EthereumHandlerKind.Block:
119
+ return [];
120
+ case common_ethereum_1.EthereumHandlerKind.Call: {
121
+ for (const filter of filterList) {
122
+ if (filter.from !== undefined ||
123
+ filter.to !== undefined ||
124
+ filter.function) {
125
+ queryEntries.push(callFilterToQueryEntry(filter));
126
+ }
127
+ else {
128
+ return [];
129
+ }
130
+ }
131
+ break;
132
+ }
133
+ case common_ethereum_1.EthereumHandlerKind.Event: {
134
+ for (const filter of filterList) {
135
+ if (filter.address || filter.topics) {
136
+ queryEntries.push(eventFilterToQueryEntry(filter));
137
+ }
138
+ else {
139
+ return [];
140
+ }
141
+ }
142
+ break;
143
+ }
144
+ default:
145
+ }
146
+ }
147
+ }
148
+ return (0, lodash_1.uniqBy)(queryEntries, (item) => `${item.entity}|${JSON.stringify((0, lodash_1.sortBy)(item.conditions, (c) => c.field))}`);
149
+ }
150
+ updateDictionary() {
151
+ var _a;
152
+ this.dictionaryQueryEntries = this.getDictionaryQueryEntries();
153
+ this.useDictionary =
154
+ !!((_a = this.dictionaryQueryEntries) === null || _a === void 0 ? void 0 : _a.length) &&
155
+ !!this.project.network.dictionary;
156
+ }
157
+ async init(startHeight) {
158
+ if (this.api) {
159
+ const CHAIN_INTERVAL = (0, utils_ethereum_1.calcInterval)(this.api) * INTERVAL_PERCENT;
160
+ BLOCK_TIME_VARIANCE = Math.min(BLOCK_TIME_VARIANCE, CHAIN_INTERVAL);
161
+ this.schedulerRegistry.addInterval('getLatestBlockHead', setInterval(() => void this.getBestBlockHead(), BLOCK_TIME_VARIANCE));
162
+ }
163
+ await this.syncDynamicDatascourcesFromMeta();
164
+ this.updateDictionary();
165
+ this.eventEmitter.emit(node_core_1.IndexerEvent.UsingDictionary, {
166
+ value: Number(this.useDictionary),
167
+ });
168
+ await this.getFinalizedBlockHead();
169
+ await this.getBestBlockHead();
170
+ await this.blockDispatcher.init(this.resetForNewDs.bind(this));
171
+ void this.startLoop(startHeight);
172
+ }
173
+ checkBatchScale() {
174
+ if (this.nodeConfig['scale-batch-size']) {
175
+ const scale = (0, node_core_1.checkMemoryUsage)(this.batchSizeScale, this.nodeConfig);
176
+ if (this.batchSizeScale !== scale) {
177
+ this.batchSizeScale = scale;
178
+ }
179
+ }
180
+ }
181
+ async getFinalizedBlockHead() {
182
+ if (!this.api) {
183
+ logger.debug(`Skip fetch finalized block until API is ready`);
184
+ return;
185
+ }
186
+ try {
187
+ const currentFinalizedHeight = await this.api.getFinalizedBlockHeight();
188
+ if (this.latestFinalizedHeight !== currentFinalizedHeight) {
189
+ this.latestFinalizedHeight = currentFinalizedHeight;
190
+ this.eventEmitter.emit(node_core_1.IndexerEvent.BlockTarget, {
191
+ height: this.latestFinalizedHeight,
192
+ });
193
+ }
194
+ }
195
+ catch (e) {
196
+ logger.error(e, `Having a problem when get finalized block`);
197
+ }
198
+ }
199
+ async getBestBlockHead() {
200
+ if (!this.api) {
201
+ logger.debug(`Skip fetch best block until API is ready`);
202
+ return;
203
+ }
204
+ try {
205
+ const currentBestHeight = await this.api.getLastHeight();
206
+ if (this.latestBestHeight !== currentBestHeight) {
207
+ this.latestBestHeight = currentBestHeight;
208
+ this.eventEmitter.emit(node_core_1.IndexerEvent.BlockBest, {
209
+ height: this.latestBestHeight,
210
+ });
211
+ }
212
+ }
213
+ catch (e) {
214
+ logger.error(e, `Having a problem when get best block`);
215
+ }
216
+ }
217
+ async startLoop(initBlockHeight) {
218
+ await this.fillNextBlockBuffer(initBlockHeight);
219
+ }
220
+ getModulos() {
221
+ const modulos = [];
222
+ for (const ds of this.project.dataSources) {
223
+ if ((0, common_ethereum_1.isCustomDs)(ds)) {
224
+ continue;
225
+ }
226
+ for (const handler of ds.mapping.handlers) {
227
+ if (handler.kind === common_ethereum_1.EthereumHandlerKind.Block &&
228
+ handler.filter &&
229
+ handler.filter.modulo) {
230
+ modulos.push(handler.filter.modulo);
231
+ }
232
+ }
233
+ }
234
+ return modulos;
235
+ }
236
+ getModuloBlocks(startHeight, endHeight) {
237
+ const modulos = this.getModulos();
238
+ const moduloBlocks = [];
239
+ for (let i = startHeight; i < endHeight; i++) {
240
+ if (modulos.find((m) => i % m === 0)) {
241
+ moduloBlocks.push(i);
242
+ }
243
+ }
244
+ return moduloBlocks;
245
+ }
246
+ async fillNextBlockBuffer(initBlockHeight) {
247
+ let startBlockHeight;
248
+ let scaledBatchSize;
249
+ const getStartBlockHeight = () => {
250
+ return this.blockDispatcher.latestBufferedHeight
251
+ ? this.blockDispatcher.latestBufferedHeight + 1
252
+ : initBlockHeight;
253
+ };
254
+ while (!this.isShutdown) {
255
+ startBlockHeight = getStartBlockHeight();
256
+ scaledBatchSize = Math.max(Math.round(this.batchSizeScale * this.nodeConfig.batchSize), Math.min(MINIMUM_BATCH_SIZE, this.nodeConfig.batchSize * 3));
257
+ if (this.blockDispatcher.freeSize < scaledBatchSize ||
258
+ startBlockHeight > this.latestFinalizedHeight) {
259
+ await (0, node_core_1.delay)(1);
260
+ continue;
261
+ }
262
+ if (this.useDictionary) {
263
+ const queryEndBlock = startBlockHeight + DICTIONARY_MAX_QUERY_SIZE;
264
+ const moduloBlocks = this.getModuloBlocks(startBlockHeight, queryEndBlock);
265
+ try {
266
+ const dictionary = await this.dictionaryService.getDictionary(startBlockHeight, queryEndBlock, scaledBatchSize, this.dictionaryQueryEntries);
267
+ if (startBlockHeight !== getStartBlockHeight()) {
268
+ logger.debug(`Queue was reset for new DS, discarding dictionary query result`);
269
+ continue;
270
+ }
271
+ if (dictionary &&
272
+ this.dictionaryValidation(dictionary, startBlockHeight)) {
273
+ let { batchBlocks } = dictionary;
274
+ batchBlocks = batchBlocks
275
+ .concat(moduloBlocks)
276
+ .sort((a, b) => a - b);
277
+ if (batchBlocks.length === 0) {
278
+ // There we're no blocks in this query range, we can set a new height we're up to
279
+ this.blockDispatcher.latestBufferedHeight = Math.min(queryEndBlock - 1, dictionary._metadata.lastProcessedHeight);
280
+ }
281
+ else {
282
+ const maxBlockSize = Math.min(batchBlocks.length, this.blockDispatcher.freeSize);
283
+ batchBlocks = batchBlocks.slice(0, maxBlockSize);
284
+ this.blockDispatcher.enqueueBlocks(batchBlocks);
285
+ }
286
+ continue; // skip nextBlockRange() way
287
+ }
288
+ // else use this.nextBlockRange()
289
+ }
290
+ catch (e) {
291
+ logger.debug(`Fetch dictionary stopped: ${e.message}`);
292
+ this.eventEmitter.emit(node_core_1.IndexerEvent.SkipDictionary);
293
+ }
294
+ }
295
+ // the original method: fill next batch size of blocks
296
+ const endHeight = this.nextEndBlockHeight(startBlockHeight, scaledBatchSize);
297
+ this.blockDispatcher.enqueueBlocks((0, lodash_1.range)(startBlockHeight, endHeight + 1));
298
+ }
299
+ }
300
+ nextEndBlockHeight(startBlockHeight, scaledBatchSize) {
301
+ let endBlockHeight = startBlockHeight + scaledBatchSize - 1;
302
+ if (endBlockHeight > this.latestFinalizedHeight) {
303
+ endBlockHeight = this.latestFinalizedHeight;
304
+ }
305
+ return endBlockHeight;
306
+ }
307
+ dictionaryValidation({ _metadata: metaData }, startBlockHeight) {
308
+ if (metaData.genesisHash !== this.api.getGenesisHash()) {
309
+ 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');
310
+ this.useDictionary = false;
311
+ this.eventEmitter.emit(node_core_1.IndexerEvent.UsingDictionary, {
312
+ value: Number(this.useDictionary),
313
+ });
314
+ this.eventEmitter.emit(node_core_1.IndexerEvent.SkipDictionary);
315
+ return false;
316
+ }
317
+ if (metaData.lastProcessedHeight < startBlockHeight) {
318
+ logger.warn(`Dictionary indexed block is behind current indexing block height`);
319
+ this.eventEmitter.emit(node_core_1.IndexerEvent.SkipDictionary);
320
+ return false;
321
+ }
322
+ return true;
323
+ }
324
+ async resetForNewDs(blockHeight) {
325
+ await this.syncDynamicDatascourcesFromMeta();
326
+ this.updateDictionary();
327
+ this.blockDispatcher.flushQueue(blockHeight);
328
+ }
329
+ };
330
+ __decorate([
331
+ (0, schedule_1.Interval)(CHECK_MEMORY_INTERVAL),
332
+ __metadata("design:type", Function),
333
+ __metadata("design:paramtypes", []),
334
+ __metadata("design:returntype", void 0)
335
+ ], FetchService.prototype, "checkBatchScale", null);
336
+ __decorate([
337
+ (0, schedule_1.Interval)(BLOCK_TIME_VARIANCE * 1000),
338
+ __metadata("design:type", Function),
339
+ __metadata("design:paramtypes", []),
340
+ __metadata("design:returntype", Promise)
341
+ ], FetchService.prototype, "getFinalizedBlockHead", null);
342
+ __decorate([
343
+ (0, schedule_1.Interval)(BLOCK_TIME_VARIANCE * 1000),
344
+ __metadata("design:type", Function),
345
+ __metadata("design:paramtypes", []),
346
+ __metadata("design:returntype", Promise)
347
+ ], FetchService.prototype, "getBestBlockHead", null);
348
+ FetchService = __decorate([
349
+ (0, common_1.Injectable)(),
350
+ __param(3, (0, common_1.Inject)('IBlockDispatcher')),
351
+ __metadata("design:paramtypes", [node_core_1.ApiService,
352
+ node_core_1.NodeConfig,
353
+ SubqueryProject_1.SubqueryProject, Object, dictionary_service_1.DictionaryService,
354
+ dynamic_ds_service_1.DynamicDsService,
355
+ event_emitter_1.EventEmitter2,
356
+ schedule_1.SchedulerRegistry])
357
+ ], FetchService);
358
+ exports.FetchService = FetchService;
359
+ //# sourceMappingURL=fetch.service.js.map