@subql/node-ethereum 0.3.0 → 0.3.1-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/configure/SubqueryProject.js +1 -1
- package/dist/configure/SubqueryProject.js.map +1 -1
- package/dist/ethereum/api.ethereum.d.ts +3 -3
- package/dist/ethereum/api.ethereum.js +7 -8
- package/dist/ethereum/api.ethereum.js.map +1 -1
- package/dist/indexer/fetch.module.js +2 -0
- package/dist/indexer/fetch.module.js.map +1 -1
- package/dist/indexer/fetch.service.d.ts +3 -1
- package/dist/indexer/fetch.service.js +14 -5
- package/dist/indexer/fetch.service.js.map +1 -1
- package/dist/indexer/indexer.manager.d.ts +4 -1
- package/dist/indexer/indexer.manager.js +14 -3
- package/dist/indexer/indexer.manager.js.map +1 -1
- package/dist/indexer/indexer.module.js +2 -0
- package/dist/indexer/indexer.module.js.map +1 -1
- package/dist/indexer/project.service.d.ts +6 -1
- package/dist/indexer/project.service.js +26 -2
- package/dist/indexer/project.service.js.map +1 -1
- package/dist/indexer/types.d.ts +1 -0
- package/dist/indexer/types.js.map +1 -1
- package/dist/indexer/unfinalizedBlocks.service.d.ts +36 -0
- package/dist/indexer/unfinalizedBlocks.service.js +203 -0
- package/dist/indexer/unfinalizedBlocks.service.js.map +1 -0
- package/dist/indexer/unfinalizedBlocks.spec.d.ts +1 -0
- package/dist/indexer/unfinalizedBlocks.spec.js +188 -0
- package/dist/indexer/unfinalizedBlocks.spec.js.map +1 -0
- package/package.json +5 -4
|
@@ -101,7 +101,7 @@ async function generateTimestampReferenceForBlockFilters(dataSources, api) {
|
|
|
101
101
|
if (handler.kind === common_ethereum_1.EthereumHandlerKind.Block) {
|
|
102
102
|
if ((_a = handler.filter) === null || _a === void 0 ? void 0 : _a.timestamp) {
|
|
103
103
|
if (!block) {
|
|
104
|
-
block = await api.
|
|
104
|
+
block = await api.getBlockByHeightOrHash(startBlock);
|
|
105
105
|
timestampReference = new Date(block.timestamp * 1000); // Add millis
|
|
106
106
|
}
|
|
107
107
|
try {
|
|
@@ -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 { 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 (!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
|
+
{"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 (!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.getBlockByHeightOrHash(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"]}
|
|
@@ -9,13 +9,13 @@ export declare class EthereumApi implements ApiWrapper<EthereumBlockWrapper> {
|
|
|
9
9
|
private chainId;
|
|
10
10
|
constructor(endpoint: string);
|
|
11
11
|
init(): Promise<void>;
|
|
12
|
-
|
|
12
|
+
getFinalizedBlockHeight(): Promise<number>;
|
|
13
|
+
getBestBlockHeight(): Promise<number>;
|
|
13
14
|
getRuntimeChain(): string;
|
|
14
15
|
getChainId(): number;
|
|
15
16
|
getGenesisHash(): string;
|
|
16
17
|
getSpecName(): string;
|
|
17
|
-
|
|
18
|
-
getBlockByHeight(height: number): Promise<Block>;
|
|
18
|
+
getBlockByHeightOrHash(heightOrHash: number | string): Promise<Block>;
|
|
19
19
|
getBlockPromise(num: number): Promise<any>;
|
|
20
20
|
getTransactionReceipt(transactionHash: string | Promise<string>): Promise<TransactionReceipt>;
|
|
21
21
|
fetchBlock(num: number): Promise<EthereumBlockWrapper>;
|
|
@@ -62,8 +62,11 @@ class EthereumApi {
|
|
|
62
62
|
this.genesisBlock = await this.client.getBlock(0);
|
|
63
63
|
this.chainId = (await this.client.getNetwork()).chainId;
|
|
64
64
|
}
|
|
65
|
-
async
|
|
66
|
-
return this.client.
|
|
65
|
+
async getFinalizedBlockHeight() {
|
|
66
|
+
return (await this.client.getBlock('finalized')).number;
|
|
67
|
+
}
|
|
68
|
+
async getBestBlockHeight() {
|
|
69
|
+
return (await this.client.getBlock('safe')).number;
|
|
67
70
|
}
|
|
68
71
|
getRuntimeChain() {
|
|
69
72
|
return 'ethereum';
|
|
@@ -77,12 +80,8 @@ class EthereumApi {
|
|
|
77
80
|
getSpecName() {
|
|
78
81
|
return 'ethereum';
|
|
79
82
|
}
|
|
80
|
-
async
|
|
81
|
-
|
|
82
|
-
return this.client.getBlockNumber();
|
|
83
|
-
}
|
|
84
|
-
async getBlockByHeight(height) {
|
|
85
|
-
return this.client.getBlock(height);
|
|
83
|
+
async getBlockByHeightOrHash(heightOrHash) {
|
|
84
|
+
return this.client.getBlock(heightOrHash);
|
|
86
85
|
}
|
|
87
86
|
async getBlockPromise(num) {
|
|
88
87
|
return (0, project_1.retryOnFailEth)(() => this.client.send('eth_getBlockByNumber', [(0, utils_1.hexValue)(num), true]));
|
|
@@ -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 { Block, TransactionReceipt } from '@ethersproject/abstract-provider';\nimport { JsonRpcProvider, WebSocketProvider } 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 { ConnectionInfo, hexDataSlice, hexValue } from 'ethers/lib/utils';\nimport { retryOnFailEth } from '../utils/project';\nimport { EthereumBlockWrapped } from './block.ethereum';\nimport {\n formatBlock,\n formatReceipt,\n formatTransaction,\n} from './utils.ethereum';\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: JsonRpcProvider;\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\n const protocolStr = protocol.replace(':', '');\n\n logger.info(this.endpoint.split('?')[0]);\n if (protocolStr === 'https' || protocolStr === 'http') {\n const connection: ConnectionInfo = {\n url: this.endpoint.split('?')[0],\n headers: {\n 'User-Agent': `Subquery-Node ${packageVersion}`,\n },\n };\n searchParams.forEach((value, name, searchParams) => {\n (connection.headers as any)[name] = value;\n });\n this.client = new JsonRpcProvider(connection);\n } else if (protocolStr === 'ws' || protocolStr === 'wss') {\n this.client = new WebSocketProvider(this.endpoint);\n } else {\n throw new Error(`Unsupported protocol: ${protocol}`);\n }\n }\n\n async init(): Promise<void> {\n this.genesisBlock = await this.client.getBlock(0);\n\n this.chainId = (await this.client.getNetwork()).chainId;\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 getBlockPromise(num: number): Promise<any> {\n return retryOnFailEth(() =>\n this.client.send('eth_getBlockByNumber', [hexValue(num), true]),\n );\n }\n\n async getTransactionReceipt(\n transactionHash: string | Promise<string>,\n ): Promise<TransactionReceipt> {\n return retryOnFailEth<TransactionReceipt>(\n this.client.getTransactionReceipt.bind(this.client, transactionHash),\n );\n }\n async fetchBlock(num: number): Promise<EthereumBlockWrapper> {\n const block_promise = await this.getBlockPromise(num);\n\n const block = formatBlock(block_promise);\n block.stateRoot = this.client.formatter.hash(block.stateRoot);\n\n const transactions = await Promise.all(\n block.transactions.map(async (tx) => {\n const transaction = formatTransaction(tx);\n const receipt = await this.getTransactionReceipt(tx.hash);\n transaction.receipt = formatReceipt(receipt, block);\n return transaction;\n }),\n );\n return new EthereumBlockWrapped(block, transactions);\n }\n\n async fetchBlocks(bufferBlocks: number[]): Promise<EthereumBlockWrapper[]> {\n return Promise.all(\n bufferBlocks.map(async (num) => {\n try {\n // Fetch Block\n return await this.fetchBlock(num);\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":";AAAA,gEAAgE;AAChE,sCAAsC;;;;;;AAEtC,4CAAoB;AAGpB,4CAA+C;AAE/C,wDAA8E;AAE9E,gDAA6C;AAS7C,4CAA0E;AAC1E,8CAAkD;AAClD,qDAAwD;AACxD,qDAI0B;AAE1B,8DAA8D;AAC9D,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAElE,MAAM,MAAM,GAAG,IAAA,qBAAS,EAAC,cAAc,CAAC,CAAC;AAEzC,KAAK,UAAU,UAAU,CACvB,EAA2B;IAE3B,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE;QACd,OAAO,EAAE,CAAC;KACX;IACD,MAAM,GAAG,GAA2B,EAAE,CAAC;IAEvC,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;QACxD,IAAI;YACF,GAAG,CAAC,IAAI,CAAC,GAAG,MAAM,YAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;SACpE;QAAC,OAAO,CAAC,EAAE;YACV,MAAM,IAAI,KAAK,CAAC,mCAAmC,IAAI,EAAE,CAAC,CAAC;SAC5D;KACF;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAa,WAAW;IAMtB,YAAoB,QAAgB;QAAhB,aAAQ,GAAR,QAAQ,CAAQ;QAH5B,uBAAkB,GAA8B,EAAE,CAAC;QAIzD,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI,GAAG,CAClE,QAAQ,CACT,CAAC;QAEF,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAE9C,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzC,IAAI,WAAW,KAAK,OAAO,IAAI,WAAW,KAAK,MAAM,EAAE;YACrD,MAAM,UAAU,GAAmB;gBACjC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAChC,OAAO,EAAE;oBACP,YAAY,EAAE,iBAAiB,cAAc,EAAE;iBAChD;aACF,CAAC;YACF,YAAY,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE;gBAChD,UAAU,CAAC,OAAe,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;YAC5C,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,GAAG,IAAI,2BAAe,CAAC,UAAU,CAAC,CAAC;SAC/C;aAAM,IAAI,WAAW,KAAK,IAAI,IAAI,WAAW,KAAK,KAAK,EAAE;YACxD,IAAI,CAAC,MAAM,GAAG,IAAI,6BAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;SACpD;aAAM;YACL,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAC;SACtD;IACH,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,YAAY,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAElD,IAAI,CAAC,OAAO,GAAG,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC;IAC1D,CAAC;IAED,KAAK,CAAC,uBAAuB;QAC3B,OAAO,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC;IAC1D,CAAC;IAED,KAAK,CAAC,kBAAkB;QACtB,OAAO,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;IACrD,CAAC;IAED,eAAe;QACb,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;IAChC,CAAC;IAED,WAAW;QACT,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAC,YAA6B;QACxD,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,GAAW;QAC/B,OAAO,IAAA,wBAAc,EAAC,GAAG,EAAE,CACzB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,sBAAsB,EAAE,CAAC,IAAA,gBAAQ,EAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,CAChE,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,qBAAqB,CACzB,eAAyC;QAEzC,OAAO,IAAA,wBAAc,EACnB,IAAI,CAAC,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,eAAe,CAAC,CACrE,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,GAAW;QAC1B,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;QAEtD,MAAM,KAAK,GAAG,IAAA,4BAAW,EAAC,aAAa,CAAC,CAAC;QACzC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAE9D,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CACpC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;YAClC,MAAM,WAAW,GAAG,IAAA,kCAAiB,EAAC,EAAE,CAAC,CAAC;YAC1C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;YAC1D,WAAW,CAAC,OAAO,GAAG,IAAA,8BAAa,EAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YACpD,OAAO,WAAW,CAAC;QACrB,CAAC,CAAC,CACH,CAAC;QACF,OAAO,IAAI,qCAAoB,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,YAAsB;QACtC,OAAO,OAAO,CAAC,GAAG,CAChB,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YAC7B,IAAI;gBACF,cAAc;gBACd,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;aACnC;YAAC,OAAO,CAAC,EAAE;gBACV,yEAAyE;gBACzE,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;gBACnC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,mCAAmC,GAAG,EAAE,CAAC,CAAC;gBAC9D,MAAM,KAAK,CAAC;aACb;QACH,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAED,SAAS,CAAC,SAAc,EAAE,YAA0B;QAClD,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACvC,CAAC;IAEO,cAAc,CACpB,OAAe,EACf,MAA8B;QAE9B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;YACpB,MAAM,IAAI,KAAK,CAAC,cAAc,OAAO,4BAA4B,CAAC,CAAC;SACpE;QAED,uFAAuF;QACvF,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE;YACrC,+CAA+C;YAC/C,IAAI;gBACF,IAAI,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;gBAEzC;;;mBAGG;gBACH,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,GAAG,EAAE;oBACxC,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC;iBACrB;gBAED,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,GAAG,IAAI,eAAS,CAAC,MAAM,CAAC,CAAC;aAC1D;YAAC,OAAO,CAAC,EAAE;gBACV,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;gBAClD,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;aACnC;SACF;QAED,OAAO,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,QAAQ,CACZ,GAAgB,EAChB,EAA2B;;QAE3B,IAAI;YACF,IAAI,CAAC,CAAA,MAAA,EAAE,aAAF,EAAE,uBAAF,EAAE,CAAE,OAAO,0CAAE,GAAG,CAAA,EAAE;gBACrB,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;gBAC9C,OAAO,GAAG,CAAC;aACZ;YACD,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;YACxE,uCACK,GAAG,KACN,IAAI,EAAE,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,QAAQ,CAAC,GAAG,EAAE,IAAS,IACpC;SACH;QAAC,OAAO,CAAC,EAAE;YACV,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YACtD,OAAO,GAAG,CAAC;SACZ;IACH,CAAC;IAED,KAAK,CAAC,gBAAgB,CACpB,WAAgC,EAChC,EAA2B;;QAE3B,IAAI;YACF,IAAI,CAAC,CAAA,MAAA,EAAE,aAAF,EAAE,uBAAF,EAAE,CAAE,OAAO,0CAAE,GAAG,CAAA,EAAE;gBACrB,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;gBAC9C,OAAO,WAAW,CAAC;aACpB;YACD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,EAAE,CAAC,CAAC;YACpC,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC1D,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,CAAC,IAAA,oBAAY,EAAC,WAAW,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACtE,MAAM,IAAI,GAAG,KAAK,CAAC,kBAAkB,CAAC,IAAI,EAAE,WAAW,CAAC,KAAK,CAAM,CAAC;YACpE,uCACK,WAAW,KACd,IAAI,IACJ;SACH;QAAC,OAAO,CAAC,EAAE;YACV,MAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YAC9D,OAAO,WAAW,CAAC;SACpB;IACH,CAAC;CACF;AA9LD,kCA8LC","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, TransactionReceipt } from '@ethersproject/abstract-provider';\nimport { JsonRpcProvider, WebSocketProvider } 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 { ConnectionInfo, hexDataSlice, hexValue } from 'ethers/lib/utils';\nimport { retryOnFailEth } from '../utils/project';\nimport { EthereumBlockWrapped } from './block.ethereum';\nimport {\n formatBlock,\n formatReceipt,\n formatTransaction,\n} from './utils.ethereum';\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: JsonRpcProvider;\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\n const protocolStr = protocol.replace(':', '');\n\n logger.info(this.endpoint.split('?')[0]);\n if (protocolStr === 'https' || protocolStr === 'http') {\n const connection: ConnectionInfo = {\n url: this.endpoint.split('?')[0],\n headers: {\n 'User-Agent': `Subquery-Node ${packageVersion}`,\n },\n };\n searchParams.forEach((value, name, searchParams) => {\n (connection.headers as any)[name] = value;\n });\n this.client = new JsonRpcProvider(connection);\n } else if (protocolStr === 'ws' || protocolStr === 'wss') {\n this.client = new WebSocketProvider(this.endpoint);\n } else {\n throw new Error(`Unsupported protocol: ${protocol}`);\n }\n }\n\n async init(): Promise<void> {\n this.genesisBlock = await this.client.getBlock(0);\n\n this.chainId = (await this.client.getNetwork()).chainId;\n }\n\n async getFinalizedBlockHeight(): Promise<number> {\n return (await this.client.getBlock('finalized')).number;\n }\n\n async getBestBlockHeight(): Promise<number> {\n return (await this.client.getBlock('safe')).number;\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 getBlockByHeightOrHash(heightOrHash: number | string): Promise<Block> {\n return this.client.getBlock(heightOrHash);\n }\n\n async getBlockPromise(num: number): Promise<any> {\n return retryOnFailEth(() =>\n this.client.send('eth_getBlockByNumber', [hexValue(num), true]),\n );\n }\n\n async getTransactionReceipt(\n transactionHash: string | Promise<string>,\n ): Promise<TransactionReceipt> {\n return retryOnFailEth<TransactionReceipt>(\n this.client.getTransactionReceipt.bind(this.client, transactionHash),\n );\n }\n async fetchBlock(num: number): Promise<EthereumBlockWrapper> {\n const block_promise = await this.getBlockPromise(num);\n\n const block = formatBlock(block_promise);\n block.stateRoot = this.client.formatter.hash(block.stateRoot);\n\n const transactions = await Promise.all(\n block.transactions.map(async (tx) => {\n const transaction = formatTransaction(tx);\n const receipt = await this.getTransactionReceipt(tx.hash);\n transaction.receipt = formatReceipt(receipt, block);\n return transaction;\n }),\n );\n return new EthereumBlockWrapped(block, transactions);\n }\n\n async fetchBlocks(bufferBlocks: number[]): Promise<EthereumBlockWrapper[]> {\n return Promise.all(\n bufferBlocks.map(async (num) => {\n try {\n // Fetch Block\n return await this.fetchBlock(num);\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"]}
|
|
@@ -22,6 +22,7 @@ const fetch_service_1 = require("./fetch.service");
|
|
|
22
22
|
const indexer_manager_1 = require("./indexer.manager");
|
|
23
23
|
const project_service_1 = require("./project.service");
|
|
24
24
|
const sandbox_service_1 = require("./sandbox.service");
|
|
25
|
+
const unfinalizedBlocks_service_1 = require("./unfinalizedBlocks.service");
|
|
25
26
|
let FetchModule = class FetchModule {
|
|
26
27
|
};
|
|
27
28
|
FetchModule = __decorate([
|
|
@@ -60,6 +61,7 @@ FetchModule = __decorate([
|
|
|
60
61
|
node_core_1.PoiService,
|
|
61
62
|
node_core_1.MmrService,
|
|
62
63
|
project_service_1.ProjectService,
|
|
64
|
+
unfinalizedBlocks_service_1.UnfinalizedBlocksService,
|
|
63
65
|
],
|
|
64
66
|
exports: [node_core_1.StoreService, node_core_1.MmrService],
|
|
65
67
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.module.js","sourceRoot":"","sources":["../../src/indexer/fetch.module.ts"],"names":[],"mappings":";AAAA,gEAAgE;AAChE,sCAAsC;;;;;;;;;AAEtC,2CAAwC;AACxC,yDAAsD;AACtD,gDAO0B;AAC1B,kEAA+D;AAC/D,2EAAsE;AACtE,uDAG2B;AAC3B,6DAAyD;AACzD,iEAA4D;AAC5D,6DAAwD;AACxD,mDAA+C;AAC/C,uDAAmD;AACnD,uDAAmD;AACnD,uDAAmD;
|
|
1
|
+
{"version":3,"file":"fetch.module.js","sourceRoot":"","sources":["../../src/indexer/fetch.module.ts"],"names":[],"mappings":";AAAA,gEAAgE;AAChE,sCAAsC;;;;;;;;;AAEtC,2CAAwC;AACxC,yDAAsD;AACtD,gDAO0B;AAC1B,kEAA+D;AAC/D,2EAAsE;AACtE,uDAG2B;AAC3B,6DAAyD;AACzD,iEAA4D;AAC5D,6DAAwD;AACxD,mDAA+C;AAC/C,uDAAmD;AACnD,uDAAmD;AACnD,uDAAmD;AACnD,2EAAuE;AA2DhE,IAAM,WAAW,GAAjB,MAAM,WAAW;CAAG,CAAA;AAAd,WAAW;IAzDvB,IAAA,eAAM,EAAC;QACN,SAAS,EAAE;YACT,wBAAY;YACZ;gBACE,OAAO,EAAE,sBAAU;gBACnB,UAAU,EAAE,KAAK,EAAE,OAAwB,EAAE,EAAE;oBAC7C,MAAM,UAAU,GAAG,IAAI,yCAAkB,CAAC,OAAO,CAAC,CAAC;oBAEnD,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;oBACxB,OAAO,UAAU,CAAC;gBACpB,CAAC;gBACD,MAAM,EAAE,CAAC,iCAAe,CAAC;aAC1B;YACD,gCAAc;YACd;gBACE,OAAO,EAAE,kBAAkB;gBAC3B,UAAU,EAAE,CACV,UAAsB,EACtB,YAA2B,EAC3B,cAA8B,EAC9B,UAAsB,EACtB,cAA8B,EAC9B,EAAE,CACF,UAAU,CAAC,OAAO,KAAK,SAAS;oBAC9B,CAAC,CAAC,IAAI,8CAA4B,CAC9B,UAAU,EACV,YAAY,EACZ,cAAc,CACf;oBACH,CAAC,CAAC,IAAI,wCAAsB,CACxB,UAAU,EACV,UAAU,EACV,cAAc,EACd,YAAY,EACZ,cAAc,CACf;gBACP,MAAM,EAAE;oBACN,sBAAU;oBACV,6BAAa;oBACb,gCAAc;oBACd,sBAAU;oBACV,gCAAc;iBACf;aACF;YACD,4BAAY;YACZ,4BAAgB;YAChB,sCAAiB;YACjB,gCAAc;YACd,yCAAkB;YAClB,qCAAgB;YAChB,sBAAU;YACV,sBAAU;YACV,gCAAc;YACd,oDAAwB;SACzB;QACD,OAAO,EAAE,CAAC,wBAAY,EAAE,sBAAU,CAAC;KACpC,CAAC;GACW,WAAW,CAAG;AAAd,kCAAW","sourcesContent":["// Copyright 2020-2022 OnFinality Limited authors & contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Module } from '@nestjs/common';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport {\n BenchmarkService,\n MmrService,\n StoreService,\n PoiService,\n ApiService,\n NodeConfig,\n} from '@subql/node-core';\nimport { SubqueryProject } from '../configure/SubqueryProject';\nimport { EthereumApiService } from '../ethereum/api.service.ethereum';\nimport {\n BlockDispatcherService,\n WorkerBlockDispatcherService,\n} from './blockDispatcher';\nimport { DictionaryService } from './dictionary.service';\nimport { DsProcessorService } from './ds-processor.service';\nimport { DynamicDsService } from './dynamic-ds.service';\nimport { FetchService } from './fetch.service';\nimport { IndexerManager } from './indexer.manager';\nimport { ProjectService } from './project.service';\nimport { SandboxService } from './sandbox.service';\nimport { UnfinalizedBlocksService } from './unfinalizedBlocks.service';\n\n@Module({\n providers: [\n StoreService,\n {\n provide: ApiService,\n useFactory: async (project: SubqueryProject) => {\n const apiService = new EthereumApiService(project);\n\n await apiService.init();\n return apiService;\n },\n inject: [SubqueryProject],\n },\n IndexerManager,\n {\n provide: 'IBlockDispatcher',\n useFactory: (\n nodeConfig: NodeConfig,\n eventEmitter: EventEmitter2,\n projectService: ProjectService,\n apiService: ApiService,\n indexerManager: IndexerManager,\n ) =>\n nodeConfig.workers !== undefined\n ? new WorkerBlockDispatcherService(\n nodeConfig,\n eventEmitter,\n projectService,\n )\n : new BlockDispatcherService(\n apiService,\n nodeConfig,\n indexerManager,\n eventEmitter,\n projectService,\n ),\n inject: [\n NodeConfig,\n EventEmitter2,\n ProjectService,\n ApiService,\n IndexerManager,\n ],\n },\n FetchService,\n BenchmarkService,\n DictionaryService,\n SandboxService,\n DsProcessorService,\n DynamicDsService,\n PoiService,\n MmrService,\n ProjectService,\n UnfinalizedBlocksService,\n ],\n exports: [StoreService, MmrService],\n})\nexport class FetchModule {}\n"]}
|
|
@@ -7,6 +7,7 @@ import { SubqueryProject } from '../configure/SubqueryProject';
|
|
|
7
7
|
import { IBlockDispatcher } from './blockDispatcher';
|
|
8
8
|
import { DictionaryService } from './dictionary.service';
|
|
9
9
|
import { DynamicDsService } from './dynamic-ds.service';
|
|
10
|
+
import { UnfinalizedBlocksService } from './unfinalizedBlocks.service';
|
|
10
11
|
export declare class FetchService implements OnApplicationShutdown {
|
|
11
12
|
private apiService;
|
|
12
13
|
private nodeConfig;
|
|
@@ -14,6 +15,7 @@ export declare class FetchService implements OnApplicationShutdown {
|
|
|
14
15
|
private blockDispatcher;
|
|
15
16
|
private dictionaryService;
|
|
16
17
|
private dynamicDsService;
|
|
18
|
+
private unfinalizedBlocksService;
|
|
17
19
|
private eventEmitter;
|
|
18
20
|
private schedulerRegistry;
|
|
19
21
|
private latestBestHeight;
|
|
@@ -24,7 +26,7 @@ export declare class FetchService implements OnApplicationShutdown {
|
|
|
24
26
|
private templateDynamicDatasouces;
|
|
25
27
|
private dictionaryGenesisMatches;
|
|
26
28
|
private evmChainId;
|
|
27
|
-
constructor(apiService: ApiService, nodeConfig: NodeConfig, project: SubqueryProject, blockDispatcher: IBlockDispatcher, dictionaryService: DictionaryService, dynamicDsService: DynamicDsService, eventEmitter: EventEmitter2, schedulerRegistry: SchedulerRegistry);
|
|
29
|
+
constructor(apiService: ApiService, nodeConfig: NodeConfig, project: SubqueryProject, blockDispatcher: IBlockDispatcher, dictionaryService: DictionaryService, dynamicDsService: DynamicDsService, unfinalizedBlocksService: UnfinalizedBlocksService, eventEmitter: EventEmitter2, schedulerRegistry: SchedulerRegistry);
|
|
28
30
|
onApplicationShutdown(): void;
|
|
29
31
|
get api(): ApiWrapper;
|
|
30
32
|
syncDynamicDatascourcesFromMeta(): Promise<void>;
|
|
@@ -26,6 +26,7 @@ const utils_ethereum_1 = require("../ethereum/utils.ethereum");
|
|
|
26
26
|
const string_1 = require("../utils/string");
|
|
27
27
|
const dictionary_service_1 = require("./dictionary.service");
|
|
28
28
|
const dynamic_ds_service_1 = require("./dynamic-ds.service");
|
|
29
|
+
const unfinalizedBlocks_service_1 = require("./unfinalizedBlocks.service");
|
|
29
30
|
const logger = (0, node_core_1.getLogger)('fetch');
|
|
30
31
|
let BLOCK_TIME_VARIANCE = 5000;
|
|
31
32
|
const DICTIONARY_MAX_QUERY_SIZE = 10000;
|
|
@@ -81,13 +82,14 @@ function callFilterToQueryEntry(filter) {
|
|
|
81
82
|
};
|
|
82
83
|
}
|
|
83
84
|
let FetchService = class FetchService {
|
|
84
|
-
constructor(apiService, nodeConfig, project, blockDispatcher, dictionaryService, dynamicDsService, eventEmitter, schedulerRegistry) {
|
|
85
|
+
constructor(apiService, nodeConfig, project, blockDispatcher, dictionaryService, dynamicDsService, unfinalizedBlocksService, eventEmitter, schedulerRegistry) {
|
|
85
86
|
this.apiService = apiService;
|
|
86
87
|
this.nodeConfig = nodeConfig;
|
|
87
88
|
this.project = project;
|
|
88
89
|
this.blockDispatcher = blockDispatcher;
|
|
89
90
|
this.dictionaryService = dictionaryService;
|
|
90
91
|
this.dynamicDsService = dynamicDsService;
|
|
92
|
+
this.unfinalizedBlocksService = unfinalizedBlocksService;
|
|
91
93
|
this.eventEmitter = eventEmitter;
|
|
92
94
|
this.schedulerRegistry = schedulerRegistry;
|
|
93
95
|
this.isShutdown = false;
|
|
@@ -195,12 +197,17 @@ let FetchService = class FetchService {
|
|
|
195
197
|
}
|
|
196
198
|
try {
|
|
197
199
|
const currentFinalizedHeight = await this.api.getFinalizedBlockHeight();
|
|
200
|
+
logger.debug(`finalized:${currentFinalizedHeight.toString()}`);
|
|
201
|
+
const finalizedHeader = await this.api.getBlockByHeightOrHash(currentFinalizedHeight);
|
|
198
202
|
if (this.latestFinalizedHeight !== currentFinalizedHeight) {
|
|
199
203
|
this.latestFinalizedHeight = currentFinalizedHeight;
|
|
204
|
+
this.unfinalizedBlocksService.registerFinalizedBlock(finalizedHeader);
|
|
200
205
|
if (!this.nodeConfig.unfinalizedBlocks) {
|
|
201
|
-
this.
|
|
202
|
-
|
|
203
|
-
|
|
206
|
+
if (!this.nodeConfig.unfinalizedBlocks) {
|
|
207
|
+
this.eventEmitter.emit(node_core_1.IndexerEvent.BlockTarget, {
|
|
208
|
+
height: this.latestFinalizedHeight,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
204
211
|
}
|
|
205
212
|
}
|
|
206
213
|
}
|
|
@@ -214,7 +221,8 @@ let FetchService = class FetchService {
|
|
|
214
221
|
return;
|
|
215
222
|
}
|
|
216
223
|
try {
|
|
217
|
-
const currentBestHeight = await this.api.
|
|
224
|
+
const currentBestHeight = await this.api.getBestBlockHeight();
|
|
225
|
+
logger.debug(`best:${currentBestHeight.toString()}`);
|
|
218
226
|
if (this.latestBestHeight !== currentBestHeight) {
|
|
219
227
|
this.latestBestHeight = currentBestHeight;
|
|
220
228
|
this.eventEmitter.emit(node_core_1.IndexerEvent.BlockBest, {
|
|
@@ -395,6 +403,7 @@ FetchService = __decorate([
|
|
|
395
403
|
node_core_1.NodeConfig,
|
|
396
404
|
SubqueryProject_1.SubqueryProject, Object, dictionary_service_1.DictionaryService,
|
|
397
405
|
dynamic_ds_service_1.DynamicDsService,
|
|
406
|
+
unfinalizedBlocks_service_1.UnfinalizedBlocksService,
|
|
398
407
|
event_emitter_1.EventEmitter2,
|
|
399
408
|
schedule_1.SchedulerRegistry])
|
|
400
409
|
], FetchService);
|
|
@@ -1 +1 @@
|
|
|
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 { IBlockDispatcher } from './blockDispatcher';\nimport { DictionaryService } from './dictionary.service';\nimport { DynamicDsService } from './dynamic-ds.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 dictionaryQueryEntries?: DictionaryQueryEntry[];\n private batchSizeScale: number;\n private templateDynamicDatasouces: SubqlProjectDs[];\n private dictionaryGenesisMatches = true;\n private evmChainId: string;\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 buildDictionaryQueryEntries(startBlock: number): DictionaryQueryEntry[] {\n const queryEntries: DictionaryQueryEntry[] = [];\n\n // Only run the ds that is equal or less than startBlock\n // sort array from lowest ds.startBlock to highest\n const filteredDs = this.project.dataSources\n .concat(this.templateDynamicDatasouces)\n .filter((ds) => ds.startBlock <= startBlock)\n .sort((a, b) => a.startBlock - b.startBlock);\n\n for (const ds of filteredDs) {\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.dictionaryService.buildDictionaryEntryMap<SubqlProjectDs>(\n this.project.dataSources.concat(this.templateDynamicDatasouces),\n this.buildDictionaryQueryEntries.bind(this),\n );\n }\n\n private get useDictionary(): boolean {\n return (\n !!this.project.network.dictionary &&\n this.dictionaryGenesisMatches &&\n !!this.dictionaryService.getDictionaryQueryEntries(\n this.blockDispatcher.latestBufferedHeight ??\n Math.min(...this.project.dataSources.map((ds) => ds.startBlock)),\n ).length\n );\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\n this.updateDictionary();\n this.eventEmitter.emit(IndexerEvent.UsingDictionary, {\n value: Number(this.useDictionary),\n });\n\n if (this.project.network.dictionary) {\n this.evmChainId = await this.dictionaryService.getEvmChainId();\n }\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 if (!this.nodeConfig.unfinalizedBlocks) {\n this.eventEmitter.emit(IndexerEvent.BlockTarget, {\n height: this.latestFinalizedHeight,\n });\n }\n }\n } catch (e) {\n logger.warn(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 if (this.nodeConfig.unfinalizedBlocks) {\n this.eventEmitter.emit(IndexerEvent.BlockTarget, {\n height: this.latestBestHeight,\n });\n }\n }\n } catch (e) {\n logger.warn(e, `Having a problem when get best block`);\n }\n }\n\n private 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 const latestHeight = this.nodeConfig.unfinalizedBlocks\n ? this.latestBestHeight\n : this.latestFinalizedHeight;\n\n if (\n this.blockDispatcher.freeSize < scaledBatchSize ||\n startBlockHeight > latestHeight\n ) {\n await delay(1);\n continue;\n }\n\n if (this.useDictionary) {\n const queryEndBlock = startBlockHeight + DICTIONARY_MAX_QUERY_SIZE;\n const moduloBlocks = this.getModuloBlocks(\n startBlockHeight,\n queryEndBlock,\n );\n\n try {\n const dictionary =\n await this.dictionaryService.scopedDictionaryEntries(\n startBlockHeight,\n queryEndBlock,\n scaledBatchSize,\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\n const endHeight = this.nextEndBlockHeight(\n startBlockHeight,\n scaledBatchSize,\n );\n\n if (handlers.length && 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 if (this.nodeConfig.unfinalizedBlocks) {\n if (endBlockHeight >= this.latestBestHeight) {\n endBlockHeight = this.latestBestHeight;\n }\n } else {\n endBlockHeight = this.latestFinalizedHeight;\n }\n }\n return endBlockHeight;\n }\n\n private dictionaryValidation(\n { _metadata: metaData }: Dictionary,\n startBlockHeight: number,\n ): boolean {\n if (\n metaData.genesisHash !== this.api.getGenesisHash() &&\n this.evmChainId !== this.api.getChainId().toString()\n ) {\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.dictionaryGenesisMatches = 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 async resetForIncorrectBestBlock(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 { IBlockDispatcher } from './blockDispatcher';\nimport { DictionaryService } from './dictionary.service';\nimport { DynamicDsService } from './dynamic-ds.service';\nimport { UnfinalizedBlocksService } from './unfinalizedBlocks.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 dictionaryQueryEntries?: DictionaryQueryEntry[];\n private batchSizeScale: number;\n private templateDynamicDatasouces: SubqlProjectDs[];\n private dictionaryGenesisMatches = true;\n private evmChainId: string;\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 unfinalizedBlocksService: UnfinalizedBlocksService,\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 buildDictionaryQueryEntries(startBlock: number): DictionaryQueryEntry[] {\n const queryEntries: DictionaryQueryEntry[] = [];\n\n // Only run the ds that is equal or less than startBlock\n // sort array from lowest ds.startBlock to highest\n const filteredDs = this.project.dataSources\n .concat(this.templateDynamicDatasouces)\n .filter((ds) => ds.startBlock <= startBlock)\n .sort((a, b) => a.startBlock - b.startBlock);\n\n for (const ds of filteredDs) {\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.dictionaryService.buildDictionaryEntryMap<SubqlProjectDs>(\n this.project.dataSources.concat(this.templateDynamicDatasouces),\n this.buildDictionaryQueryEntries.bind(this),\n );\n }\n\n private get useDictionary(): boolean {\n return (\n !!this.project.network.dictionary &&\n this.dictionaryGenesisMatches &&\n !!this.dictionaryService.getDictionaryQueryEntries(\n this.blockDispatcher.latestBufferedHeight ??\n Math.min(...this.project.dataSources.map((ds) => ds.startBlock)),\n ).length\n );\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\n this.updateDictionary();\n this.eventEmitter.emit(IndexerEvent.UsingDictionary, {\n value: Number(this.useDictionary),\n });\n\n if (this.project.network.dictionary) {\n this.evmChainId = await this.dictionaryService.getEvmChainId();\n }\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 logger.debug(`finalized:${currentFinalizedHeight.toString()}`);\n const finalizedHeader = await this.api.getBlockByHeightOrHash(\n currentFinalizedHeight,\n );\n if (this.latestFinalizedHeight !== currentFinalizedHeight) {\n this.latestFinalizedHeight = currentFinalizedHeight;\n this.unfinalizedBlocksService.registerFinalizedBlock(finalizedHeader);\n if (!this.nodeConfig.unfinalizedBlocks) {\n if (!this.nodeConfig.unfinalizedBlocks) {\n this.eventEmitter.emit(IndexerEvent.BlockTarget, {\n height: this.latestFinalizedHeight,\n });\n }\n }\n }\n } catch (e) {\n logger.warn(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.getBestBlockHeight();\n logger.debug(`best:${currentBestHeight.toString()}`);\n if (this.latestBestHeight !== currentBestHeight) {\n this.latestBestHeight = currentBestHeight;\n this.eventEmitter.emit(IndexerEvent.BlockBest, {\n height: this.latestBestHeight,\n });\n\n if (this.nodeConfig.unfinalizedBlocks) {\n this.eventEmitter.emit(IndexerEvent.BlockTarget, {\n height: this.latestBestHeight,\n });\n }\n }\n } catch (e) {\n logger.warn(e, `Having a problem when get best block`);\n }\n }\n\n private 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 const latestHeight = this.nodeConfig.unfinalizedBlocks\n ? this.latestBestHeight\n : this.latestFinalizedHeight;\n\n if (\n this.blockDispatcher.freeSize < scaledBatchSize ||\n startBlockHeight > latestHeight\n ) {\n await delay(1);\n continue;\n }\n\n if (this.useDictionary) {\n const queryEndBlock = startBlockHeight + DICTIONARY_MAX_QUERY_SIZE;\n const moduloBlocks = this.getModuloBlocks(\n startBlockHeight,\n queryEndBlock,\n );\n\n try {\n const dictionary =\n await this.dictionaryService.scopedDictionaryEntries(\n startBlockHeight,\n queryEndBlock,\n scaledBatchSize,\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\n const endHeight = this.nextEndBlockHeight(\n startBlockHeight,\n scaledBatchSize,\n );\n\n if (handlers.length && 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 if (this.nodeConfig.unfinalizedBlocks) {\n if (endBlockHeight >= this.latestBestHeight) {\n endBlockHeight = this.latestBestHeight;\n }\n } else {\n endBlockHeight = this.latestFinalizedHeight;\n }\n }\n return endBlockHeight;\n }\n\n private dictionaryValidation(\n { _metadata: metaData }: Dictionary,\n startBlockHeight: number,\n ): boolean {\n if (\n metaData.genesisHash !== this.api.getGenesisHash() &&\n this.evmChainId !== this.api.getChainId().toString()\n ) {\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.dictionaryGenesisMatches = 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 async resetForIncorrectBestBlock(blockHeight: number): Promise<void> {\n await this.syncDynamicDatascourcesFromMeta();\n this.updateDictionary();\n this.blockDispatcher.flushQueue(blockHeight);\n }\n}\n"]}
|
|
@@ -6,6 +6,7 @@ import { DsProcessorService } from './ds-processor.service';
|
|
|
6
6
|
import { DynamicDsService } from './dynamic-ds.service';
|
|
7
7
|
import { ProjectService } from './project.service';
|
|
8
8
|
import { SandboxService } from './sandbox.service';
|
|
9
|
+
import { UnfinalizedBlocksService } from './unfinalizedBlocks.service';
|
|
9
10
|
export declare class IndexerManager {
|
|
10
11
|
private storeService;
|
|
11
12
|
private apiService;
|
|
@@ -15,17 +16,19 @@ export declare class IndexerManager {
|
|
|
15
16
|
private nodeConfig;
|
|
16
17
|
private sandboxService;
|
|
17
18
|
private dynamicDsService;
|
|
19
|
+
private unfinalizedBlocksService;
|
|
18
20
|
private dsProcessorService;
|
|
19
21
|
private projectService;
|
|
20
22
|
private api;
|
|
21
23
|
private filteredDataSources;
|
|
22
|
-
constructor(storeService: StoreService, apiService: ApiService, poiService: PoiService, sequelize: Sequelize, project: SubqueryProject, nodeConfig: NodeConfig, sandboxService: SandboxService, dynamicDsService: DynamicDsService, dsProcessorService: DsProcessorService, projectService: ProjectService);
|
|
24
|
+
constructor(storeService: StoreService, apiService: ApiService, poiService: PoiService, sequelize: Sequelize, project: SubqueryProject, nodeConfig: NodeConfig, sandboxService: SandboxService, dynamicDsService: DynamicDsService, unfinalizedBlocksService: UnfinalizedBlocksService, dsProcessorService: DsProcessorService, projectService: ProjectService);
|
|
23
25
|
indexBlock(blockContent: EthereumBlockWrapper): Promise<{
|
|
24
26
|
dynamicDsCreated: boolean;
|
|
25
27
|
operationHash: Uint8Array;
|
|
26
28
|
reindexBlockHeight: null;
|
|
27
29
|
}>;
|
|
28
30
|
start(): Promise<void>;
|
|
31
|
+
private processUnfinalizedBlocks;
|
|
29
32
|
private filterDataSources;
|
|
30
33
|
private indexBlockData;
|
|
31
34
|
private indexBlockContent;
|
|
@@ -24,10 +24,11 @@ const ds_processor_service_1 = require("./ds-processor.service");
|
|
|
24
24
|
const dynamic_ds_service_1 = require("./dynamic-ds.service");
|
|
25
25
|
const project_service_1 = require("./project.service");
|
|
26
26
|
const sandbox_service_1 = require("./sandbox.service");
|
|
27
|
+
const unfinalizedBlocks_service_1 = require("./unfinalizedBlocks.service");
|
|
27
28
|
const NULL_MERKEL_ROOT = (0, util_1.hexToU8a)('0x00');
|
|
28
29
|
const logger = (0, node_core_1.getLogger)('indexer');
|
|
29
30
|
let IndexerManager = class IndexerManager {
|
|
30
|
-
constructor(storeService, apiService, poiService, sequelize, project, nodeConfig, sandboxService, dynamicDsService, dsProcessorService, projectService) {
|
|
31
|
+
constructor(storeService, apiService, poiService, sequelize, project, nodeConfig, sandboxService, dynamicDsService, unfinalizedBlocksService, dsProcessorService, projectService) {
|
|
31
32
|
this.storeService = storeService;
|
|
32
33
|
this.apiService = apiService;
|
|
33
34
|
this.poiService = poiService;
|
|
@@ -36,14 +37,16 @@ let IndexerManager = class IndexerManager {
|
|
|
36
37
|
this.nodeConfig = nodeConfig;
|
|
37
38
|
this.sandboxService = sandboxService;
|
|
38
39
|
this.dynamicDsService = dynamicDsService;
|
|
40
|
+
this.unfinalizedBlocksService = unfinalizedBlocksService;
|
|
39
41
|
this.dsProcessorService = dsProcessorService;
|
|
40
42
|
this.projectService = projectService;
|
|
41
43
|
logger.info('indexer manager start');
|
|
42
44
|
this.api = this.apiService.api;
|
|
43
45
|
}
|
|
44
46
|
async indexBlock(blockContent) {
|
|
45
|
-
const { blockHeight } = blockContent;
|
|
47
|
+
const { block, blockHeight } = blockContent;
|
|
46
48
|
let dynamicDsCreated = false;
|
|
49
|
+
let reindexBlockHeight = null;
|
|
47
50
|
const tx = await this.sequelize.transaction();
|
|
48
51
|
this.storeService.setTransaction(tx);
|
|
49
52
|
this.storeService.setBlockHeight(blockHeight);
|
|
@@ -52,6 +55,7 @@ let IndexerManager = class IndexerManager {
|
|
|
52
55
|
try {
|
|
53
56
|
this.filteredDataSources = this.filterDataSources(blockHeight);
|
|
54
57
|
const datasources = this.filteredDataSources.concat(...(await this.dynamicDsService.getDynamicDatasources()));
|
|
58
|
+
reindexBlockHeight = await this.processUnfinalizedBlocks(block, tx);
|
|
55
59
|
await this.indexBlockData(blockContent, datasources,
|
|
56
60
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
57
61
|
async (ds) => {
|
|
@@ -96,13 +100,19 @@ let IndexerManager = class IndexerManager {
|
|
|
96
100
|
return {
|
|
97
101
|
dynamicDsCreated,
|
|
98
102
|
operationHash,
|
|
99
|
-
reindexBlockHeight
|
|
103
|
+
reindexBlockHeight,
|
|
100
104
|
};
|
|
101
105
|
}
|
|
102
106
|
async start() {
|
|
103
107
|
await this.projectService.init();
|
|
104
108
|
logger.info('indexer manager started');
|
|
105
109
|
}
|
|
110
|
+
async processUnfinalizedBlocks(block, tx) {
|
|
111
|
+
if (this.nodeConfig.unfinalizedBlocks) {
|
|
112
|
+
return this.unfinalizedBlocksService.processUnfinalizedBlocks(block, tx);
|
|
113
|
+
}
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
106
116
|
filterDataSources(nextProcessingHeight) {
|
|
107
117
|
const filteredDs = this.projectService.dataSources.filter((ds) => ds.startBlock <= nextProcessingHeight);
|
|
108
118
|
if (filteredDs.length === 0) {
|
|
@@ -248,6 +258,7 @@ IndexerManager = __decorate([
|
|
|
248
258
|
node_core_1.NodeConfig,
|
|
249
259
|
sandbox_service_1.SandboxService,
|
|
250
260
|
dynamic_ds_service_1.DynamicDsService,
|
|
261
|
+
unfinalizedBlocks_service_1.UnfinalizedBlocksService,
|
|
251
262
|
ds_processor_service_1.DsProcessorService,
|
|
252
263
|
project_service_1.ProjectService])
|
|
253
264
|
], IndexerManager);
|