@lodestar/fork-choice 1.51.0-dev.99edacec52 → 1.51.0-dev.9bcbf1838a

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.
@@ -123,7 +123,7 @@ export interface IForkChoice {
123
123
  */
124
124
  shouldOverrideForkChoiceUpdate(
125
125
  headBlock: ProtoBlock,
126
- secFromSlot: number,
126
+ msFromSlot: number,
127
127
  currentSlot: Slot
128
128
  ): ShouldOverrideForkChoiceUpdateResult;
129
129
  /**
@@ -159,8 +159,8 @@ export interface IForkChoice {
159
159
  onBlock(
160
160
  block: BeaconBlock,
161
161
  state: IBeaconStateView,
162
- receiveDelaySec: number,
163
- importDelaySec: number,
162
+ receiveDelayMs: number,
163
+ importDelayMs: number,
164
164
  currentSlot: Slot,
165
165
  executionStatus: BlockExecutionStatus,
166
166
  dataAvailabilityStatus: DataAvailabilityStatus
@@ -279,6 +279,12 @@ export interface IForkChoice {
279
279
  shouldExtendPayload(blockRoot: RootHex): boolean;
280
280
  /** Spec: should_build_on_full(store, head, slot) */
281
281
  shouldBuildOnFull(head: ProtoBlock, slot: Slot): boolean;
282
+ /** Inclusion list verdict for the payload of `blockRoot`, as reported by the execution engine. True if it changed */
283
+ recordPayloadInclusionListSatisfaction(blockRoot: RootHex, satisfied: boolean): boolean;
284
+ /** True once the payload is delivered and not recorded unsatisfied */
285
+ isPayloadInclusionListSatisfied(blockRoot: RootHex): boolean;
286
+ /** Engine verdict recorded for the payload of `blockRoot`, null when none was recorded */
287
+ getPayloadInclusionListSatisfaction(blockRoot: RootHex): boolean | null;
282
288
  getFinalizedBlock(): ProtoBlock;
283
289
  getJustifiedBlock(): ProtoBlock;
284
290
  getFinalizedCheckpointSlot(): Slot;
@@ -344,7 +350,9 @@ export interface IForkChoice {
344
350
  * `CheckpointWithHex` / finalized root without a specific payload-status variant in mind.
345
351
  */
346
352
  forwardIterateDescendantsDefaultStatus(blockRoot: RootHex): IterableIterator<ProtoBlock>;
353
+ /** One summary per block, its default variant (FULL pre-Gloas, PENDING for Gloas) */
347
354
  getBlockSummariesByParentRoot(parentRoot: RootHex): ProtoBlock[];
355
+ /** One summary per block, its default variant (FULL pre-Gloas, PENDING for Gloas) */
348
356
  getBlockSummariesAtSlot(slot: Slot): ProtoBlock[];
349
357
  /** Returns the distance of common ancestor of nodes to the max of the newNode and the prevNode. */
350
358
  getCommonAncestorDepth(prevBlock: ProtoBlock, newBlock: ProtoBlock): AncestorResult;
package/src/metrics.ts CHANGED
@@ -19,6 +19,10 @@ export function getForkChoiceMetrics(register: MetricsRegisterExtra) {
19
19
  name: "beacon_fork_choice_requests_total",
20
20
  help: "Count of occasions where fork choice has tried to find a head",
21
21
  }),
22
+ unsatisfiedInclusionListBlocks: register.gauge({
23
+ name: "beacon_fork_choice_unsatisfied_inclusion_list_blocks_total",
24
+ help: "Count of payloads not extended because they did not satisfy the inclusion list constraints",
25
+ }),
22
26
  errors: register.gauge<{entrypoint: UpdateHeadOpt}>({
23
27
  name: "beacon_fork_choice_errors_total",
24
28
  help: "Count of occasions where fork choice has returned an error when trying to find a head",
@@ -122,6 +122,11 @@ export class ProtoArray {
122
122
  * when called with the negative parameter value.
123
123
  */
124
124
  private ptcAttested = new Map<RootHex, BitArray>();
125
+ /**
126
+ * Execution engine inclusion list verdict per block, recorded on payload import from heze.
127
+ * Spec: heze/fork-choice.md#modified-store (payload_inclusion_list_satisfaction)
128
+ */
129
+ private payloadInclusionListSatisfaction = new Map<RootHex, boolean>();
125
130
 
126
131
  constructor({
127
132
  pruneThreshold,
@@ -938,6 +943,27 @@ export class ProtoArray {
938
943
  return this.getParentPayloadStatus(block) === PayloadStatus.FULL;
939
944
  }
940
945
 
946
+ /** Spec: heze/fork-choice.md#new-record_payload_inclusion_list_satisfaction. Returns whether the verdict changed */
947
+ recordPayloadInclusionListSatisfaction(blockRoot: RootHex, satisfied: boolean): boolean {
948
+ const previous = this.payloadInclusionListSatisfaction.get(blockRoot);
949
+ this.payloadInclusionListSatisfaction.set(blockRoot, satisfied);
950
+ return previous !== satisfied;
951
+ }
952
+
953
+ /**
954
+ * Spec: heze/fork-choice.md#new-is_payload_inclusion_list_satisfied
955
+ *
956
+ * False until the payload is delivered. A delivered payload without a verdict is pre-heze, where
957
+ * no inclusion list constraints apply.
958
+ */
959
+ isPayloadInclusionListSatisfied(blockRoot: RootHex): boolean {
960
+ return this.hasPayload(blockRoot) && this.payloadInclusionListSatisfaction.get(blockRoot) !== false;
961
+ }
962
+
963
+ getPayloadInclusionListSatisfaction(blockRoot: RootHex): boolean | null {
964
+ return this.payloadInclusionListSatisfaction.get(blockRoot) ?? null;
965
+ }
966
+
941
967
  /**
942
968
  * Determine if we should extend the payload (prefer FULL over EMPTY)
943
969
  * Spec: gloas/fork-choice.md#new-should_extend_payload
@@ -956,6 +982,10 @@ export class ProtoArray {
956
982
  return false;
957
983
  }
958
984
 
985
+ if (this.payloadInclusionListSatisfaction.get(blockRoot) === false) {
986
+ return false;
987
+ }
988
+
959
989
  // Condition 1: Payload is timely AND data is available
960
990
  if (this.isPayloadTimely(blockRoot) && this.isPayloadDataAvailable(blockRoot)) {
961
991
  return true;
@@ -1265,6 +1295,15 @@ export class ProtoArray {
1265
1295
 
1266
1296
  // For Gloas: check if from previous slot
1267
1297
  if (node.slot + 1 !== currentSlot) {
1298
+ // During the block's own slot a payload known to not satisfy the inclusion list
1299
+ // constraints ranks below its EMPTY variant, as it will from the next slot on
1300
+ if (
1301
+ node.slot === currentSlot &&
1302
+ node.payloadStatus === PayloadStatus.FULL &&
1303
+ this.payloadInclusionListSatisfaction.get(node.blockRoot) === false
1304
+ ) {
1305
+ return PayloadStatus.PENDING;
1306
+ }
1268
1307
  return node.payloadStatus;
1269
1308
  }
1270
1309
 
@@ -1399,6 +1438,7 @@ export class ProtoArray {
1399
1438
  this.payloadTimelinessVotes.delete(root);
1400
1439
  this.ptcAttested.delete(root);
1401
1440
  this.payloadDataAvailabilityVotes.delete(root);
1441
+ this.payloadInclusionListSatisfaction.delete(root);
1402
1442
  }
1403
1443
 
1404
1444
  // Store nodes prior to finalization