@subql/node-ethereum 1.10.1-1 → 1.10.1-2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/configure/SubqueryProject.d.ts +10 -1
- package/dist/configure/SubqueryProject.js +53 -2
- package/dist/configure/SubqueryProject.js.map +1 -1
- package/dist/ethereum/api.ethereum.d.ts +2 -0
- package/dist/ethereum/api.ethereum.js +3 -0
- package/dist/ethereum/api.ethereum.js.map +1 -1
- package/dist/indexer/dynamic-ds.service.d.ts +2 -0
- package/dist/indexer/dynamic-ds.service.js +25 -6
- package/dist/indexer/dynamic-ds.service.js.map +1 -1
- package/dist/indexer/fetch.service.d.ts +1 -0
- package/dist/indexer/fetch.service.js +12 -2
- package/dist/indexer/fetch.service.js.map +1 -1
- package/dist/indexer/indexer.manager.js +4 -8
- package/dist/indexer/indexer.manager.js.map +1 -1
- package/dist/indexer/project.service.d.ts +2 -1
- package/dist/indexer/project.service.js +4 -0
- package/dist/indexer/project.service.js.map +1 -1
- package/package.json +5 -4
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import { RegisteredTypes } from '@polkadot/types/types';
|
|
2
2
|
import { ReaderOptions, RunnerSpecs } from '@subql/common';
|
|
3
|
-
import { EthereumProjectNetworkConfig, SubqlEthereumDataSource, FileType } from '@subql/common-ethereum';
|
|
3
|
+
import { EthereumProjectNetworkConfig, SubqlEthereumDataSource, EthereumBlockFilter, FileType } from '@subql/common-ethereum';
|
|
4
|
+
import Cron from 'cron-converter';
|
|
4
5
|
import { GraphQLSchema } from 'graphql';
|
|
6
|
+
import { EthereumApi } from '../ethereum/api.ethereum';
|
|
5
7
|
export declare type SubqlProjectDs = SubqlEthereumDataSource & {
|
|
6
8
|
mapping: SubqlEthereumDataSource['mapping'] & {
|
|
7
9
|
entryScript: string;
|
|
8
10
|
};
|
|
9
11
|
};
|
|
12
|
+
export declare type SubqlProjectBlockFilter = EthereumBlockFilter & {
|
|
13
|
+
cronSchedule?: {
|
|
14
|
+
schedule: Cron.Seeker;
|
|
15
|
+
next: number;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
10
18
|
export declare type SubqlProjectDsTemplate = Omit<SubqlProjectDs, 'startBlock'> & {
|
|
11
19
|
name: string;
|
|
12
20
|
};
|
|
@@ -27,3 +35,4 @@ export interface SubqueryProjectNetwork {
|
|
|
27
35
|
dictionary?: string;
|
|
28
36
|
chaintypes?: FileType;
|
|
29
37
|
}
|
|
38
|
+
export declare function generateTimestampReferenceForBlockFilters(dataSources: SubqlProjectDs[], api: EthereumApi): Promise<SubqlProjectDs[]>;
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// Copyright 2020-2022 OnFinality Limited authors & contributors
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6
|
+
};
|
|
4
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
exports.SubqueryProject = void 0;
|
|
8
|
+
exports.generateTimestampReferenceForBlockFilters = exports.SubqueryProject = void 0;
|
|
6
9
|
const common_1 = require("@subql/common");
|
|
7
10
|
const common_ethereum_1 = require("@subql/common-ethereum");
|
|
8
11
|
const utils_1 = require("@subql/utils");
|
|
12
|
+
const cron_converter_1 = __importDefault(require("cron-converter"));
|
|
9
13
|
const project_1 = require("../utils/project");
|
|
10
14
|
const NOT_SUPPORT = (name) => {
|
|
11
15
|
throw new Error(`Manifest specVersion ${name}() is not supported`);
|
|
@@ -57,6 +61,7 @@ async function loadProjectFromManifestBase(projectManifest, reader, path, networ
|
|
|
57
61
|
? await (0, project_1.getChainTypes)(reader, root, projectManifest.network.chaintypes.file)
|
|
58
62
|
: undefined;
|
|
59
63
|
const dataSources = await (0, project_1.updateDataSourcesV0_2_0)(projectManifest.dataSources, reader, root);
|
|
64
|
+
const templates = await loadProjectTemplates(projectManifest, root, reader);
|
|
60
65
|
return {
|
|
61
66
|
id: reader.root ? reader.root : path,
|
|
62
67
|
root,
|
|
@@ -64,7 +69,7 @@ async function loadProjectFromManifestBase(projectManifest, reader, path, networ
|
|
|
64
69
|
dataSources,
|
|
65
70
|
schema,
|
|
66
71
|
chainTypes,
|
|
67
|
-
templates
|
|
72
|
+
templates,
|
|
68
73
|
};
|
|
69
74
|
}
|
|
70
75
|
const { name: packageName, version: packageVersion, } = require('../../package.json');
|
|
@@ -79,4 +84,50 @@ async function loadProjectFromManifest1_0_0(projectManifest, reader, path, netwo
|
|
|
79
84
|
}
|
|
80
85
|
return project;
|
|
81
86
|
}
|
|
87
|
+
async function loadProjectTemplates(projectManifest, root, reader) {
|
|
88
|
+
if (projectManifest.templates && projectManifest.templates.length !== 0) {
|
|
89
|
+
const dsTemplates = await (0, project_1.updateDataSourcesV0_2_0)(projectManifest.templates, reader, root);
|
|
90
|
+
return dsTemplates.map((ds, index) => (Object.assign(Object.assign({}, ds), { name: projectManifest.templates[index].name })));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
94
|
+
async function generateTimestampReferenceForBlockFilters(dataSources, api) {
|
|
95
|
+
const cron = new cron_converter_1.default();
|
|
96
|
+
dataSources = await Promise.all(dataSources.map(async (ds) => {
|
|
97
|
+
var _a;
|
|
98
|
+
if ((0, common_ethereum_1.isRuntimeDs)(ds)) {
|
|
99
|
+
const startBlock = (_a = ds.startBlock) !== null && _a !== void 0 ? _a : 1;
|
|
100
|
+
let block;
|
|
101
|
+
let timestampReference;
|
|
102
|
+
ds.mapping.handlers = await Promise.all(ds.mapping.handlers.map(async (handler) => {
|
|
103
|
+
var _a;
|
|
104
|
+
if (handler.kind === common_ethereum_1.EthereumHandlerKind.Block) {
|
|
105
|
+
if ((_a = handler.filter) === null || _a === void 0 ? void 0 : _a.timestamp) {
|
|
106
|
+
if (!block) {
|
|
107
|
+
block = await api.getBlockByHeight(startBlock);
|
|
108
|
+
timestampReference = new Date(block.timestamp * 1000); // Add millis
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
cron.fromString(handler.filter.timestamp);
|
|
112
|
+
}
|
|
113
|
+
catch (e) {
|
|
114
|
+
throw new Error(`Invalid Cron string: ${handler.filter.timestamp}`);
|
|
115
|
+
}
|
|
116
|
+
const schedule = cron.schedule(timestampReference);
|
|
117
|
+
handler.filter.cronSchedule = {
|
|
118
|
+
schedule: schedule,
|
|
119
|
+
get next() {
|
|
120
|
+
return Date.parse(this.schedule.next().format());
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return handler;
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
return ds;
|
|
129
|
+
}));
|
|
130
|
+
return dataSources;
|
|
131
|
+
}
|
|
132
|
+
exports.generateTimestampReferenceForBlockFilters = generateTimestampReferenceForBlockFilters;
|
|
82
133
|
//# sourceMappingURL=SubqueryProject.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubqueryProject.js","sourceRoot":"","sources":["../../src/configure/SubqueryProject.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2020-2022 OnFinality Limited authors & contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport { RegisteredTypes } from '@polkadot/types/types';\nimport {\n ReaderFactory,\n ReaderOptions,\n Reader,\n RunnerSpecs,\n validateSemver,\n} from '@subql/common';\nimport {\n EthereumProjectNetworkConfig,\n parseEthereumProjectManifest,\n SubqlEthereumDataSource,\n FileType,\n ProjectManifestV1_0_0Impl,\n} from '@subql/common-ethereum';\nimport { buildSchemaFromString } from '@subql/utils';\nimport { GraphQLSchema } from 'graphql';\nimport {\n getChainTypes,\n getProjectRoot,\n updateDataSourcesV0_2_0,\n} from '../utils/project';\n\nexport type SubqlProjectDs = SubqlEthereumDataSource & {\n mapping: SubqlEthereumDataSource['mapping'] & { entryScript: string };\n};\n\nexport type SubqlProjectDsTemplate = Omit<SubqlProjectDs, 'startBlock'> & {\n name: string;\n};\n\nconst NOT_SUPPORT = (name: string) => {\n throw new Error(`Manifest specVersion ${name}() is not supported`);\n};\n\nexport class SubqueryProject {\n id: string;\n root: string;\n network: Partial<EthereumProjectNetworkConfig>;\n dataSources: SubqlProjectDs[];\n schema: GraphQLSchema;\n templates: SubqlProjectDsTemplate[];\n chainTypes?: RegisteredTypes;\n runner?: RunnerSpecs;\n\n static async create(\n path: string,\n networkOverrides?: Partial<EthereumProjectNetworkConfig>,\n readerOptions?: ReaderOptions,\n ): Promise<SubqueryProject> {\n // We have to use reader here, because path can be remote or local\n // and the `loadProjectManifest(projectPath)` only support local mode\n const reader = await ReaderFactory.create(path, readerOptions);\n const projectSchema = await reader.getProjectSchema();\n if (projectSchema === undefined) {\n throw new Error(`Get manifest from project path ${path} failed`);\n }\n const manifest = parseEthereumProjectManifest(projectSchema);\n\n if (manifest.isV1_0_0) {\n return loadProjectFromManifest1_0_0(\n manifest.asV1_0_0,\n reader,\n path,\n networkOverrides,\n );\n } else {\n NOT_SUPPORT(manifest.specVersion);\n }\n }\n}\n\nexport interface SubqueryProjectNetwork {\n chainId: string;\n endpoint?: string;\n dictionary?: string;\n chaintypes?: FileType;\n}\n\nfunction processChainId(network: any): SubqueryProjectNetwork {\n if (network.chainId && network.genesisHash) {\n throw new Error('Please only provide one of chainId and genesisHash');\n } else if (network.genesisHash && !network.chainId) {\n network.chainId = network.genesisHash;\n }\n delete network.genesisHash;\n return network;\n}\n\ntype SUPPORT_MANIFEST = ProjectManifestV1_0_0Impl;\n\nasync function loadProjectFromManifestBase(\n projectManifest: SUPPORT_MANIFEST,\n reader: Reader,\n path: string,\n networkOverrides?: Partial<EthereumProjectNetworkConfig>,\n): Promise<SubqueryProject> {\n const root = await getProjectRoot(reader);\n\n const network = processChainId({\n ...projectManifest.network,\n ...networkOverrides,\n });\n\n if (!network.endpoint) {\n throw new Error(\n `Network endpoint must be provided for network. chainId=\"${network.chainId}\"`,\n );\n }\n\n let schemaString: string;\n try {\n schemaString = await reader.getFile(projectManifest.schema.file);\n } catch (e) {\n throw new Error(\n `unable to fetch the schema from ${projectManifest.schema.file}`,\n );\n }\n const schema = buildSchemaFromString(schemaString);\n\n const chainTypes = projectManifest.network.chaintypes\n ? await getChainTypes(reader, root, projectManifest.network.chaintypes.file)\n : undefined;\n\n const dataSources = await updateDataSourcesV0_2_0(\n projectManifest.dataSources,\n reader,\n root,\n );\n return {\n id: reader.root ? reader.root : path, //TODO, need to method to get project_id\n root,\n network,\n dataSources,\n schema,\n chainTypes,\n templates: [],\n };\n}\n\nconst {\n name: packageName,\n version: packageVersion,\n} = require('../../package.json');\n\nasync function loadProjectFromManifest1_0_0(\n projectManifest: ProjectManifestV1_0_0Impl,\n reader: Reader,\n path: string,\n networkOverrides?: Partial<EthereumProjectNetworkConfig>,\n): Promise<SubqueryProject> {\n const project = await loadProjectFromManifestBase(\n projectManifest,\n reader,\n path,\n networkOverrides,\n );\n project.runner = projectManifest.runner;\n if (packageName !== project.runner.node.name) {\n throw new Error(\n `Runner requires ${project.runner.node.name}, current node ${packageName}`,\n );\n }\n if (!validateSemver(packageVersion, project.runner.node.version)) {\n throw new Error(\n `Runner require node version ${project.runner.node.version}, current node ${packageVersion}`,\n );\n }\n return project;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SubqueryProject.js","sourceRoot":"","sources":["../../src/configure/SubqueryProject.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2020-2022 OnFinality Limited authors & contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Block } from '@ethersproject/abstract-provider';\nimport { RegisteredTypes } from '@polkadot/types/types';\nimport {\n ReaderFactory,\n ReaderOptions,\n Reader,\n RunnerSpecs,\n validateSemver,\n} from '@subql/common';\nimport {\n EthereumProjectNetworkConfig,\n parseEthereumProjectManifest,\n SubqlEthereumDataSource,\n EthereumBlockFilter,\n FileType,\n ProjectManifestV1_0_0Impl,\n isRuntimeDs,\n EthereumHandlerKind,\n} from '@subql/common-ethereum';\nimport { buildSchemaFromString } from '@subql/utils';\nimport Cron from 'cron-converter';\nimport { GraphQLSchema } from 'graphql';\nimport { EthereumApi } from '../ethereum/api.ethereum';\nimport {\n getChainTypes,\n getProjectRoot,\n updateDataSourcesV0_2_0,\n} from '../utils/project';\n// import { getBlockByHeight, getTimestamp } from '../utils/substrate';\n\nexport type SubqlProjectDs = SubqlEthereumDataSource & {\n mapping: SubqlEthereumDataSource['mapping'] & { entryScript: string };\n};\n\nexport type SubqlProjectBlockFilter = EthereumBlockFilter & {\n cronSchedule?: {\n schedule: Cron.Seeker;\n next: number;\n };\n};\n\nexport type SubqlProjectDsTemplate = Omit<SubqlProjectDs, 'startBlock'> & {\n name: string;\n};\n\nconst NOT_SUPPORT = (name: string) => {\n throw new Error(`Manifest specVersion ${name}() is not supported`);\n};\n\nexport class SubqueryProject {\n id: string;\n root: string;\n network: Partial<EthereumProjectNetworkConfig>;\n dataSources: SubqlProjectDs[];\n schema: GraphQLSchema;\n templates: SubqlProjectDsTemplate[];\n chainTypes?: RegisteredTypes;\n runner?: RunnerSpecs;\n\n static async create(\n path: string,\n networkOverrides?: Partial<EthereumProjectNetworkConfig>,\n readerOptions?: ReaderOptions,\n ): Promise<SubqueryProject> {\n // We have to use reader here, because path can be remote or local\n // and the `loadProjectManifest(projectPath)` only support local mode\n const reader = await ReaderFactory.create(path, readerOptions);\n const projectSchema = await reader.getProjectSchema();\n if (projectSchema === undefined) {\n throw new Error(`Get manifest from project path ${path} failed`);\n }\n const manifest = parseEthereumProjectManifest(projectSchema);\n\n if (manifest.isV1_0_0) {\n return loadProjectFromManifest1_0_0(\n manifest.asV1_0_0,\n reader,\n path,\n networkOverrides,\n );\n } else {\n NOT_SUPPORT(manifest.specVersion);\n }\n }\n}\n\nexport interface SubqueryProjectNetwork {\n chainId: string;\n endpoint?: string;\n dictionary?: string;\n chaintypes?: FileType;\n}\n\nfunction processChainId(network: any): SubqueryProjectNetwork {\n if (network.chainId && network.genesisHash) {\n throw new Error('Please only provide one of chainId and genesisHash');\n } else if (network.genesisHash && !network.chainId) {\n network.chainId = network.genesisHash;\n }\n delete network.genesisHash;\n return network;\n}\n\ntype SUPPORT_MANIFEST = ProjectManifestV1_0_0Impl;\n\nasync function loadProjectFromManifestBase(\n projectManifest: SUPPORT_MANIFEST,\n reader: Reader,\n path: string,\n networkOverrides?: Partial<EthereumProjectNetworkConfig>,\n): Promise<SubqueryProject> {\n const root = await getProjectRoot(reader);\n\n const network = processChainId({\n ...projectManifest.network,\n ...networkOverrides,\n });\n\n if (!network.endpoint) {\n throw new Error(\n `Network endpoint must be provided for network. chainId=\"${network.chainId}\"`,\n );\n }\n\n let schemaString: string;\n try {\n schemaString = await reader.getFile(projectManifest.schema.file);\n } catch (e) {\n throw new Error(\n `unable to fetch the schema from ${projectManifest.schema.file}`,\n );\n }\n const schema = buildSchemaFromString(schemaString);\n\n const chainTypes = projectManifest.network.chaintypes\n ? await getChainTypes(reader, root, projectManifest.network.chaintypes.file)\n : undefined;\n\n const dataSources = await updateDataSourcesV0_2_0(\n projectManifest.dataSources,\n reader,\n root,\n );\n\n const templates = await loadProjectTemplates(projectManifest, root, reader);\n\n return {\n id: reader.root ? reader.root : path, //TODO, need to method to get project_id\n root,\n network,\n dataSources,\n schema,\n chainTypes,\n templates,\n };\n}\n\nconst {\n name: packageName,\n version: packageVersion,\n} = require('../../package.json');\n\nasync function loadProjectFromManifest1_0_0(\n projectManifest: ProjectManifestV1_0_0Impl,\n reader: Reader,\n path: string,\n networkOverrides?: Partial<EthereumProjectNetworkConfig>,\n): Promise<SubqueryProject> {\n const project = await loadProjectFromManifestBase(\n projectManifest,\n reader,\n path,\n networkOverrides,\n );\n project.runner = projectManifest.runner;\n if (packageName !== project.runner.node.name) {\n throw new Error(\n `Runner requires ${project.runner.node.name}, current node ${packageName}`,\n );\n }\n if (!validateSemver(packageVersion, project.runner.node.version)) {\n throw new Error(\n `Runner require node version ${project.runner.node.version}, current node ${packageVersion}`,\n );\n }\n return project;\n}\n\nasync function loadProjectTemplates(\n projectManifest: ProjectManifestV1_0_0Impl,\n root: string,\n reader: Reader,\n): Promise<SubqlProjectDsTemplate[]> {\n if (projectManifest.templates && projectManifest.templates.length !== 0) {\n const dsTemplates = await updateDataSourcesV0_2_0(\n projectManifest.templates,\n reader,\n root,\n );\n return dsTemplates.map((ds, index) => ({\n ...ds,\n name: projectManifest.templates[index].name,\n }));\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/require-await\nexport async function generateTimestampReferenceForBlockFilters(\n dataSources: SubqlProjectDs[],\n api: EthereumApi,\n): Promise<SubqlProjectDs[]> {\n const cron = new Cron();\n\n dataSources = await Promise.all(\n dataSources.map(async (ds) => {\n if (isRuntimeDs(ds)) {\n const startBlock = ds.startBlock ?? 1;\n let block: Block;\n let timestampReference: Date;\n\n ds.mapping.handlers = await Promise.all(\n ds.mapping.handlers.map(async (handler) => {\n if (handler.kind === EthereumHandlerKind.Block) {\n if (handler.filter?.timestamp) {\n if (!block) {\n block = await api.getBlockByHeight(startBlock);\n timestampReference = new Date(block.timestamp * 1000); // Add millis\n }\n try {\n cron.fromString(handler.filter.timestamp);\n } catch (e) {\n throw new Error(\n `Invalid Cron string: ${handler.filter.timestamp}`,\n );\n }\n\n const schedule = cron.schedule(timestampReference);\n (handler.filter as SubqlProjectBlockFilter).cronSchedule = {\n schedule: schedule,\n get next() {\n return Date.parse(this.schedule.next().format());\n },\n };\n }\n }\n return handler;\n }),\n );\n }\n return ds;\n }),\n );\n\n return dataSources;\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Block } from '@ethersproject/abstract-provider';
|
|
1
2
|
import { RuntimeDataSourceV0_2_0 } from '@subql/common-ethereum';
|
|
2
3
|
import { ApiWrapper, BlockWrapper, EthereumBlockWrapper, EthereumTransaction, EthereumResult, EthereumLog } from '@subql/types-ethereum';
|
|
3
4
|
export declare class EthereumApi implements ApiWrapper<EthereumBlockWrapper> {
|
|
@@ -14,6 +15,7 @@ export declare class EthereumApi implements ApiWrapper<EthereumBlockWrapper> {
|
|
|
14
15
|
getGenesisHash(): string;
|
|
15
16
|
getSpecName(): string;
|
|
16
17
|
getFinalizedBlockHeight(): Promise<number>;
|
|
18
|
+
getBlockByHeight(height: number): Promise<Block>;
|
|
17
19
|
fetchBlocks(bufferBlocks: number[]): Promise<EthereumBlockWrapper[]>;
|
|
18
20
|
freezeApi(processor: any, blockContent: BlockWrapper): void;
|
|
19
21
|
private buildInterface;
|
|
@@ -114,6 +114,9 @@ class EthereumApi {
|
|
|
114
114
|
// Doesn't seem to be a difference between finalized and latest
|
|
115
115
|
return this.client.getBlockNumber();
|
|
116
116
|
}
|
|
117
|
+
async getBlockByHeight(height) {
|
|
118
|
+
return this.client.getBlock(height);
|
|
119
|
+
}
|
|
117
120
|
async fetchBlocks(bufferBlocks) {
|
|
118
121
|
return Promise.all(bufferBlocks.map(async (num) => {
|
|
119
122
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.ethereum.js","sourceRoot":"","sources":["../../src/ethereum/api.ethereum.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 http from 'http';\nimport https from 'https';\nimport { Interface } from '@ethersproject/abi';\nimport { Web3Provider } from '@ethersproject/providers';\nimport { RuntimeDataSourceV0_2_0 } from '@subql/common-ethereum';\nimport { getLogger } from '@subql/node-core';\nimport {\n ApiWrapper,\n BlockWrapper,\n EthereumBlockWrapper,\n EthereumTransaction,\n EthereumResult,\n EthereumLog,\n} from '@subql/types-ethereum';\nimport { hexDataSlice, hexValue } from 'ethers/lib/utils';\nimport { EthereumBlockWrapped } from './block.ethereum';\nimport {\n formatBlock,\n formatReceipt,\n formatTransaction,\n} from './utils.ethereum';\nconst Web3HttpProvider = require('web3-providers-http');\nconst Web3WsProvider = require('web3-providers-ws');\n\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version: packageVersion } = require('../../package.json');\n\nconst logger = getLogger('api.ethereum');\n\nasync function loadAssets(\n ds: RuntimeDataSourceV0_2_0,\n): Promise<Record<string, string>> {\n if (!ds.assets) {\n return {};\n }\n const res: Record<string, string> = {};\n\n for (const [name, { file }] of Object.entries(ds.assets)) {\n try {\n res[name] = await fs.promises.readFile(file, { encoding: 'utf8' });\n } catch (e) {\n throw new Error(`Failed to load datasource asset ${file}`);\n }\n }\n\n return res;\n}\n\nexport class EthereumApi implements ApiWrapper<EthereumBlockWrapper> {\n private client: Web3Provider;\n private genesisBlock: Record<string, any>;\n private contractInterfaces: Record<string, Interface> = {};\n private chainId: number;\n\n constructor(private endpoint: string) {\n const { hostname, pathname, port, protocol, searchParams } = new URL(\n endpoint,\n );\n const httpAgent = new http.Agent({ keepAlive: true, maxSockets: 10 });\n const httpsAgent = new https.Agent({ keepAlive: true, maxSockets: 10 });\n\n const protocolStr = protocol.replace(':', '');\n const portNum = port\n ? parseInt(port, 10)\n : protocolStr === 'https'\n ? undefined\n : 80;\n\n let provider;\n if (protocolStr === 'https' || protocolStr === 'http') {\n const options = {\n keepAlive: true,\n headers: [\n {\n name: 'User-Agent',\n value: `Subquery-Node ${packageVersion}`,\n },\n ],\n agent: {\n http: httpAgent,\n https: httpsAgent,\n },\n };\n if ((searchParams as any).apiKey) {\n (options.headers as any).apiKey = searchParams.get('apiKey');\n }\n provider = new Web3HttpProvider(this.endpoint, options);\n } else if (protocolStr === 'ws' || protocolStr === 'wss') {\n const options = {\n headers: {\n 'User-Agent': `Subquery-Node ${packageVersion}`,\n },\n clientConfig: {\n keepAlive: true,\n },\n };\n if ((searchParams as any).apiKey) {\n (options.headers as any).apiKey = searchParams.get('apiKey');\n }\n\n provider = new Web3WsProvider(endpoint, options);\n } else {\n throw new Error(`Unsupported protocol: ${protocol}`);\n }\n\n this.client = new Web3Provider(provider);\n }\n\n async init(): Promise<void> {\n this.genesisBlock = await this.client.send('eth_getBlockByNumber', [\n hexValue(0),\n true,\n ]);\n logger.info(this.endpoint);\n\n this.chainId = await this.client.send('net_version', []);\n }\n\n async getLastHeight(): Promise<number> {\n return this.client.getBlockNumber();\n }\n\n getRuntimeChain(): string {\n return 'ethereum';\n }\n\n getChainId(): number {\n return this.chainId;\n }\n\n getGenesisHash(): string {\n return this.genesisBlock.hash;\n }\n\n getSpecName(): string {\n return 'ethereum';\n }\n\n async getFinalizedBlockHeight(): Promise<number> {\n // Doesn't seem to be a difference between finalized and latest\n return this.client.getBlockNumber();\n }\n\n async fetchBlocks(bufferBlocks: number[]): Promise<EthereumBlockWrapper[]> {\n return Promise.all(\n bufferBlocks.map(async (num) => {\n try {\n // Fetch Block\n const block_promise = await this.client.send('eth_getBlockByNumber', [\n hexValue(num),\n true,\n ]);\n\n const block = formatBlock(block_promise);\n //const block = this.client.formatter.blockWithTransactions(rawBlock);\n block.stateRoot = this.client.formatter.hash(block.stateRoot);\n // Get transaction receipts\n const transactions = await Promise.all(\n block.transactions.map(async (tx) => {\n //logger.info(JSON.stringify(tx))\n const transaction = formatTransaction(tx);\n const receipt = await this.client.send(\n 'eth_getTransactionReceipt',\n [tx.hash],\n );\n\n transaction.receipt = formatReceipt(receipt, block);\n return transaction;\n }),\n );\n return new EthereumBlockWrapped(block, transactions);\n } catch (e) {\n // Wrap error from an axios error to fix issue with error being undefined\n const error = new Error(e.message);\n logger.error(error, `Failed to fetch block at height ${num}`);\n throw error;\n }\n }),\n );\n }\n\n freezeApi(processor: any, blockContent: BlockWrapper): void {\n processor.freeze(this.client, 'api');\n }\n\n private buildInterface(\n abiName: string,\n assets: Record<string, string>,\n ): Interface | undefined {\n if (!assets[abiName]) {\n throw new Error(`ABI named \"${abiName}\" not referenced in assets`);\n }\n\n // This assumes that all datasources have a different abi name or they are the same abi\n if (!this.contractInterfaces[abiName]) {\n // Constructing the interface validates the ABI\n try {\n let abiObj = JSON.parse(assets[abiName]);\n\n /*\n * Allows parsing JSON artifacts as well as ABIs\n * https://trufflesuite.github.io/artifact-updates/background.html#what-are-artifacts\n */\n if (!Array.isArray(abiObj) && abiObj.abi) {\n abiObj = abiObj.abi;\n }\n\n this.contractInterfaces[abiName] = new Interface(abiObj);\n } catch (e) {\n logger.error(`Unable to parse ABI: ${e.message}`);\n throw new Error('ABI is invalid');\n }\n }\n\n return this.contractInterfaces[abiName];\n }\n\n async parseLog<T extends EthereumResult = EthereumResult>(\n log: EthereumLog,\n ds: RuntimeDataSourceV0_2_0,\n ): Promise<EthereumLog<T> | EthereumLog> {\n try {\n if (!ds?.options?.abi) {\n logger.warn('No ABI provided for datasource');\n return log;\n }\n const iface = this.buildInterface(ds.options.abi, await loadAssets(ds));\n return {\n ...log,\n args: iface?.parseLog(log).args as T,\n };\n } catch (e) {\n logger.warn(`Failed to parse log data: ${e.message}`);\n return log;\n }\n }\n\n async parseTransaction<T extends EthereumResult = EthereumResult>(\n transaction: EthereumTransaction,\n ds: RuntimeDataSourceV0_2_0,\n ): Promise<EthereumTransaction<T> | EthereumTransaction> {\n try {\n if (!ds?.options?.abi) {\n logger.warn('No ABI provided for datasource');\n return transaction;\n }\n const assets = await loadAssets(ds);\n const iface = this.buildInterface(ds.options.abi, assets);\n const func = iface.getFunction(hexDataSlice(transaction.input, 0, 4));\n const args = iface.decodeFunctionData(func, transaction.input) as T;\n return {\n ...transaction,\n args,\n };\n } catch (e) {\n logger.warn(`Failed to parse transaction data: ${e.message}`);\n return transaction;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"api.ethereum.js","sourceRoot":"","sources":["../../src/ethereum/api.ethereum.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 http from 'http';\nimport https from 'https';\nimport { Interface } from '@ethersproject/abi';\nimport { Block } from '@ethersproject/abstract-provider';\nimport { Web3Provider } from '@ethersproject/providers';\nimport { RuntimeDataSourceV0_2_0 } from '@subql/common-ethereum';\nimport { getLogger } from '@subql/node-core';\nimport {\n ApiWrapper,\n BlockWrapper,\n EthereumBlockWrapper,\n EthereumTransaction,\n EthereumResult,\n EthereumLog,\n} from '@subql/types-ethereum';\nimport { hexDataSlice, hexValue } from 'ethers/lib/utils';\nimport { EthereumBlockWrapped } from './block.ethereum';\nimport {\n formatBlock,\n formatReceipt,\n formatTransaction,\n} from './utils.ethereum';\nconst Web3HttpProvider = require('web3-providers-http');\nconst Web3WsProvider = require('web3-providers-ws');\n\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version: packageVersion } = require('../../package.json');\n\nconst logger = getLogger('api.ethereum');\n\nasync function loadAssets(\n ds: RuntimeDataSourceV0_2_0,\n): Promise<Record<string, string>> {\n if (!ds.assets) {\n return {};\n }\n const res: Record<string, string> = {};\n\n for (const [name, { file }] of Object.entries(ds.assets)) {\n try {\n res[name] = await fs.promises.readFile(file, { encoding: 'utf8' });\n } catch (e) {\n throw new Error(`Failed to load datasource asset ${file}`);\n }\n }\n\n return res;\n}\n\nexport class EthereumApi implements ApiWrapper<EthereumBlockWrapper> {\n private client: Web3Provider;\n private genesisBlock: Record<string, any>;\n private contractInterfaces: Record<string, Interface> = {};\n private chainId: number;\n\n constructor(private endpoint: string) {\n const { hostname, pathname, port, protocol, searchParams } = new URL(\n endpoint,\n );\n const httpAgent = new http.Agent({ keepAlive: true, maxSockets: 10 });\n const httpsAgent = new https.Agent({ keepAlive: true, maxSockets: 10 });\n\n const protocolStr = protocol.replace(':', '');\n const portNum = port\n ? parseInt(port, 10)\n : protocolStr === 'https'\n ? undefined\n : 80;\n\n let provider;\n if (protocolStr === 'https' || protocolStr === 'http') {\n const options = {\n keepAlive: true,\n headers: [\n {\n name: 'User-Agent',\n value: `Subquery-Node ${packageVersion}`,\n },\n ],\n agent: {\n http: httpAgent,\n https: httpsAgent,\n },\n };\n if ((searchParams as any).apiKey) {\n (options.headers as any).apiKey = searchParams.get('apiKey');\n }\n provider = new Web3HttpProvider(this.endpoint, options);\n } else if (protocolStr === 'ws' || protocolStr === 'wss') {\n const options = {\n headers: {\n 'User-Agent': `Subquery-Node ${packageVersion}`,\n },\n clientConfig: {\n keepAlive: true,\n },\n };\n if ((searchParams as any).apiKey) {\n (options.headers as any).apiKey = searchParams.get('apiKey');\n }\n\n provider = new Web3WsProvider(endpoint, options);\n } else {\n throw new Error(`Unsupported protocol: ${protocol}`);\n }\n\n this.client = new Web3Provider(provider);\n }\n\n async init(): Promise<void> {\n this.genesisBlock = await this.client.send('eth_getBlockByNumber', [\n hexValue(0),\n true,\n ]);\n logger.info(this.endpoint);\n\n this.chainId = await this.client.send('net_version', []);\n }\n\n async getLastHeight(): Promise<number> {\n return this.client.getBlockNumber();\n }\n\n getRuntimeChain(): string {\n return 'ethereum';\n }\n\n getChainId(): number {\n return this.chainId;\n }\n\n getGenesisHash(): string {\n return this.genesisBlock.hash;\n }\n\n getSpecName(): string {\n return 'ethereum';\n }\n\n async getFinalizedBlockHeight(): Promise<number> {\n // Doesn't seem to be a difference between finalized and latest\n return this.client.getBlockNumber();\n }\n\n async getBlockByHeight(height: number): Promise<Block> {\n return this.client.getBlock(height);\n }\n\n async fetchBlocks(bufferBlocks: number[]): Promise<EthereumBlockWrapper[]> {\n return Promise.all(\n bufferBlocks.map(async (num) => {\n try {\n // Fetch Block\n const block_promise = await this.client.send('eth_getBlockByNumber', [\n hexValue(num),\n true,\n ]);\n\n const block = formatBlock(block_promise);\n //const block = this.client.formatter.blockWithTransactions(rawBlock);\n block.stateRoot = this.client.formatter.hash(block.stateRoot);\n // Get transaction receipts\n const transactions = await Promise.all(\n block.transactions.map(async (tx) => {\n //logger.info(JSON.stringify(tx))\n const transaction = formatTransaction(tx);\n const receipt = await this.client.send(\n 'eth_getTransactionReceipt',\n [tx.hash],\n );\n\n transaction.receipt = formatReceipt(receipt, block);\n return transaction;\n }),\n );\n return new EthereumBlockWrapped(block, transactions);\n } catch (e) {\n // Wrap error from an axios error to fix issue with error being undefined\n const error = new Error(e.message);\n logger.error(error, `Failed to fetch block at height ${num}`);\n throw error;\n }\n }),\n );\n }\n\n freezeApi(processor: any, blockContent: BlockWrapper): void {\n processor.freeze(this.client, 'api');\n }\n\n private buildInterface(\n abiName: string,\n assets: Record<string, string>,\n ): Interface | undefined {\n if (!assets[abiName]) {\n throw new Error(`ABI named \"${abiName}\" not referenced in assets`);\n }\n\n // This assumes that all datasources have a different abi name or they are the same abi\n if (!this.contractInterfaces[abiName]) {\n // Constructing the interface validates the ABI\n try {\n let abiObj = JSON.parse(assets[abiName]);\n\n /*\n * Allows parsing JSON artifacts as well as ABIs\n * https://trufflesuite.github.io/artifact-updates/background.html#what-are-artifacts\n */\n if (!Array.isArray(abiObj) && abiObj.abi) {\n abiObj = abiObj.abi;\n }\n\n this.contractInterfaces[abiName] = new Interface(abiObj);\n } catch (e) {\n logger.error(`Unable to parse ABI: ${e.message}`);\n throw new Error('ABI is invalid');\n }\n }\n\n return this.contractInterfaces[abiName];\n }\n\n async parseLog<T extends EthereumResult = EthereumResult>(\n log: EthereumLog,\n ds: RuntimeDataSourceV0_2_0,\n ): Promise<EthereumLog<T> | EthereumLog> {\n try {\n if (!ds?.options?.abi) {\n logger.warn('No ABI provided for datasource');\n return log;\n }\n const iface = this.buildInterface(ds.options.abi, await loadAssets(ds));\n return {\n ...log,\n args: iface?.parseLog(log).args as T,\n };\n } catch (e) {\n logger.warn(`Failed to parse log data: ${e.message}`);\n return log;\n }\n }\n\n async parseTransaction<T extends EthereumResult = EthereumResult>(\n transaction: EthereumTransaction,\n ds: RuntimeDataSourceV0_2_0,\n ): Promise<EthereumTransaction<T> | EthereumTransaction> {\n try {\n if (!ds?.options?.abi) {\n logger.warn('No ABI provided for datasource');\n return transaction;\n }\n const assets = await loadAssets(ds);\n const iface = this.buildInterface(ds.options.abi, assets);\n const func = iface.getFunction(hexDataSlice(transaction.input, 0, 4));\n const args = iface.decodeFunctionData(func, transaction.input) as T;\n return {\n ...transaction,\n args,\n };\n } catch (e) {\n logger.warn(`Failed to parse transaction data: ${e.message}`);\n return transaction;\n }\n }\n}\n"]}
|
|
@@ -11,11 +11,13 @@ export declare class DynamicDsService {
|
|
|
11
11
|
private readonly dsProcessorService;
|
|
12
12
|
private readonly project;
|
|
13
13
|
private metaDataRepo;
|
|
14
|
+
private tempDsRecords;
|
|
14
15
|
constructor(dsProcessorService: DsProcessorService, project: SubqueryProject);
|
|
15
16
|
init(metaDataRepo: MetadataRepo): void;
|
|
16
17
|
private _datasources;
|
|
17
18
|
createDynamicDatasource(params: DatasourceParams, tx: Transaction): Promise<SubqlProjectDs>;
|
|
18
19
|
getDynamicDatasources(): Promise<SubqlProjectDs[]>;
|
|
20
|
+
deleteTempDsRecords(blockHeight: number): void;
|
|
19
21
|
private getDynamicDatasourceParams;
|
|
20
22
|
private saveDynamicDatasourceParams;
|
|
21
23
|
private getDatasource;
|
|
@@ -19,10 +19,12 @@ const assert_1 = __importDefault(require("assert"));
|
|
|
19
19
|
const common_1 = require("@nestjs/common");
|
|
20
20
|
const common_ethereum_1 = require("@subql/common-ethereum");
|
|
21
21
|
const node_core_1 = require("@subql/node-core");
|
|
22
|
+
const lodash_1 = require("lodash");
|
|
22
23
|
const SubqueryProject_1 = require("../configure/SubqueryProject");
|
|
23
24
|
const ds_processor_service_1 = require("./ds-processor.service");
|
|
24
25
|
const logger = (0, node_core_1.getLogger)('dynamic-ds');
|
|
25
26
|
const METADATA_KEY = 'dynamicDatasources';
|
|
27
|
+
const TEMP_DS_PREFIX = 'ds_';
|
|
26
28
|
let DynamicDsService = class DynamicDsService {
|
|
27
29
|
constructor(dsProcessorService, project) {
|
|
28
30
|
this.dsProcessorService = dsProcessorService;
|
|
@@ -59,22 +61,39 @@ let DynamicDsService = class DynamicDsService {
|
|
|
59
61
|
}
|
|
60
62
|
return this._datasources;
|
|
61
63
|
}
|
|
62
|
-
|
|
64
|
+
deleteTempDsRecords(blockHeight) {
|
|
65
|
+
delete this.tempDsRecords[TEMP_DS_PREFIX + blockHeight];
|
|
66
|
+
}
|
|
67
|
+
async getDynamicDatasourceParams(blockHeight) {
|
|
68
|
+
var _a;
|
|
63
69
|
(0, assert_1.default)(this.metaDataRepo, `Model _metadata does not exist`);
|
|
64
70
|
const record = await this.metaDataRepo.findByPk(METADATA_KEY);
|
|
65
|
-
|
|
71
|
+
let results = record === null || record === void 0 ? void 0 : record.value;
|
|
66
72
|
if (!results || typeof results !== 'string') {
|
|
67
|
-
|
|
73
|
+
if (blockHeight !== undefined) {
|
|
74
|
+
results = (_a = this.tempDsRecords) === null || _a === void 0 ? void 0 : _a[TEMP_DS_PREFIX + blockHeight];
|
|
75
|
+
if (!results || typeof results !== 'string') {
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
68
82
|
}
|
|
69
83
|
return JSON.parse(results);
|
|
70
84
|
}
|
|
71
85
|
async saveDynamicDatasourceParams(dsParams, tx) {
|
|
72
|
-
const existing = await this.getDynamicDatasourceParams();
|
|
86
|
+
const existing = await this.getDynamicDatasourceParams(dsParams.startBlock);
|
|
73
87
|
(0, assert_1.default)(this.metaDataRepo, `Model _metadata does not exist`);
|
|
74
|
-
|
|
88
|
+
const dsRecords = JSON.stringify([...existing, dsParams]);
|
|
89
|
+
await this.metaDataRepo
|
|
90
|
+
.upsert({ key: METADATA_KEY, value: dsRecords }, { transaction: tx })
|
|
91
|
+
.then(() => {
|
|
92
|
+
this.tempDsRecords = Object.assign(Object.assign({}, this.tempDsRecords), { [TEMP_DS_PREFIX + dsParams.startBlock]: dsRecords });
|
|
93
|
+
});
|
|
75
94
|
}
|
|
76
95
|
async getDatasource(params) {
|
|
77
|
-
const template = this.project.templates.find((t) => t.name === params.templateName);
|
|
96
|
+
const template = (0, lodash_1.cloneDeep)(this.project.templates.find((t) => t.name === params.templateName));
|
|
78
97
|
if (!template) {
|
|
79
98
|
throw new Error(`Unable to find matching template in project for name: "${params.templateName}"`);
|
|
80
99
|
}
|
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"dynamic-ds.service.js","sourceRoot":"","sources":["../../src/indexer/dynamic-ds.service.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2020-2022 OnFinality Limited authors & contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport assert from 'assert';\nimport { Injectable } from '@nestjs/common';\nimport { isCustomDs, isRuntimeDs } from '@subql/common-ethereum';\nimport { getLogger, MetadataRepo } from '@subql/node-core';\nimport { cloneDeep } from 'lodash';\nimport { Transaction } from 'sequelize/types';\nimport { SubqlProjectDs, SubqueryProject } from '../configure/SubqueryProject';\nimport { DsProcessorService } from './ds-processor.service';\n\nconst logger = getLogger('dynamic-ds');\n\nconst METADATA_KEY = 'dynamicDatasources';\nconst TEMP_DS_PREFIX = 'ds_';\n\ninterface DatasourceParams {\n templateName: string;\n args?: Record<string, unknown>;\n startBlock: number;\n}\n\n@Injectable()\nexport class DynamicDsService {\n private metaDataRepo: MetadataRepo;\n private tempDsRecords: Record<string, string>;\n\n constructor(\n private readonly dsProcessorService: DsProcessorService,\n private readonly project: SubqueryProject,\n ) {}\n\n init(metaDataRepo: MetadataRepo): void {\n this.metaDataRepo = metaDataRepo;\n }\n\n private _datasources: SubqlProjectDs[];\n\n async createDynamicDatasource(\n params: DatasourceParams,\n tx: Transaction,\n ): Promise<SubqlProjectDs> {\n try {\n const ds = await this.getDatasource(params);\n\n await this.saveDynamicDatasourceParams(params, tx);\n\n logger.info(\n `Created new dynamic datasource from template: \"${params.templateName}\"`,\n );\n\n if (!this._datasources) this._datasources = [];\n this._datasources.push(ds);\n\n return ds;\n } catch (e) {\n logger.error(e.message);\n process.exit(1);\n }\n }\n\n async getDynamicDatasources(): Promise<SubqlProjectDs[]> {\n if (!this._datasources) {\n try {\n const params = await this.getDynamicDatasourceParams();\n\n this._datasources = await Promise.all(\n params.map((params) => this.getDatasource(params)),\n );\n } catch (e) {\n logger.error(`Unable to get dynamic datasources:\\n${e.message}`);\n process.exit(1);\n }\n }\n\n return this._datasources;\n }\n\n deleteTempDsRecords(blockHeight: number) {\n delete this.tempDsRecords[TEMP_DS_PREFIX + blockHeight];\n }\n\n private async getDynamicDatasourceParams(\n blockHeight?: number,\n ): Promise<DatasourceParams[]> {\n assert(this.metaDataRepo, `Model _metadata does not exist`);\n const record = await this.metaDataRepo.findByPk(METADATA_KEY);\n let results = record?.value;\n\n if (!results || typeof results !== 'string') {\n if (blockHeight !== undefined) {\n results = this.tempDsRecords?.[TEMP_DS_PREFIX + blockHeight];\n if (!results || typeof results !== 'string') {\n return [];\n }\n } else {\n return [];\n }\n }\n\n return JSON.parse(results);\n }\n\n private async saveDynamicDatasourceParams(\n dsParams: DatasourceParams,\n tx: Transaction,\n ): Promise<void> {\n const existing = await this.getDynamicDatasourceParams(dsParams.startBlock);\n\n assert(this.metaDataRepo, `Model _metadata does not exist`);\n const dsRecords = JSON.stringify([...existing, dsParams]);\n await this.metaDataRepo\n .upsert({ key: METADATA_KEY, value: dsRecords }, { transaction: tx })\n .then(() => {\n this.tempDsRecords = {\n ...this.tempDsRecords,\n ...{ [TEMP_DS_PREFIX + dsParams.startBlock]: dsRecords },\n };\n });\n }\n\n private async getDatasource(\n params: DatasourceParams,\n ): Promise<SubqlProjectDs> {\n const template = cloneDeep(\n this.project.templates.find((t) => t.name === params.templateName),\n );\n\n if (!template) {\n throw new Error(\n `Unable to find matching template in project for name: \"${params.templateName}\"`,\n );\n }\n\n logger.info(\n `Initialised dynamic datasource from template: \"${params.templateName}\"`,\n );\n\n const dsObj = {\n ...template,\n startBlock: params.startBlock,\n } as SubqlProjectDs;\n delete dsObj.name;\n try {\n if (isCustomDs(dsObj)) {\n dsObj.processor.options = {\n ...dsObj.processor.options,\n ...params.args,\n };\n await this.dsProcessorService.validateCustomDs([dsObj]);\n } else if (isRuntimeDs(dsObj)) {\n // XXX add any modifications to the ds here\n }\n\n return dsObj;\n } catch (e) {\n throw new Error(`Unable to create dynamic datasource.\\n ${e.message}`);\n }\n }\n}\n"]}
|
|
@@ -36,6 +36,7 @@ export declare class FetchService implements OnApplicationShutdown {
|
|
|
36
36
|
startLoop(initBlockHeight: number): Promise<void>;
|
|
37
37
|
getModulos(): number[];
|
|
38
38
|
getModuloBlocks(startHeight: number, endHeight: number): number[];
|
|
39
|
+
getEnqueuedModuloBlocks(startBlockHeight: number): number[];
|
|
39
40
|
fillNextBlockBuffer(initBlockHeight: number): Promise<void>;
|
|
40
41
|
private nextEndBlockHeight;
|
|
41
42
|
private dictionaryValidation;
|
|
@@ -243,9 +243,14 @@ let FetchService = class FetchService {
|
|
|
243
243
|
}
|
|
244
244
|
return moduloBlocks;
|
|
245
245
|
}
|
|
246
|
+
getEnqueuedModuloBlocks(startBlockHeight) {
|
|
247
|
+
return this.getModuloBlocks(startBlockHeight, this.nodeConfig.batchSize * Math.max(...this.getModulos()) +
|
|
248
|
+
startBlockHeight).slice(0, this.nodeConfig.batchSize);
|
|
249
|
+
}
|
|
246
250
|
async fillNextBlockBuffer(initBlockHeight) {
|
|
247
251
|
let startBlockHeight;
|
|
248
252
|
let scaledBatchSize;
|
|
253
|
+
const handlers = [].concat(...this.project.dataSources.map((ds) => ds.mapping.handlers));
|
|
249
254
|
const getStartBlockHeight = () => {
|
|
250
255
|
return this.blockDispatcher.latestBufferedHeight
|
|
251
256
|
? this.blockDispatcher.latestBufferedHeight + 1
|
|
@@ -292,9 +297,13 @@ let FetchService = class FetchService {
|
|
|
292
297
|
this.eventEmitter.emit(node_core_1.IndexerEvent.SkipDictionary);
|
|
293
298
|
}
|
|
294
299
|
}
|
|
295
|
-
// the original method: fill next batch size of blocks
|
|
296
300
|
const endHeight = this.nextEndBlockHeight(startBlockHeight, scaledBatchSize);
|
|
297
|
-
this.
|
|
301
|
+
if (this.getModulos().length === handlers.length) {
|
|
302
|
+
this.blockDispatcher.enqueueBlocks(this.getEnqueuedModuloBlocks(startBlockHeight));
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
this.blockDispatcher.enqueueBlocks((0, lodash_1.range)(startBlockHeight, endHeight + 1));
|
|
306
|
+
}
|
|
298
307
|
}
|
|
299
308
|
}
|
|
300
309
|
nextEndBlockHeight(startBlockHeight, scaledBatchSize) {
|
|
@@ -323,6 +332,7 @@ let FetchService = class FetchService {
|
|
|
323
332
|
}
|
|
324
333
|
async resetForNewDs(blockHeight) {
|
|
325
334
|
await this.syncDynamicDatascourcesFromMeta();
|
|
335
|
+
this.dynamicDsService.deleteTempDsRecords(blockHeight);
|
|
326
336
|
this.updateDictionary();
|
|
327
337
|
this.blockDispatcher.flushQueue(blockHeight);
|
|
328
338
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.service.js","sourceRoot":"","sources":["../../src/indexer/fetch.service.ts"],"names":[],"mappings":";AAAA,gEAAgE;AAChE,sCAAsC;;;;;;;;;;;;;;;AAEtC,2CAA2E;AAC3E,yDAAsD;AACtD,+CAA+D;AAC/D,4DAIgC;AAChC,gDAQ0B;AAO1B,mCAA+C;AAC/C,kEAA+E;AAC/E,+DAA0D;AAC1D,4CAAkE;AAClE,6DAAyD;AACzD,6DAAwD;AAGxD,MAAM,MAAM,GAAG,IAAA,qBAAS,EAAC,OAAO,CAAC,CAAC;AAClC,IAAI,mBAAmB,GAAG,IAAI,CAAC;AAC/B,MAAM,yBAAyB,GAAG,KAAK,CAAC;AACxC,MAAM,qBAAqB,GAAG,KAAK,CAAC;AACpC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAC7B,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAE7B,SAAS,uBAAuB,CAC9B,MAAyB;IAEzB,MAAM,UAAU,GAAG,EAAE,CAAC;IACtB,IAAI,MAAM,CAAC,OAAO,EAAE;QAClB,UAAU,CAAC,IAAI,CAAC;YACd,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE;SACpC,CAAC,CAAC;KACJ;IACD,IAAI,MAAM,CAAC,MAAM,EAAE;QACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YAC1D,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC/B,IAAI,CAAC,KAAK,EAAE;gBACV,SAAS;aACV;YACD,MAAM,KAAK,GAAG,SAAS,CAAC,EAAE,CAAC;YAC3B,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,IAAA,qBAAY,EAAC,KAAK,CAAC,EAAE,CAAC,CAAC;SACxD;KACF;IACD,OAAO;QACL,MAAM,EAAE,SAAS;QACjB,UAAU;KACX,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAC7B,MAAiC;IAEjC,MAAM,UAAU,GAAG,EAAE,CAAC;IACtB,IAAI,MAAM,CAAC,IAAI,EAAE;QACf,UAAU,CAAC,IAAI,CAAC;YACd,KAAK,EAAE,MAAM;YACb,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE;SACjC,CAAC,CAAC;KACJ;IACD,IAAI,MAAM,CAAC,EAAE,EAAE;QACb,UAAU,CAAC,IAAI,CAAC;YACd,KAAK,EAAE,IAAI;YACX,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE;SAC/B,CAAC,CAAC;KACJ;IACD,IAAI,MAAM,CAAC,QAAQ,EAAE;QACnB,UAAU,CAAC,IAAI,CAAC;YACd,KAAK,EAAE,MAAM;YACb,KAAK,EAAE,IAAA,0BAAiB,EAAC,MAAM,CAAC,QAAQ,CAAC;SAC1C,CAAC,CAAC;KACJ;IACD,OAAO;QACL,MAAM,EAAE,iBAAiB;QACzB,UAAU;KACX,CAAC;AACJ,CAAC;AAGM,IAAM,YAAY,GAAlB,MAAM,YAAY;IASvB,YACU,UAAsB,EACtB,UAAsB,EACtB,OAAwB,EACI,eAAiC,EAC7D,iBAAoC,EACpC,gBAAkC,EAClC,YAA2B,EAC3B,iBAAoC;QAPpC,eAAU,GAAV,UAAU,CAAY;QACtB,eAAU,GAAV,UAAU,CAAY;QACtB,YAAO,GAAP,OAAO,CAAiB;QACI,oBAAe,GAAf,eAAe,CAAkB;QAC7D,sBAAiB,GAAjB,iBAAiB,CAAmB;QACpC,qBAAgB,GAAhB,gBAAgB,CAAkB;QAClC,iBAAY,GAAZ,YAAY,CAAe;QAC3B,sBAAiB,GAAjB,iBAAiB,CAAmB;QAdtC,eAAU,GAAG,KAAK,CAAC;QAgBzB,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED,qBAAqB;QACnB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;IACzB,CAAC;IAED,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,+BAA+B;QACnC,IAAI,CAAC,yBAAyB;YAC5B,MAAM,IAAI,CAAC,gBAAgB,CAAC,qBAAqB,EAAE,CAAC;IACxD,CAAC;IAED,6EAA6E;IAC7E,yBAAyB;QACvB,MAAM,YAAY,GAA2B,EAAE,CAAC;QAEhD,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;QAC7C,KAAK,MAAM,EAAE,IAAI,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,EAAE;YACnE,KAAK,MAAM,OAAO,IAAI,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE;gBACzC,IAAI,UAAgC,CAAC;gBACrC,UAAU,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBAC9B,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;gBACzC,IAAI,CAAC,UAAU,CAAC,MAAM;oBAAE,OAAO,EAAE,CAAC;gBAClC,QAAQ,OAAO,CAAC,IAAI,EAAE;oBACpB,KAAK,qCAAmB,CAAC,KAAK;wBAC5B,OAAO,EAAE,CAAC;oBACZ,KAAK,qCAAmB,CAAC,IAAI,CAAC,CAAC;wBAC7B,KAAK,MAAM,MAAM,IAAI,UAAyC,EAAE;4BAC9D,IACE,MAAM,CAAC,IAAI,KAAK,SAAS;gCACzB,MAAM,CAAC,EAAE,KAAK,SAAS;gCACvB,MAAM,CAAC,QAAQ,EACf;gCACA,YAAY,CAAC,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,CAAC;6BACnD;iCAAM;gCACL,OAAO,EAAE,CAAC;6BACX;yBACF;wBACD,MAAM;qBACP;oBACD,KAAK,qCAAmB,CAAC,KAAK,CAAC,CAAC;wBAC9B,KAAK,MAAM,MAAM,IAAI,UAAiC,EAAE;4BACtD,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE;gCACnC,YAAY,CAAC,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC,CAAC;6BACpD;iCAAM;gCACL,OAAO,EAAE,CAAC;6BACX;yBACF;wBACD,MAAM;qBACP;oBACD,QAAQ;iBACT;aACF;SACF;QAED,OAAO,IAAA,eAAM,EACX,YAAY,EACZ,CAAC,IAAI,EAAE,EAAE,CACP,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS,CAC9B,IAAA,eAAM,EAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CACxC,EAAE,CACN,CAAC;IACJ,CAAC;IAED,gBAAgB;;QACd,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,yBAAyB,EAAE,CAAC;QAC/D,IAAI,CAAC,aAAa;YAChB,CAAC,CAAC,CAAA,MAAA,IAAI,CAAC,sBAAsB,0CAAE,MAAM,CAAA;gBACrC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,WAAmB;QAC5B,IAAI,IAAI,CAAC,GAAG,EAAE;YACZ,MAAM,cAAc,GAAG,IAAA,6BAAY,EAAC,IAAI,CAAC,GAAG,CAAC,GAAG,gBAAgB,CAAC;YAEjE,mBAAmB,GAAG,IAAI,CAAC,GAAG,CAAC,mBAAmB,EAAE,cAAc,CAAC,CAAC;YAEpE,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAChC,oBAAoB,EACpB,WAAW,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,gBAAgB,EAAE,EAAE,mBAAmB,CAAC,CACrE,CAAC;SACH;QACD,MAAM,IAAI,CAAC,+BAA+B,EAAE,CAAC;QAC7C,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,wBAAY,CAAC,eAAe,EAAE;YACnD,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;SAClC,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;QACnC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAE9B,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAE/D,KAAK,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC;IAGD,eAAe;QACb,IAAI,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE;YACvC,MAAM,KAAK,GAAG,IAAA,4BAAgB,EAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;YAErE,IAAI,IAAI,CAAC,cAAc,KAAK,KAAK,EAAE;gBACjC,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;aAC7B;SACF;IACH,CAAC;IAGK,AAAN,KAAK,CAAC,qBAAqB;QACzB,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;YACb,MAAM,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;YAC9D,OAAO;SACR;QACD,IAAI;YACF,MAAM,sBAAsB,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,uBAAuB,EAAE,CAAC;YACxE,IAAI,IAAI,CAAC,qBAAqB,KAAK,sBAAsB,EAAE;gBACzD,IAAI,CAAC,qBAAqB,GAAG,sBAAsB,CAAC;gBACpD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,wBAAY,CAAC,WAAW,EAAE;oBAC/C,MAAM,EAAE,IAAI,CAAC,qBAAqB;iBACnC,CAAC,CAAC;aACJ;SACF;QAAC,OAAO,CAAC,EAAE;YACV,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,2CAA2C,CAAC,CAAC;SAC9D;IACH,CAAC;IAGK,AAAN,KAAK,CAAC,gBAAgB;QACpB,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;YACb,MAAM,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;YACzD,OAAO;SACR;QACD,IAAI;YACF,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YACzD,IAAI,IAAI,CAAC,gBAAgB,KAAK,iBAAiB,EAAE;gBAC/C,IAAI,CAAC,gBAAgB,GAAG,iBAAiB,CAAC;gBAC1C,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,wBAAY,CAAC,SAAS,EAAE;oBAC7C,MAAM,EAAE,IAAI,CAAC,gBAAgB;iBAC9B,CAAC,CAAC;aACJ;SACF;QAAC,OAAO,CAAC,EAAE;YACV,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,sCAAsC,CAAC,CAAC;SACzD;IACH,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,eAAuB;QACrC,MAAM,IAAI,CAAC,mBAAmB,CAAC,eAAe,CAAC,CAAC;IAClD,CAAC;IAED,UAAU;QACR,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE;YACzC,IAAI,IAAA,4BAAU,EAAC,EAAE,CAAC,EAAE;gBAClB,SAAS;aACV;YACD,KAAK,MAAM,OAAO,IAAI,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE;gBACzC,IACE,OAAO,CAAC,IAAI,KAAK,qCAAmB,CAAC,KAAK;oBAC1C,OAAO,CAAC,MAAM;oBACd,OAAO,CAAC,MAAM,CAAC,MAAM,EACrB;oBACA,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;iBACrC;aACF;SACF;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,eAAe,CAAC,WAAmB,EAAE,SAAiB;QACpD,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAClC,MAAM,YAAY,GAAa,EAAE,CAAC;QAClC,KAAK,IAAI,CAAC,GAAG,WAAW,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE;YAC5C,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE;gBACpC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aACtB;SACF;QACD,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,mBAAmB,CAAC,eAAuB;QAC/C,IAAI,gBAAwB,CAAC;QAC7B,IAAI,eAAuB,CAAC;QAE5B,MAAM,mBAAmB,GAAG,GAAW,EAAE;YACvC,OAAO,IAAI,CAAC,eAAe,CAAC,oBAAoB;gBAC9C,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,oBAAoB,GAAG,CAAC;gBAC/C,CAAC,CAAC,eAAe,CAAC;QACtB,CAAC,CAAC;QAEF,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE;YACvB,gBAAgB,GAAG,mBAAmB,EAAE,CAAC;YAEzC,eAAe,GAAG,IAAI,CAAC,GAAG,CACxB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAC3D,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,CAAC,UAAU,CAAC,SAAS,GAAG,CAAC,CAAC,CAC5D,CAAC;YAEF,IACE,IAAI,CAAC,eAAe,CAAC,QAAQ,GAAG,eAAe;gBAC/C,gBAAgB,GAAG,IAAI,CAAC,qBAAqB,EAC7C;gBACA,MAAM,IAAA,iBAAK,EAAC,CAAC,CAAC,CAAC;gBACf,SAAS;aACV;YACD,IAAI,IAAI,CAAC,aAAa,EAAE;gBACtB,MAAM,aAAa,GAAG,gBAAgB,GAAG,yBAAyB,CAAC;gBACnE,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CACvC,gBAAgB,EAChB,aAAa,CACd,CAAC;gBACF,IAAI;oBACF,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAC3D,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,IAAI,CAAC,sBAAsB,CAC5B,CAAC;oBAEF,IAAI,gBAAgB,KAAK,mBAAmB,EAAE,EAAE;wBAC9C,MAAM,CAAC,KAAK,CACV,gEAAgE,CACjE,CAAC;wBACF,SAAS;qBACV;oBAED,IACE,UAAU;wBACV,IAAI,CAAC,oBAAoB,CAAC,UAAU,EAAE,gBAAgB,CAAC,EACvD;wBACA,IAAI,EAAE,WAAW,EAAE,GAAG,UAAU,CAAC;wBACjC,WAAW,GAAG,WAAW;6BACtB,MAAM,CAAC,YAAY,CAAC;6BACpB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;wBACzB,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE;4BAC5B,iFAAiF;4BACjF,IAAI,CAAC,eAAe,CAAC,oBAAoB,GAAG,IAAI,CAAC,GAAG,CAClD,aAAa,GAAG,CAAC,EACjB,UAAU,CAAC,SAAS,CAAC,mBAAmB,CACzC,CAAC;yBACH;6BAAM;4BACL,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAC3B,WAAW,CAAC,MAAM,EAClB,IAAI,CAAC,eAAe,CAAC,QAAQ,CAC9B,CAAC;4BACF,WAAW,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;4BACjD,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;yBACjD;wBACD,SAAS,CAAC,4BAA4B;qBACvC;oBACD,iCAAiC;iBAClC;gBAAC,OAAO,CAAC,EAAE;oBACV,MAAM,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;oBACvD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,wBAAY,CAAC,cAAc,CAAC,CAAC;iBACrD;aACF;YACD,sDAAsD;YACtD,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,CACvC,gBAAgB,EAChB,eAAe,CAChB,CAAC;YACF,IAAI,CAAC,eAAe,CAAC,aAAa,CAChC,IAAA,cAAK,EAAC,gBAAgB,EAAE,SAAS,GAAG,CAAC,CAAC,CACvC,CAAC;SACH;IACH,CAAC;IAEO,kBAAkB,CACxB,gBAAwB,EACxB,eAAuB;QAEvB,IAAI,cAAc,GAAG,gBAAgB,GAAG,eAAe,GAAG,CAAC,CAAC;QAE5D,IAAI,cAAc,GAAG,IAAI,CAAC,qBAAqB,EAAE;YAC/C,cAAc,GAAG,IAAI,CAAC,qBAAqB,CAAC;SAC7C;QACD,OAAO,cAAc,CAAC;IACxB,CAAC;IAEO,oBAAoB,CAC1B,EAAE,SAAS,EAAE,QAAQ,EAAc,EACnC,gBAAwB;QAExB,IAAI,QAAQ,CAAC,WAAW,KAAK,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,EAAE;YACtD,MAAM,CAAC,KAAK,CACV,+KAA+K,CAChL,CAAC;YACF,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;YAC3B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,wBAAY,CAAC,eAAe,EAAE;gBACnD,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;aAClC,CAAC,CAAC;YACH,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,wBAAY,CAAC,cAAc,CAAC,CAAC;YACpD,OAAO,KAAK,CAAC;SACd;QACD,IAAI,QAAQ,CAAC,mBAAmB,GAAG,gBAAgB,EAAE;YACnD,MAAM,CAAC,IAAI,CACT,kEAAkE,CACnE,CAAC;YACF,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,wBAAY,CAAC,cAAc,CAAC,CAAC;YACpD,OAAO,KAAK,CAAC;SACd;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,WAAmB;QACrC,MAAM,IAAI,CAAC,+BAA+B,EAAE,CAAC;QAC7C,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;IAC/C,CAAC;CACF,CAAA;AApNC;IAAC,IAAA,mBAAQ,EAAC,qBAAqB,CAAC;;;;mDAS/B;AAGK;IADL,IAAA,mBAAQ,EAAC,mBAAmB,GAAG,IAAI,CAAC;;;;yDAiBpC;AAGK;IADL,IAAA,mBAAQ,EAAC,mBAAmB,GAAG,IAAI,CAAC;;;;oDAiBpC;AArKU,YAAY;IADxB,IAAA,mBAAU,GAAE;IAcR,WAAA,IAAA,eAAM,EAAC,kBAAkB,CAAC,CAAA;qCAHP,sBAAU;QACV,sBAAU;QACb,iCAAe,UAEL,sCAAiB;QAClB,qCAAgB;QACpB,6BAAa;QACR,4BAAiB;GAjBnC,YAAY,CA0UxB;AA1UY,oCAAY","sourcesContent":["// Copyright 2020-2022 OnFinality Limited authors & contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport { Interval, SchedulerRegistry } from '@nestjs/schedule';\nimport {\n isCustomDs,\n EthereumHandlerKind,\n SubqlHandlerFilter,\n} from '@subql/common-ethereum';\nimport {\n ApiService,\n Dictionary,\n delay,\n checkMemoryUsage,\n NodeConfig,\n IndexerEvent,\n getLogger,\n} from '@subql/node-core';\nimport {\n DictionaryQueryEntry,\n ApiWrapper,\n EthereumLogFilter,\n EthereumTransactionFilter,\n} from '@subql/types-ethereum';\nimport { range, sortBy, uniqBy } from 'lodash';\nimport { SubqlProjectDs, SubqueryProject } from '../configure/SubqueryProject';\nimport { calcInterval } from '../ethereum/utils.ethereum';\nimport { eventToTopic, functionToSighash } from '../utils/string';\nimport { DictionaryService } from './dictionary.service';\nimport { DynamicDsService } from './dynamic-ds.service';\nimport { IBlockDispatcher } from './worker/block-dispatcher.service';\n\nconst logger = getLogger('fetch');\nlet BLOCK_TIME_VARIANCE = 5000;\nconst DICTIONARY_MAX_QUERY_SIZE = 10000;\nconst CHECK_MEMORY_INTERVAL = 60000;\nconst MINIMUM_BATCH_SIZE = 5;\nconst INTERVAL_PERCENT = 0.9;\n\nfunction eventFilterToQueryEntry(\n filter: EthereumLogFilter,\n): DictionaryQueryEntry {\n const conditions = [];\n if (filter.address) {\n conditions.push({\n field: 'address',\n value: filter.address.toLowerCase(),\n });\n }\n if (filter.topics) {\n for (let i = 0; i < Math.min(filter.topics.length, 4); i++) {\n const topic = filter.topics[i];\n if (!topic) {\n continue;\n }\n const field = `topics${i}`;\n conditions.push({ field, value: eventToTopic(topic) });\n }\n }\n return {\n entity: 'evmLogs',\n conditions,\n };\n}\n\nfunction callFilterToQueryEntry(\n filter: EthereumTransactionFilter,\n): DictionaryQueryEntry {\n const conditions = [];\n if (filter.from) {\n conditions.push({\n field: 'from',\n value: filter.from.toLowerCase(),\n });\n }\n if (filter.to) {\n conditions.push({\n field: 'to',\n value: filter.to.toLowerCase(),\n });\n }\n if (filter.function) {\n conditions.push({\n field: 'func',\n value: functionToSighash(filter.function),\n });\n }\n return {\n entity: 'evmTransactions',\n conditions,\n };\n}\n\n@Injectable()\nexport class FetchService implements OnApplicationShutdown {\n private latestBestHeight: number;\n private latestFinalizedHeight: number;\n private isShutdown = false;\n private useDictionary: boolean;\n private dictionaryQueryEntries?: DictionaryQueryEntry[];\n private batchSizeScale: number;\n private templateDynamicDatasouces: SubqlProjectDs[];\n\n constructor(\n private apiService: ApiService,\n private nodeConfig: NodeConfig,\n private project: SubqueryProject,\n @Inject('IBlockDispatcher') private blockDispatcher: IBlockDispatcher,\n private dictionaryService: DictionaryService,\n private dynamicDsService: DynamicDsService,\n private eventEmitter: EventEmitter2,\n private schedulerRegistry: SchedulerRegistry,\n ) {\n this.batchSizeScale = 1;\n }\n\n onApplicationShutdown(): void {\n this.isShutdown = true;\n }\n\n get api(): ApiWrapper {\n return this.apiService.api;\n }\n\n async syncDynamicDatascourcesFromMeta(): Promise<void> {\n this.templateDynamicDatasouces =\n await this.dynamicDsService.getDynamicDatasources();\n }\n\n // TODO: if custom ds doesn't support dictionary, use baseFilter, if yes, let\n getDictionaryQueryEntries(): DictionaryQueryEntry[] {\n const queryEntries: DictionaryQueryEntry[] = [];\n\n const dataSources = this.project.dataSources;\n for (const ds of dataSources.concat(this.templateDynamicDatasouces)) {\n for (const handler of ds.mapping.handlers) {\n let filterList: SubqlHandlerFilter[];\n filterList = [handler.filter];\n filterList = filterList.filter((f) => f);\n if (!filterList.length) return [];\n switch (handler.kind) {\n case EthereumHandlerKind.Block:\n return [];\n case EthereumHandlerKind.Call: {\n for (const filter of filterList as EthereumTransactionFilter[]) {\n if (\n filter.from !== undefined ||\n filter.to !== undefined ||\n filter.function\n ) {\n queryEntries.push(callFilterToQueryEntry(filter));\n } else {\n return [];\n }\n }\n break;\n }\n case EthereumHandlerKind.Event: {\n for (const filter of filterList as EthereumLogFilter[]) {\n if (filter.address || filter.topics) {\n queryEntries.push(eventFilterToQueryEntry(filter));\n } else {\n return [];\n }\n }\n break;\n }\n default:\n }\n }\n }\n\n return uniqBy(\n queryEntries,\n (item) =>\n `${item.entity}|${JSON.stringify(\n sortBy(item.conditions, (c) => c.field),\n )}`,\n );\n }\n\n updateDictionary(): void {\n this.dictionaryQueryEntries = this.getDictionaryQueryEntries();\n this.useDictionary =\n !!this.dictionaryQueryEntries?.length &&\n !!this.project.network.dictionary;\n }\n\n async init(startHeight: number): Promise<void> {\n if (this.api) {\n const CHAIN_INTERVAL = calcInterval(this.api) * INTERVAL_PERCENT;\n\n BLOCK_TIME_VARIANCE = Math.min(BLOCK_TIME_VARIANCE, CHAIN_INTERVAL);\n\n this.schedulerRegistry.addInterval(\n 'getLatestBlockHead',\n setInterval(() => void this.getBestBlockHead(), BLOCK_TIME_VARIANCE),\n );\n }\n await this.syncDynamicDatascourcesFromMeta();\n this.updateDictionary();\n this.eventEmitter.emit(IndexerEvent.UsingDictionary, {\n value: Number(this.useDictionary),\n });\n await this.getFinalizedBlockHead();\n await this.getBestBlockHead();\n\n await this.blockDispatcher.init(this.resetForNewDs.bind(this));\n\n void this.startLoop(startHeight);\n }\n\n @Interval(CHECK_MEMORY_INTERVAL)\n checkBatchScale(): void {\n if (this.nodeConfig['scale-batch-size']) {\n const scale = checkMemoryUsage(this.batchSizeScale, this.nodeConfig);\n\n if (this.batchSizeScale !== scale) {\n this.batchSizeScale = scale;\n }\n }\n }\n\n @Interval(BLOCK_TIME_VARIANCE * 1000)\n async getFinalizedBlockHead(): Promise<void> {\n if (!this.api) {\n logger.debug(`Skip fetch finalized block until API is ready`);\n return;\n }\n try {\n const currentFinalizedHeight = await this.api.getFinalizedBlockHeight();\n if (this.latestFinalizedHeight !== currentFinalizedHeight) {\n this.latestFinalizedHeight = currentFinalizedHeight;\n this.eventEmitter.emit(IndexerEvent.BlockTarget, {\n height: this.latestFinalizedHeight,\n });\n }\n } catch (e) {\n logger.error(e, `Having a problem when get finalized block`);\n }\n }\n\n @Interval(BLOCK_TIME_VARIANCE * 1000)\n async getBestBlockHead(): Promise<void> {\n if (!this.api) {\n logger.debug(`Skip fetch best block until API is ready`);\n return;\n }\n try {\n const currentBestHeight = await this.api.getLastHeight();\n if (this.latestBestHeight !== currentBestHeight) {\n this.latestBestHeight = currentBestHeight;\n this.eventEmitter.emit(IndexerEvent.BlockBest, {\n height: this.latestBestHeight,\n });\n }\n } catch (e) {\n logger.error(e, `Having a problem when get best block`);\n }\n }\n\n async startLoop(initBlockHeight: number): Promise<void> {\n await this.fillNextBlockBuffer(initBlockHeight);\n }\n\n getModulos(): number[] {\n const modulos: number[] = [];\n for (const ds of this.project.dataSources) {\n if (isCustomDs(ds)) {\n continue;\n }\n for (const handler of ds.mapping.handlers) {\n if (\n handler.kind === EthereumHandlerKind.Block &&\n handler.filter &&\n handler.filter.modulo\n ) {\n modulos.push(handler.filter.modulo);\n }\n }\n }\n return modulos;\n }\n\n getModuloBlocks(startHeight: number, endHeight: number): number[] {\n const modulos = this.getModulos();\n const moduloBlocks: number[] = [];\n for (let i = startHeight; i < endHeight; i++) {\n if (modulos.find((m) => i % m === 0)) {\n moduloBlocks.push(i);\n }\n }\n return moduloBlocks;\n }\n\n async fillNextBlockBuffer(initBlockHeight: number): Promise<void> {\n let startBlockHeight: number;\n let scaledBatchSize: number;\n\n const getStartBlockHeight = (): number => {\n return this.blockDispatcher.latestBufferedHeight\n ? this.blockDispatcher.latestBufferedHeight + 1\n : initBlockHeight;\n };\n\n while (!this.isShutdown) {\n startBlockHeight = getStartBlockHeight();\n\n scaledBatchSize = Math.max(\n Math.round(this.batchSizeScale * this.nodeConfig.batchSize),\n Math.min(MINIMUM_BATCH_SIZE, this.nodeConfig.batchSize * 3),\n );\n\n if (\n this.blockDispatcher.freeSize < scaledBatchSize ||\n startBlockHeight > this.latestFinalizedHeight\n ) {\n await delay(1);\n continue;\n }\n if (this.useDictionary) {\n const queryEndBlock = startBlockHeight + DICTIONARY_MAX_QUERY_SIZE;\n const moduloBlocks = this.getModuloBlocks(\n startBlockHeight,\n queryEndBlock,\n );\n try {\n const dictionary = await this.dictionaryService.getDictionary(\n startBlockHeight,\n queryEndBlock,\n scaledBatchSize,\n this.dictionaryQueryEntries,\n );\n\n if (startBlockHeight !== getStartBlockHeight()) {\n logger.debug(\n `Queue was reset for new DS, discarding dictionary query result`,\n );\n continue;\n }\n\n if (\n dictionary &&\n this.dictionaryValidation(dictionary, startBlockHeight)\n ) {\n let { batchBlocks } = dictionary;\n batchBlocks = batchBlocks\n .concat(moduloBlocks)\n .sort((a, b) => a - b);\n if (batchBlocks.length === 0) {\n // There we're no blocks in this query range, we can set a new height we're up to\n this.blockDispatcher.latestBufferedHeight = Math.min(\n queryEndBlock - 1,\n dictionary._metadata.lastProcessedHeight,\n );\n } else {\n const maxBlockSize = Math.min(\n batchBlocks.length,\n this.blockDispatcher.freeSize,\n );\n batchBlocks = batchBlocks.slice(0, maxBlockSize);\n this.blockDispatcher.enqueueBlocks(batchBlocks);\n }\n continue; // skip nextBlockRange() way\n }\n // else use this.nextBlockRange()\n } catch (e) {\n logger.debug(`Fetch dictionary stopped: ${e.message}`);\n this.eventEmitter.emit(IndexerEvent.SkipDictionary);\n }\n }\n // the original method: fill next batch size of blocks\n const endHeight = this.nextEndBlockHeight(\n startBlockHeight,\n scaledBatchSize,\n );\n this.blockDispatcher.enqueueBlocks(\n range(startBlockHeight, endHeight + 1),\n );\n }\n }\n\n private nextEndBlockHeight(\n startBlockHeight: number,\n scaledBatchSize: number,\n ): number {\n let endBlockHeight = startBlockHeight + scaledBatchSize - 1;\n\n if (endBlockHeight > this.latestFinalizedHeight) {\n endBlockHeight = this.latestFinalizedHeight;\n }\n return endBlockHeight;\n }\n\n private dictionaryValidation(\n { _metadata: metaData }: Dictionary,\n startBlockHeight: number,\n ): boolean {\n if (metaData.genesisHash !== this.api.getGenesisHash()) {\n logger.error(\n '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',\n );\n this.useDictionary = false;\n this.eventEmitter.emit(IndexerEvent.UsingDictionary, {\n value: Number(this.useDictionary),\n });\n this.eventEmitter.emit(IndexerEvent.SkipDictionary);\n return false;\n }\n if (metaData.lastProcessedHeight < startBlockHeight) {\n logger.warn(\n `Dictionary indexed block is behind current indexing block height`,\n );\n this.eventEmitter.emit(IndexerEvent.SkipDictionary);\n return false;\n }\n return true;\n }\n\n async resetForNewDs(blockHeight: number): Promise<void> {\n await this.syncDynamicDatascourcesFromMeta();\n this.updateDictionary();\n this.blockDispatcher.flushQueue(blockHeight);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"fetch.service.js","sourceRoot":"","sources":["../../src/indexer/fetch.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 { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport { Interval, SchedulerRegistry } from '@nestjs/schedule';\nimport {\n isCustomDs,\n EthereumHandlerKind,\n SubqlHandlerFilter,\n} from '@subql/common-ethereum';\nimport {\n ApiService,\n Dictionary,\n checkMemoryUsage,\n delay,\n getLogger,\n IndexerEvent,\n NodeConfig,\n} from '@subql/node-core';\nimport {\n DictionaryQueryEntry,\n ApiWrapper,\n EthereumLogFilter,\n EthereumTransactionFilter,\n} from '@subql/types-ethereum';\nimport { range, sortBy, uniqBy } from 'lodash';\nimport { SubqlProjectDs, SubqueryProject } from '../configure/SubqueryProject';\nimport { calcInterval } from '../ethereum/utils.ethereum';\nimport { eventToTopic, functionToSighash } from '../utils/string';\nimport { DictionaryService } from './dictionary.service';\nimport { DynamicDsService } from './dynamic-ds.service';\nimport { IBlockDispatcher } from './worker/block-dispatcher.service';\n\nconst logger = getLogger('fetch');\nlet BLOCK_TIME_VARIANCE = 5000;\nconst DICTIONARY_MAX_QUERY_SIZE = 10000;\nconst CHECK_MEMORY_INTERVAL = 60000;\nconst MINIMUM_BATCH_SIZE = 5;\nconst INTERVAL_PERCENT = 0.9;\n\nfunction eventFilterToQueryEntry(\n filter: EthereumLogFilter,\n): DictionaryQueryEntry {\n const conditions = [];\n if (filter.address) {\n conditions.push({\n field: 'address',\n value: filter.address.toLowerCase(),\n });\n }\n if (filter.topics) {\n for (let i = 0; i < Math.min(filter.topics.length, 4); i++) {\n const topic = filter.topics[i];\n if (!topic) {\n continue;\n }\n const field = `topics${i}`;\n conditions.push({ field, value: eventToTopic(topic) });\n }\n }\n return {\n entity: 'evmLogs',\n conditions,\n };\n}\n\nfunction callFilterToQueryEntry(\n filter: EthereumTransactionFilter,\n): DictionaryQueryEntry {\n const conditions = [];\n if (filter.from) {\n conditions.push({\n field: 'from',\n value: filter.from.toLowerCase(),\n });\n }\n if (filter.to) {\n conditions.push({\n field: 'to',\n value: filter.to.toLowerCase(),\n });\n }\n if (filter.function) {\n conditions.push({\n field: 'func',\n value: functionToSighash(filter.function),\n });\n }\n return {\n entity: 'evmTransactions',\n conditions,\n };\n}\n\n@Injectable()\nexport class FetchService implements OnApplicationShutdown {\n private latestBestHeight: number;\n private latestFinalizedHeight: number;\n private isShutdown = false;\n private useDictionary: boolean;\n private dictionaryQueryEntries?: DictionaryQueryEntry[];\n private batchSizeScale: number;\n private templateDynamicDatasouces: SubqlProjectDs[];\n\n constructor(\n private apiService: ApiService,\n private nodeConfig: NodeConfig,\n private project: SubqueryProject,\n @Inject('IBlockDispatcher') private blockDispatcher: IBlockDispatcher,\n private dictionaryService: DictionaryService,\n private dynamicDsService: DynamicDsService,\n private eventEmitter: EventEmitter2,\n private schedulerRegistry: SchedulerRegistry,\n ) {\n this.batchSizeScale = 1;\n }\n\n onApplicationShutdown(): void {\n this.isShutdown = true;\n }\n\n get api(): ApiWrapper {\n return this.apiService.api;\n }\n\n async syncDynamicDatascourcesFromMeta(): Promise<void> {\n this.templateDynamicDatasouces =\n await this.dynamicDsService.getDynamicDatasources();\n }\n\n // TODO: if custom ds doesn't support dictionary, use baseFilter, if yes, let\n getDictionaryQueryEntries(): DictionaryQueryEntry[] {\n const queryEntries: DictionaryQueryEntry[] = [];\n\n const dataSources = this.project.dataSources;\n for (const ds of dataSources.concat(this.templateDynamicDatasouces)) {\n for (const handler of ds.mapping.handlers) {\n let filterList: SubqlHandlerFilter[];\n filterList = [handler.filter];\n filterList = filterList.filter((f) => f);\n if (!filterList.length) return [];\n switch (handler.kind) {\n case EthereumHandlerKind.Block:\n return [];\n case EthereumHandlerKind.Call: {\n for (const filter of filterList as EthereumTransactionFilter[]) {\n if (\n filter.from !== undefined ||\n filter.to !== undefined ||\n filter.function\n ) {\n queryEntries.push(callFilterToQueryEntry(filter));\n } else {\n return [];\n }\n }\n break;\n }\n case EthereumHandlerKind.Event: {\n for (const filter of filterList as EthereumLogFilter[]) {\n if (filter.address || filter.topics) {\n queryEntries.push(eventFilterToQueryEntry(filter));\n } else {\n return [];\n }\n }\n break;\n }\n default:\n }\n }\n }\n\n return uniqBy(\n queryEntries,\n (item) =>\n `${item.entity}|${JSON.stringify(\n sortBy(item.conditions, (c) => c.field),\n )}`,\n );\n }\n\n updateDictionary(): void {\n this.dictionaryQueryEntries = this.getDictionaryQueryEntries();\n this.useDictionary =\n !!this.dictionaryQueryEntries?.length &&\n !!this.project.network.dictionary;\n }\n\n async init(startHeight: number): Promise<void> {\n if (this.api) {\n const CHAIN_INTERVAL = calcInterval(this.api) * INTERVAL_PERCENT;\n\n BLOCK_TIME_VARIANCE = Math.min(BLOCK_TIME_VARIANCE, CHAIN_INTERVAL);\n\n this.schedulerRegistry.addInterval(\n 'getLatestBlockHead',\n setInterval(() => void this.getBestBlockHead(), BLOCK_TIME_VARIANCE),\n );\n }\n await this.syncDynamicDatascourcesFromMeta();\n this.updateDictionary();\n this.eventEmitter.emit(IndexerEvent.UsingDictionary, {\n value: Number(this.useDictionary),\n });\n await this.getFinalizedBlockHead();\n await this.getBestBlockHead();\n\n await this.blockDispatcher.init(this.resetForNewDs.bind(this));\n\n void this.startLoop(startHeight);\n }\n\n @Interval(CHECK_MEMORY_INTERVAL)\n checkBatchScale(): void {\n if (this.nodeConfig['scale-batch-size']) {\n const scale = checkMemoryUsage(this.batchSizeScale, this.nodeConfig);\n\n if (this.batchSizeScale !== scale) {\n this.batchSizeScale = scale;\n }\n }\n }\n\n @Interval(BLOCK_TIME_VARIANCE * 1000)\n async getFinalizedBlockHead(): Promise<void> {\n if (!this.api) {\n logger.debug(`Skip fetch finalized block until API is ready`);\n return;\n }\n try {\n const currentFinalizedHeight = await this.api.getFinalizedBlockHeight();\n if (this.latestFinalizedHeight !== currentFinalizedHeight) {\n this.latestFinalizedHeight = currentFinalizedHeight;\n this.eventEmitter.emit(IndexerEvent.BlockTarget, {\n height: this.latestFinalizedHeight,\n });\n }\n } catch (e) {\n logger.error(e, `Having a problem when get finalized block`);\n }\n }\n\n @Interval(BLOCK_TIME_VARIANCE * 1000)\n async getBestBlockHead(): Promise<void> {\n if (!this.api) {\n logger.debug(`Skip fetch best block until API is ready`);\n return;\n }\n try {\n const currentBestHeight = await this.api.getLastHeight();\n if (this.latestBestHeight !== currentBestHeight) {\n this.latestBestHeight = currentBestHeight;\n this.eventEmitter.emit(IndexerEvent.BlockBest, {\n height: this.latestBestHeight,\n });\n }\n } catch (e) {\n logger.error(e, `Having a problem when get best block`);\n }\n }\n\n async startLoop(initBlockHeight: number): Promise<void> {\n await this.fillNextBlockBuffer(initBlockHeight);\n }\n\n getModulos(): number[] {\n const modulos: number[] = [];\n for (const ds of this.project.dataSources) {\n if (isCustomDs(ds)) {\n continue;\n }\n for (const handler of ds.mapping.handlers) {\n if (\n handler.kind === EthereumHandlerKind.Block &&\n handler.filter &&\n handler.filter.modulo\n ) {\n modulos.push(handler.filter.modulo);\n }\n }\n }\n return modulos;\n }\n\n getModuloBlocks(startHeight: number, endHeight: number): number[] {\n const modulos = this.getModulos();\n const moduloBlocks: number[] = [];\n for (let i = startHeight; i < endHeight; i++) {\n if (modulos.find((m) => i % m === 0)) {\n moduloBlocks.push(i);\n }\n }\n return moduloBlocks;\n }\n\n getEnqueuedModuloBlocks(startBlockHeight: number): number[] {\n return this.getModuloBlocks(\n startBlockHeight,\n this.nodeConfig.batchSize * Math.max(...this.getModulos()) +\n startBlockHeight,\n ).slice(0, this.nodeConfig.batchSize);\n }\n\n async fillNextBlockBuffer(initBlockHeight: number): Promise<void> {\n let startBlockHeight: number;\n let scaledBatchSize: number;\n const handlers = [].concat(\n ...this.project.dataSources.map((ds) => ds.mapping.handlers),\n );\n\n const getStartBlockHeight = (): number => {\n return this.blockDispatcher.latestBufferedHeight\n ? this.blockDispatcher.latestBufferedHeight + 1\n : initBlockHeight;\n };\n\n while (!this.isShutdown) {\n startBlockHeight = getStartBlockHeight();\n\n scaledBatchSize = Math.max(\n Math.round(this.batchSizeScale * this.nodeConfig.batchSize),\n Math.min(MINIMUM_BATCH_SIZE, this.nodeConfig.batchSize * 3),\n );\n if (\n this.blockDispatcher.freeSize < scaledBatchSize ||\n startBlockHeight > this.latestFinalizedHeight\n ) {\n await delay(1);\n continue;\n }\n if (this.useDictionary) {\n const queryEndBlock = startBlockHeight + DICTIONARY_MAX_QUERY_SIZE;\n const moduloBlocks = this.getModuloBlocks(\n startBlockHeight,\n queryEndBlock,\n );\n try {\n const dictionary = await this.dictionaryService.getDictionary(\n startBlockHeight,\n queryEndBlock,\n scaledBatchSize,\n this.dictionaryQueryEntries,\n );\n\n if (startBlockHeight !== getStartBlockHeight()) {\n logger.debug(\n `Queue was reset for new DS, discarding dictionary query result`,\n );\n continue;\n }\n\n if (\n dictionary &&\n this.dictionaryValidation(dictionary, startBlockHeight)\n ) {\n let { batchBlocks } = dictionary;\n\n batchBlocks = batchBlocks\n .concat(moduloBlocks)\n .sort((a, b) => a - b);\n if (batchBlocks.length === 0) {\n // There we're no blocks in this query range, we can set a new height we're up to\n this.blockDispatcher.latestBufferedHeight = Math.min(\n queryEndBlock - 1,\n dictionary._metadata.lastProcessedHeight,\n );\n } else {\n const maxBlockSize = Math.min(\n batchBlocks.length,\n this.blockDispatcher.freeSize,\n );\n batchBlocks = batchBlocks.slice(0, maxBlockSize);\n this.blockDispatcher.enqueueBlocks(batchBlocks);\n }\n continue; // skip nextBlockRange() way\n }\n // else use this.nextBlockRange()\n } catch (e) {\n logger.debug(`Fetch dictionary stopped: ${e.message}`);\n this.eventEmitter.emit(IndexerEvent.SkipDictionary);\n }\n }\n const endHeight = this.nextEndBlockHeight(\n startBlockHeight,\n scaledBatchSize,\n );\n\n if (this.getModulos().length === handlers.length) {\n this.blockDispatcher.enqueueBlocks(\n this.getEnqueuedModuloBlocks(startBlockHeight),\n );\n } else {\n this.blockDispatcher.enqueueBlocks(\n range(startBlockHeight, endHeight + 1),\n );\n }\n }\n }\n\n private nextEndBlockHeight(\n startBlockHeight: number,\n scaledBatchSize: number,\n ): number {\n let endBlockHeight = startBlockHeight + scaledBatchSize - 1;\n\n if (endBlockHeight > this.latestFinalizedHeight) {\n endBlockHeight = this.latestFinalizedHeight;\n }\n return endBlockHeight;\n }\n\n private dictionaryValidation(\n { _metadata: metaData }: Dictionary,\n startBlockHeight: number,\n ): boolean {\n if (metaData.genesisHash !== this.api.getGenesisHash()) {\n logger.error(\n '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',\n );\n this.useDictionary = false;\n this.eventEmitter.emit(IndexerEvent.UsingDictionary, {\n value: Number(this.useDictionary),\n });\n this.eventEmitter.emit(IndexerEvent.SkipDictionary);\n return false;\n }\n if (metaData.lastProcessedHeight < startBlockHeight) {\n logger.warn(\n `Dictionary indexed block is behind current indexing block height`,\n );\n this.eventEmitter.emit(IndexerEvent.SkipDictionary);\n return false;\n }\n return true;\n }\n\n async resetForNewDs(blockHeight: number): Promise<void> {\n await this.syncDynamicDatascourcesFromMeta();\n this.dynamicDsService.deleteTempDsRecords(blockHeight);\n this.updateDictionary();\n this.blockDispatcher.flushQueue(blockHeight);\n }\n}\n"]}
|
|
@@ -100,16 +100,12 @@ let IndexerManager = class IndexerManager {
|
|
|
100
100
|
}
|
|
101
101
|
async start() {
|
|
102
102
|
await this.projectService.init();
|
|
103
|
+
logger.info('indexer manager started');
|
|
103
104
|
}
|
|
104
|
-
filterDataSources(
|
|
105
|
-
|
|
105
|
+
filterDataSources(nextProcessingHeight) {
|
|
106
|
+
const filteredDs = this.projectService.dataSources.filter((ds) => ds.startBlock <= nextProcessingHeight);
|
|
106
107
|
if (filteredDs.length === 0) {
|
|
107
|
-
logger.error(`
|
|
108
|
-
process.exit(1);
|
|
109
|
-
}
|
|
110
|
-
filteredDs = filteredDs.filter((ds) => ds.startBlock <= processedHeight);
|
|
111
|
-
if (filteredDs.length === 0) {
|
|
112
|
-
logger.error(`Your start block is greater than the current indexed block height in your database. Either change your startBlock (project.yaml) to <= ${processedHeight}
|
|
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}
|
|
113
109
|
or delete your database and start again from the currently specified startBlock`);
|
|
114
110
|
process.exit(1);
|
|
115
111
|
}
|