@lodestar/fork-choice 1.42.0-dev.f6213da56d → 1.42.0-dev.fb8f8a700e

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,4 @@
1
- import {CachedBeaconStateAllForks, EffectiveBalanceIncrements} from "@lodestar/state-transition";
1
+ import {EffectiveBalanceIncrements, IBeaconStateView} from "@lodestar/state-transition";
2
2
  import {RootHex, Slot, ValidatorIndex, phase0} from "@lodestar/types";
3
3
  import {toRootHex} from "@lodestar/utils";
4
4
  import {PayloadStatus} from "../protoArray/interface.js";
@@ -30,7 +30,7 @@ export type JustifiedBalances = EffectiveBalanceIncrements;
30
30
  */
31
31
  export type JustifiedBalancesGetter = (
32
32
  checkpoint: CheckpointWithPayloadStatus,
33
- blockState: CachedBeaconStateAllForks
33
+ blockState: IBeaconStateView
34
34
  ) => JustifiedBalances;
35
35
 
36
36
  /**
package/src/index.ts CHANGED
@@ -31,10 +31,11 @@ export {
31
31
  } from "./forkChoice/store.js";
32
32
  export {type ForkChoiceMetrics, getForkChoiceMetrics} from "./metrics.js";
33
33
  export type {
34
+ BlockExecutionStatus,
34
35
  BlockExtraMeta,
35
36
  LVHInvalidResponse,
36
37
  LVHValidResponse,
37
- MaybeValidExecutionStatus,
38
+ PayloadExecutionStatus,
38
39
  ProtoBlock,
39
40
  ProtoNode,
40
41
  } from "./protoArray/interface.js";
@@ -64,7 +64,18 @@ export type LVHInvalidResponse = {
64
64
  };
65
65
  export type LVHExecResponse = LVHValidResponse | LVHInvalidResponse;
66
66
 
67
- export type MaybeValidExecutionStatus = Exclude<ExecutionStatus, ExecutionStatus.Invalid>;
67
+ /**
68
+ * Any execution status that is not definitively invalid.
69
+ * Pre-Gloas: Valid | Syncing | PreMerge
70
+ * Post-Gloas: execution status must be PayloadSeparated (beacon block imported before its payload arrives via SignedExecutionPayloadEnvelope)
71
+ */
72
+ export type BlockExecutionStatus = Exclude<ExecutionStatus, ExecutionStatus.Invalid>;
73
+
74
+ /**
75
+ * Execution status for a block whose execution payload is present and has been submitted to the EL.
76
+ * Used post-Gloas when transitioning a PayloadSeparated block to FULL via onExecutionPayload().
77
+ */
78
+ export type PayloadExecutionStatus = ExecutionStatus.Valid | ExecutionStatus.Syncing;
68
79
 
69
80
  export type BlockExtraMeta =
70
81
  | {
@@ -9,6 +9,7 @@ import {
9
9
  ExecutionStatus,
10
10
  HEX_ZERO_HASH,
11
11
  LVHExecResponse,
12
+ PayloadExecutionStatus,
12
13
  PayloadStatus,
13
14
  ProtoBlock,
14
15
  ProtoNode,
@@ -541,7 +542,8 @@ export class ProtoArray {
541
542
  executionPayloadBlockHash: RootHex,
542
543
  executionPayloadNumber: number,
543
544
  executionPayloadStateRoot: RootHex,
544
- proposerBoostRoot: RootHex | null
545
+ proposerBoostRoot: RootHex | null,
546
+ executionStatus: PayloadExecutionStatus
545
547
  ): void {
546
548
  // First check if block exists
547
549
  const variants = this.indices.get(blockRoot);
@@ -591,7 +593,8 @@ export class ProtoArray {
591
593
  weight: 0,
592
594
  bestChild: undefined,
593
595
  bestDescendant: undefined,
594
- executionStatus: ExecutionStatus.Valid,
596
+ // TODO GLOAS: handle optimistic sync
597
+ executionStatus,
595
598
  executionPayloadBlockHash,
596
599
  executionPayloadNumber,
597
600
  stateRoot: executionPayloadStateRoot,
@@ -650,9 +653,7 @@ export class ProtoArray {
650
653
  }
651
654
 
652
655
  // If payload is not locally available, it's not timely
653
- // In our implementation, payload is locally available if proto array has FULL variant of the block
654
- const fullNodeIndex = this.getNodeIndexByRootAndStatus(blockRoot, PayloadStatus.FULL);
655
- if (fullNodeIndex === undefined) {
656
+ if (!this.hasPayload(blockRoot)) {
656
657
  return false;
657
658
  }
658
659
 
@@ -1059,10 +1060,8 @@ export class ProtoArray {
1059
1060
  });
1060
1061
  }
1061
1062
 
1062
- // Find the minimum index among all variants to ensure we don't prune too much
1063
- const finalizedIndex = Array.isArray(variants)
1064
- ? Math.min(...variants.filter((idx) => idx !== undefined))
1065
- : variants;
1063
+ // For Gloas, PENDING variant (index 0) is always the smallest since it's inserted first
1064
+ const finalizedIndex = Array.isArray(variants) ? variants[PayloadStatus.PENDING] : variants;
1066
1065
 
1067
1066
  if (finalizedIndex < this.pruneThreshold) {
1068
1067
  // Pruning at small numbers incurs more cost than benefit
@@ -1672,6 +1671,16 @@ export class ProtoArray {
1672
1671
  return this.getDefaultNodeIndex(blockRoot) !== undefined;
1673
1672
  }
1674
1673
 
1674
+ /**
1675
+ * Check if a FULL payload variant (execution payload envelope) exists for this block root.
1676
+ * Returns true once the SignedExecutionPayloadEnvelope for this block has been received and processed.
1677
+ */
1678
+ hasPayload(blockRoot: RootHex): boolean {
1679
+ // we should also make sure this blockRoot is a gloas block, however we only call this function
1680
+ // starting from GLOAS_FORK_EPOCH, so we can assume the blockRoot is from gloas block
1681
+ return this.getNodeIndexByRootAndStatus(blockRoot, PayloadStatus.FULL) !== undefined;
1682
+ }
1683
+
1675
1684
  /**
1676
1685
  * Return ProtoNode for blockRoot with explicit payload status
1677
1686
  *