@lodestar/fork-choice 1.47.0-dev.931ecbec99 → 1.47.0-dev.9ba9a5ce85

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.
@@ -180,7 +180,8 @@ export declare class ForkChoice implements IForkChoice {
180
180
  * https://github.com/ethereum/consensus-specs/pull/3034 for info about proposer boost reorg
181
181
  * This function should only be called during block proposal and only be called after `updateHead()` in `updateAndGetHead()`
182
182
  *
183
- * Same as https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.4/specs/phase0/fork-choice.md#get_proposer_head
183
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.14/specs/phase0/fork-choice.md#get_proposer_head
184
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.14/specs/gloas/fork-choice.md#modified-get_proposer_head
184
185
  */
185
186
  getProposerHead(headBlock: ProtoBlock, secFromSlot: number, slot: Slot): {
186
187
  proposerHead: ProtoBlock;
@@ -461,6 +462,38 @@ export declare class ForkChoice implements IForkChoice {
461
462
  * Child class can overwrite this for testing purpose.
462
463
  */
463
464
  protected isBlockTimely(block: BeaconBlock, blockDelaySec: number): boolean;
465
+ /**
466
+ * Return true if the block arrived before the PTC (payload-timeliness committee) deadline,
467
+ * ie. block_timeliness[PTC_TIMELINESS_INDEX]. should_apply_proposer_boost uses this as the
468
+ * definition of an "early" proposer equivocation: only a sibling seen by the PTC deadline
469
+ * proves the proposer equivocated soon enough that honest nodes could have withheld the boost.
470
+ *
471
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.14/specs/gloas/fork-choice.md#modified-record_block_timeliness
472
+ *
473
+ * Child class can overwrite this for testing purpose.
474
+ */
475
+ protected isBlockPtcTimely(block: BeaconBlock, blockDelaySec: number): boolean;
476
+ /**
477
+ * Determine whether proposer boost should be applied to `proposerBoostRoot`.
478
+ *
479
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.14/specs/gloas/fork-choice.md#new-should_apply_proposer_boost
480
+ *
481
+ * Pre-gloas blocks always receive the boost (unconditional, backward compatible). For gloas
482
+ * blocks the boost is withheld when the parent is a weak block from the previous slot and the
483
+ * proposer of that parent equivocated (published another PTC-timely block at the same slot).
484
+ */
485
+ private shouldApplyProposerBoost;
486
+ /**
487
+ * Return true if another block at the same slot from the same proposer is known to fork choice.
488
+ *
489
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.14/specs/phase0/fork-choice.md#is_proposer_equivocation
490
+ */
491
+ private isProposerEquivocation;
492
+ /**
493
+ * The proposer boost to apply to `proposerBoostRoot`, propagated up the branch by
494
+ * applyScoreChanges() together with the deltas.
495
+ */
496
+ private getProposerBoost;
464
497
  /**
465
498
  * https://github.com/ethereum/consensus-specs/blob/v1.5.0/specs/phase0/fork-choice.md#is_proposing_on_time
466
499
  */
@@ -487,6 +520,8 @@ export declare class ForkChoice implements IForkChoice {
487
520
  * May need the justified balances of:
488
521
  * - unrealizedJustified: Already available in `CheckpointWithBalance`
489
522
  * Since this balances are already available the getter is just `() => balances`, without cache interaction
523
+ *
524
+ * @returns Whether either checkpoint was updated.
490
525
  */
491
526
  private updateCheckpoints;
492
527
  /**
@@ -529,6 +564,8 @@ export declare class ForkChoice implements IForkChoice {
529
564
  * Equivalent to:
530
565
  *
531
566
  * https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/phase0/fork-choice.md#on_tick
567
+ *
568
+ * @returns Whether an epoch-boundary checkpoint was updated.
532
569
  */
533
570
  private onTick;
534
571
  /**
@@ -538,6 +575,7 @@ export declare class ForkChoice implements IForkChoice {
538
575
  *
539
576
  */
540
577
  private getPreliminaryProposerHead;
578
+ /** Returns whether it recomputed the head, so the caller can avoid a redundant `updateHead()`. */
541
579
  private runFastConfirmation;
542
580
  private createFastConfirmationContext;
543
581
  }
@@ -1 +1 @@
1
- {"version":3,"file":"forkChoice.d.ts","sourceRoot":"","sources":["../../src/forkChoice/forkChoice.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"forkChoice.d.ts","sourceRoot":"","sources":["../../src/forkChoice/forkChoice.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAQjD,OAAO,EACL,sBAAsB,EAEtB,gBAAgB,EAQjB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,gBAAgB,EAChB,WAAW,EAEX,kBAAkB,EAClB,IAAI,EACJ,OAAO,EACP,IAAI,EAKL,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAC,MAAM,EAAmD,MAAM,iBAAiB,CAAC;AACzF,OAAO,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AAGhD,OAAO,EACL,oBAAoB,EAGpB,eAAe,EAEf,sBAAsB,EACtB,aAAa,EACb,UAAU,EACV,SAAS,EAGV,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAC,UAAU,EAAC,MAAM,6BAA6B,CAAC;AAEvD,OAAO,EAKL,KAAK,0BAA0B,EAChC,MAAM,4CAA4C,CAAC;AACpD,OAAO,EACL,cAAc,EAEd,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,oCAAoC,EACrC,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAC,iBAAiB,EAAE,gBAAgB,EAAyC,MAAM,YAAY,CAAC;AAEvG,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;AAIF,oBAAY,aAAa;IACvB,gBAAgB,qBAAqB,CAAE,uBAAuB;IAC9D,eAAe,oBAAoB,CAAE,uBAAuB;IAC5D,wBAAwB,6BAA6B;CACtD;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAC,IAAI,EAAE,aAAa,CAAC,gBAAgB,CAAA;CAAC,GACtC;IAAC,IAAI,EAAE,aAAa,CAAC,eAAe,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAC,GACtE;IAAC,IAAI,EAAE,aAAa,CAAC,wBAAwB,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAC,CAAC;AAKpF;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,UAAW,YAAW,WAAW;IA6D1C,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,sDAAsD;IACtD,OAAO,CAAC,QAAQ,CAAC,UAAU;IAE3B,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI;IAC1C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAnE1B,kBAAkB,CAAC,EAAE,KAAK,CAAC;IAC3B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAc;IACjD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAc;IAC9C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IAEvC;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAEjC;IAEF;;;OAGG;IACH,OAAO,CAAC,8BAA8B,CAAK;IAO3C,kBAAkB;IAClB,OAAO,CAAC,IAAI,CAAa;IACzB;;QAEI;IACJ,OAAO,CAAC,yBAAyB,CAAqB;IACtD,kEAAkE;IAClE,OAAO,CAAC,iBAAiB,CAAwB;IACjD,+EAA+E;IAC/E,OAAO,CAAC,2BAA2B,CAAuB;IAC1D,qCAAqC;IACrC,OAAO,CAAC,QAAQ,CAA6B;IAC7C,qDAAqD;IACrD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAwB;IAC9D,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAA0B;IACnE,OAAO,CAAC,sBAAsB,CAAS;IACvC;;;;OAIG;IACH,YACmB,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,gBAAgB;IAC1C,sDAAsD;IACrC,UAAU,EAAE,UAAU,EACvC,cAAc,EAAE,MAAM,EACb,OAAO,EAAE,iBAAiB,GAAG,IAAI,EACzB,IAAI,CAAC,EAAE,cAAc,YAAA,EACrB,MAAM,CAAC,EAAE,MAAM,YAAA,EA0BjC;IAED;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,GAAG,SAAS,CAE7D;IAED;;OAEG;IACH,WAAW,IAAI,OAAO,CAErB;IAED;;OAEG;IACH,OAAO,IAAI,UAAU,CAEpB;IAED,gBAAgB,IAAI,OAAO,CAE1B;IAED,wBAAwB,IAAI,0BAA0B,CASrD;IAED,iBAAiB,IAAI,UAAU,GAAG,IAAI,CAErC;IAED,sBAAsB,IAAI,IAAI,CAE7B;IAED,qBAAqB,IAAI,IAAI,CAE5B;IAED,OAAO,CAAC,sBAAsB;IAoB9B,OAAO,CAAC,mBAAmB;IAa3B;;;;;;;;;OASG;IACH,gBAAgB,CAAC,GAAG,EAAE,mBAAmB,GAAG;QAC1C,IAAI,EAAE,UAAU,CAAC;QACjB,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;KACrC,CAoBA;IAOD,8BAA8B,CAC5B,SAAS,EAAE,UAAU,EACrB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,IAAI,GAChB,oCAAoC,CA6DtC;IAED;;OAEG;IACH,oBAAoB,IAAI,OAAO,CAE9B;IAED,4BAA4B,IAAI,OAAO,CAEtC;IAED;;;OAGG;IACH,mBAAmB,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAE/C;IAED,oDAAoD;IACpD,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAEvD;IAED;;;;;;;;;OASG;IACH,mBAAmB,CAAC,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,GAAG,UAAU,CA+B7F;IAED;;;;;;;;OAQG;IACH,eAAe,CACb,SAAS,EAAE,UAAU,EACrB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,IAAI,GACT;QAAC,YAAY,EAAE,UAAU,CAAC;QAAC,YAAY,EAAE,OAAO,CAAC;QAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;KAAC,CAwFxF;IAED;;;;;;;;;;;OAWG;IACH,UAAU,IAAI,UAAU,CAyFvB;IAED;;;;OAIG;IACH,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE3C;IAED,yBAAyB,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,GAAG;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,CAEvG;IAED,wFAAwF;IACxF,QAAQ,IAAI,UAAU,EAAE,CAEvB;IAED,0DAA0D;IAC1D,cAAc,IAAI;QAAC,IAAI,EAAE,OAAO,CAAC;QAAC,aAAa,EAAE,aAAa,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAC,EAAE,CAEhF;IAED,qCAAqC;IACrC,WAAW,IAAI,SAAS,EAAE,CAEzB;IAED,sBAAsB,IAAI,iBAAiB,CAE1C;IAED,sBAAsB,IAAI,iBAAiB,CAE1C;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CACL,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,gBAAgB,EACvB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,IAAI,EACjB,eAAe,EAAE,oBAAoB,EACrC,sBAAsB,EAAE,sBAAsB,GAC7C,UAAU,CAgOZ;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,aAAa,CAAC,WAAW,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,IAAI,CAiF/F;IAED;;;;OAIG;IACH,kBAAkB,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAM3D;IAED;;;;OAIG;IACH,iBAAiB,CACf,SAAS,EAAE,OAAO,EAClB,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,MAAM,EAAE,EACpB,cAAc,EAAE,OAAO,EACvB,iBAAiB,EAAE,OAAO,GACzB,IAAI,CAEN;IAED;;;;OAIG;IACH,kBAAkB,CAChB,SAAS,EAAE,OAAO,EAClB,yBAAyB,EAAE,OAAO,EAClC,sBAAsB,EAAE,MAAM,EAC9B,wBAAwB,EAAE,MAAM,EAChC,eAAe,EAAE,sBAAsB,EACvC,sBAAsB,EAAE,sBAAsB,GAC7C,IAAI,CAWN;IAED;;;;;;;OAOG;IACH,UAAU,CAAC,WAAW,EAAE,IAAI,GAAG,IAAI,CAqBlC;IAED,OAAO,IAAI,IAAI,CAEd;IAED,uFAAuF;IACvF,QAAQ,CAAC,SAAS,EAAE,IAAI,GAAG,OAAO,CAEjC;IACD,+FAA+F;IAC/F,QAAQ,CAAC,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,aAAa,GAAG,UAAU,GAAG,IAAI,CAEzE;IAED,qBAAqB,CAAC,SAAS,EAAE,IAAI,GAAG,UAAU,GAAG,IAAI,CAExD;IAED;;;OAGG;IACH,WAAW,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAQvC;IAED;;OAEG;IACH,cAAc,CAAC,SAAS,EAAE,IAAI,GAAG,OAAO,CAEvC;IAED;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAE7C;IAED;;;OAGG;IACH,gBAAgB,CAAC,SAAS,EAAE,IAAI,GAAG,OAAO,CAEzC;IAED;;OAEG;IACH,mBAAmB,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAE/C;IAED,WAAW,CAAC,YAAY,EAAE,OAAO,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAI5D;IAED,gBAAgB,CAAC,YAAY,EAAE,OAAO,GAAG;QACvC,aAAa,EAAE,MAAM,CAAC;QACtB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,kBAAkB,EAAE,MAAM,CAAC;KAC5B,GAAG,IAAI,CAEP;IAED,yBAAyB,CAAC,YAAY,EAAE,OAAO,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAE1E;IAED,+BAA+B,CAAC,YAAY,EAAE,OAAO,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAEhF;IAED,gCAAgC,IAAI,iBAAiB,CAEpD;IAED,gCAAgC,IAAI,iBAAiB,CAEpD;IAED;;OAEG;IACH,WAAW,CAAC,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,GAAG,UAAU,GAAG,IAAI,CAa/E;IAED;;;;;;;OAOG;IACH,wBAAwB,CAAC,SAAS,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,CAO9D;IAED;;OAEG;IACH,uBAAuB,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,CAEjF;IAED,iBAAiB,IAAI,UAAU,CAU9B;IAED,iBAAiB,IAAI,UAAU,CAU9B;IAED,0BAA0B,IAAI,IAAI,CAGjC;IAED;;;;;OAKG;IACH,YAAY,CACV,YAAY,EAAE,OAAO,EACrB,qBAAqB,EAAE,aAAa,EACpC,cAAc,EAAE,OAAO,EACvB,uBAAuB,EAAE,aAAa,GACrC,OAAO,CAET;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,EAAE,OAAO,GAAG,UAAU,EAAE,CA2B1C;IAED,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAEzC;IAED;;;OAGG;IACH,qBAAqB,CAAC,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAEpG;IAED;;;;OAIG;IACH,oBAAoB,CAAC,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,GAAG,UAAU,EAAE,CAEnF;IAED;;OAEG;IACH,uBAAuB,CAAC,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,GAAG,UAAU,EAAE,CAEtF;IAED;;;;;;OAMG;IACH,kCAAkC,CAChC,SAAS,EAAE,OAAO,EAClB,aAAa,EAAE,aAAa,GAC3B;QAAC,SAAS,EAAE,UAAU,EAAE,CAAC;QAAC,YAAY,EAAE,UAAU,EAAE,CAAA;KAAC,CAEvD;IAED;;OAEG;IACH,+CAA+C,CAAC,SAAS,EAAE,OAAO,GAAG;QACnE,SAAS,EAAE,UAAU,EAAE,CAAC;QACxB,YAAY,EAAE,UAAU,EAAE,CAAC;KAC5B,CASA;IAED,uBAAuB,CAAC,SAAS,EAAE,IAAI,GAAG,UAAU,GAAG,IAAI,CAa1D;IAED,uBAAuB,CAAC,IAAI,EAAE,IAAI,GAAG,UAAU,GAAG,IAAI,CAerD;IAED,+BAA+B,CAAC,IAAI,EAAE,IAAI,GAAG,UAAU,GAAG,IAAI,CAW7D;IAED,sGAAsG;IACtG,4BAA4B,IAAI,UAAU,EAAE,CAE3C;IAEA,yBAAyB,CAAC,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAiBzG;IAED,sCAAsC,CAAC,SAAS,EAAE,OAAO,GAAG,gBAAgB,CAAC,UAAU,CAAC,CASvF;IAED,sGAAsG;IACtG,6BAA6B,CAAC,UAAU,EAAE,OAAO,GAAG,UAAU,EAAE,CAE/D;IAED,sGAAsG;IACtG,uBAAuB,CAAC,IAAI,EAAE,IAAI,GAAG,UAAU,EAAE,CAUhD;IAED,mGAAmG;IACnG,sBAAsB,CAAC,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,GAAG,cAAc,CAmBlF;IAED;;;;;;;OAOG;IACH,kBAAkB,CAAC,YAAY,EAAE,eAAe,GAAG,IAAI,CAQtD;IAED;;;;;;;;;;;;;;OAcG;IACH,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,eAAe,GAAG,OAAO,CA2C7E;IAED;;;;;;;;;OASG;IACH,OAAO,CAAC,gCAAgC;IAkBxC;;;;;;OAMG;IACH,OAAO,CAAC,UAAU;IAwDlB;;;;;;OAMG;IACH,OAAO,CAAC,cAAc;IAiBtB;;;OAGG;IACH,SAAS,CAAC,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAI1E;IAED;;;;;;;;;OASG;IACH,SAAS,CAAC,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAG7E;IAED;;;;;;;;OAQG;IACH,OAAO,CAAC,wBAAwB;IAsChC;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;IAM9B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAgBxB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,qBAAqB;IAM7B,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,sBAAsB;IAU9B;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,OAAO,CAAC,iBAAiB;IAwBzB;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAgBnC;;;;;;;;OAQG;IACH,OAAO,CAAC,qBAAqB;IA4B7B,OAAO,CAAC,uBAAuB;IAwJ/B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,gBAAgB;IA8BxB;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAsB/B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,MAAM;IAgCd;;;;;OAKG;IACH,OAAO,CAAC,0BAA0B;IA8ClC,kGAAkG;IAClG,OAAO,CAAC,mBAAmB;IAyC3B,OAAO,CAAC,6BAA6B;CA+CtC"}
@@ -260,12 +260,22 @@ export class ForkChoice {
260
260
  if (parentBlock === undefined) {
261
261
  return { shouldOverrideFcu: false, reason: NotReorgedReason.ParentBlockNotAvailable };
262
262
  }
263
+ const currentTimeOk = headBlock.slot === currentSlot ||
264
+ (proposalSlot === currentSlot && this.isProposingOnTime(secFromSlot, currentSlot));
265
+ // Mirror the proposer equivocation branch of getProposerHead(). The head slot's attestations are
266
+ // still queued at this point so the head is assumed weak, same as for the regular branch below.
267
+ if (currentTimeOk && this.isProposerEquivocation(headBlock)) {
268
+ this.logger?.verbose("Head proposer equivocated. Should override forkchoice update", {
269
+ blockRoot: headBlock.blockRoot,
270
+ slot: currentSlot,
271
+ proposerIndex: headBlock.proposerIndex,
272
+ });
273
+ return { shouldOverrideFcu: true, parentBlock };
274
+ }
263
275
  const { prelimProposerHead, prelimNotReorgedReason } = this.getPreliminaryProposerHead(headBlock, parentBlock, proposalSlot);
264
276
  if (prelimProposerHead === headBlock) {
265
277
  return { shouldOverrideFcu: false, reason: prelimNotReorgedReason ?? NotReorgedReason.Unknown };
266
278
  }
267
- const currentTimeOk = headBlock.slot === currentSlot ||
268
- (proposalSlot === currentSlot && this.isProposingOnTime(secFromSlot, currentSlot));
269
279
  if (!currentTimeOk) {
270
280
  return { shouldOverrideFcu: false, reason: NotReorgedReason.ReorgMoreThanOneSlot };
271
281
  }
@@ -339,7 +349,8 @@ export class ForkChoice {
339
349
  * https://github.com/ethereum/consensus-specs/pull/3034 for info about proposer boost reorg
340
350
  * This function should only be called during block proposal and only be called after `updateHead()` in `updateAndGetHead()`
341
351
  *
342
- * Same as https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.4/specs/phase0/fork-choice.md#get_proposer_head
352
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.14/specs/phase0/fork-choice.md#get_proposer_head
353
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.14/specs/gloas/fork-choice.md#modified-get_proposer_head
343
354
  */
344
355
  getProposerHead(headBlock, secFromSlot, slot) {
345
356
  const isHeadTimely = headBlock.timeliness;
@@ -359,6 +370,24 @@ export class ForkChoice {
359
370
  if (parentBlock === undefined) {
360
371
  return { proposerHead, isHeadTimely, notReorgedReason: NotReorgedReason.ParentBlockNotAvailable };
361
372
  }
373
+ // Half of single_slot_reorg check in the spec is done in getPreliminaryProposerHead()
374
+ const currentTimeOk = headBlock.slot + 1 === slot;
375
+ const isProposerBoostWornOff = this.proposerBoostRoot !== headBlock.blockRoot;
376
+ // Re-org more aggressively if there is a proposer equivocation in the previous slot, skipping the
377
+ // regular reorg conditions. Any known equivocation counts here, timely or not.
378
+ if (currentTimeOk &&
379
+ isProposerBoostWornOff &&
380
+ this.isProposerEquivocation(headBlock) &&
381
+ this.isHeadWeak(headBlock.blockRoot)) {
382
+ this.logger?.verbose("Performing single-slot reorg to remove weak head of equivocating proposer", {
383
+ slot,
384
+ proposerHead: parentBlock.blockRoot,
385
+ weakHead: headBlock.blockRoot,
386
+ proposerIndex: headBlock.proposerIndex,
387
+ });
388
+ proposerHead = parentBlock;
389
+ return { proposerHead, isHeadTimely };
390
+ }
362
391
  const { prelimProposerHead, prelimNotReorgedReason } = this.getPreliminaryProposerHead(headBlock, parentBlock, slot);
363
392
  if (prelimProposerHead === headBlock && prelimNotReorgedReason !== undefined) {
364
393
  return { proposerHead, isHeadTimely, notReorgedReason: prelimNotReorgedReason };
@@ -368,13 +397,10 @@ export class ForkChoice {
368
397
  return { proposerHead, isHeadTimely, notReorgedReason: NotReorgedReason.NotProposingOnTime };
369
398
  }
370
399
  // No reorg if attempted reorg is more than a single slot
371
- // Half of single_slot_reorg check in the spec is done in getPreliminaryProposerHead()
372
- const currentTimeOk = headBlock.slot + 1 === slot;
373
400
  if (!currentTimeOk) {
374
401
  return { proposerHead, isHeadTimely, notReorgedReason: NotReorgedReason.ReorgMoreThanOneSlot };
375
402
  }
376
403
  // No reorg if proposer boost is still in effect
377
- const isProposerBoostWornOff = this.proposerBoostRoot !== headBlock.blockRoot;
378
404
  if (!isProposerBoostWornOff) {
379
405
  return { proposerHead, isHeadTimely, notReorgedReason: NotReorgedReason.ProposerBoostNotWornOff };
380
406
  }
@@ -429,30 +455,45 @@ export class ForkChoice {
429
455
  computeDeltasMetrics?.unchangedVoteValidators.set(unchangedVoteValidators);
430
456
  computeDeltasMetrics?.newVoteValidators.set(newVoteValidators);
431
457
  this.balances = newBalances;
432
- /**
433
- * The structure in line with deltas to propagate boost up the branch
434
- * starting from the proposerIndex
435
- */
436
- let proposerBoost = null;
437
- if (this.opts?.proposerBoost && this.proposerBoostRoot) {
438
- const proposerBoostScore = this.justifiedProposerBoostScore ??
439
- getCommitteeFraction(this.fcStore.justified.totalBalance, {
440
- slotsPerEpoch: SLOTS_PER_EPOCH,
441
- committeePercent: this.config.PROPOSER_SCORE_BOOST,
442
- });
443
- proposerBoost = { root: this.proposerBoostRoot, score: proposerBoostScore };
444
- this.justifiedProposerBoostScore = proposerBoostScore;
445
- }
446
458
  const currentSlot = this.fcStore.currentSlot;
447
- this.protoArray.applyScoreChanges({
448
- attestationDeltas,
449
- proposerBoost,
459
+ const checkpoints = {
450
460
  justifiedEpoch: this.fcStore.justified.checkpoint.epoch,
451
461
  justifiedRoot: this.fcStore.justified.checkpoint.rootHex,
452
462
  finalizedEpoch: this.fcStore.finalizedCheckpoint.epoch,
453
463
  finalizedRoot: this.fcStore.finalizedCheckpoint.rootHex,
454
464
  currentSlot,
455
- });
465
+ };
466
+ const boostedBlock = this.opts?.proposerBoost && this.proposerBoostRoot ? this.getBlockHexDefaultStatus(this.proposerBoostRoot) : null;
467
+ if (boostedBlock && isGloasBlock(boostedBlock)) {
468
+ // should_apply_proposer_boost judges the parent against the attestations known to the store,
469
+ // via is_head_weak (which also assumes equivocators' votes were already discounted before
470
+ // their balance is added back). Apply the attestation deltas first so the decision reads
471
+ // post-delta scores, then apply the boost in a second pass.
472
+ // TODO GLOAS: applyScoreChanges() updates weights and best child/descendant in one call;
473
+ // splitting them would let the two passes update weights and recompute best child/descendant
474
+ // once at the end.
475
+ // https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.14/specs/gloas/fork-choice.md#new-should_apply_proposer_boost
476
+ this.protoArray.applyScoreChanges({ attestationDeltas, proposerBoost: null, ...checkpoints });
477
+ const proposerBoost = this.shouldApplyProposerBoost() ? this.getProposerBoost() : null;
478
+ // The first pass already rolled back the previous boost and left a coherent tree, so a
479
+ // withheld boost needs no second pass
480
+ if (proposerBoost !== null) {
481
+ this.protoArray.applyScoreChanges({
482
+ attestationDeltas: new Array(this.protoArray.nodes.length).fill(0),
483
+ proposerBoost,
484
+ ...checkpoints,
485
+ });
486
+ }
487
+ }
488
+ else {
489
+ // Pre-gloas the boost is unconditional, so attestation deltas and boost deltas can propagate
490
+ // up the branch in a single pass
491
+ this.protoArray.applyScoreChanges({
492
+ attestationDeltas,
493
+ proposerBoost: boostedBlock ? this.getProposerBoost() : null,
494
+ ...checkpoints,
495
+ });
496
+ }
456
497
  // findHead returns the ProtoNode representing the head
457
498
  const head = this.protoArray.findHead(this.fcStore.justified.checkpoint.rootHex, currentSlot);
458
499
  this.head = head;
@@ -633,6 +674,8 @@ export class ForkChoice {
633
674
  targetRoot: toRootHex(targetRoot),
634
675
  stateRoot: toRootHex(block.stateRoot),
635
676
  timeliness: isTimely,
677
+ ptcTimeliness: this.isBlockPtcTimely(block, blockDelaySec),
678
+ proposerIndex: block.proposerIndex,
636
679
  justifiedEpoch: stateJustifiedEpoch,
637
680
  justifiedRoot: toRootHex(state.currentJustifiedCheckpoint.root),
638
681
  finalizedEpoch: finalizedCheckpoint.epoch,
@@ -842,11 +885,18 @@ export class ForkChoice {
842
885
  while (this.fcStore.currentSlot < currentSlot) {
843
886
  const previousSlot = this.fcStore.currentSlot;
844
887
  // Note: we are relying upon `onTick` to update `fcStore.time` to ensure we don't get stuck in a loop.
845
- this.onTick(previousSlot + 1);
888
+ const didUpdateCheckpoints = this.onTick(previousSlot + 1);
846
889
  this.queuedAttestationsPreviousSlot = 0;
847
890
  // Process any attestations that might now be eligible before running FCR for this slot.
848
891
  this.processAttestationQueue();
849
- this.runFastConfirmation();
892
+ const didRecomputeHead = this.runFastConfirmation();
893
+ // An epoch-boundary checkpoint pull-up can move the head's dependent root and stale the cached
894
+ // head before block 0 of the new epoch is imported, making isProposerBoostSameDependentRoot()
895
+ // wrong for that block. Recompute the head so it reflects the new checkpoint and the queued
896
+ // votes — unless fast confirmation already did, to avoid a redundant head calculation.
897
+ if (didUpdateCheckpoints && !didRecomputeHead) {
898
+ this.updateHead();
899
+ }
850
900
  this.validatedAttestationDatas = new Set();
851
901
  }
852
902
  }
@@ -1281,7 +1331,8 @@ export class ForkChoice {
1281
1331
  // Only ever called on a block already in fork choice, so a miss is a broken invariant.
1282
1332
  const node = this.protoArray.getNodeDefaultStatus(blockRoot);
1283
1333
  if (node === undefined) {
1284
- // this is called for head so we should always have this in forkchoice, otherwise we have a serious error
1334
+ // this is called for head or the boosted block's parent, both of which should always be
1335
+ // in forkchoice, otherwise we have a serious error
1285
1336
  throw new ForkChoiceError({ code: ForkChoiceErrorCode.MISSING_PROTO_ARRAY_BLOCK, root: blockRoot });
1286
1337
  }
1287
1338
  const reorgThreshold = getCommitteeFraction(this.fcStore.justified.totalBalance, {
@@ -1297,7 +1348,7 @@ export class ForkChoice {
1297
1348
  // always 0. Return before fetching the state and walking the block's committees.
1298
1349
  if (equivocatingIndices.size > 0) {
1299
1350
  const state = this.fcStore.stateGetter({ stateRoot: node.stateRoot });
1300
- // Only ever called on the head, so the state is always cached.
1351
+ // Only ever called on the head or the boosted block's parent, so the state is always cached.
1301
1352
  // A miss is a broken invariant, not a recoverable state.
1302
1353
  if (state === null) {
1303
1354
  throw new ForkChoiceError({
@@ -1353,6 +1404,83 @@ export class ForkChoice {
1353
1404
  const isBeforeLateBlockCutoff = blockDelaySec * 1000 < this.config.getAttestationDueMs(fork);
1354
1405
  return this.fcStore.currentSlot === block.slot && isBeforeLateBlockCutoff;
1355
1406
  }
1407
+ /**
1408
+ * Return true if the block arrived before the PTC (payload-timeliness committee) deadline,
1409
+ * ie. block_timeliness[PTC_TIMELINESS_INDEX]. should_apply_proposer_boost uses this as the
1410
+ * definition of an "early" proposer equivocation: only a sibling seen by the PTC deadline
1411
+ * proves the proposer equivocated soon enough that honest nodes could have withheld the boost.
1412
+ *
1413
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.14/specs/gloas/fork-choice.md#modified-record_block_timeliness
1414
+ *
1415
+ * Child class can overwrite this for testing purpose.
1416
+ */
1417
+ isBlockPtcTimely(block, blockDelaySec) {
1418
+ const ptcThresholdMs = this.config.getSlotComponentDurationMs(this.config.PAYLOAD_ATTESTATION_DUE_BPS);
1419
+ return this.fcStore.currentSlot === block.slot && blockDelaySec * 1000 < ptcThresholdMs;
1420
+ }
1421
+ /**
1422
+ * Determine whether proposer boost should be applied to `proposerBoostRoot`.
1423
+ *
1424
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.14/specs/gloas/fork-choice.md#new-should_apply_proposer_boost
1425
+ *
1426
+ * Pre-gloas blocks always receive the boost (unconditional, backward compatible). For gloas
1427
+ * blocks the boost is withheld when the parent is a weak block from the previous slot and the
1428
+ * proposer of that parent equivocated (published another PTC-timely block at the same slot).
1429
+ */
1430
+ shouldApplyProposerBoost() {
1431
+ if (!this.proposerBoostRoot) {
1432
+ return false;
1433
+ }
1434
+ const boostedBlock = this.getBlockHexDefaultStatus(this.proposerBoostRoot);
1435
+ // Pre-gloas blocks always get boost
1436
+ if (!boostedBlock || !isGloasBlock(boostedBlock)) {
1437
+ return true;
1438
+ }
1439
+ const parentBlock = this.getBlockHexDefaultStatus(boostedBlock.parentRoot);
1440
+ if (!parentBlock) {
1441
+ return true;
1442
+ }
1443
+ // Apply proposer boost if parent is not from the previous slot
1444
+ if (parentBlock.slot + 1 < boostedBlock.slot) {
1445
+ return true;
1446
+ }
1447
+ // Apply proposer boost if parent is not weak
1448
+ if (!this.isHeadWeak(parentBlock.blockRoot)) {
1449
+ return true;
1450
+ }
1451
+ // Parent is weak and from the previous slot: apply boost only if there are no early
1452
+ // equivocations, ie. no other PTC-timely block at the parent's slot from the same proposer.
1453
+ return !this.protoArray.hasEquivocatingBlock(parentBlock.proposerIndex, parentBlock.slot, parentBlock.blockRoot,
1454
+ // Only a sibling seen before the PTC deadline counts. A late released one might not have been
1455
+ // seen by the proposer, so it cannot be expected to reorg it and is not denied the boost for it.
1456
+ true);
1457
+ }
1458
+ /**
1459
+ * Return true if another block at the same slot from the same proposer is known to fork choice.
1460
+ *
1461
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.14/specs/phase0/fork-choice.md#is_proposer_equivocation
1462
+ */
1463
+ isProposerEquivocation(block) {
1464
+ // Any known sibling counts, timely or not. Timeliness only matters for withholding the boost from
1465
+ // the next proposer, the reorg itself is safe to attempt whenever the equivocation is visible.
1466
+ return this.protoArray.hasEquivocatingBlock(block.proposerIndex, block.slot, block.blockRoot, false);
1467
+ }
1468
+ /**
1469
+ * The proposer boost to apply to `proposerBoostRoot`, propagated up the branch by
1470
+ * applyScoreChanges() together with the deltas.
1471
+ */
1472
+ getProposerBoost() {
1473
+ if (!this.proposerBoostRoot) {
1474
+ return null;
1475
+ }
1476
+ const proposerBoostScore = this.justifiedProposerBoostScore ??
1477
+ getCommitteeFraction(this.fcStore.justified.totalBalance, {
1478
+ slotsPerEpoch: SLOTS_PER_EPOCH,
1479
+ committeePercent: this.config.PROPOSER_SCORE_BOOST,
1480
+ });
1481
+ this.justifiedProposerBoostScore = proposerBoostScore;
1482
+ return { root: this.proposerBoostRoot, score: proposerBoostScore };
1483
+ }
1356
1484
  /**
1357
1485
  * https://github.com/ethereum/consensus-specs/blob/v1.5.0/specs/phase0/fork-choice.md#is_proposing_on_time
1358
1486
  */
@@ -1395,18 +1523,24 @@ export class ForkChoice {
1395
1523
  * May need the justified balances of:
1396
1524
  * - unrealizedJustified: Already available in `CheckpointWithBalance`
1397
1525
  * Since this balances are already available the getter is just `() => balances`, without cache interaction
1526
+ *
1527
+ * @returns Whether either checkpoint was updated.
1398
1528
  */
1399
1529
  updateCheckpoints(justifiedCheckpoint, finalizedCheckpoint, getJustifiedBalances) {
1530
+ let updated = false;
1400
1531
  // Update justified checkpoint.
1401
1532
  if (justifiedCheckpoint.epoch > this.fcStore.justified.checkpoint.epoch) {
1402
1533
  this.fcStore.justified = { checkpoint: justifiedCheckpoint, balances: getJustifiedBalances() };
1403
1534
  this.justifiedProposerBoostScore = null;
1535
+ updated = true;
1404
1536
  }
1405
1537
  // Update finalized checkpoint.
1406
1538
  if (finalizedCheckpoint.epoch > this.fcStore.finalizedCheckpoint.epoch) {
1407
1539
  this.fcStore.finalizedCheckpoint = finalizedCheckpoint;
1408
1540
  this.justifiedProposerBoostScore = null;
1541
+ updated = true;
1409
1542
  }
1543
+ return updated;
1410
1544
  }
1411
1545
  /**
1412
1546
  * Update unrealized checkpoints in store if necessary
@@ -1650,6 +1784,8 @@ export class ForkChoice {
1650
1784
  * Equivalent to:
1651
1785
  *
1652
1786
  * https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/phase0/fork-choice.md#on_tick
1787
+ *
1788
+ * @returns Whether an epoch-boundary checkpoint was updated.
1653
1789
  */
1654
1790
  onTick(time) {
1655
1791
  const previousSlot = this.fcStore.currentSlot;
@@ -1669,10 +1805,10 @@ export class ForkChoice {
1669
1805
  }
1670
1806
  // Not a new epoch, return.
1671
1807
  if (computeSlotsSinceEpochStart(time) !== 0) {
1672
- return;
1808
+ return false;
1673
1809
  }
1674
- // If a new epoch, pull-up justification and finalization from previous epoch
1675
- this.updateCheckpoints(this.fcStore.unrealizedJustified.checkpoint, this.fcStore.unrealizedFinalizedCheckpoint, () => this.fcStore.unrealizedJustified.balances);
1810
+ // If a new epoch, pull-up justification and finalization from previous epoch.
1811
+ return this.updateCheckpoints(this.fcStore.unrealizedJustified.checkpoint, this.fcStore.unrealizedFinalizedCheckpoint, () => this.fcStore.unrealizedJustified.balances);
1676
1812
  }
1677
1813
  /**
1678
1814
  *
@@ -1715,11 +1851,12 @@ export class ForkChoice {
1715
1851
  prelimProposerHead = parentBlock;
1716
1852
  return { prelimProposerHead };
1717
1853
  }
1854
+ /** Returns whether it recomputed the head, so the caller can avoid a redundant `updateHead()`. */
1718
1855
  runFastConfirmation() {
1719
1856
  const fastConfirmationRule = this.fastConfirmationRule;
1720
1857
  const fastConfirmationContext = this.fastConfirmationContext;
1721
1858
  if (!fastConfirmationRule || !fastConfirmationContext)
1722
- return;
1859
+ return false;
1723
1860
  if (this.fastConfirmationPaused) {
1724
1861
  // Keep consumers on a safe, available root while the rule is paused
1725
1862
  this.fcStore.confirmedRoot = this.fcStore.finalizedCheckpoint.rootHex;
@@ -1730,7 +1867,7 @@ export class ForkChoice {
1730
1867
  // Runs outside the timed try/catch below; a throw would escape to the clock listener
1731
1868
  this.logger?.debug("Fast confirmation notify failed", { slot: this.fcStore.currentSlot }, err);
1732
1869
  }
1733
- return;
1870
+ return false;
1734
1871
  }
1735
1872
  withObservedDuration(this.metrics?.fastConfirmation.totalDuration.startTimer(), () => {
1736
1873
  try {
@@ -1745,6 +1882,7 @@ export class ForkChoice {
1745
1882
  this.logger?.debug("Fast confirmation failed", { slot: this.fcStore.currentSlot, head: this.head.blockRoot, confirmedRoot: this.fcStore.confirmedRoot }, err);
1746
1883
  }
1747
1884
  });
1885
+ return true;
1748
1886
  }
1749
1887
  createFastConfirmationContext() {
1750
1888
  const confirmationByzantineThreshold = this.config.CONFIRMATION_BYZANTINE_THRESHOLD;