@lodestar/fork-choice 1.45.0-dev.d7859e978b → 1.45.0-dev.e6c77a6488

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.
Files changed (33) hide show
  1. package/lib/forkChoice/fastConfirmation/data.d.ts.map +1 -1
  2. package/lib/forkChoice/fastConfirmation/data.js +1 -0
  3. package/lib/forkChoice/fastConfirmation/data.js.map +1 -1
  4. package/lib/forkChoice/fastConfirmation/types.d.ts +3 -0
  5. package/lib/forkChoice/fastConfirmation/types.d.ts.map +1 -1
  6. package/lib/forkChoice/fastConfirmation/types.js.map +1 -1
  7. package/lib/forkChoice/fastConfirmation/utils.d.ts +3 -3
  8. package/lib/forkChoice/fastConfirmation/utils.d.ts.map +1 -1
  9. package/lib/forkChoice/fastConfirmation/utils.js +27 -19
  10. package/lib/forkChoice/fastConfirmation/utils.js.map +1 -1
  11. package/lib/forkChoice/forkChoice.d.ts +7 -7
  12. package/lib/forkChoice/forkChoice.d.ts.map +1 -1
  13. package/lib/forkChoice/forkChoice.js +45 -41
  14. package/lib/forkChoice/forkChoice.js.map +1 -1
  15. package/lib/forkChoice/interface.d.ts +6 -6
  16. package/lib/forkChoice/interface.d.ts.map +1 -1
  17. package/lib/forkChoice/interface.js +1 -1
  18. package/lib/forkChoice/interface.js.map +1 -1
  19. package/lib/protoArray/computeDeltas.d.ts.map +1 -1
  20. package/lib/protoArray/computeDeltas.js +19 -15
  21. package/lib/protoArray/computeDeltas.js.map +1 -1
  22. package/lib/protoArray/protoArray.d.ts +6 -1
  23. package/lib/protoArray/protoArray.d.ts.map +1 -1
  24. package/lib/protoArray/protoArray.js +13 -5
  25. package/lib/protoArray/protoArray.js.map +1 -1
  26. package/package.json +8 -8
  27. package/src/forkChoice/fastConfirmation/data.ts +1 -0
  28. package/src/forkChoice/fastConfirmation/types.ts +4 -0
  29. package/src/forkChoice/fastConfirmation/utils.ts +39 -16
  30. package/src/forkChoice/forkChoice.ts +56 -53
  31. package/src/forkChoice/interface.ts +6 -16
  32. package/src/protoArray/computeDeltas.ts +21 -17
  33. package/src/protoArray/protoArray.ts +15 -5
@@ -1,14 +1,5 @@
1
1
  import {DataAvailabilityStatus, EffectiveBalanceIncrements, IBeaconStateView} from "@lodestar/state-transition";
