@subql/node-ethereum 6.3.4-1 → 6.4.0-2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -2,17 +2,16 @@ import { UnfinalizedBlocksService as BaseUnfinalizedBlocksService, Header, NodeC
|
|
|
2
2
|
import { BlockchainService } from '../blockchain.service';
|
|
3
3
|
import { BlockContent } from './types';
|
|
4
4
|
export declare class UnfinalizedBlocksService extends BaseUnfinalizedBlocksService<BlockContent> {
|
|
5
|
-
private supportsFinalization?;
|
|
6
5
|
private startupCheck;
|
|
7
6
|
constructor(nodeConfig: NodeConfig, storeModelProvider: IStoreModelProvider, blockchainService: BlockchainService);
|
|
8
7
|
/**
|
|
9
8
|
* @param reindex - the function to reindex back before a fork
|
|
10
|
-
* @param supportsFinalization - If the chain supports the 'finalized' block tag this should be true.
|
|
11
9
|
* */
|
|
12
|
-
init(reindex: (targetHeight: Header) => Promise<void
|
|
10
|
+
init(reindex: (targetHeight: Header) => Promise<void>): Promise<Header | undefined>;
|
|
13
11
|
/**
|
|
14
|
-
* Checks if a fork has happened
|
|
15
|
-
*
|
|
12
|
+
* Checks if a fork has happened during startup by verifying the last unfinalized block hash.
|
|
13
|
+
* Runtime fork detection is handled by node-core's registerUnfinalizedBlock which validates parentHash chain.
|
|
14
|
+
* @returns (Header | undefined) - The header if fork is detected at startup
|
|
16
15
|
* */
|
|
17
16
|
protected hasForked(): Promise<Header | undefined>;
|
|
18
17
|
/**
|
|
@@ -22,7 +22,6 @@ const blockchain_service_1 = require("../blockchain.service");
|
|
|
22
22
|
const NodeConfig_1 = require("../configure/NodeConfig");
|
|
23
23
|
const logger = (0, node_core_1.getLogger)('UnfinalizedBlocksService');
|
|
24
24
|
let UnfinalizedBlocksService = class UnfinalizedBlocksService extends node_core_1.UnfinalizedBlocksService {
|
|
25
|
-
supportsFinalization;
|
|
26
25
|
startupCheck = true;
|
|
27
26
|
constructor(nodeConfig, storeModelProvider, blockchainService) {
|
|
28
27
|
// blockchain service cast is due to unsolvable typescript generic error, it wokrs on the main sdk but not here
|
|
@@ -30,22 +29,18 @@ let UnfinalizedBlocksService = class UnfinalizedBlocksService extends node_core_
|
|
|
30
29
|
}
|
|
31
30
|
/**
|
|
32
31
|
* @param reindex - the function to reindex back before a fork
|
|
33
|
-
* @param supportsFinalization - If the chain supports the 'finalized' block tag this should be true.
|
|
34
32
|
* */
|
|
35
33
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
36
|
-
async init(reindex
|
|
37
|
-
this.supportsFinalization = supportsFinalisation;
|
|
34
|
+
async init(reindex) {
|
|
38
35
|
return super.init(reindex);
|
|
39
36
|
}
|
|
40
37
|
/**
|
|
41
|
-
* Checks if a fork has happened
|
|
42
|
-
*
|
|
38
|
+
* Checks if a fork has happened during startup by verifying the last unfinalized block hash.
|
|
39
|
+
* Runtime fork detection is handled by node-core's registerUnfinalizedBlock which validates parentHash chain.
|
|
40
|
+
* @returns (Header | undefined) - The header if fork is detected at startup
|
|
43
41
|
* */
|
|
44
42
|
async hasForked() {
|
|
45
|
-
|
|
46
|
-
return super.hasForked();
|
|
47
|
-
}
|
|
48
|
-
// Startup check helps speed up finding a fork by checking the hash of the last unfinalized block
|
|
43
|
+
// Startup check verifies the last unfinalized block hash against the chain
|
|
49
44
|
if (this.startupCheck) {
|
|
50
45
|
this.startupCheck = false;
|
|
51
46
|
const lastUnfinalized = (0, lodash_1.last)(this.unfinalizedBlocks);
|
|
@@ -62,6 +57,7 @@ let UnfinalizedBlocksService = class UnfinalizedBlocksService extends node_core_
|
|
|
62
57
|
const i = this.unfinalizedBlocks.length - 1;
|
|
63
58
|
const current = this.unfinalizedBlocks[i];
|
|
64
59
|
const parent = this.unfinalizedBlocks[i - 1];
|
|
60
|
+
// this now won't find fork as such cases has been covered when registerUnfinalizedBlock() is called
|
|
65
61
|
if (current.parentHash !== parent.blockHash) {
|
|
66
62
|
// We've found a fork now we need to find where the fork happened
|
|
67
63
|
logger.warn(`Block fork detected at ${current.blockHeight}. Parent hash ${current.parentHash} doesn't match indexed parent ${parent.blockHash}.`);
|
|
@@ -74,9 +70,6 @@ let UnfinalizedBlocksService = class UnfinalizedBlocksService extends node_core_
|
|
|
74
70
|
* @return (number | undefined) - The block height to rewind to to remove forked data
|
|
75
71
|
**/
|
|
76
72
|
async getLastCorrectFinalizedBlock(forkedHeader) {
|
|
77
|
-
if (this.supportsFinalization) {
|
|
78
|
-
return super.getLastCorrectFinalizedBlock(forkedHeader);
|
|
79
|
-
}
|
|
80
73
|
const bestVerifiableBlocks = this.unfinalizedBlocks.filter(({ blockHeight }) => blockHeight < forkedHeader.blockHeight);
|
|
81
74
|
let checkingHeader = forkedHeader;
|
|
82
75
|
// Work backwards through the blocks until we find a matching hash
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unfinalizedBlocks.service.js","sourceRoot":"","sources":["../../src/indexer/unfinalizedBlocks.service.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;;;;;;;;;;;;;;AAEnC,2CAAoD;AACpD,gDAS0B;AAC1B,mCAA8B;AAC9B,8DAA0D;AAC1D,wDAA6D;AAG7D,MAAM,MAAM,GAAG,IAAA,qBAAS,EAAC,0BAA0B,CAAC,CAAC;AAG9C,IAAM,wBAAwB,GAA9B,MAAM,wBAAyB,SAAQ,oCAA0C;IAC9E,
|
|
1
|
+
{"version":3,"file":"unfinalizedBlocks.service.js","sourceRoot":"","sources":["../../src/indexer/unfinalizedBlocks.service.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport { Inject, Injectable } from '@nestjs/common';\nimport {\n UnfinalizedBlocksService as BaseUnfinalizedBlocksService,\n Header,\n NodeConfig,\n getLogger,\n profiler,\n POI_NOT_ENABLED_ERROR_MESSAGE,\n IStoreModelProvider,\n IBlockchainService,\n} from '@subql/node-core';\nimport { last } from 'lodash';\nimport { BlockchainService } from '../blockchain.service';\nimport { EthereumNodeConfig } from '../configure/NodeConfig';\nimport { BlockContent } from './types';\n\nconst logger = getLogger('UnfinalizedBlocksService');\n\n@Injectable()\nexport class UnfinalizedBlocksService extends BaseUnfinalizedBlocksService<BlockContent> {\n private startupCheck = true;\n\n constructor(\n nodeConfig: NodeConfig,\n @Inject('IStoreModelProvider') storeModelProvider: IStoreModelProvider,\n @Inject('IBlockchainService') blockchainService: BlockchainService,\n ) {\n // blockchain service cast is due to unsolvable typescript generic error, it wokrs on the main sdk but not here\n super(\n new EthereumNodeConfig(nodeConfig),\n storeModelProvider,\n blockchainService as IBlockchainService,\n );\n }\n\n /**\n * @param reindex - the function to reindex back before a fork\n * */\n // eslint-disable-next-line @typescript-eslint/require-await\n async init(\n reindex: (targetHeight: Header) => Promise<void>,\n ): Promise<Header | undefined> {\n return super.init(reindex);\n }\n\n /**\n * Checks if a fork has happened during startup by verifying the last unfinalized block hash.\n * Runtime fork detection is handled by node-core's registerUnfinalizedBlock which validates parentHash chain.\n * @returns (Header | undefined) - The header if fork is detected at startup\n * */\n @profiler()\n protected async hasForked(): Promise<Header | undefined> {\n // Startup check verifies the last unfinalized block hash against the chain\n if (this.startupCheck) {\n this.startupCheck = false;\n const lastUnfinalized = last(this.unfinalizedBlocks);\n if (lastUnfinalized) {\n const checkUnfinalized =\n await this.blockchainService.getHeaderForHeight(\n lastUnfinalized.blockHeight,\n );\n\n if (lastUnfinalized.blockHash !== checkUnfinalized.blockHash) {\n return checkUnfinalized;\n }\n }\n }\n\n if (this.unfinalizedBlocks.length <= 2) {\n return;\n }\n\n const i = this.unfinalizedBlocks.length - 1;\n const current = this.unfinalizedBlocks[i];\n const parent = this.unfinalizedBlocks[i - 1];\n\n // this now won't find fork as such cases has been covered when registerUnfinalizedBlock() is called\n if (current.parentHash !== parent.blockHash) {\n // We've found a fork now we need to find where the fork happened\n logger.warn(\n `Block fork detected at ${current.blockHeight}. Parent hash ${current.parentHash} doesn't match indexed parent ${parent.blockHash}.`,\n );\n\n return current;\n }\n\n return;\n }\n\n /**\n * Finds the height before the fork occurred based on the result of hasForked\n * @return (number | undefined) - The block height to rewind to to remove forked data\n **/\n protected async getLastCorrectFinalizedBlock(\n forkedHeader: Header,\n ): Promise<Header | undefined> {\n const bestVerifiableBlocks = this.unfinalizedBlocks.filter(\n ({ blockHeight }) => blockHeight < forkedHeader.blockHeight,\n );\n\n let checkingHeader = forkedHeader;\n\n // Work backwards through the blocks until we find a matching hash\n for (const header of bestVerifiableBlocks.reverse()) {\n if (\n header.blockHash === checkingHeader.blockHash ||\n header.blockHash === checkingHeader.parentHash\n ) {\n return header;\n }\n\n // Get the new parent\n if (!checkingHeader.parentHash) {\n throw new Error('Unable to get parent hash for header');\n }\n const parentHeight = checkingHeader.blockHeight - 1;\n try {\n checkingHeader = await this.blockchainService.getHeaderForHash(\n checkingHeader.parentHash,\n );\n } catch {\n // Parent block not found on chain (orphaned), fall back to height-based check\n logger.warn(\n `Failed to get block by hash, falling back to height-based check at height ${parentHeight}`,\n );\n checkingHeader = await this.blockchainService.getHeaderForHeight(\n parentHeight,\n );\n }\n }\n\n try {\n const poiHeader = await this.findFinalizedUsingPOI(checkingHeader);\n return poiHeader;\n } catch (e: any) {\n if (e.message === POI_NOT_ENABLED_ERROR_MESSAGE) {\n return this.blockchainService.getHeaderForHeight(\n Math.max(\n 0,\n forkedHeader.blockHeight -\n (this.nodeConfig as EthereumNodeConfig).blockForkReindex,\n ),\n );\n }\n // TODO rewind back 1000+ blocks\n logger.info('Failed to use POI to rewind block');\n throw e;\n }\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@subql/node-ethereum",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.4.0-2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "Ian He",
|
|
6
6
|
"license": "GPL-3.0",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"@nestjs/schedule": "^5.0.1",
|
|
27
27
|
"@subql/common": "^5.8.2",
|
|
28
28
|
"@subql/common-ethereum": "4.10.1",
|
|
29
|
-
"@subql/node-core": "^19.
|
|
29
|
+
"@subql/node-core": "^19.2.0",
|
|
30
30
|
"@subql/testing": "^2.2.1",
|
|
31
31
|
"@subql/types-ethereum": "4.2.3",
|
|
32
32
|
"cacheable-lookup": "6",
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
"CHANGELOG.md",
|
|
71
71
|
"LICENSE"
|
|
72
72
|
],
|
|
73
|
-
"stableVersion": "6.
|
|
73
|
+
"stableVersion": "6.4.0-1"
|
|
74
74
|
}
|