@lodestar/fork-choice 1.46.0-dev.e6f04acd82 → 1.46.0-dev.f0f5d069e2

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.
@@ -1,4 +1,5 @@
1
1
  import { Root, RootHex } from "@lodestar/types";
2
+ import { LogLevel, Logger } from "@lodestar/utils";
2
3
  import { IForkChoice } from "./interface.js";
3
4
  /**
4
5
  * Under honest majority and certain network synchronicity assumptions there exists a block
@@ -9,9 +10,21 @@ import { IForkChoice } from "./interface.js";
9
10
  */
10
11
  export declare function getSafeBeaconBlockRoot(fc: IForkChoice): Root;
11
12
  /**
12
- * Get execution payload hash for the safe block
13
+ * Get execution payload hash to report as `safeBlockHash` in `engine_forkchoiceUpdated`.
13
14
  *
14
- * https://github.com/ethereum/consensus-specs/blob/master/fork_choice/safe-block.md#get_safe_execution_block_hash
15
+ * Pre-Gloas: the confirmed block's own payload hash.
16
+ * Post-Gloas: the confirmed block's bid `parent_block_hash` — under ePBS the block's own
17
+ * payload may not yet be confirmed canonical, so we report the parent EL block which has
18
+ * been (the bid commits to extending it).
19
+ *
20
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.13/specs/bellatrix/fast-confirmation.md#new-get_safe_execution_block_hash
21
+ */
22
+ export declare function getSafeExecutionBlockHash(forkChoice: IForkChoice, logger?: Pick<Logger, LogLevel.warn>): RootHex;
23
+ /**
24
+ * Get execution payload hash to report as `finalizedBlockHash` in `engine_forkchoiceUpdated`.
25
+ * Mirrors `getSafeExecutionBlockHash`: post-Gloas returns the bid `parent_block_hash`.
26
+ *
27
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.13/specs/gloas/fork-choice.md#notify_forkchoice_updated
15
28
  */
16
- export declare function getSafeExecutionBlockHash(forkChoice: IForkChoice): RootHex;
29
+ export declare function getFinalizedExecutionBlockHash(forkChoice: IForkChoice, logger?: Pick<Logger, LogLevel.warn>): RootHex;
17
30
  //# sourceMappingURL=safeBlocks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"safeBlocks.d.ts","sourceRoot":"","sources":["../../src/forkChoice/safeBlocks.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,IAAI,EAAE,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAE3C;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI,CAM5D;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,WAAW,GAAG,OAAO,CAS1E"}
