@lodestar/fork-choice 1.44.0-dev.6ef8199cfa → 1.44.0-dev.79c77e2e57

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.
@@ -3,6 +3,11 @@ import { DataAvailabilityStatus } from "@lodestar/state-transition";
3
3
  import { Epoch, RootHex, Slot } from "@lodestar/types";
4
4
  import { LVHExecError } from "./errors.js";
5
5
  import { LVHExecResponse, PayloadExecutionStatus, PayloadStatus, ProtoBlock, ProtoNode } from "./interface.js";
6
+ /**
7
+ * popcount(attended AND NOT yes) — explicit False-vote count.
8
+ * Excludes PTC members who didn't attest (the None state).
9
+ */
10
+ export declare function countNoVotes(attended: BitArray, yes: BitArray): number;
6
11
  export declare const DEFAULT_PRUNE_THRESHOLD = 0;
7
12
  type ProposerBoost = {
8
13
  root: RootHex;
@@ -40,12 +45,25 @@ export declare class ProtoArray {
40
45
  /**
41
46
  * PTC (Payload Timeliness Committee) votes per block as bitvectors
42
47
  * Maps block root to BitArray of PTC_SIZE bits (512 mainnet, 2 minimal)
43
- * Spec: gloas/fork-choice.md#modified-store (line 148)
48
+ * Spec: gloas/fork-choice.md#modified-store (payload_timeliness_vote)
44
49
  *
45
- * Bit i is set if PTC member i voted payload_present=true
46
- * Used by is_payload_timely() to determine if payload is timely
50
+ * Bit i = PTC member i voted payloadPresent=true (timeliness YES vote)
51
+ */
52
+ private payloadTimelinessVotes;
53
+ /**
54
+ * Blob data availability votes per block.
55
+ * Spec: gloas/fork-choice.md#modified-store (payload_data_availability_vote)
56
+ *
57
+ * Bit i = PTC member i voted blobDataAvailable=true (DA YES vote)
58
+ */
59
+ private payloadDataAvailabilityVotes;
60
+ /**
61
+ * Tracks which PTC members have attested at all (any payload_status).
62
+ * Without this, we cannot tell "didn't vote" (None) from "voted false" —
63
+ * a distinction required by payload_timeliness/payload_data_availability
64
+ * when called with the negative parameter value.
47
65
  */
48
- private ptcVotes;
66
+ private ptcAttested;
49
67
  constructor({ pruneThreshold, justifiedEpoch, justifiedRoot, finalizedEpoch, finalizedRoot }: {
50
68
  pruneThreshold: number;
51
69
  justifiedEpoch: Epoch;
@@ -150,29 +168,58 @@ export declare class ProtoArray {
150
168
  *
151
169
  * Spec: gloas/fork-choice.md (on_execution_payload event)
152
170
  */
153
- onExecutionPayload(blockRoot: RootHex, currentSlot: Slot, executionPayloadBlockHash: RootHex, executionPayloadNumber: number, proposerBoostRoot: RootHex | null, executionStatus: PayloadExecutionStatus, dataAvailabilityStatus: DataAvailabilityStatus): void;
171
+ onExecutionPayload(blockRoot: RootHex, currentSlot: Slot, executionPayloadBlockHash: RootHex, executionPayloadNumber: number, executionPayloadGasLimit: number, proposerBoostRoot: RootHex | null, executionStatus: PayloadExecutionStatus, dataAvailabilityStatus: DataAvailabilityStatus): void;
154
172
  /**
155
173
  * Update PTC votes for multiple validators attesting to a block
156
- * Spec: gloas/fork-choice.md#new-on_payload_attestation_message
157
- *
158
- * @param blockRoot - The beacon block root being attested
159
- * @param ptcIndices - Array of PTC committee indices that voted (0..PTC_SIZE-1)
160
- * @param payloadPresent - Whether the validators attest the payload is present
174
+ * Spec: gloas/fork-choice.md#new-notify_ptc_messages
161
175
  */
162
- notifyPtcMessages(blockRoot: RootHex, ptcIndices: number[], payloadPresent: boolean): void;
176
+ notifyPtcMessages(blockRoot: RootHex, slot: Slot, ptcIndices: number[], payloadPresent: boolean, blobDataAvailable: boolean): void;
163
177
  getPTCVotes(blockRootHex: RootHex): BitArray | null;
164
178
  /**
165
- * Check if execution payload for a block is timely
166
- * Spec: gloas/fork-choice.md#new-is_payload_timely
167
- *
168
- * Returns true if:
169
- * 1. Block has PTC votes tracked
170
- * 2. Payload is locally available (FULL variant exists in proto array)
171
- * 3. More than PAYLOAD_TIMELY_THRESHOLD (>50% of PTC) members voted payload_present=true
172
- *
173
- * @param blockRoot - The beacon block root to check
179
+ * Raw PTC vote tallies for a block root, for the debug fork choice endpoint.
180
+ * Returns `null` for pre-Gloas (or pruned) roots, which have no vote maps.
181
+ */
182
+ getPTCVoteCounts(blockRootHex: RootHex): {
183
+ attesterCount: number;
184
+ payloadPresentCount: number;
185
+ dataAvailableCount: number;
186
+ } | null;
187
+ getPreviousProposerBoostRoot(): RootHex;
188
+ /**
189
+ * Timeliness votes per PTC position, `null` where the member has not attested.
190
+ * Returns `null` if the block is unknown or not a Gloas block.
191
+ */
192
+ getPayloadTimelinessVotes(blockRootHex: RootHex): (boolean | null)[] | null;
193
+ /**
194
+ * Data-availability votes per PTC position, `null` where the member has not attested.
195
+ * Returns `null` if the block is unknown or not a Gloas block.
196
+ */
197
+ getPayloadDataAvailabilityVotes(blockRootHex: RootHex): (boolean | null)[] | null;
198
+ private toAttendanceAwareVotes;
199
+ /**
200
+ * Spec: payload_timeliness(store, root, timely=True)
174
201
  */
175
202
  isPayloadTimely(blockRoot: RootHex): boolean;
203
+ /**
204
+ * Spec: payload_timeliness(store, root, timely=False)
205
+ */
206
+ isPayloadNotTimely(blockRoot: RootHex): boolean;
207
+ /**
208
+ * Spec: payload_data_availability(store, root, available=True)
209
+ */
210
+ isPayloadDataAvailable(blockRoot: RootHex): boolean;
211
+ /**
212
+ * Spec: payload_data_availability(store, root, available=False)
213
+ */
214
+ isPayloadDataNotAvailable(blockRoot: RootHex): boolean;
215
+ /**
216
+ * Spec: should_build_on_full(store, head)
217
+ *
218
+ * The proposer is forced to build on the EMPTY variant (effectively reorging)
219
+ * when the PTC majority voted that the blob data is not available or that the
220
+ * payload was not timely.
221
+ */
222
+ shouldBuildOnFull(head: ProtoBlock, slot: Slot): boolean;
176
223
  /**
177
224
  * Check if parent node is FULL
178
225
  * Spec: gloas/fork-choice.md#new-is_parent_node_full
@@ -185,7 +232,7 @@ export declare class ProtoArray {
185
232
  * Spec: gloas/fork-choice.md#new-should_extend_payload
186
233
  *
187
234
  * Returns true if payload is verified (FULL variant exists) AND:
188
- * 1. Payload is timely, OR
235
+ * 1. Payload is timely AND data is available, OR
189
236
  * 2. No proposer boost root (empty/zero hash), OR
190
237
  * 3. Proposer boost root's parent is not this block, OR
191
238
  * 4. Proposer boost root extends FULL parent
@@ -1 +1 @@
1
- {"version":3,"file":"protoArray.d.ts","sourceRoot":"","sources":["../../src/protoArray/protoArray.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAExC,OAAO,EAAC,sBAAsB,EAA8C,MAAM,4BAA4B,CAAC;AAC/G,OAAO,EAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAC,MAAM,iBAAiB,CAAC;AAGrD,OAAO,EAAC,YAAY,EAAyD,MAAM,aAAa,CAAC;AACjG,OAAO,EAGL,eAAe,EACf,sBAAsB,EACtB,aAAa,EACb,UAAU,EACV,SAAS,EAEV,MAAM,gBAAgB,CAAC;AAQxB,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,KAAK,aAAa,GAAG;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,CAAC;AAIpD,yEAAyE;AACzE,KAAK,oBAAoB,GAAG,MAAM,CAAC;AACnC;;;;GAIG;AACH,KAAK,mBAAmB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AACvE,KAAK,cAAc,GAAG,oBAAoB,GAAG,mBAAmB,CAAC;AAEjE,qBAAa,UAAU;IAGrB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,KAAK,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,KAAK,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,EAAE,SAAS,EAAE,CAAM;IACxB;;;;;;;;;OASG;IACH,OAAO,8BAAsC;IAC7C,QAAQ,CAAC,EAAE,YAAY,CAAC;IAExB,OAAO,CAAC,qBAAqB,CAA8B;IAE3D;;;;;;;OAOG;IACH,OAAO,CAAC,QAAQ,CAAgC;IAEhD,YAAY,EACV,cAAc,EACd,cAAc,EACd,aAAa,EACb,cAAc,EACd,aAAa,EACd,EAAE;QACD,cAAc,EAAE,MAAM,CAAC;QACvB,cAAc,EAAE,KAAK,CAAC;QACtB,aAAa,EAAE,OAAO,CAAC;QACvB,cAAc,EAAE,KAAK,CAAC;QACtB,aAAa,EAAE,OAAO,CAAC;KACxB,EAMA;IAED,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,EAAE,WAAW,EAAE,IAAI,GAAG,UAAU,CAmBtF;IAED;;;;;;;;;;;;OAYG;IACH,2BAA2B,CAAC,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAqB3F;IAED;;;;;;;OAOG;IACH,iBAAiB,CAAC,SAAS,EAAE,OAAO,GAAG,aAAa,GAAG,SAAS,CAa/D;IAED;;;;OAIG;IACH,mBAAmB,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAa1D;IAED;;;;;;;;;;;;;;;OAeG;IACH,sBAAsB,CAAC,KAAK,EAAE,UAAU,GAAG,aAAa,CAsBvD;IAED;;OAEG;IACH,SAAS,CAAC,UAAU,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,GAAG,IAAI,GAAG,UAAU,GAAG,IAAI,CAoBjF;IAED;;;OAGG;IACH,8BAA8B,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CA0BzF;IAED;;OAEG;IACH,uBAAuB,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,CAGjF;IAED;;;;;;;;;;;;;;OAcG;IACH,iBAAiB,CAAC,EAChB,MAAM,EACN,aAAa,EACb,cAAc,EACd,aAAa,EACb,cAAc,EACd,aAAa,EACb,WAAW,EACZ,EAAE;QACD,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;QACpC,cAAc,EAAE,KAAK,CAAC;QACtB,aAAa,EAAE,OAAO,CAAC;QACvB,cAAc,EAAE,KAAK,CAAC;QACtB,aAAa,EAAE,OAAO,CAAC;QACvB,WAAW,EAAE,IAAI,CAAC;KACnB,GAAG,IAAI,CAoGP;IAED;;;;OAIG;IACH,OAAO,CAAC,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI,CA8GrF;IAED;;;;;;OAMG;IACH,kBAAkB,CAChB,SAAS,EAAE,OAAO,EAClB,WAAW,EAAE,IAAI,EACjB,yBAAyB,EAAE,OAAO,EAClC,sBAAsB,EAAE,MAAM,EAC9B,iBAAiB,EAAE,OAAO,GAAG,IAAI,EACjC,eAAe,EAAE,sBAAsB,EACvC,sBAAsB,EAAE,sBAAsB,GAC7C,IAAI,CAqEN;IAED;;;;;;;OAOG;IACH,iBAAiB,CAAC,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,cAAc,EAAE,OAAO,GAAG,IAAI,CAczF;IAED,WAAW,CAAC,YAAY,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAQlD;IAED;;;;;;;;;;OAUG;IACH,eAAe,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAe3C;IAED;;;;;OAKG;IACH,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAE3C;IAED;;;;;;;;;;;;OAYG;IACH,mBAAmB,CAAC,SAAS,EAAE,OAAO,EAAE,iBAAiB,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,CAmClF;IAED;;;;OAIG;IAEH,kBAAkB,CAAC,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,IAAI,GAAG,IAAI,CA4EzE;IAED,OAAO,CAAC,oCAAoC;IAa5C;;;;;;;;OAQG;IAEH,OAAO,CAAC,sCAAsC;IAoC9C,OAAO,CAAC,mBAAmB;IAe3B,OAAO,CAAC,qBAAqB;IA0C7B,OAAO,CAAC,mBAAmB;IA2B3B;;;;;;;;;OASG;IACH,OAAO,CAAC,0BAA0B;IAsBlC;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,GAAG,SAAS,CA8D7D;IAED;;;;;;;;;;;;;;OAcG;IACH,UAAU,CAAC,aAAa,EAAE,OAAO,GAAG,UAAU,EAAE,CAqG/C;IAED;;;;;;;;;;;;;OAaG;IAEH,iCAAiC,CAC/B,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,IAAI,EACjB,iBAAiB,EAAE,OAAO,GAAG,IAAI,GAChC,IAAI,CAsHN;IAED;;;OAGG;IACH,qBAAqB,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,GAAG,OAAO,CAiBjE;IAED;;;;;;;OAOG;IACH,mBAAmB,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,GAAG,OAAO,CAqB/D;IAED;;;;OAIG;IACH,2BAA2B,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAgBpD;IAED;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,GAAG,SAAS,GAAG,IAAI,CAM1E;IAED;;;;;;;;;;;;;OAaG;IACH,WAAW,CAAC,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,GAAG,SAAS,CAwE7D;IAED;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAiB1B;;;;OAIG;IACF,oBAAoB,CAAC,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAenG;IAED;;;;;OAKG;IACF,4BAA4B,CAAC,IAAI,EAAE,SAAS,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAU1E;IAED;;;;OAIG;IACH,mBAAmB,CAAC,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,GAAG,SAAS,EAAE,CAgCjF;IAED;;;;;;;OAOG;IACH,sBAAsB,CAAC,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,GAAG,SAAS,EAAE,CAkCpF;IAED;;;;OAIG;IACH,iCAAiC,CAC/B,SAAS,EAAE,OAAO,EAClB,aAAa,EAAE,aAAa,GAC3B;QAAC,SAAS,EAAE,SAAS,EAAE,CAAC;QAAC,YAAY,EAAE,SAAS,EAAE,CAAA;KAAC,CA2CrD;IAED;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAEpC;IAED;;;OAGG;IACH,UAAU,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAItC;IAED;;;;;;;;;OASG;IACH,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,GAAG,SAAS,GAAG,SAAS,CAM/E;IAED;;;;;;;;;OASG;IACH,QAAQ,CAAC,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,GAAG,UAAU,GAAG,SAAS,CAQjF;IAED;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,GAAG,UAAU,CAM7E;IAED;;;;OAIG;IACH,YAAY,CACV,YAAY,EAAE,OAAO,EACrB,qBAAqB,EAAE,aAAa,EACpC,cAAc,EAAE,OAAO,EACvB,uBAAuB,EAAE,aAAa,GACrC,OAAO,CAmBT;IAED;;OAEG;IACH,iBAAiB,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,IAAI,CAmCtE;IAED,MAAM,IAAI,MAAM,CAEf;IAED,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,eAAe;CAcxB"}
1
+ {"version":3,"file":"protoArray.d.ts","sourceRoot":"","sources":["../../src/protoArray/protoArray.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,28 @@ import { ExecutionStatus, HEX_ZERO_HASH, PayloadStatus, isGloasBlock, } from "./
10
10
  * Spec: gloas/fork-choice.md (PAYLOAD_TIMELY_THRESHOLD = PTC_SIZE // 2)
11
11
  */
12
12
  const PAYLOAD_TIMELY_THRESHOLD = Math.floor(PTC_SIZE / 2);
13
+ /**
14
+ * Threshold for blob data availability via PTC vote
15
+ * Spec: gloas/fork-choice.md (DATA_AVAILABILITY_TIMELY_THRESHOLD = PTC_SIZE // 2)
16
+ */
17
+ const DATA_AVAILABILITY_TIMELY_THRESHOLD = Math.floor(PTC_SIZE / 2);
18
+ /**
19
+ * popcount(attended AND NOT yes) — explicit False-vote count.
20
+ * Excludes PTC members who didn't attest (the None state).
21
+ */
22
+ export function countNoVotes(attended, yes) {
23
+ const a = attended.uint8Array;
24
+ const y = yes.uint8Array;
25
+ let count = 0;
26
+ for (let i = 0; i < a.length; i++) {
27
+ let byte = a[i] & ~y[i] & 0xff;
28
+ while (byte) {
29
+ byte &= byte - 1;
30
+ count++;
31
+ }
32
+ }
33
+ return count;
34
+ }
13
35
  export const DEFAULT_PRUNE_THRESHOLD = 0;
14
36
  const ZERO_HASH_HEX = toRootHex(Buffer.alloc(32, 0));
15
37
  export class ProtoArray {
@@ -37,12 +59,25 @@ export class ProtoArray {
37
59
  /**
38
60
  * PTC (Payload Timeliness Committee) votes per block as bitvectors
39
61
  * Maps block root to BitArray of PTC_SIZE bits (512 mainnet, 2 minimal)
40
- * Spec: gloas/fork-choice.md#modified-store (line 148)
62
+ * Spec: gloas/fork-choice.md#modified-store (payload_timeliness_vote)
63
+ *
64
+ * Bit i = PTC member i voted payloadPresent=true (timeliness YES vote)
65
+ */
66
+ payloadTimelinessVotes = new Map();
67
+ /**
68
+ * Blob data availability votes per block.
69
+ * Spec: gloas/fork-choice.md#modified-store (payload_data_availability_vote)
41
70
  *
42
- * Bit i is set if PTC member i voted payload_present=true
43
- * Used by is_payload_timely() to determine if payload is timely
71
+ * Bit i = PTC member i voted blobDataAvailable=true (DA YES vote)
72
+ */
73
+ payloadDataAvailabilityVotes = new Map();
74
+ /**
75
+ * Tracks which PTC members have attested at all (any payload_status).
76
+ * Without this, we cannot tell "didn't vote" (None) from "voted false" —
77
+ * a distinction required by payload_timeliness/payload_data_availability
78
+ * when called with the negative parameter value.
44
79
  */
45
- ptcVotes = new Map();
80
+ ptcAttested = new Map();
46
81
  constructor({ pruneThreshold, justifiedEpoch, justifiedRoot, finalizedEpoch, finalizedRoot, }) {
47
82
  this.pruneThreshold = pruneThreshold;
48
83
  this.justifiedEpoch = justifiedEpoch;
@@ -401,9 +436,11 @@ export class ProtoArray {
401
436
  }
402
437
  // Update bestChild for PENDING → EMPTY edge
403
438
  this.maybeUpdateBestChildAndDescendant(pendingIndex, emptyIndex, currentSlot, proposerBoostRoot);
404
- // Initialize PTC votes for this block (all false initially)
405
- // Spec: gloas/fork-choice.md#modified-on_block (line 645)
406
- this.ptcVotes.set(block.blockRoot, BitArray.fromBitLen(PTC_SIZE));
439
+ // Initialize PTC vote bitvectors for this block.
440
+ // Spec: gloas/fork-choice.md#modified-on_block
441
+ this.payloadTimelinessVotes.set(block.blockRoot, BitArray.fromBitLen(PTC_SIZE));
442
+ this.ptcAttested.set(block.blockRoot, BitArray.fromBitLen(PTC_SIZE));
443
+ this.payloadDataAvailabilityVotes.set(block.blockRoot, BitArray.fromBitLen(PTC_SIZE));
407
444
  }
408
445
  else {
409
446
  // Pre-Gloas: Only create FULL node (payload embedded in block)
@@ -436,7 +473,7 @@ export class ProtoArray {
436
473
  *
437
474
  * Spec: gloas/fork-choice.md (on_execution_payload event)
438
475
  */
439
- onExecutionPayload(blockRoot, currentSlot, executionPayloadBlockHash, executionPayloadNumber, proposerBoostRoot, executionStatus, dataAvailabilityStatus) {
476
+ onExecutionPayload(blockRoot, currentSlot, executionPayloadBlockHash, executionPayloadNumber, executionPayloadGasLimit, proposerBoostRoot, executionStatus, dataAvailabilityStatus) {
440
477
  // First check if block exists
441
478
  const variants = this.indices.get(blockRoot);
442
479
  if (variants == null) {
@@ -483,6 +520,7 @@ export class ProtoArray {
483
520
  executionStatus,
484
521
  executionPayloadBlockHash,
485
522
  executionPayloadNumber,
523
+ executionPayloadGasLimit,
486
524
  dataAvailabilityStatus,
487
525
  };
488
526
  const fullIndex = this.nodes.length;
@@ -499,27 +537,33 @@ export class ProtoArray {
499
537
  }
500
538
  /**
501
539
  * Update PTC votes for multiple validators attesting to a block
502
- * Spec: gloas/fork-choice.md#new-on_payload_attestation_message
503
- *
504
- * @param blockRoot - The beacon block root being attested
505
- * @param ptcIndices - Array of PTC committee indices that voted (0..PTC_SIZE-1)
506
- * @param payloadPresent - Whether the validators attest the payload is present
540
+ * Spec: gloas/fork-choice.md#new-notify_ptc_messages
507
541
  */
508
- notifyPtcMessages(blockRoot, ptcIndices, payloadPresent) {
509
- const votes = this.ptcVotes.get(blockRoot);
510
- if (votes === undefined) {
542
+ notifyPtcMessages(blockRoot, slot, ptcIndices, payloadPresent, blobDataAvailable) {
543
+ const votes = this.payloadTimelinessVotes.get(blockRoot);
544
+ const attended = this.ptcAttested.get(blockRoot);
545
+ const daVotes = this.payloadDataAvailabilityVotes.get(blockRoot);
546
+ if (votes === undefined || attended === undefined || daVotes === undefined) {
511
547
  // Block not found or not a Gloas block, ignore
512
548
  return;
513
549
  }
550
+ // PTC votes can only change the vote for their assigned beacon block, return early otherwise
551
+ const nodeIndex = this.getDefaultNodeIndex(blockRoot);
552
+ const node = nodeIndex !== undefined ? this.getNodeByIndex(nodeIndex) : undefined;
553
+ if (node === undefined || node.slot !== slot) {
554
+ return;
555
+ }
514
556
  for (const ptcIndex of ptcIndices) {
515
557
  if (ptcIndex < 0 || ptcIndex >= PTC_SIZE) {
516
558
  throw new Error(`Invalid PTC index: ${ptcIndex}, must be 0..${PTC_SIZE - 1}`);
517
559
  }
518
560
  votes.set(ptcIndex, payloadPresent);
561
+ daVotes.set(ptcIndex, blobDataAvailable);
562
+ attended.set(ptcIndex, true);
519
563
  }
520
564
  }
521
565
  getPTCVotes(blockRootHex) {
522
- const votes = this.ptcVotes.get(blockRootHex);
566
+ const votes = this.payloadTimelinessVotes.get(blockRootHex);
523
567
  if (votes === undefined) {
524
568
  // Block not found or not a Gloas block
525
569
  return null;
@@ -527,29 +571,116 @@ export class ProtoArray {
527
571
  return votes;
528
572
  }
529
573
  /**
530
- * Check if execution payload for a block is timely
531
- * Spec: gloas/fork-choice.md#new-is_payload_timely
532
- *
533
- * Returns true if:
534
- * 1. Block has PTC votes tracked
535
- * 2. Payload is locally available (FULL variant exists in proto array)
536
- * 3. More than PAYLOAD_TIMELY_THRESHOLD (>50% of PTC) members voted payload_present=true
537
- *
538
- * @param blockRoot - The beacon block root to check
574
+ * Raw PTC vote tallies for a block root, for the debug fork choice endpoint.
575
+ * Returns `null` for pre-Gloas (or pruned) roots, which have no vote maps.
576
+ */
577
+ getPTCVoteCounts(blockRootHex) {
578
+ const attended = this.ptcAttested.get(blockRootHex);
579
+ const timelinessVotes = this.payloadTimelinessVotes.get(blockRootHex);
580
+ const daVotes = this.payloadDataAvailabilityVotes.get(blockRootHex);
581
+ // The three maps share a lifecycle (set together in onBlock, deleted together on prune)
582
+ if (attended === undefined || timelinessVotes === undefined || daVotes === undefined) {
583
+ return null;
584
+ }
585
+ return {
586
+ attesterCount: bitCount(attended.uint8Array),
587
+ payloadPresentCount: bitCount(timelinessVotes.uint8Array),
588
+ dataAvailableCount: bitCount(daVotes.uint8Array),
589
+ };
590
+ }
591
+ getPreviousProposerBoostRoot() {
592
+ return this.previousProposerBoost?.root ?? HEX_ZERO_HASH;
593
+ }
594
+ /**
595
+ * Timeliness votes per PTC position, `null` where the member has not attested.
596
+ * Returns `null` if the block is unknown or not a Gloas block.
597
+ */
598
+ getPayloadTimelinessVotes(blockRootHex) {
599
+ return this.toAttendanceAwareVotes(this.payloadTimelinessVotes.get(blockRootHex), blockRootHex);
600
+ }
601
+ /**
602
+ * Data-availability votes per PTC position, `null` where the member has not attested.
603
+ * Returns `null` if the block is unknown or not a Gloas block.
604
+ */
605
+ getPayloadDataAvailabilityVotes(blockRootHex) {
606
+ return this.toAttendanceAwareVotes(this.payloadDataAvailabilityVotes.get(blockRootHex), blockRootHex);
607
+ }
608
+ toAttendanceAwareVotes(votes, blockRootHex) {
609
+ const attended = this.ptcAttested.get(blockRootHex);
610
+ if (votes === undefined || attended === undefined) {
611
+ return null;
612
+ }
613
+ return Array.from({ length: PTC_SIZE }, (_, i) => (attended.get(i) ? votes.get(i) : null));
614
+ }
615
+ /**
616
+ * Spec: payload_timeliness(store, root, timely=True)
539
617
  */
540
618
  isPayloadTimely(blockRoot) {
541
- const votes = this.ptcVotes.get(blockRoot);
542
- if (votes === undefined) {
543
- // Block not found or not a Gloas block
619
+ const votes = this.payloadTimelinessVotes.get(blockRoot);
620
+ if (votes === undefined)
544
621
  return false;
545
- }
546
- // If payload is not locally available, it's not timely
547
- if (!this.hasPayload(blockRoot)) {
622
+ if (!this.hasPayload(blockRoot))
623
+ return false;
624
+ return bitCount(votes.uint8Array) > PAYLOAD_TIMELY_THRESHOLD;
625
+ }
626
+ /**
627
+ * Spec: payload_timeliness(store, root, timely=False)
628
+ */
629
+ isPayloadNotTimely(blockRoot) {
630
+ const votes = this.payloadTimelinessVotes.get(blockRoot);
631
+ const attended = this.ptcAttested.get(blockRoot);
632
+ if (votes === undefined || attended === undefined)
633
+ return false;
634
+ // Spec: not verified locally → returns `not False = True`
635
+ if (!this.hasPayload(blockRoot))
636
+ return true;
637
+ return countNoVotes(attended, votes) > PAYLOAD_TIMELY_THRESHOLD;
638
+ }
639
+ /**
640
+ * Spec: payload_data_availability(store, root, available=True)
641
+ */
642
+ isPayloadDataAvailable(blockRoot) {
643
+ const daVotes = this.payloadDataAvailabilityVotes.get(blockRoot);
644
+ if (daVotes === undefined)
645
+ return false;
646
+ if (!this.hasPayload(blockRoot))
647
+ return false;
648
+ return bitCount(daVotes.uint8Array) > DATA_AVAILABILITY_TIMELY_THRESHOLD;
649
+ }
650
+ /**
651
+ * Spec: payload_data_availability(store, root, available=False)
652
+ */
653
+ isPayloadDataNotAvailable(blockRoot) {
654
+ const daVotes = this.payloadDataAvailabilityVotes.get(blockRoot);
655
+ const attended = this.ptcAttested.get(blockRoot);
656
+ if (daVotes === undefined || attended === undefined)
548
657
  return false;
658
+ // Spec: not verified locally → returns `not False = True`
659
+ if (!this.hasPayload(blockRoot))
660
+ return true;
661
+ return countNoVotes(attended, daVotes) > DATA_AVAILABILITY_TIMELY_THRESHOLD;
662
+ }
663
+ /**
664
+ * Spec: should_build_on_full(store, head)
665
+ *
666
+ * The proposer is forced to build on the EMPTY variant (effectively reorging)
667
+ * when the PTC majority voted that the blob data is not available or that the
668
+ * payload was not timely.
669
+ */
670
+ shouldBuildOnFull(head, slot) {
671
+ if (head.payloadStatus === PayloadStatus.PENDING) {
672
+ throw new Error("shouldBuildOnFull called with PENDING head");
549
673
  }
550
- // Count votes for payload_present=true
551
- const yesVotes = bitCount(votes.uint8Array);
552
- return yesVotes > PAYLOAD_TIMELY_THRESHOLD;
674
+ if (head.payloadStatus === PayloadStatus.EMPTY)
675
+ return false;
676
+ // The PTC data availability and timeliness views are only consulted for a head from the
677
+ // previous slot. For an earlier head the empty/full variant has already been resolved by
678
+ // weight in getHead.
679
+ if (head.slot + 1 !== slot)
680
+ return true;
681
+ if (this.isPayloadDataNotAvailable(head.blockRoot))
682
+ return false;
683
+ return !this.isPayloadNotTimely(head.blockRoot);
553
684
  }
554
685
  /**
555
686
  * Check if parent node is FULL
@@ -565,7 +696,7 @@ export class ProtoArray {
565
696
  * Spec: gloas/fork-choice.md#new-should_extend_payload
566
697
  *
567
698
  * Returns true if payload is verified (FULL variant exists) AND:
568
- * 1. Payload is timely, OR
699
+ * 1. Payload is timely AND data is available, OR
569
700
  * 2. No proposer boost root (empty/zero hash), OR
570
701
  * 3. Proposer boost root's parent is not this block, OR
571
702
  * 4. Proposer boost root extends FULL parent
@@ -577,8 +708,8 @@ export class ProtoArray {
577
708
  if (!this.hasPayload(blockRoot)) {
578
709
  return false;
579
710
  }
580
- // Condition 1: Payload is timely
581
- if (this.isPayloadTimely(blockRoot)) {
711
+ // Condition 1: Payload is timely AND data is available
712
+ if (this.isPayloadTimely(blockRoot) && this.isPayloadDataAvailable(blockRoot)) {
582
713
  return true;
583
714
  }
584
715
  // Condition 2: No proposer boost root
@@ -933,7 +1064,9 @@ export class ProtoArray {
933
1064
  this.indices.delete(root);
934
1065
  // Prune PTC votes for this block to prevent memory leak
935
1066
  // Spec: gloas/fork-choice.md (implicit - finalized blocks don't need PTC votes)
936
- this.ptcVotes.delete(root);
1067
+ this.payloadTimelinessVotes.delete(root);
1068
+ this.ptcAttested.delete(root);
1069
+ this.payloadDataAvailabilityVotes.delete(root);
937
1070
  }
938
1071
  // Store nodes prior to finalization
939
1072
  const removed = this.nodes.slice(0, finalizedIndex);