@lodestar/fork-choice 1.42.0 → 1.43.0-dev.07875b3e0c

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.
@@ -108,6 +108,7 @@ export class ProtoArray {
108
108
  currentSlot,
109
109
  null
110
110
  );
111
+
111
112
  return protoArray;
112
113
  }
113
114
 
@@ -354,9 +355,15 @@ export class ProtoArray {
354
355
  continue;
355
356
  }
356
357
 
357
- const currentBoost = proposerBoost && proposerBoost.root === node.blockRoot ? proposerBoost.score : 0;
358
+ // For Gloas blocks, PENDING/EMPTY/FULL all share the same blockRoot.
359
+ // Only apply proposer boost to PENDING (for Gloas) or FULL (for pre-Gloas) — to avoid
360
+ // double-counting the boost across variants during delta back-propagation, and to keep
361
+ // the boost neutral with respect to EMPTY vs FULL selection.
362
+ const isBoostVariant = isGloasBlock(node) ? node.payloadStatus === PayloadStatus.PENDING : true; // pre-Gloas has only FULL, always boost
363
+ const currentBoost =
364
+ proposerBoost && proposerBoost.root === node.blockRoot && isBoostVariant ? proposerBoost.score : 0;
358
365
  const previousBoost =
359
- this.previousProposerBoost && this.previousProposerBoost.root === node.blockRoot
366
+ this.previousProposerBoost && this.previousProposerBoost.root === node.blockRoot && isBoostVariant
360
367
  ? this.previousProposerBoost.score
361
368
  : 0;
362
369
 
@@ -541,7 +548,6 @@ export class ProtoArray {
541
548
  currentSlot: Slot,
542
549
  executionPayloadBlockHash: RootHex,
543
550
  executionPayloadNumber: number,
544
- executionPayloadStateRoot: RootHex,
545
551
  proposerBoostRoot: RootHex | null,
546
552
  executionStatus: PayloadExecutionStatus
547
553
  ): void {
@@ -597,7 +603,6 @@ export class ProtoArray {
597
603
  executionStatus,
598
604
  executionPayloadBlockHash,
599
605
  executionPayloadNumber,
600
- stateRoot: executionPayloadStateRoot,
601
606
  };
602
607
 
603
608
  const fullIndex = this.nodes.length;
@@ -676,7 +681,7 @@ export class ProtoArray {
676
681
  * Determine if we should extend the payload (prefer FULL over EMPTY)
677
682
  * Spec: gloas/fork-choice.md#new-should_extend_payload
678
683
  *
679
- * Returns true if:
684
+ * Returns true if payload is verified (FULL variant exists) AND:
680
685
  * 1. Payload is timely, OR
681
686
  * 2. No proposer boost root (empty/zero hash), OR
682
687
  * 3. Proposer boost root's parent is not this block, OR
@@ -686,6 +691,10 @@ export class ProtoArray {
686
691
  * @param proposerBoostRoot - Current proposer boost root (from ForkChoice)
687
692
  */
688
693
  shouldExtendPayload(blockRoot: RootHex, proposerBoostRoot: RootHex | null): boolean {
694
+ if (!this.hasPayload(blockRoot)) {
695
+ return false;
696
+ }
697
+
689
698
  // Condition 1: Payload is timely
690
699
  if (this.isPayloadTimely(blockRoot)) {
691
700
  return true;
@@ -1478,9 +1487,16 @@ export class ProtoArray {
1478
1487
  */
1479
1488
  private getParentNodeIndex(node: ProtoNode): number | undefined {
1480
1489
  if (isGloasBlock(node)) {
1481
- // Use getParentPayloadStatus for Gloas blocks to get correct EMPTY/FULL variant
1482
- const parentPayloadStatus = this.getParentPayloadStatus(node);
1483
- return this.getNodeIndexByRootAndStatus(node.parentRoot, parentPayloadStatus);
1490
+ // Traversal may reach the finalized ProtoBlock, should not throw error in that case
1491
+ try {
1492
+ const parentPayloadStatus = this.getParentPayloadStatus(node);
1493
+ return this.getNodeIndexByRootAndStatus(node.parentRoot, parentPayloadStatus);
1494
+ } catch (e) {
1495
+ if (e instanceof ProtoArrayError && e.type.code === ProtoArrayErrorCode.UNKNOWN_PARENT_BLOCK) {
1496
+ return undefined;
1497
+ }
1498
+ throw e;
1499
+ }
1484
1500
  }
1485
1501
  // Simple parent traversal for pre-Gloas blocks (includes fork transition)
1486
1502
  return node.parent;
@@ -1634,10 +1650,9 @@ export class ProtoArray {
1634
1650
  const ancestors: ProtoNode[] = [];
1635
1651
  const nonAncestors: ProtoNode[] = [];
1636
1652
 
1637
- // Include starting node if it's not PENDING (i.e., pre-Gloas or EMPTY/FULL variant post-Gloas)
1638
- if (node.payloadStatus !== PayloadStatus.PENDING) {
1639
- ancestors.push(node);
1640
- }
1653
+ // caller of this method may pass default status
1654
+ // this is the only node that we accept PENDING
1655
+ ancestors.push(node);
1641
1656
 
1642
1657
  let nodeIndex = startIndex;
1643
1658
  while (node.parent !== undefined) {