@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.
@@ -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.getBlockByHeight(startBlock);
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":";AAAA,gEAAgE;AAChE,sCAAsC;;;;;;AAItC,0CAMuB;AACvB,4DASgC;AAChC,wCAAqD;AACrD,oEAAkC;AAGlC,8CAI0B;AAkB1B,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,EAAE;IACnC,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,qBAAqB,CAAC,CAAC;AACrE,CAAC,CAAC;AAEF,MAAa,eAAe;IAU1B,MAAM,CAAC,KAAK,CAAC,MAAM,CACjB,IAAY,EACZ,gBAAwD,EACxD,aAA6B;QAE7B,kEAAkE;QAClE,qEAAqE;QACrE,MAAM,MAAM,GAAG,MAAM,sBAAa,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;QAC/D,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,gBAAgB,EAAE,CAAC;QACtD,IAAI,aAAa,KAAK,SAAS,EAAE;YAC/B,MAAM,IAAI,KAAK,CAAC,kCAAkC,IAAI,SAAS,CAAC,CAAC;SAClE;QACD,MAAM,QAAQ,GAAG,IAAA,8CAA4B,EAAC,aAAa,CAAC,CAAC;QAE7D,IAAI,QAAQ,CAAC,QAAQ,EAAE;YACrB,OAAO,4BAA4B,CACjC,QAAQ,CAAC,QAAQ,EACjB,MAAM,EACN,IAAI,EACJ,gBAAgB,CACjB,CAAC;SACH;aAAM;YACL,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;SACnC;IACH,CAAC;CACF;AAnCD,0CAmCC;AASD,SAAS,cAAc,CAAC,OAAY;IAClC,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,WAAW,EAAE;QAC1C,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;KACvE;SAAM,IAAI,OAAO,CAAC,WAAW,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;QAClD,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC;KACvC;IACD,OAAO,OAAO,CAAC,WAAW,CAAC;IAC3B,OAAO,OAAO,CAAC;AACjB,CAAC;AAID,KAAK,UAAU,2BAA2B,CACxC,eAAiC,EACjC,MAAc,EACd,IAAY,EACZ,gBAAwD;IAExD,MAAM,IAAI,GAAG,MAAM,IAAA,wBAAc,EAAC,MAAM,CAAC,CAAC;IAE1C,MAAM,OAAO,GAAG,cAAc,iCACzB,eAAe,CAAC,OAAO,GACvB,gBAAgB,EACnB,CAAC;IAEH,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE;QACrB,MAAM,IAAI,KAAK,CACb,2DAA2D,OAAO,CAAC,OAAO,GAAG,CAC9E,CAAC;KACH;IAED,IAAI,YAAoB,CAAC;IACzB,IAAI;QACF,YAAY,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;KAClE;IAAC,OAAO,CAAC,EAAE;QACV,MAAM,IAAI,KAAK,CACb,mCAAmC,eAAe,CAAC,MAAM,CAAC,IAAI,EAAE,CACjE,CAAC;KACH;IACD,MAAM,MAAM,GAAG,IAAA,6BAAqB,EAAC,YAAY,CAAC,CAAC;IAEnD,MAAM,UAAU,GAAG,eAAe,CAAC,OAAO,CAAC,UAAU;QACnD,CAAC,CAAC,MAAM,IAAA,uBAAa,EAAC,MAAM,EAAE,IAAI,EAAE,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;QAC5E,CAAC,CAAC,SAAS,CAAC;IAEd,MAAM,WAAW,GAAG,MAAM,IAAA,iCAAuB,EAC/C,eAAe,CAAC,WAAW,EAC3B,MAAM,EACN,IAAI,CACL,CAAC;IAEF,MAAM,SAAS,GAAG,MAAM,oBAAoB,CAAC,eAAe,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAE5E,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;QACpC,IAAI;QACJ,OAAO;QACP,WAAW;QACX,MAAM;QACN,UAAU;QACV,SAAS;KACV,CAAC;AACJ,CAAC;AAED,MAAM,EACJ,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,cAAc,GACxB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAElC,KAAK,UAAU,4BAA4B,CACzC,eAA0C,EAC1C,MAAc,EACd,IAAY,EACZ,gBAAwD;IAExD,MAAM,OAAO,GAAG,MAAM,2BAA2B,CAC/C,eAAe,EACf,MAAM,EACN,IAAI,EACJ,gBAAgB,CACjB,CAAC;IACF,OAAO,CAAC,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC;IACxC,IAAI,CAAC,IAAA,uBAAc,EAAC,cAAc,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;QAChE,MAAM,IAAI,KAAK,CACb,+BAA+B,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,kBAAkB,cAAc,EAAE,CAC7F,CAAC;KACH;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,oBAAoB,CACjC,eAA0C,EAC1C,IAAY,EACZ,MAAc;IAEd,IAAI,eAAe,CAAC,SAAS,IAAI,eAAe,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE;QACvE,MAAM,WAAW,GAAG,MAAM,IAAA,iCAAuB,EAC/C,eAAe,CAAC,SAAS,EACzB,MAAM,EACN,IAAI,CACL,CAAC;QACF,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,iCACjC,EAAE,KACL,IAAI,EAAE,eAAe,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,IAC3C,CAAC,CAAC;KACL;AACH,CAAC;AAED,4DAA4D;AACrD,KAAK,UAAU,yCAAyC,CAC7D,WAA6B,EAC7B,GAAgB;IAEhB,MAAM,IAAI,GAAG,IAAI,wBAAI,EAAE,CAAC;IAExB,WAAW,GAAG,MAAM,OAAO,CAAC,GAAG,CAC7B,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;;QAC3B,IAAI,IAAA,6BAAW,EAAC,EAAE,CAAC,EAAE;YACnB,MAAM,UAAU,GAAG,MAAA,EAAE,CAAC,UAAU,mCAAI,CAAC,CAAC;YACtC,IAAI,KAAY,CAAC;YACjB,IAAI,kBAAwB,CAAC;YAE7B,EAAE,CAAC,OAAO,CAAC,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CACrC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;;gBACxC,IAAI,OAAO,CAAC,IAAI,KAAK,qCAAmB,CAAC,KAAK,EAAE;oBAC9C,IAAI,MAAA,OAAO,CAAC,MAAM,0CAAE,SAAS,EAAE;wBAC7B,IAAI,CAAC,KAAK,EAAE;4BACV,KAAK,GAAG,MAAM,GAAG,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;4BAC/C,kBAAkB,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,aAAa;yBACrE;wBACD,IAAI;4BACF,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;yBAC3C;wBAAC,OAAO,CAAC,EAAE;4BACV,MAAM,IAAI,KAAK,CACb,wBAAwB,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,CACnD,CAAC;yBACH;wBAED,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;wBAClD,OAAO,CAAC,MAAkC,CAAC,YAAY,GAAG;4BACzD,QAAQ,EAAE,QAAQ;4BAClB,IAAI,IAAI;gCACN,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;4BACnD,CAAC;yBACF,CAAC;qBACH;iBACF;gBACD,OAAO,OAAO,CAAC;YACjB,CAAC,CAAC,CACH,CAAC;SACH;QACD,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC,CACH,CAAC;IAEF,OAAO,WAAW,CAAC;AACrB,CAAC;AA/CD,8FA+CC","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
- getLastHeight(): Promise<number>;
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
- getFinalizedBlockHeight(): Promise<number>;
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 getLastHeight() {
66
- return this.client.getBlockNumber();
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 getFinalizedBlockHeight() {
81
- // Doesn't seem to be a difference between finalized and latest
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":"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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 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;AA0D5C,IAAM,WAAW,GAAjB,MAAM,WAAW;CAAG,CAAA;AAAd,WAAW;IAxDvB,IAAA,eAAM,EAAC;QACN,SAAS,EAAE;YACT,wBAAY;YACZ;gBACE,OAAO,EAAE,sBAAU;gBACnB,UAAU,EAAE,KAAK,EAAE,OAAwB,EAAE,EAAE;oBAC7C,MAAM,UAAU,GAAG,IAAI,yCAAkB,CAAC,OAAO,CAAC,CAAC;oBAEnD,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;oBACxB,OAAO,UAAU,CAAC;gBACpB,CAAC;gBACD,MAAM,EAAE,CAAC,iCAAe,CAAC;aAC1B;YACD,gCAAc;YACd;gBACE,OAAO,EAAE,kBAAkB;gBAC3B,UAAU,EAAE,CACV,UAAsB,EACtB,YAA2B,EAC3B,cAA8B,EAC9B,UAAsB,EACtB,cAA8B,EAC9B,EAAE,CACF,UAAU,CAAC,OAAO,KAAK,SAAS;oBAC9B,CAAC,CAAC,IAAI,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;SACf;QACD,OAAO,EAAE,CAAC,wBAAY,EAAE,sBAAU,CAAC;KACpC,CAAC;GACW,WAAW,CAAG;AAAd,kCAAW","sourcesContent":["// Copyright 2020-2022 OnFinality Limited authors & contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Module } from '@nestjs/common';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport {\n BenchmarkService,\n MmrService,\n StoreService,\n PoiService,\n ApiService,\n NodeConfig,\n} from '@subql/node-core';\nimport { SubqueryProject } from '../configure/SubqueryProject';\nimport { EthereumApiService } from '../ethereum/api.service.ethereum';\nimport {\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';\n\n@Module({\n providers: [\n StoreService,\n {\n provide: ApiService,\n useFactory: async (project: SubqueryProject) => {\n const apiService = new EthereumApiService(project);\n\n await apiService.init();\n return apiService;\n },\n inject: [SubqueryProject],\n },\n IndexerManager,\n {\n provide: 'IBlockDispatcher',\n useFactory: (\n nodeConfig: NodeConfig,\n eventEmitter: EventEmitter2,\n projectService: ProjectService,\n apiService: ApiService,\n indexerManager: IndexerManager,\n ) =>\n nodeConfig.workers !== undefined\n ? new WorkerBlockDispatcherService(\n nodeConfig,\n eventEmitter,\n projectService,\n )\n : new BlockDispatcherService(\n apiService,\n nodeConfig,\n indexerManager,\n eventEmitter,\n projectService,\n ),\n inject: [\n NodeConfig,\n EventEmitter2,\n ProjectService,\n ApiService,\n IndexerManager,\n ],\n },\n FetchService,\n BenchmarkService,\n DictionaryService,\n SandboxService,\n DsProcessorService,\n DynamicDsService,\n PoiService,\n MmrService,\n ProjectService,\n ],\n exports: [StoreService, MmrService],\n})\nexport class FetchModule {}\n"]}
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.eventEmitter.emit(node_core_1.IndexerEvent.BlockTarget, {
202
- height: this.latestFinalizedHeight,
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.getLastHeight();
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: null,
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);