1
+ {"version":3,"file":"safeBlocks.d.ts","sourceRoot":"","sources":["../../src/forkChoice/safeBlocks.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,IAAI,EAAE,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAU,MAAM,iBAAiB,CAAC;AAE1D,OAAO,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAE3C;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI,CAM5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,CAUhH;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAAC,UAAU,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,CAErH"}
@@ -1,5 +1,6 @@
1
- import { ZERO_HASH_HEX } from "@lodestar/params";
1
+ import { GENESIS_SLOT, ZERO_HASH_HEX } from "@lodestar/params";
2
2
  import { fromHex } from "@lodestar/utils";
3
+ import { HEX_ZERO_HASH, isGloasBlock } from "../protoArray/interface.js";
3
4
  /**
4
5
  * Under honest majority and certain network synchronicity assumptions there exists a block
5
6
  * that is safe from re-orgs. Normally this block is pretty close to the head of canonical
@@ -15,18 +16,51 @@ export function getSafeBeaconBlockRoot(fc) {
15
16
  return fc.getJustifiedCheckpoint().root;
16
17
  }
17
18
  /**
18
- * Get execution payload hash for the safe block
19
+ * Get execution payload hash to report as `safeBlockHash` in `engine_forkchoiceUpdated`.
19
20
  *
20
- * https://github.com/ethereum/consensus-specs/blob/master/fork_choice/safe-block.md#get_safe_execution_block_hash
21
+ * Pre-Gloas: the confirmed block's own payload hash.
22
+ * Post-Gloas: the confirmed block's bid `parent_block_hash` — under ePBS the block's own
23
+ * payload may not yet be confirmed canonical, so we report the parent EL block which has
24
+ * been (the bid commits to extending it).
25
+ *
26
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.13/specs/bellatrix/fast-confirmation.md#new-get_safe_execution_block_hash
21
27
  */
22
- export function getSafeExecutionBlockHash(forkChoice) {
23
- const confirmedRoot = forkChoice.getConfirmedRoot();
24
- if (confirmedRoot) {
25
- const confirmedBlock = forkChoice.getBlockHexDefaultStatus(confirmedRoot);
26
- if (confirmedBlock?.executionPayloadBlockHash) {
27
- return confirmedBlock.executionPayloadBlockHash;
28
- }
28
+ export function getSafeExecutionBlockHash(forkChoice, logger) {
29
+ const confirmedBlock = forkChoice.getConfirmedBlock();
30
+ if (confirmedBlock === null) {
31
+ logger?.warn("Confirmed block not found, using zero safe execution block hash", {
32
+ confirmedRoot: forkChoice.getConfirmedRoot(),
33
+ });
34
+ return ZERO_HASH_HEX;
35
+ }
36
+ return getExecutionBlockHash(confirmedBlock, logger);
37
+ }
38
+ /**
39
+ * Get execution payload hash to report as `finalizedBlockHash` in `engine_forkchoiceUpdated`.
40
+ * Mirrors `getSafeExecutionBlockHash`: post-Gloas returns the bid `parent_block_hash`.
41
+ *
42
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.13/specs/gloas/fork-choice.md#notify_forkchoice_updated
43
+ */
44
+ export function getFinalizedExecutionBlockHash(forkChoice, logger) {
45
+ return getExecutionBlockHash(forkChoice.getFinalizedBlock(), logger);
46
+ }
47
+ function getExecutionBlockHash(block, logger) {
48
+ if (isGloasBlock(block)) {
49
+ return block.parentBlockHash;
50
+ }
51
+ // The genesis block body carries a default execution payload, so it is not an execution block
52
+ // per the spec (`is_execution_block`); its proto-array payload hash comes from the anchor
53
+ // state header instead of a block body and must not be reported as safe.
54
+ if (block.slot === GENESIS_SLOT) {
55
+ return HEX_ZERO_HASH;
56
+ }
57
+ if (block.executionPayloadBlockHash === null) {
58
+ logger?.warn("Execution payload block hash not found, using zero hash", {
59
+ blockRoot: block.blockRoot,
60
+ slot: block.slot,
61
+ });
62
+ return HEX_ZERO_HASH;
29
63
  }
30
- return ZERO_HASH_HEX;
64
+ return block.executionPayloadBlockHash;
31
65
  }
32
66
  //# sourceMappingURL=safeBlocks.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"safeBlocks.js","sourceRoot":"","sources":["../../src/forkChoice/safeBlocks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAC,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAGxC;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,EAAe;IACpD,MAAM,aAAa,GAAG,EAAE,CAAC,gBAAgB,EAAE,CAAC;IAC5C,IAAI,aAAa,IAAI,EAAE,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,CAAC;QACnD,OAAO,OAAO,CAAC,aAAa,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,EAAE,CAAC,sBAAsB,EAAE,CAAC,IAAI,CAAC;AAC1C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CAAC,UAAuB;IAC/D,MAAM,aAAa,GAAG,UAAU,CAAC,gBAAgB,EAAE,CAAC;IACpD,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,cAAc,GAAG,UAAU,CAAC,wBAAwB,CAAC,aAAa,CAAC,CAAC;QAC1E,IAAI,cAAc,EAAE,yBAAyB,EAAE,CAAC;YAC9C,OAAO,cAAc,CAAC,yBAAyB,CAAC;QAClD,CAAC;IACH,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC"}
1
+ {"version":3,"file":"safeBlocks.js","sourceRoot":"","sources":["../../src/forkChoice/safeBlocks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAE7D,OAAO,EAAmB,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAC,aAAa,EAAc,YAAY,EAAC,MAAM,4BAA4B,CAAC;AAGnF;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,EAAe;IACpD,MAAM,aAAa,GAAG,EAAE,CAAC,gBAAgB,EAAE,CAAC;IAC5C,IAAI,aAAa,IAAI,EAAE,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,CAAC;QACnD,OAAO,OAAO,CAAC,aAAa,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,EAAE,CAAC,sBAAsB,EAAE,CAAC,IAAI,CAAC;AAC1C,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,yBAAyB,CAAC,UAAuB,EAAE,MAAoC;IACrG,MAAM,cAAc,GAAG,UAAU,CAAC,iBAAiB,EAAE,CAAC;IACtD,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;QAC5B,MAAM,EAAE,IAAI,CAAC,iEAAiE,EAAE;YAC9E,aAAa,EAAE,UAAU,CAAC,gBAAgB,EAAE;SAC7C,CAAC,CAAC;QACH,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,OAAO,qBAAqB,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;AACvD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,8BAA8B,CAAC,UAAuB,EAAE,MAAoC;IAC1G,OAAO,qBAAqB,CAAC,UAAU,CAAC,iBAAiB,EAAE,EAAE,MAAM,CAAC,CAAC;AACvE,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAiB,EAAE,MAAoC;IACpF,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,KAAK,CAAC,eAAe,CAAC;IAC/B,CAAC;IAED,8FAA8F;IAC9F,0FAA0F;IAC1F,yEAAyE;IACzE,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QAChC,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,IAAI,KAAK,CAAC,yBAAyB,KAAK,IAAI,EAAE,CAAC;QAC7C,MAAM,EAAE,IAAI,CAAC,yDAAyD,EAAE;YACtE,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,IAAI,EAAE,KAAK,CAAC,IAAI;SACjB,CAAC,CAAC;QACH,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,OAAO,KAAK,CAAC,yBAAyB,CAAC;AACzC,CAAC"}
@@ -40,7 +40,9 @@ export declare enum PayloadStatus {
40
40
  /**
41
41
  * Check if a block is in the Gloas fork (ePBS enabled)
42
42
  */
43
- export declare function isGloasBlock(block: ProtoBlock): boolean;
43
+ export declare function isGloasBlock(block: ProtoBlock): block is ProtoBlock & {
44
+ parentBlockHash: RootHex;
45
+ };
44
46
  export type LVHValidResponse = {
45
47
  executionStatus: ExecutionStatus.Valid;
46
48
  latestValidExecHash: RootHex;
@@ -1 +1 @@
1
- {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/protoArray/interface.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/protoArray/interface.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "bugs": {
12
12
  "url": "https://github.com/ChainSafe/lodestar/issues"
13
13
  },
14
- "version": "1.46.0-dev.e6f04acd82",
14
+ "version": "1.46.0-dev.f0f5d069e2",
15
15
  "type": "module",
16
16
  "exports": {
17
17
  ".": {
@@ -40,11 +40,11 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@chainsafe/ssz": "^1.6.2",
43
- "@lodestar/config": "^1.46.0-dev.e6f04acd82",
44
- "@lodestar/params": "^1.46.0-dev.e6f04acd82",
45
- "@lodestar/state-transition": "^1.46.0-dev.e6f04acd82",
46
- "@lodestar/types": "^1.46.0-dev.e6f04acd82",
47
- "@lodestar/utils": "^1.46.0-dev.e6f04acd82"
43
+ "@lodestar/config": "^1.46.0-dev.f0f5d069e2",
44
+ "@lodestar/params": "^1.46.0-dev.f0f5d069e2",
45
+ "@lodestar/state-transition": "^1.46.0-dev.f0f5d069e2",
46
+ "@lodestar/types": "^1.46.0-dev.f0f5d069e2",
47
+ "@lodestar/utils": "^1.46.0-dev.f0f5d069e2"
48
48
  },
49
49
  "keywords": [
50
50
  "ethereum",
@@ -52,5 +52,5 @@
52
52
  "beacon",
53
53
  "blockchain"
54
54
  ],
55
- "gitHead": "402a1913262b99cdeb71922eb306786e1a590e5e"
55
+ "gitHead": "7b4da150e5f67b4863516f2155e131b99ad1c6c9"
56
56
  }
@@ -1,6 +1,7 @@
1
- import {ZERO_HASH_HEX} from "@lodestar/params";
1
+ import {GENESIS_SLOT, ZERO_HASH_HEX} from "@lodestar/params";
2
2
  import {Root, RootHex} from "@lodestar/types";
3
- import {fromHex} from "@lodestar/utils";
3
+ import {LogLevel, Logger, fromHex} from "@lodestar/utils";
4
+ import {HEX_ZERO_HASH, ProtoBlock, isGloasBlock} from "../protoArray/interface.js";
4
5
  import {IForkChoice} from "./interface.js";
5
6
 
6
7
  /**
@@ -19,17 +20,56 @@ export function getSafeBeaconBlockRoot(fc: IForkChoice): Root {
19
20
  }
20
21
 
21
22
  /**
22
- * Get execution payload hash for the safe block
23
+ * Get execution payload hash to report as `safeBlockHash` in `engine_forkchoiceUpdated`.
23
24
  *
24
- * https://github.com/ethereum/consensus-specs/blob/master/fork_choice/safe-block.md#get_safe_execution_block_hash
25
+ * Pre-Gloas: the confirmed block's own payload hash.
26
+ * Post-Gloas: the confirmed block's bid `parent_block_hash` — under ePBS the block's own
27
+ * payload may not yet be confirmed canonical, so we report the parent EL block which has
28
+ * been (the bid commits to extending it).
29
+ *
30
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.13/specs/bellatrix/fast-confirmation.md#new-get_safe_execution_block_hash
25
31
  */
26
- export function getSafeExecutionBlockHash(forkChoice: IForkChoice): RootHex {
27
- const confirmedRoot = forkChoice.getConfirmedRoot();
28
- if (confirmedRoot) {
29
- const confirmedBlock = forkChoice.getBlockHexDefaultStatus(confirmedRoot);
30
- if (confirmedBlock?.executionPayloadBlockHash) {
31
- return confirmedBlock.executionPayloadBlockHash;
32
- }
32
+ export function getSafeExecutionBlockHash(forkChoice: IForkChoice, logger?: Pick<Logger, LogLevel.warn>): RootHex {
33
+ const confirmedBlock = forkChoice.getConfirmedBlock();
34
+ if (confirmedBlock === null) {
35
+ logger?.warn("Confirmed block not found, using zero safe execution block hash", {
36
+ confirmedRoot: forkChoice.getConfirmedRoot(),
37
+ });
38
+ return ZERO_HASH_HEX;
33
39
  }
34
- return ZERO_HASH_HEX;
40
+
41
+ return getExecutionBlockHash(confirmedBlock, logger);
42
+ }
43
+
44
+ /**
45
+ * Get execution payload hash to report as `finalizedBlockHash` in `engine_forkchoiceUpdated`.
46
+ * Mirrors `getSafeExecutionBlockHash`: post-Gloas returns the bid `parent_block_hash`.
47
+ *
48
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.13/specs/gloas/fork-choice.md#notify_forkchoice_updated
49
+ */
50
+ export function getFinalizedExecutionBlockHash(forkChoice: IForkChoice, logger?: Pick<Logger, LogLevel.warn>): RootHex {
51
+ return getExecutionBlockHash(forkChoice.getFinalizedBlock(), logger);
52
+ }
53
+
54
+ function getExecutionBlockHash(block: ProtoBlock, logger?: Pick<Logger, LogLevel.warn>): RootHex {
55
+ if (isGloasBlock(block)) {
56
+ return block.parentBlockHash;
57
+ }
58
+
59
+ // The genesis block body carries a default execution payload, so it is not an execution block
60
+ // per the spec (`is_execution_block`); its proto-array payload hash comes from the anchor
61
+ // state header instead of a block body and must not be reported as safe.
62
+ if (block.slot === GENESIS_SLOT) {
63
+ return HEX_ZERO_HASH;
64
+ }
65
+
66
+ if (block.executionPayloadBlockHash === null) {
67
+ logger?.warn("Execution payload block hash not found, using zero hash", {
68
+ blockRoot: block.blockRoot,
69
+ slot: block.slot,
70
+ });
71
+ return HEX_ZERO_HASH;
72
+ }
73
+
74
+ return block.executionPayloadBlockHash;
35
75
  }
@@ -48,7 +48,7 @@ export enum PayloadStatus {
48
48
  /**
49
49
  * Check if a block is in the Gloas fork (ePBS enabled)
50
50
  */
51
- export function isGloasBlock(block: ProtoBlock): boolean {
51
+ export function isGloasBlock(block: ProtoBlock): block is ProtoBlock & {parentBlockHash: RootHex} {
52
52
  return block.parentBlockHash !== null;
53
53
  }
54
54