@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.
Files changed (118) hide show
  1. package/CHANGELOG.md +11 -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 +38 -0
  11. package/dist/configure/SubqueryProject.js +133 -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 +24 -0
  20. package/dist/ethereum/api.ethereum.js +177 -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 +25 -0
  41. package/dist/indexer/dynamic-ds.service.js +124 -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 +44 -0
  47. package/dist/indexer/fetch.service.js +369 -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 +266 -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 +40 -0
  56. package/dist/indexer/project.service.js +259 -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,266 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.IndexerManager = void 0;
15
+ const common_1 = require("@nestjs/common");
16
+ const util_1 = require("@polkadot/util");
17
+ const common_ethereum_1 = require("@subql/common-ethereum");
18
+ const node_core_1 = require("@subql/node-core");
19
+ const sequelize_1 = require("sequelize");
20
+ const SubqueryProject_1 = require("../configure/SubqueryProject");
21
+ const block_ethereum_1 = require("../ethereum/block.ethereum");
22
+ const yargs_1 = require("../yargs");
23
+ const ds_processor_service_1 = require("./ds-processor.service");
24
+ const dynamic_ds_service_1 = require("./dynamic-ds.service");
25
+ const project_service_1 = require("./project.service");
26
+ const sandbox_service_1 = require("./sandbox.service");
27
+ const NULL_MERKEL_ROOT = (0, util_1.hexToU8a)('0x00');
28
+ const logger = (0, node_core_1.getLogger)('indexer');
29
+ let IndexerManager = class IndexerManager {
30
+ constructor(storeService, apiService, poiService, sequelize, project, nodeConfig, sandboxService, dynamicDsService, dsProcessorService, projectService) {
31
+ this.storeService = storeService;
32
+ this.apiService = apiService;
33
+ this.poiService = poiService;
34
+ this.sequelize = sequelize;
35
+ this.project = project;
36
+ this.nodeConfig = nodeConfig;
37
+ this.sandboxService = sandboxService;
38
+ this.dynamicDsService = dynamicDsService;
39
+ this.dsProcessorService = dsProcessorService;
40
+ this.projectService = projectService;
41
+ logger.info('indexer manager start');
42
+ this.api = this.apiService.api;
43
+ }
44
+ async indexBlock(blockContent) {
45
+ const { blockHeight } = blockContent;
46
+ let dynamicDsCreated = false;
47
+ const tx = await this.sequelize.transaction();
48
+ this.storeService.setTransaction(tx);
49
+ this.storeService.setBlockHeight(blockHeight);
50
+ let operationHash = NULL_MERKEL_ROOT;
51
+ let poiBlockHash;
52
+ try {
53
+ this.filteredDataSources = this.filterDataSources(blockHeight);
54
+ const datasources = this.filteredDataSources.concat(...(await this.dynamicDsService.getDynamicDatasources()));
55
+ await this.indexBlockData(blockContent, datasources,
56
+ // eslint-disable-next-line @typescript-eslint/require-await
57
+ async (ds) => {
58
+ const vm = this.sandboxService.getDsProcessorWrapper(ds, this.api, blockContent);
59
+ // Inject function to create ds into vm
60
+ vm.freeze(async (templateName, args) => {
61
+ const newDs = await this.dynamicDsService.createDynamicDatasource({
62
+ templateName,
63
+ args,
64
+ startBlock: blockHeight,
65
+ }, tx);
66
+ // Push the newly created dynamic ds to be processed this block on any future extrinsics/events
67
+ datasources.push(newDs);
68
+ dynamicDsCreated = true;
69
+ }, 'createDynamicDatasource');
70
+ return vm;
71
+ });
72
+ await this.storeService.setMetadataBatch([
73
+ { key: 'lastProcessedHeight', value: blockHeight },
74
+ { key: 'lastProcessedTimestamp', value: Date.now() },
75
+ ], { transaction: tx });
76
+ // Db Metadata increase BlockCount, in memory ref to block-dispatcher _processedBlockCount
77
+ await this.storeService.incrementBlockCount(tx);
78
+ // Need calculate operationHash to ensure correct offset insert all time
79
+ operationHash = this.storeService.getOperationMerkleRoot();
80
+ if (this.nodeConfig.proofOfIndex) {
81
+ //check if operation is null, then poi will not be inserted
82
+ if (!(0, util_1.u8aEq)(operationHash, NULL_MERKEL_ROOT)) {
83
+ const poiBlock = node_core_1.PoiBlock.create(blockHeight, blockContent.block.hash, operationHash, await this.poiService.getLatestPoiBlockHash(), this.project.id);
84
+ poiBlockHash = poiBlock.hash;
85
+ await this.storeService.setPoi(poiBlock, { transaction: tx });
86
+ this.poiService.setLatestPoiBlockHash(poiBlockHash);
87
+ await this.storeService.setMetadataBatch([{ key: 'lastPoiHeight', value: blockHeight }], { transaction: tx });
88
+ }
89
+ }
90
+ }
91
+ catch (e) {
92
+ await tx.rollback();
93
+ throw e;
94
+ }
95
+ await tx.commit();
96
+ return {
97
+ dynamicDsCreated,
98
+ operationHash,
99
+ };
100
+ }
101
+ async start() {
102
+ await this.projectService.init();
103
+ logger.info('indexer manager started');
104
+ }
105
+ filterDataSources(nextProcessingHeight) {
106
+ const filteredDs = this.projectService.dataSources.filter((ds) => ds.startBlock <= nextProcessingHeight);
107
+ if (filteredDs.length === 0) {
108
+ logger.error(`Your start block is greater than the current indexed block height in your database. Either change your startBlock (project.yaml) to <= ${nextProcessingHeight}
109
+ or delete your database and start again from the currently specified startBlock`);
110
+ process.exit(1);
111
+ }
112
+ // perform filter for custom ds
113
+ if (!filteredDs.length) {
114
+ logger.error(`Did not find any datasources with associated processor`);
115
+ process.exit(1);
116
+ }
117
+ return filteredDs;
118
+ }
119
+ async indexBlockData({ block, logs, transactions }, dataSources, getVM) {
120
+ await this.indexBlockContent(block, dataSources, getVM);
121
+ for (const log of logs) {
122
+ await this.indexEvent(log, dataSources, getVM);
123
+ }
124
+ for (const tx of transactions) {
125
+ await this.indexExtrinsic(tx, dataSources, getVM);
126
+ }
127
+ }
128
+ async indexBlockContent(block, dataSources, getVM) {
129
+ for (const ds of dataSources) {
130
+ await this.indexData(common_ethereum_1.EthereumHandlerKind.Block, block, ds, getVM);
131
+ }
132
+ }
133
+ async indexExtrinsic(tx, dataSources, getVM) {
134
+ for (const ds of dataSources) {
135
+ await this.indexData(common_ethereum_1.EthereumHandlerKind.Call, tx, ds, getVM);
136
+ }
137
+ }
138
+ async indexEvent(log, dataSources, getVM) {
139
+ for (const ds of dataSources) {
140
+ await this.indexData(common_ethereum_1.EthereumHandlerKind.Event, log, ds, getVM);
141
+ }
142
+ }
143
+ async indexData(kind, data, ds, getVM) {
144
+ let vm;
145
+ if ((0, common_ethereum_1.isRuntimeDs)(ds)) {
146
+ const handlers = ds.mapping.handlers.filter((h) => h.kind === kind &&
147
+ FilterTypeMap[kind](data, h.filter, ds.options.address));
148
+ if (!handlers.length) {
149
+ return;
150
+ }
151
+ const parsedData = await DataAbiParser[kind](this.api)(data, ds);
152
+ for (const handler of handlers) {
153
+ vm = vm !== null && vm !== void 0 ? vm : (await getVM(ds));
154
+ this.nodeConfig.profiler
155
+ ? await (0, node_core_1.profilerWrap)(vm.securedExec.bind(vm), 'handlerPerformance', handler.handler)(handler.handler, [parsedData])
156
+ : await vm.securedExec(handler.handler, [parsedData]);
157
+ }
158
+ }
159
+ else if ((0, common_ethereum_1.isCustomDs)(ds)) {
160
+ const handlers = this.filterCustomDsHandlers(ds, data, ProcessorTypeMap[kind], (data, baseFilter) => {
161
+ switch (kind) {
162
+ case common_ethereum_1.EthereumHandlerKind.Block:
163
+ return block_ethereum_1.EthereumBlockWrapped.filterBlocksProcessor(data, baseFilter);
164
+ case common_ethereum_1.EthereumHandlerKind.Call:
165
+ return block_ethereum_1.EthereumBlockWrapped.filterTransactionsProcessor(data, baseFilter);
166
+ case common_ethereum_1.EthereumHandlerKind.Event:
167
+ return block_ethereum_1.EthereumBlockWrapped.filterLogsProcessor(data, baseFilter);
168
+ default:
169
+ throw new Error('Unsupported handler kind');
170
+ }
171
+ });
172
+ if (!handlers.length) {
173
+ return;
174
+ }
175
+ const parsedData = await DataAbiParser[kind](this.api)(data, ds);
176
+ for (const handler of handlers) {
177
+ vm = vm !== null && vm !== void 0 ? vm : (await getVM(ds));
178
+ await this.transformAndExecuteCustomDs(ds, vm, handler, parsedData);
179
+ }
180
+ }
181
+ }
182
+ filterCustomDsHandlers(ds, data, baseHandlerCheck, baseFilter) {
183
+ const plugin = this.dsProcessorService.getDsProcessor(ds);
184
+ return ds.mapping.handlers
185
+ .filter((handler) => {
186
+ const processor = plugin.handlerProcessors[handler.kind];
187
+ if (baseHandlerCheck(processor)) {
188
+ processor.baseFilter;
189
+ return baseFilter(data, processor.baseFilter);
190
+ }
191
+ return false;
192
+ })
193
+ .filter((handler) => {
194
+ const processor = (0, ds_processor_service_1.asSecondLayerHandlerProcessor_1_0_0)(plugin.handlerProcessors[handler.kind]);
195
+ try {
196
+ return processor.filterProcessor({
197
+ filter: handler.filter,
198
+ input: data,
199
+ ds,
200
+ });
201
+ }
202
+ catch (e) {
203
+ logger.error(e, 'Failed to run ds processer filter.');
204
+ throw e;
205
+ }
206
+ });
207
+ }
208
+ async transformAndExecuteCustomDs(ds, vm, handler, data) {
209
+ const plugin = this.dsProcessorService.getDsProcessor(ds);
210
+ const assets = await this.dsProcessorService.getAssets(ds);
211
+ const processor = (0, ds_processor_service_1.asSecondLayerHandlerProcessor_1_0_0)(plugin.handlerProcessors[handler.kind]);
212
+ const transformedData = await processor
213
+ .transformer({
214
+ input: data,
215
+ ds,
216
+ api: this.api,
217
+ filter: handler.filter,
218
+ assets,
219
+ })
220
+ .catch((e) => {
221
+ logger.error(e, 'Failed to transform data with ds processor.');
222
+ throw e;
223
+ });
224
+ // We can not run this in parallel. the transformed data items may be dependent on one another.
225
+ // An example of this is with Acala EVM packing multiple EVM logs into a single Substrate event
226
+ for (const _data of transformedData) {
227
+ await vm.securedExec(handler.handler, [_data]);
228
+ }
229
+ }
230
+ };
231
+ __decorate([
232
+ (0, node_core_1.profiler)(yargs_1.yargsOptions.argv.profiler),
233
+ __metadata("design:type", Function),
234
+ __metadata("design:paramtypes", [Object]),
235
+ __metadata("design:returntype", Promise)
236
+ ], IndexerManager.prototype, "indexBlock", null);
237
+ IndexerManager = __decorate([
238
+ (0, common_1.Injectable)(),
239
+ __metadata("design:paramtypes", [node_core_1.StoreService,
240
+ node_core_1.ApiService,
241
+ node_core_1.PoiService,
242
+ sequelize_1.Sequelize,
243
+ SubqueryProject_1.SubqueryProject,
244
+ node_core_1.NodeConfig,
245
+ sandbox_service_1.SandboxService,
246
+ dynamic_ds_service_1.DynamicDsService,
247
+ ds_processor_service_1.DsProcessorService,
248
+ project_service_1.ProjectService])
249
+ ], IndexerManager);
250
+ exports.IndexerManager = IndexerManager;
251
+ const ProcessorTypeMap = {
252
+ [common_ethereum_1.EthereumHandlerKind.Block]: common_ethereum_1.isBlockHandlerProcessor,
253
+ [common_ethereum_1.EthereumHandlerKind.Event]: common_ethereum_1.isEventHandlerProcessor,
254
+ [common_ethereum_1.EthereumHandlerKind.Call]: common_ethereum_1.isCallHandlerProcessor,
255
+ };
256
+ const FilterTypeMap = {
257
+ [common_ethereum_1.EthereumHandlerKind.Block]: block_ethereum_1.EthereumBlockWrapped.filterBlocksProcessor,
258
+ [common_ethereum_1.EthereumHandlerKind.Event]: block_ethereum_1.EthereumBlockWrapped.filterLogsProcessor,
259
+ [common_ethereum_1.EthereumHandlerKind.Call]: block_ethereum_1.EthereumBlockWrapped.filterTransactionsProcessor,
260
+ };
261
+ const DataAbiParser = {
262
+ [common_ethereum_1.EthereumHandlerKind.Block]: () => (data) => data,
263
+ [common_ethereum_1.EthereumHandlerKind.Event]: (api) => api.parseLog.bind(api),
264
+ [common_ethereum_1.EthereumHandlerKind.Call]: (api) => api.parseTransaction.bind(api),
265
+ };
266
+ //# sourceMappingURL=indexer.manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexer.manager.js","sourceRoot":"","sources":["../../src/indexer/indexer.manager.ts"],"names":[],"mappings":";AAAA,gEAAgE;AAChE,sCAAsC;;;;;;;;;;;;AAEtC,2CAA4C;AAC5C,yCAAiD;AACjD,4DAUgC;AAChC,gDAU0B;AAQ1B,yCAAsC;AACtC,kEAA+E;AAE/E,+DAAkE;AAClE,oCAAwC;AACxC,iEAGgC;AAChC,6DAAwD;AACxD,uDAAmD;AACnD,uDAAmD;AAEnD,MAAM,gBAAgB,GAAG,IAAA,eAAQ,EAAC,MAAM,CAAC,CAAC;AAE1C,MAAM,MAAM,GAAG,IAAA,qBAAS,EAAC,SAAS,CAAC,CAAC;AAG7B,IAAM,cAAc,GAApB,MAAM,cAAc;IAIzB,YACU,YAA0B,EAC1B,UAAsB,EACtB,UAAsB,EACtB,SAAoB,EACpB,OAAwB,EACxB,UAAsB,EACtB,cAA8B,EAC9B,gBAAkC,EAClC,kBAAsC,EACtC,cAA8B;QAT9B,iBAAY,GAAZ,YAAY,CAAc;QAC1B,eAAU,GAAV,UAAU,CAAY;QACtB,eAAU,GAAV,UAAU,CAAY;QACtB,cAAS,GAAT,SAAS,CAAW;QACpB,YAAO,GAAP,OAAO,CAAiB;QACxB,eAAU,GAAV,UAAU,CAAY;QACtB,mBAAc,GAAd,cAAc,CAAgB;QAC9B,qBAAgB,GAAhB,gBAAgB,CAAkB;QAClC,uBAAkB,GAAlB,kBAAkB,CAAoB;QACtC,mBAAc,GAAd,cAAc,CAAgB;QAEtC,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAErC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;IACjC,CAAC;IAGK,AAAN,KAAK,CAAC,UAAU,CACd,YAAkC;QAElC,MAAM,EAAE,WAAW,EAAE,GAAG,YAAY,CAAC;QACrC,IAAI,gBAAgB,GAAG,KAAK,CAAC;QAC7B,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;QAC9C,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QACrC,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QAE9C,IAAI,aAAa,GAAG,gBAAgB,CAAC;QACrC,IAAI,YAAwB,CAAC;QAE7B,IAAI;YACF,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;YAE/D,MAAM,WAAW,GAAG,IAAI,CAAC,mBAAmB,CAAC,MAAM,CACjD,GAAG,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,qBAAqB,EAAE,CAAC,CACzD,CAAC;YAEF,MAAM,IAAI,CAAC,cAAc,CACvB,YAAY,EACZ,WAAW;YACX,4DAA4D;YAC5D,KAAK,EAAE,EAAkB,EAAE,EAAE;gBAC3B,MAAM,EAAE,GAAG,IAAI,CAAC,cAAc,CAAC,qBAAqB,CAClD,EAAE,EACF,IAAI,CAAC,GAAG,EACR,YAAY,CACb,CAAC;gBAEF,uCAAuC;gBACvC,EAAE,CAAC,MAAM,CACP,KAAK,EAAE,YAAoB,EAAE,IAA8B,EAAE,EAAE;oBAC7D,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,uBAAuB,CAC/D;wBACE,YAAY;wBACZ,IAAI;wBACJ,UAAU,EAAE,WAAW;qBACxB,EACD,EAAE,CACH,CAAC;oBACF,+FAA+F;oBAC/F,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBACxB,gBAAgB,GAAG,IAAI,CAAC;gBAC1B,CAAC,EACD,yBAAyB,CAC1B,CAAC;gBAEF,OAAO,EAAE,CAAC;YACZ,CAAC,CACF,CAAC;YAEF,MAAM,IAAI,CAAC,YAAY,CAAC,gBAAgB,CACtC;gBACE,EAAE,GAAG,EAAE,qBAAqB,EAAE,KAAK,EAAE,WAAW,EAAE;gBAClD,EAAE,GAAG,EAAE,wBAAwB,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE;aACrD,EACD,EAAE,WAAW,EAAE,EAAE,EAAE,CACpB,CAAC;YACF,0FAA0F;YAC1F,MAAM,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC;YAEhD,wEAAwE;YACxE,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,sBAAsB,EAAE,CAAC;YAC3D,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE;gBAChC,2DAA2D;gBAC3D,IAAI,CAAC,IAAA,YAAK,EAAC,aAAa,EAAE,gBAAgB,CAAC,EAAE;oBAC3C,MAAM,QAAQ,GAAG,oBAAQ,CAAC,MAAM,CAC9B,WAAW,EACX,YAAY,CAAC,KAAK,CAAC,IAAI,EACvB,aAAa,EACb,MAAM,IAAI,CAAC,UAAU,CAAC,qBAAqB,EAAE,EAC7C,IAAI,CAAC,OAAO,CAAC,EAAE,CAChB,CAAC;oBACF,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC;oBAC7B,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC;oBAC9D,IAAI,CAAC,UAAU,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC;oBACpD,MAAM,IAAI,CAAC,YAAY,CAAC,gBAAgB,CACtC,CAAC,EAAE,GAAG,EAAE,eAAe,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,EAC9C,EAAE,WAAW,EAAE,EAAE,EAAE,CACpB,CAAC;iBACH;aACF;SACF;QAAC,OAAO,CAAC,EAAE;YACV,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC;YACpB,MAAM,CAAC,CAAC;SACT;QAED,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC;QAElB,OAAO;YACL,gBAAgB;YAChB,aAAa;SACd,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IACzC,CAAC;IAEO,iBAAiB,CAAC,oBAA4B;QACpD,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,MAAM,CACvD,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,IAAI,oBAAoB,CAC9C,CAAC;QAEF,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE;YAC3B,MAAM,CAAC,KAAK,CACV,0IAA0I,oBAAoB;yFAC7E,CAClF,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;SACjB;QACD,+BAA+B;QAC/B,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE;YACtB,MAAM,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;YACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;SACjB;QACD,OAAO,UAAU,CAAC;IACpB,CAAC;IAEO,KAAK,CAAC,cAAc,CAC1B,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAwB,EACnD,WAA6B,EAC7B,KAAqD;QAErD,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;QAExD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;YACtB,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;SAChD;QAED,KAAK,MAAM,EAAE,IAAI,YAAY,EAAE;YAC7B,MAAM,IAAI,CAAC,cAAc,CAAC,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;SACnD;IACH,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAC7B,KAAoB,EACpB,WAA6B,EAC7B,KAAqD;QAErD,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE;YAC5B,MAAM,IAAI,CAAC,SAAS,CAAC,qCAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;SACnE;IACH,CAAC;IAEO,KAAK,CAAC,cAAc,CAC1B,EAAuB,EACvB,WAA6B,EAC7B,KAAqD;QAErD,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE;YAC5B,MAAM,IAAI,CAAC,SAAS,CAAC,qCAAmB,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;SAC/D;IACH,CAAC;IAEO,KAAK,CAAC,UAAU,CACtB,GAAgB,EAChB,WAA6B,EAC7B,KAAqD;QAErD,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE;YAC5B,MAAM,IAAI,CAAC,SAAS,CAAC,qCAAmB,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;SACjE;IACH,CAAC;IAEO,KAAK,CAAC,SAAS,CACrB,IAAO,EACP,IAAuC,EACvC,EAAkB,EAClB,KAAsD;QAEtD,IAAI,EAAkB,CAAC;QACvB,IAAI,IAAA,6BAAW,EAAC,EAAE,CAAC,EAAE;YACnB,MAAM,QAAQ,GAAI,EAAE,CAAC,OAAO,CAAC,QAAkC,CAAC,MAAM,CACpE,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,IAAI,KAAK,IAAI;gBACf,aAAa,CAAC,IAAI,CAAC,CAAC,IAAW,EAAE,CAAC,CAAC,MAAa,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CACxE,CAAC;YAEF,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;gBACpB,OAAO;aACR;YACD,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAEjE,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;gBAC9B,EAAE,GAAG,EAAE,aAAF,EAAE,cAAF,EAAE,GAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC7B,IAAI,CAAC,UAAU,CAAC,QAAQ;oBACtB,CAAC,CAAC,MAAM,IAAA,wBAAY,EAChB,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,EACvB,oBAAoB,EACpB,OAAO,CAAC,OAAO,CAChB,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC,CAAC;oBAClC,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;aACzD;SACF;aAAM,IAAI,IAAA,4BAAU,EAAC,EAAE,CAAC,EAAE;YACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,sBAAsB,CAC1C,EAAE,EACF,IAAI,EACJ,gBAAgB,CAAC,IAAI,CAAC,EACtB,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE;gBACnB,QAAQ,IAAI,EAAE;oBACZ,KAAK,qCAAmB,CAAC,KAAK;wBAC5B,OAAO,qCAAoB,CAAC,qBAAqB,CAC/C,IAAqB,EACrB,UAAU,CACX,CAAC;oBACJ,KAAK,qCAAmB,CAAC,IAAI;wBAC3B,OAAO,qCAAoB,CAAC,2BAA2B,CACrD,IAA2B,EAC3B,UAAU,CACX,CAAC;oBACJ,KAAK,qCAAmB,CAAC,KAAK;wBAC5B,OAAO,qCAAoB,CAAC,mBAAmB,CAC7C,IAAmB,EACnB,UAAU,CACX,CAAC;oBACJ;wBACE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;iBAC/C;YACH,CAAC,CACF,CAAC;YAEF,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;gBACpB,OAAO;aACR;YAED,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAEjE,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;gBAC9B,EAAE,GAAG,EAAE,aAAF,EAAE,cAAF,EAAE,GAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC7B,MAAM,IAAI,CAAC,2BAA2B,CAAC,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;aACrE;SACF;IACH,CAAC;IAEO,sBAAsB,CAC5B,EAA8C,EAC9C,IAAuC,EACvC,gBAAqC,EACrC,UAGY;QAEZ,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QAE1D,OAAO,EAAE,CAAC,OAAO,CAAC,QAAQ;aACvB,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;YAClB,MAAM,SAAS,GAAG,MAAM,CAAC,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACzD,IAAI,gBAAgB,CAAC,SAAS,CAAC,EAAE;gBAC/B,SAAS,CAAC,UAAU,CAAC;gBAErB,OAAO,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;aAC/C;YACD,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;YAClB,MAAM,SAAS,GAAG,IAAA,0DAAmC,EACnD,MAAM,CAAC,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,CACvC,CAAC;YAEF,IAAI;gBACF,OAAO,SAAS,CAAC,eAAe,CAAC;oBAC/B,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,KAAK,EAAE,IAAI;oBACX,EAAE;iBACH,CAAC,CAAC;aACJ;YAAC,OAAO,CAAC,EAAE;gBACV,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,oCAAoC,CAAC,CAAC;gBACtD,MAAM,CAAC,CAAC;aACT;QACH,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,KAAK,CAAC,2BAA2B,CACvC,EAA8C,EAC9C,EAAkB,EAClB,OAA2B,EAC3B,IAAuC;QAEvC,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAE3D,MAAM,SAAS,GAAG,IAAA,0DAAmC,EACnD,MAAM,CAAC,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,CACvC,CAAC;QAEF,MAAM,eAAe,GAAG,MAAM,SAAS;aACpC,WAAW,CAAC;YACX,KAAK,EAAE,IAAI;YACX,EAAE;YACF,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,MAAM;SACP,CAAC;aACD,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;YACX,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,6CAA6C,CAAC,CAAC;YAC/D,MAAM,CAAC,CAAC;QACV,CAAC,CAAC,CAAC;QAEL,+FAA+F;QAC/F,+FAA+F;QAC/F,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE;YACnC,MAAM,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;SAChD;IACH,CAAC;CACF,CAAA;AApTO;IADL,IAAA,oBAAQ,EAAC,oBAAY,CAAC,IAAI,CAAC,QAAQ,CAAC;;;;gDA+FpC;AApHU,cAAc;IAD1B,IAAA,mBAAU,GAAE;qCAMa,wBAAY;QACd,sBAAU;QACV,sBAAU;QACX,qBAAS;QACX,iCAAe;QACZ,sBAAU;QACN,gCAAc;QACZ,qCAAgB;QACd,yCAAkB;QACtB,gCAAc;GAd7B,cAAc,CA0U1B;AA1UY,wCAAc;AAkV3B,MAAM,gBAAgB,GAAG;IACvB,CAAC,qCAAmB,CAAC,KAAK,CAAC,EAAE,yCAAuB;IACpD,CAAC,qCAAmB,CAAC,KAAK,CAAC,EAAE,yCAAuB;IACpD,CAAC,qCAAmB,CAAC,IAAI,CAAC,EAAE,wCAAsB;CACnD,CAAC;AAEF,MAAM,aAAa,GAAG;IACpB,CAAC,qCAAmB,CAAC,KAAK,CAAC,EAAE,qCAAoB,CAAC,qBAAqB;IACvE,CAAC,qCAAmB,CAAC,KAAK,CAAC,EAAE,qCAAoB,CAAC,mBAAmB;IACrE,CAAC,qCAAmB,CAAC,IAAI,CAAC,EAAE,qCAAoB,CAAC,2BAA2B;CAC7E,CAAC;AAEF,MAAM,aAAa,GAAG;IACpB,CAAC,qCAAmB,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,IAAmB,EAAE,EAAE,CAAC,IAAI;IAChE,CAAC,qCAAmB,CAAC,KAAK,CAAC,EAAE,CAAC,GAAgB,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC;IACzE,CAAC,qCAAmB,CAAC,IAAI,CAAC,EAAE,CAAC,GAAgB,EAAE,EAAE,CAC/C,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC;CACjC,CAAC","sourcesContent":["// Copyright 2020-2022 OnFinality Limited authors & contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Injectable } from '@nestjs/common';\nimport { hexToU8a, u8aEq } from '@polkadot/util';\nimport {\n isBlockHandlerProcessor,\n isCallHandlerProcessor,\n isEventHandlerProcessor,\n isCustomDs,\n isRuntimeDs,\n SubqlEthereumCustomDataSource,\n SubqlCustomHandler,\n EthereumHandlerKind,\n EthereumRuntimeHandlerInputMap,\n} from '@subql/common-ethereum';\nimport {\n ApiService,\n PoiBlock,\n StoreService,\n PoiService,\n NodeConfig,\n getLogger,\n profiler,\n profilerWrap,\n IndexerSandbox,\n} from '@subql/node-core';\nimport {\n EthereumTransaction,\n EthereumLog,\n SubqlRuntimeHandler,\n EthereumBlockWrapper,\n EthereumBlock,\n} from '@subql/types-ethereum';\nimport { Sequelize } from 'sequelize';\nimport { SubqlProjectDs, SubqueryProject } from '../configure/SubqueryProject';\nimport { EthereumApi } from '../ethereum';\nimport { EthereumBlockWrapped } from '../ethereum/block.ethereum';\nimport { yargsOptions } from '../yargs';\nimport {\n asSecondLayerHandlerProcessor_1_0_0,\n DsProcessorService,\n} from './ds-processor.service';\nimport { DynamicDsService } from './dynamic-ds.service';\nimport { ProjectService } from './project.service';\nimport { SandboxService } from './sandbox.service';\n\nconst NULL_MERKEL_ROOT = hexToU8a('0x00');\n\nconst logger = getLogger('indexer');\n\n@Injectable()\nexport class IndexerManager {\n private api: EthereumApi;\n private filteredDataSources: SubqlProjectDs[];\n\n constructor(\n private storeService: StoreService,\n private apiService: ApiService,\n private poiService: PoiService,\n private sequelize: Sequelize,\n private project: SubqueryProject,\n private nodeConfig: NodeConfig,\n private sandboxService: SandboxService,\n private dynamicDsService: DynamicDsService,\n private dsProcessorService: DsProcessorService,\n private projectService: ProjectService,\n ) {\n logger.info('indexer manager start');\n\n this.api = this.apiService.api;\n }\n\n @profiler(yargsOptions.argv.profiler)\n async indexBlock(\n blockContent: EthereumBlockWrapper,\n ): Promise<{ dynamicDsCreated: boolean; operationHash: Uint8Array }> {\n const { blockHeight } = blockContent;\n let dynamicDsCreated = false;\n const tx = await this.sequelize.transaction();\n this.storeService.setTransaction(tx);\n this.storeService.setBlockHeight(blockHeight);\n\n let operationHash = NULL_MERKEL_ROOT;\n let poiBlockHash: Uint8Array;\n\n try {\n this.filteredDataSources = this.filterDataSources(blockHeight);\n\n const datasources = this.filteredDataSources.concat(\n ...(await this.dynamicDsService.getDynamicDatasources()),\n );\n\n await this.indexBlockData(\n blockContent,\n datasources,\n // eslint-disable-next-line @typescript-eslint/require-await\n async (ds: SubqlProjectDs) => {\n const vm = this.sandboxService.getDsProcessorWrapper(\n ds,\n this.api,\n blockContent,\n );\n\n // Inject function to create ds into vm\n vm.freeze(\n async (templateName: string, args?: Record<string, unknown>) => {\n const newDs = await this.dynamicDsService.createDynamicDatasource(\n {\n templateName,\n args,\n startBlock: blockHeight,\n },\n tx,\n );\n // Push the newly created dynamic ds to be processed this block on any future extrinsics/events\n datasources.push(newDs);\n dynamicDsCreated = true;\n },\n 'createDynamicDatasource',\n );\n\n return vm;\n },\n );\n\n await this.storeService.setMetadataBatch(\n [\n { key: 'lastProcessedHeight', value: blockHeight },\n { key: 'lastProcessedTimestamp', value: Date.now() },\n ],\n { transaction: tx },\n );\n // Db Metadata increase BlockCount, in memory ref to block-dispatcher _processedBlockCount\n await this.storeService.incrementBlockCount(tx);\n\n // Need calculate operationHash to ensure correct offset insert all time\n operationHash = this.storeService.getOperationMerkleRoot();\n if (this.nodeConfig.proofOfIndex) {\n //check if operation is null, then poi will not be inserted\n if (!u8aEq(operationHash, NULL_MERKEL_ROOT)) {\n const poiBlock = PoiBlock.create(\n blockHeight,\n blockContent.block.hash,\n operationHash,\n await this.poiService.getLatestPoiBlockHash(),\n this.project.id,\n );\n poiBlockHash = poiBlock.hash;\n await this.storeService.setPoi(poiBlock, { transaction: tx });\n this.poiService.setLatestPoiBlockHash(poiBlockHash);\n await this.storeService.setMetadataBatch(\n [{ key: 'lastPoiHeight', value: blockHeight }],\n { transaction: tx },\n );\n }\n }\n } catch (e) {\n await tx.rollback();\n throw e;\n }\n\n await tx.commit();\n\n return {\n dynamicDsCreated,\n operationHash,\n };\n }\n\n async start(): Promise<void> {\n await this.projectService.init();\n logger.info('indexer manager started');\n }\n\n private filterDataSources(nextProcessingHeight: number): SubqlProjectDs[] {\n const filteredDs = this.projectService.dataSources.filter(\n (ds) => ds.startBlock <= nextProcessingHeight,\n );\n\n if (filteredDs.length === 0) {\n logger.error(\n `Your start block is greater than the current indexed block height in your database. Either change your startBlock (project.yaml) to <= ${nextProcessingHeight}\n or delete your database and start again from the currently specified startBlock`,\n );\n process.exit(1);\n }\n // perform filter for custom ds\n if (!filteredDs.length) {\n logger.error(`Did not find any datasources with associated processor`);\n process.exit(1);\n }\n return filteredDs;\n }\n\n private async indexBlockData(\n { block, logs, transactions }: EthereumBlockWrapper,\n dataSources: SubqlProjectDs[],\n getVM: (d: SubqlProjectDs) => Promise<IndexerSandbox>,\n ): Promise<void> {\n await this.indexBlockContent(block, dataSources, getVM);\n\n for (const log of logs) {\n await this.indexEvent(log, dataSources, getVM);\n }\n\n for (const tx of transactions) {\n await this.indexExtrinsic(tx, dataSources, getVM);\n }\n }\n\n private async indexBlockContent(\n block: EthereumBlock,\n dataSources: SubqlProjectDs[],\n getVM: (d: SubqlProjectDs) => Promise<IndexerSandbox>,\n ): Promise<void> {\n for (const ds of dataSources) {\n await this.indexData(EthereumHandlerKind.Block, block, ds, getVM);\n }\n }\n\n private async indexExtrinsic(\n tx: EthereumTransaction,\n dataSources: SubqlProjectDs[],\n getVM: (d: SubqlProjectDs) => Promise<IndexerSandbox>,\n ): Promise<void> {\n for (const ds of dataSources) {\n await this.indexData(EthereumHandlerKind.Call, tx, ds, getVM);\n }\n }\n\n private async indexEvent(\n log: EthereumLog,\n dataSources: SubqlProjectDs[],\n getVM: (d: SubqlProjectDs) => Promise<IndexerSandbox>,\n ): Promise<void> {\n for (const ds of dataSources) {\n await this.indexData(EthereumHandlerKind.Event, log, ds, getVM);\n }\n }\n\n private async indexData<K extends EthereumHandlerKind>(\n kind: K,\n data: EthereumRuntimeHandlerInputMap[K],\n ds: SubqlProjectDs,\n getVM: (ds: SubqlProjectDs) => Promise<IndexerSandbox>,\n ): Promise<void> {\n let vm: IndexerSandbox;\n if (isRuntimeDs(ds)) {\n const handlers = (ds.mapping.handlers as SubqlRuntimeHandler[]).filter(\n (h) =>\n h.kind === kind &&\n FilterTypeMap[kind](data as any, h.filter as any, ds.options.address),\n );\n\n if (!handlers.length) {\n return;\n }\n const parsedData = await DataAbiParser[kind](this.api)(data, ds);\n\n for (const handler of handlers) {\n vm = vm ?? (await getVM(ds));\n this.nodeConfig.profiler\n ? await profilerWrap(\n vm.securedExec.bind(vm),\n 'handlerPerformance',\n handler.handler,\n )(handler.handler, [parsedData])\n : await vm.securedExec(handler.handler, [parsedData]);\n }\n } else if (isCustomDs(ds)) {\n const handlers = this.filterCustomDsHandlers<K>(\n ds,\n data,\n ProcessorTypeMap[kind],\n (data, baseFilter) => {\n switch (kind) {\n case EthereumHandlerKind.Block:\n return EthereumBlockWrapped.filterBlocksProcessor(\n data as EthereumBlock,\n baseFilter,\n );\n case EthereumHandlerKind.Call:\n return EthereumBlockWrapped.filterTransactionsProcessor(\n data as EthereumTransaction,\n baseFilter,\n );\n case EthereumHandlerKind.Event:\n return EthereumBlockWrapped.filterLogsProcessor(\n data as EthereumLog,\n baseFilter,\n );\n default:\n throw new Error('Unsupported handler kind');\n }\n },\n );\n\n if (!handlers.length) {\n return;\n }\n\n const parsedData = await DataAbiParser[kind](this.api)(data, ds);\n\n for (const handler of handlers) {\n vm = vm ?? (await getVM(ds));\n await this.transformAndExecuteCustomDs(ds, vm, handler, parsedData);\n }\n }\n }\n\n private filterCustomDsHandlers<K extends EthereumHandlerKind>(\n ds: SubqlEthereumCustomDataSource<string, any>,\n data: EthereumRuntimeHandlerInputMap[K],\n baseHandlerCheck: ProcessorTypeMap[K],\n baseFilter: (\n data: EthereumRuntimeHandlerInputMap[K],\n baseFilter: any,\n ) => boolean,\n ): SubqlCustomHandler[] {\n const plugin = this.dsProcessorService.getDsProcessor(ds);\n\n return ds.mapping.handlers\n .filter((handler) => {\n const processor = plugin.handlerProcessors[handler.kind];\n if (baseHandlerCheck(processor)) {\n processor.baseFilter;\n\n return baseFilter(data, processor.baseFilter);\n }\n return false;\n })\n .filter((handler) => {\n const processor = asSecondLayerHandlerProcessor_1_0_0(\n plugin.handlerProcessors[handler.kind],\n );\n\n try {\n return processor.filterProcessor({\n filter: handler.filter,\n input: data,\n ds,\n });\n } catch (e) {\n logger.error(e, 'Failed to run ds processer filter.');\n throw e;\n }\n });\n }\n\n private async transformAndExecuteCustomDs<K extends EthereumHandlerKind>(\n ds: SubqlEthereumCustomDataSource<string, any>,\n vm: IndexerSandbox,\n handler: SubqlCustomHandler,\n data: EthereumRuntimeHandlerInputMap[K],\n ): Promise<void> {\n const plugin = this.dsProcessorService.getDsProcessor(ds);\n const assets = await this.dsProcessorService.getAssets(ds);\n\n const processor = asSecondLayerHandlerProcessor_1_0_0(\n plugin.handlerProcessors[handler.kind],\n );\n\n const transformedData = await processor\n .transformer({\n input: data,\n ds,\n api: this.api,\n filter: handler.filter,\n assets,\n })\n .catch((e) => {\n logger.error(e, 'Failed to transform data with ds processor.');\n throw e;\n });\n\n // We can not run this in parallel. the transformed data items may be dependent on one another.\n // An example of this is with Acala EVM packing multiple EVM logs into a single Substrate event\n for (const _data of transformedData) {\n await vm.securedExec(handler.handler, [_data]);\n }\n }\n}\n\ntype ProcessorTypeMap = {\n [EthereumHandlerKind.Block]: typeof isBlockHandlerProcessor;\n [EthereumHandlerKind.Event]: typeof isEventHandlerProcessor;\n [EthereumHandlerKind.Call]: typeof isCallHandlerProcessor;\n};\n\nconst ProcessorTypeMap = {\n [EthereumHandlerKind.Block]: isBlockHandlerProcessor,\n [EthereumHandlerKind.Event]: isEventHandlerProcessor,\n [EthereumHandlerKind.Call]: isCallHandlerProcessor,\n};\n\nconst FilterTypeMap = {\n [EthereumHandlerKind.Block]: EthereumBlockWrapped.filterBlocksProcessor,\n [EthereumHandlerKind.Event]: EthereumBlockWrapped.filterLogsProcessor,\n [EthereumHandlerKind.Call]: EthereumBlockWrapped.filterTransactionsProcessor,\n};\n\nconst DataAbiParser = {\n [EthereumHandlerKind.Block]: () => (data: EthereumBlock) => data,\n [EthereumHandlerKind.Event]: (api: EthereumApi) => api.parseLog.bind(api),\n [EthereumHandlerKind.Call]: (api: EthereumApi) =>\n api.parseTransaction.bind(api),\n};\n"]}
@@ -0,0 +1,2 @@
1
+ export declare class IndexerModule {
2
+ }
@@ -0,0 +1,52 @@
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.IndexerModule = void 0;
12
+ const common_1 = require("@nestjs/common");
13
+ const node_core_1 = require("@subql/node-core");
14
+ const SubqueryProject_1 = require("../configure/SubqueryProject");
15
+ const ethereum_1 = require("../ethereum");
16
+ const dictionary_service_1 = require("./dictionary.service");
17
+ const ds_processor_service_1 = require("./ds-processor.service");
18
+ const dynamic_ds_service_1 = require("./dynamic-ds.service");
19
+ const indexer_manager_1 = require("./indexer.manager");
20
+ const project_service_1 = require("./project.service");
21
+ const sandbox_service_1 = require("./sandbox.service");
22
+ const worker_service_1 = require("./worker/worker.service");
23
+ let IndexerModule = class IndexerModule {
24
+ };
25
+ IndexerModule = __decorate([
26
+ (0, common_1.Module)({
27
+ providers: [
28
+ indexer_manager_1.IndexerManager,
29
+ node_core_1.StoreService,
30
+ {
31
+ provide: node_core_1.ApiService,
32
+ useFactory: async (project) => {
33
+ const apiService = new ethereum_1.EthereumApiService(project);
34
+ await apiService.init();
35
+ return apiService;
36
+ },
37
+ inject: [SubqueryProject_1.SubqueryProject],
38
+ },
39
+ dictionary_service_1.DictionaryService,
40
+ sandbox_service_1.SandboxService,
41
+ ds_processor_service_1.DsProcessorService,
42
+ dynamic_ds_service_1.DynamicDsService,
43
+ node_core_1.PoiService,
44
+ node_core_1.MmrService,
45
+ project_service_1.ProjectService,
46
+ worker_service_1.WorkerService,
47
+ ],
48
+ exports: [node_core_1.StoreService],
49
+ })
50
+ ], IndexerModule);
51
+ exports.IndexerModule = IndexerModule;
52
+ //# sourceMappingURL=indexer.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexer.module.js","sourceRoot":"","sources":["../../src/indexer/indexer.module.ts"],"names":[],"mappings":";AAAA,gEAAgE;AAChE,sCAAsC;;;;;;;;;AAEtC,2CAAwC;AACxC,gDAK0B;AAC1B,kEAA+D;AAC/D,0CAAiD;AACjD,6DAAyD;AACzD,iEAA4D;AAC5D,6DAAwD;AACxD,uDAAmD;AACnD,uDAAmD;AACnD,uDAAmD;AACnD,4DAAwD;AA0BjD,IAAM,aAAa,GAAnB,MAAM,aAAa;CAAG,CAAA;AAAhB,aAAa;IAxBzB,IAAA,eAAM,EAAC;QACN,SAAS,EAAE;YACT,gCAAc;YACd,wBAAY;YACZ;gBACE,OAAO,EAAE,sBAAU;gBACnB,UAAU,EAAE,KAAK,EAAE,OAAwB,EAAE,EAAE;oBAC7C,MAAM,UAAU,GAAG,IAAI,6BAAkB,CAAC,OAAO,CAAC,CAAC;oBACnD,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;oBACxB,OAAO,UAAU,CAAC;gBACpB,CAAC;gBACD,MAAM,EAAE,CAAC,iCAAe,CAAC;aAC1B;YACD,sCAAiB;YACjB,gCAAc;YACd,yCAAkB;YAClB,qCAAgB;YAChB,sBAAU;YACV,sBAAU;YACV,gCAAc;YACd,8BAAa;SACd;QACD,OAAO,EAAE,CAAC,wBAAY,CAAC;KACxB,CAAC;GACW,aAAa,CAAG;AAAhB,sCAAa","sourcesContent":["// Copyright 2020-2022 OnFinality Limited authors & contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Module } from '@nestjs/common';\nimport {\n ApiService,\n StoreService,\n PoiService,\n MmrService,\n} from '@subql/node-core';\nimport { SubqueryProject } from '../configure/SubqueryProject';\nimport { EthereumApiService } from '../ethereum';\nimport { DictionaryService } from './dictionary.service';\nimport { DsProcessorService } from './ds-processor.service';\nimport { DynamicDsService } from './dynamic-ds.service';\nimport { IndexerManager } from './indexer.manager';\nimport { ProjectService } from './project.service';\nimport { SandboxService } from './sandbox.service';\nimport { WorkerService } from './worker/worker.service';\n\n@Module({\n providers: [\n IndexerManager,\n StoreService,\n {\n provide: ApiService,\n useFactory: async (project: SubqueryProject) => {\n const apiService = new EthereumApiService(project);\n await apiService.init();\n return apiService;\n },\n inject: [SubqueryProject],\n },\n DictionaryService,\n SandboxService,\n DsProcessorService,\n DynamicDsService,\n PoiService,\n MmrService,\n ProjectService,\n WorkerService,\n ],\n exports: [StoreService],\n})\nexport class IndexerModule {}\n"]}
@@ -0,0 +1,40 @@
1
+ import { EventEmitter2 } from '@nestjs/event-emitter';
2
+ import { ApiService, NodeConfig, StoreService, PoiService, MmrService } from '@subql/node-core';
3
+ import { Sequelize } from 'sequelize';
4
+ import { SubqlProjectDs, SubqueryProject } from '../configure/SubqueryProject';
5
+ import { DsProcessorService } from './ds-processor.service';
6
+ import { DynamicDsService } from './dynamic-ds.service';
7
+ export declare class ProjectService {
8
+ private readonly dsProcessorService;
9
+ private readonly apiService;
10
+ private readonly poiService;
11
+ protected readonly mmrService: MmrService;
12
+ private readonly sequelize;
13
+ private readonly project;
14
+ private readonly storeService;
15
+ private readonly nodeConfig;
16
+ private readonly dynamicDsService;
17
+ private eventEmitter;
18
+ private _schema;
19
+ private metadataRepo;
20
+ private _startHeight;
21
+ private _blockOffset;
22
+ constructor(dsProcessorService: DsProcessorService, apiService: ApiService, poiService: PoiService, mmrService: MmrService, sequelize: Sequelize, project: SubqueryProject, storeService: StoreService, nodeConfig: NodeConfig, dynamicDsService: DynamicDsService, eventEmitter: EventEmitter2);
23
+ get schema(): string;
24
+ get dataSources(): SubqlProjectDs[];
25
+ get blockOffset(): number;
26
+ get startHeight(): number;
27
+ private getExistingProjectSchema;
28
+ init(): Promise<void>;
29
+ private ensureProject;
30
+ private createProjectSchema;
31
+ private initDbSchema;
32
+ private ensureMetadata;
33
+ upsertMetadataBlockOffset(height: number): Promise<void>;
34
+ getMetadataBlockOffset(): Promise<number | undefined>;
35
+ getLastProcessedHeight(): Promise<number | undefined>;
36
+ private getStartHeight;
37
+ setBlockOffset(offset: number): Promise<void>;
38
+ getProcessedBlockCount(): Promise<number>;
39
+ private getStartBlockFromDataSources;
40
+ }