2
- import {
3
- AttesterSlashing,
4
- BeaconBlock,
5
- Epoch,
6
- IndexedAttestation,
7
- Root,
8
- RootHex,
9
- Slot,
10
- ValidatorIndex,
11
- } from "@lodestar/types";
2
+ import {AttesterSlashing, BeaconBlock, Epoch, IndexedAttestation, Root, RootHex, Slot} from "@lodestar/types";
12
3
  import {
13
4
  BlockExecutionStatus,
14
5
  LVHExecResponse,
@@ -62,7 +53,7 @@ export enum NotReorgedReason {
62
53
  HeadBlockIsTimely = "headBlockIsTimely",
63
54
  ParentBlockNotAvailable = "parentBlockNotAvailable",
64
55
  ProposerBoostReorgDisabled = "proposerBoostReorgDisabled",
65
- NotShufflingStable = "notShufflingStable",
56
+ AtEpochBoundary = "atEpochBoundary",
66
57
  NotFFGCompetitive = "notFFGCompetitive",
67
58
  ChainLongUnfinality = "chainLongUnfinality",
68
59
  ParentBlockDistanceMoreThanOneSlot = "parentBlockDistanceMoreThanOneSlot",
@@ -90,7 +81,7 @@ export interface IForkChoice {
90
81
  * ## Specification
91
82
  *
92
83
  * Modified for Gloas to return ProtoNode instead of just root:
93
- * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.1/specs/gloas/fork-choice.md#modified-get_ancestor
84
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.11/specs/gloas/fork-choice.md#modified-get_ancestor
94
85
  *
95
86
  * Pre-Gloas: Returns (root, PAYLOAD_STATUS_FULL)
96
87
  * Gloas: Returns (root, payloadStatus) based on actual node state
@@ -160,8 +151,7 @@ export interface IForkChoice {
160
151
  blockDelaySec: number,
161
152
  currentSlot: Slot,
162
153
  executionStatus: BlockExecutionStatus,
163
- dataAvailabilityStatus: DataAvailabilityStatus,
164
- expectedProposerIndex: ValidatorIndex | null
154
+ dataAvailabilityStatus: DataAvailabilityStatus
165
155
  ): ProtoBlock;
166
156
  /**
167
157
  * Register `attestation` with the fork choice DAG so that it may influence future calls to `getHead`.
@@ -196,7 +186,7 @@ export interface IForkChoice {
196
186
  *
197
187
  * ## Specification
198
188
  *
199
- * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.0/specs/gloas/fork-choice.md#new-notify_ptc_messages
189
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.11/specs/gloas/fork-choice.md#new-notify_ptc_messages
200
190
  */
201
191
  notifyPtcMessages(
202
192
  blockRoot: RootHex,
@@ -211,7 +201,7 @@ export interface IForkChoice {
211
201
  *
212
202
  * ## Specification
213
203
  *
214
- * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.1/specs/gloas/fork-choice.md#new-on_execution_payload
204
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.11/specs/gloas/fork-choice.md#new-on_execution_payload_envelope
215
205
  *
216
206
  * @param blockRoot - The beacon block root for which the payload arrived
217
207
  * @param executionPayloadBlockHash - The block hash of the execution payload
@@ -67,6 +67,27 @@ export function computeDeltas(
67
67
  currentIndex = voteCurrentIndices[vIndex];
68
68
  nextIndex = voteNextIndices[vIndex];
69
69
 
70
+ // This equivocator check MUST be the first branch in the loop body.
71
+ // Handle equivocating (attester-slashed) validators before the no-live-vote check so the sorted
72
+ // cursor always advances; a jammed cursor would skip the discount for higher-index equivocators.
73
+ if (vIndex === equivocatingValidatorIndex) {
74
+ // this function could be called multiple times but we only want to process slashing validator for 1 time
75
+ if (currentIndex !== NULL_VOTE_INDEX) {
76
+ if (currentIndex >= numProtoNodes) {
77
+ throw new ProtoArrayError({
78
+ code: ProtoArrayErrorCode.INVALID_NODE_DELTA,
79
+ index: currentIndex,
80
+ });
81
+ }
82
+ oldBalance = oldBalances[vIndex] ?? 0;
83
+ deltas[currentIndex] -= oldBalance;
84
+ }
85
+ voteCurrentIndices[vIndex] = NULL_VOTE_INDEX;
86
+ equivocatingIndex++;
87
+ equivocatingValidatorIndex = equivocatingArray[equivocatingIndex];
88
+ continue;
89
+ }
90
+
70
91
  // There is no need to create a score change if the validator has never voted or both of their
71
92
  // votes are for the zero hash (genesis block)
72
93
  if (currentIndex === NULL_VOTE_INDEX && nextIndex === NULL_VOTE_INDEX) {
@@ -85,23 +106,6 @@ export function computeDeltas(
85
106
  // on-boarded fewer validators than the prior fork.
86
107
  newBalance = newBalances === oldBalances ? oldBalance : (newBalances[vIndex] ?? 0);
87
108
 
88
- if (vIndex === equivocatingValidatorIndex) {
89
- // this function could be called multiple times but we only want to process slashing validator for 1 time
90
- if (currentIndex !== NULL_VOTE_INDEX) {
91
- if (currentIndex >= numProtoNodes) {
92
- throw new ProtoArrayError({
93
- code: ProtoArrayErrorCode.INVALID_NODE_DELTA,
94
- index: currentIndex,
95
- });
96
- }
97
- deltas[currentIndex] -= oldBalance;
98
- }
99
- voteCurrentIndices[vIndex] = NULL_VOTE_INDEX;
100
- equivocatingIndex++;
101
- equivocatingValidatorIndex = equivocatingArray[equivocatingIndex];
102
- continue;
103
- }
104
-
105
109
  if (oldBalance === 0 && newBalance === 0) {
106
110
  newInactiveValidators++;
107
111
  continue;
@@ -1584,7 +1584,7 @@ export class ProtoArray {
1584
1584
  * ### Specification
1585
1585
  *
1586
1586
  * Modified for Gloas to return node identifier instead of just root:
1587
- * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.1/specs/gloas/fork-choice.md#modified-get_ancestor
1587
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.11/specs/gloas/fork-choice.md#modified-get_ancestor
1588
1588
  *
1589
1589
  * Pre-Gloas: Returns (root, PAYLOAD_STATUS_FULL)
1590
1590
  * Gloas: Returns (root, payloadStatus) based on actual node state
@@ -1941,6 +1941,11 @@ export class ProtoArray {
1941
1941
  * Returns `true` if the `descendantRoot` has an ancestor with `ancestorRoot`.
1942
1942
  * Always returns `false` if either input roots are unknown.
1943
1943
  * Still returns `true` if `ancestorRoot` === `descendantRoot` and payload statuses match.
1944
+ *
1945
+ * Gloas payload-status matching: a `PENDING` ancestor matches any payload variant
1946
+ * (PENDING/EMPTY/FULL) of the same block, so this can also return `true` for the same
1947
+ * root when statuses differ (e.g. ancestor `PENDING`, descendant `EMPTY`/`FULL`).
1948
+ * `EMPTY` and `FULL` are mutually exclusive siblings and never match each other.
1944
1949
  */
1945
1950
  isDescendant(
1946
1951
  ancestorRoot: RootHex,
@@ -1958,11 +1963,16 @@ export class ProtoArray {
1958
1963
  }
1959
1964
 
1960
1965
  for (const node of this.iterateAncestorNodes(descendantRoot, descendantPayloadStatus)) {
1961
- if (node.slot < ancestorNode.slot) {
1962
- return false;
1966
+ if (node.blockRoot === ancestorNode.blockRoot) {
1967
+ // Gloas is_ancestor: a PENDING ancestor matches any payload variant of the same block.
1968
+ return (
1969
+ node.payloadStatus === ancestorNode.payloadStatus || ancestorNode.payloadStatus === PayloadStatus.PENDING
1970
+ );
1963
1971
  }
1964
- if (node.blockRoot === ancestorNode.blockRoot && node.payloadStatus === ancestorNode.payloadStatus) {
1965
- return true;
1972
+ // Ancestors are iterated in decreasing slot, so once we reach the ancestor's slot
1973
+ // without a root match it cannot be in this chain.
1974
+ if (node.slot <= ancestorNode.slot) {
1975
+ return false;
1966
1976
  }
1967
1977
  }
1968
1978
  return false;