@lodestar/state-transition 1.43.0-dev.aef3645690 → 1.43.0-dev.e5b13221e5

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 (56) hide show
  1. package/lib/block/processExecutionPayloadEnvelope.d.ts.map +1 -1
  2. package/lib/block/processExecutionPayloadEnvelope.js +4 -7
  3. package/lib/block/processExecutionPayloadEnvelope.js.map +1 -1
  4. package/lib/cache/epochCache.d.ts +3 -1
  5. package/lib/cache/epochCache.d.ts.map +1 -1
  6. package/lib/cache/epochCache.js +31 -13
  7. package/lib/cache/epochCache.js.map +1 -1
  8. package/lib/cache/epochTransitionCache.d.ts +5 -0
  9. package/lib/cache/epochTransitionCache.d.ts.map +1 -1
  10. package/lib/cache/epochTransitionCache.js +1 -0
  11. package/lib/cache/epochTransitionCache.js.map +1 -1
  12. package/lib/epoch/index.d.ts +3 -1
  13. package/lib/epoch/index.d.ts.map +1 -1
  14. package/lib/epoch/index.js +8 -1
  15. package/lib/epoch/index.js.map +1 -1
  16. package/lib/epoch/processPtcWindow.d.ts +11 -0
  17. package/lib/epoch/processPtcWindow.d.ts.map +1 -0
  18. package/lib/epoch/processPtcWindow.js +28 -0
  19. package/lib/epoch/processPtcWindow.js.map +1 -0
  20. package/lib/signatureSets/executionPayloadEnvelope.js +1 -1
  21. package/lib/signatureSets/executionPayloadEnvelope.js.map +1 -1
  22. package/lib/slot/upgradeStateToGloas.d.ts.map +1 -1
  23. package/lib/slot/upgradeStateToGloas.js +2 -1
  24. package/lib/slot/upgradeStateToGloas.js.map +1 -1
  25. package/lib/stateTransition.d.ts +1 -2
  26. package/lib/stateTransition.d.ts.map +1 -1
  27. package/lib/stateTransition.js +1 -2
  28. package/lib/stateTransition.js.map +1 -1
  29. package/lib/stateView/beaconStateView.d.ts +4 -8
  30. package/lib/stateView/beaconStateView.d.ts.map +1 -1
  31. package/lib/stateView/beaconStateView.js +19 -29
  32. package/lib/stateView/beaconStateView.js.map +1 -1
  33. package/lib/stateView/interface.d.ts +13 -9
  34. package/lib/stateView/interface.d.ts.map +1 -1
  35. package/lib/stateView/interface.js.map +1 -1
  36. package/lib/util/execution.d.ts +4 -2
  37. package/lib/util/execution.d.ts.map +1 -1
  38. package/lib/util/execution.js +7 -0
  39. package/lib/util/execution.js.map +1 -1
  40. package/lib/util/gloas.d.ts +8 -3
  41. package/lib/util/gloas.d.ts.map +1 -1
  42. package/lib/util/gloas.js +27 -1
  43. package/lib/util/gloas.js.map +1 -1
  44. package/package.json +8 -8
  45. package/src/block/processExecutionPayloadEnvelope.ts +4 -10
  46. package/src/cache/epochCache.ts +32 -30
  47. package/src/cache/epochTransitionCache.ts +7 -0
  48. package/src/epoch/index.ts +9 -0
  49. package/src/epoch/processPtcWindow.ts +38 -0
  50. package/src/signatureSets/executionPayloadEnvelope.ts +1 -1
  51. package/src/slot/upgradeStateToGloas.ts +2 -1
  52. package/src/stateTransition.ts +1 -2
  53. package/src/stateView/beaconStateView.ts +31 -33
  54. package/src/stateView/interface.ts +20 -9
  55. package/src/util/execution.ts +11 -1
  56. package/src/util/gloas.ts +50 -3
package/lib/util/gloas.js CHANGED
@@ -1,7 +1,10 @@
1
- import { BUILDER_INDEX_FLAG, BUILDER_PAYMENT_THRESHOLD_DENOMINATOR, BUILDER_PAYMENT_THRESHOLD_NUMERATOR, BUILDER_WITHDRAWAL_PREFIX, EFFECTIVE_BALANCE_INCREMENT, FAR_FUTURE_EPOCH, MIN_DEPOSIT_AMOUNT, SLOTS_PER_EPOCH, } from "@lodestar/params";
1
+ import { BUILDER_INDEX_FLAG, BUILDER_PAYMENT_THRESHOLD_DENOMINATOR, BUILDER_PAYMENT_THRESHOLD_NUMERATOR, BUILDER_WITHDRAWAL_PREFIX, EFFECTIVE_BALANCE_INCREMENT, FAR_FUTURE_EPOCH, MIN_DEPOSIT_AMOUNT, MIN_SEED_LOOKAHEAD, PTC_SIZE, SLOTS_PER_EPOCH, } from "@lodestar/params";
2
2
  import { byteArrayEquals } from "@lodestar/utils";
3
3
  import { getBlockRootAtSlot } from "./blockRoot.js";
4
4
  import { computeEpochAtSlot } from "./epoch.js";
5
+ import { computeEpochShuffling } from "./epochShuffling.js";
6
+ import { computePayloadTimelinessCommitteesForEpoch } from "./seed.js";
7
+ import { getActiveValidatorIndices } from "./validator.js";
5
8
  export function isBuilderWithdrawalCredential(withdrawalCredentials) {
6
9
  return withdrawalCredentials[0] === BUILDER_WITHDRAWAL_PREFIX;
7
10
  }
@@ -122,7 +125,30 @@ export function isAttestationSameSlotRootCache(rootCache, data) {
122
125
  const isCurrentBlockRoot = !byteArrayEquals(data.beaconBlockRoot, rootCache.getBlockRootAtSlot(data.slot - 1));
123
126
  return isMatchingBlockRoot && isCurrentBlockRoot;
124
127
  }
128
+ // TODO GLOAS: This function no longer exists in v1.7.0-alpha.5 specs. Remove it when appropriate to do so
125
129
  export function isParentBlockFull(state) {
126
130
  return byteArrayEquals(state.latestExecutionPayloadBid.blockHash, state.latestBlockHash);
127
131
  }
132
+ export function initializePtcWindow(state) {
133
+ const ptcWindow = Array.from({ length: SLOTS_PER_EPOCH }, () => new Uint32Array(PTC_SIZE));
134
+ const currentEpoch = state.epochCtx.epoch;
135
+ for (let epochOffset = 0; epochOffset <= MIN_SEED_LOOKAHEAD; epochOffset++) {
136
+ const epoch = currentEpoch + epochOffset;
137
+ const shuffling = state.epochCtx.getShufflingAtEpochOrNull(epoch) ??
138
+ computeEpochShuffling(state, getActiveValidatorIndices(state, epoch), epoch);
139
+ ptcWindow.push(...computePayloadTimelinessCommitteesForEpoch(state, epoch, shuffling.committees, state.epochCtx.effectiveBalanceIncrements));
140
+ }
141
+ return ptcWindow;
142
+ }
143
+ export function getPtcWindowEpochCacheData(state) {
144
+ const toUint32Arrays = (views) => views.map((v) => Uint32Array.from(v.getAll()));
145
+ const previousPtcWindow = state.ptcWindow.getReadonlyByRange(0, SLOTS_PER_EPOCH);
146
+ const currentPtcWindow = state.ptcWindow.getReadonlyByRange(SLOTS_PER_EPOCH, SLOTS_PER_EPOCH);
147
+ const nextPtcWindow = state.ptcWindow.getReadonlyByRange(2 * SLOTS_PER_EPOCH, SLOTS_PER_EPOCH);
148
+ return {
149
+ previousPayloadTimelinessCommittees: toUint32Arrays(previousPtcWindow),
150
+ payloadTimelinessCommittees: toUint32Arrays(currentPtcWindow),
151
+ nextPayloadTimelinessCommittees: toUint32Arrays(nextPtcWindow),
152
+ };
153
+ }
128
154
  //# sourceMappingURL=gloas.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gloas.js","sourceRoot":"","sources":["../../src/util/gloas.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gloas.js","sourceRoot":"","sources":["../../src/util/gloas.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "bugs": {
12
12
  "url": "https://github.com/ChainSafe/lodestar/issues"
13
13
  },
14
- "version": "1.43.0-dev.aef3645690",
14
+ "version": "1.43.0-dev.e5b13221e5",
15
15
  "type": "module",
16
16
  "exports": {
17
17
  ".": {
@@ -65,16 +65,16 @@
65
65
  "@chainsafe/persistent-merkle-tree": "^1.2.1",
66
66
  "@chainsafe/persistent-ts": "^1.0.0",
67
67
  "@chainsafe/pubkey-index-map": "^3.0.0",
68
- "@chainsafe/ssz": "^1.2.2",
68
+ "@chainsafe/ssz": "^1.4.0",
69
69
  "@chainsafe/swap-or-not-shuffle": "^1.2.1",
70
- "@lodestar/config": "^1.43.0-dev.aef3645690",
71
- "@lodestar/params": "^1.43.0-dev.aef3645690",
72
- "@lodestar/types": "^1.43.0-dev.aef3645690",
73
- "@lodestar/utils": "^1.43.0-dev.aef3645690",
70
+ "@lodestar/config": "^1.43.0-dev.e5b13221e5",
71
+ "@lodestar/params": "^1.43.0-dev.e5b13221e5",
72
+ "@lodestar/types": "^1.43.0-dev.e5b13221e5",
73
+ "@lodestar/utils": "^1.43.0-dev.e5b13221e5",
74
74
  "@vekexasia/bigint-buffer2": "^1.1.1"
75
75
  },
76
76
  "devDependencies": {
77
- "@lodestar/api": "^1.43.0-dev.aef3645690"
77
+ "@lodestar/api": "^1.43.0-dev.e5b13221e5"
78
78
  },
79
79
  "keywords": [
80
80
  "ethereum",
@@ -82,5 +82,5 @@
82
82
  "beacon",
83
83
  "blockchain"
84
84
  ],
85
- "gitHead": "ffc9f7818d18273a196890cbaf9814f62d9d04db"
85
+ "gitHead": "52a0608b862b2938272884c58061fa9da66b0b11"
86
86
  }
@@ -24,10 +24,10 @@ export function processExecutionPayloadEnvelope(
24
24
  signedEnvelope: gloas.SignedExecutionPayloadEnvelope,
25
25
  opts?: ProcessExecutionPayloadEnvelopeOpts
26
26
  ): CachedBeaconStateGloas {
27
- const {verifySignature = true, verifyStateRoot = true} = opts ?? {};
27
+ const {verifySignature = true} = opts ?? {};
28
28
  const envelope = signedEnvelope.message;
29
29
  const payload = envelope.payload;
30
- const fork = state.config.getForkSeq(envelope.slot);
30
+ const fork = state.config.getForkSeq(payload.slotNumber);
31
31
 
32
32
  if (verifySignature && !verifyExecutionPayloadEnvelopeSignature(state, signedEnvelope)) {
33
33
  throw Error(`Execution payload envelope has invalid signature builderIndex=${envelope.builderIndex}`);
@@ -74,12 +74,6 @@ export function processExecutionPayloadEnvelope(
74
74
 
75
75
  postState.commit();
76
76
 
77
- if (verifyStateRoot && !byteArrayEquals(envelope.stateRoot, postState.hashTreeRoot())) {
78
- throw new Error(
79
- `Envelope's state root does not match state envelope=${toRootHex(envelope.stateRoot)} state=${toRootHex(postState.hashTreeRoot())}`
80
- );
81
- }
82
-
83
77
  return postState;
84
78
  }
85
79
 
@@ -102,8 +96,8 @@ function validateExecutionPayloadEnvelope(
102
96
  );
103
97
  }
104
98
 
105
- if (envelope.slot !== state.slot) {
106
- throw new Error(`Slot mismatch between envelope and state envelope=${envelope.slot} state=${state.slot}`);
99
+ if (payload.slotNumber !== state.slot) {
100
+ throw new Error(`Slot mismatch between payload and state payload=${payload.slotNumber} state=${state.slot}`);
107
101
  }
108
102
 
109
103
  // Verify consistency with the committed bid
@@ -32,10 +32,10 @@ import {
32
32
  calculateShufflingDecisionRoot,
33
33
  computeEpochShuffling,
34
34
  } from "../util/epochShuffling.js";
35
+ import {getPtcWindowEpochCacheData} from "../util/gloas.js";
35
36
  import {
36
37
  computeActivationExitEpoch,
37
38
  computeEpochAtSlot,
38
- computePayloadTimelinessCommitteesForEpoch,
39
39
  computeProposers,
40
40
  computeSyncPeriodAtEpoch,
41
41
  getActivationChurnLimit,
@@ -56,7 +56,7 @@ import {sumTargetUnslashedBalanceIncrements} from "../util/targetUnslashedBalanc
56
56
  import {EffectiveBalanceIncrements, getEffectiveBalanceIncrementsWithLen} from "./effectiveBalanceIncrements.js";
57
57
  import {EpochTransitionCache} from "./epochTransitionCache.js";
58
58
  import {PubkeyCache, createPubkeyCache, syncPubkeys} from "./pubkeyCache.js";
59
- import {CachedBeaconStateAllForks, CachedBeaconStateFulu} from "./stateCache.js";
59
+ import {CachedBeaconStateAllForks, CachedBeaconStateFulu, CachedBeaconStateGloas} from "./stateCache.js";
60
60
  import {
61
61
  SyncCommitteeCache,
62
62
  SyncCommitteeCacheEmpty,
@@ -226,11 +226,12 @@ export class EpochCache {
226
226
  /** TODO: Indexed SyncCommitteeCache */
227
227
  nextSyncCommitteeIndexed: SyncCommitteeCache;
228
228
 
229
- // TODO GLOAS: See if we need to cache PTC for next epoch
230
229
  // PTC for previous epoch, required for slot N block validating slot N-1 attestations
231
230
  previousPayloadTimelinessCommittees: Uint32Array[];
232
231
  // PTC for current epoch, computed eagerly at epoch transition
233
232
  payloadTimelinessCommittees: Uint32Array[];
233
+ // PTC for next epoch, precomputed from the ptc window for future duty serving
234
+ nextPayloadTimelinessCommittees: Uint32Array[];
234
235
 
235
236
  // TODO: Helper stats
236
237
  syncPeriod: SyncPeriod;
@@ -270,6 +271,7 @@ export class EpochCache {
270
271
  nextSyncCommitteeIndexed: SyncCommitteeCache;
271
272
  previousPayloadTimelinessCommittees: Uint32Array[];
272
273
  payloadTimelinessCommittees: Uint32Array[];
274
+ nextPayloadTimelinessCommittees: Uint32Array[];
273
275
  epoch: Epoch;
274
276
  syncPeriod: SyncPeriod;
275
277
  }) {
@@ -301,6 +303,7 @@ export class EpochCache {
301
303
  this.nextSyncCommitteeIndexed = data.nextSyncCommitteeIndexed;
302
304
  this.previousPayloadTimelinessCommittees = data.previousPayloadTimelinessCommittees;
303
305
  this.payloadTimelinessCommittees = data.payloadTimelinessCommittees;
306
+ this.nextPayloadTimelinessCommittees = data.nextPayloadTimelinessCommittees;
304
307
  this.epoch = data.epoch;
305
308
  this.syncPeriod = data.syncPeriod;
306
309
  }
@@ -451,25 +454,13 @@ export class EpochCache {
451
454
  nextSyncCommitteeIndexed = new SyncCommitteeCacheEmpty();
452
455
  }
453
456
 
454
- // Compute PTC for all slots in the prev/current epoch
457
+ // Copy previous/current epoch PTC slices from state.ptcWindow once, then serve hot-path lookups from epochCtx.
455
458
  let previousPayloadTimelinessCommittees: Uint32Array[] = [];
456
459
  let payloadTimelinessCommittees: Uint32Array[] = [];
460
+ let nextPayloadTimelinessCommittees: Uint32Array[] = [];
457
461
  if (currentEpoch >= config.GLOAS_FORK_EPOCH) {
458
- payloadTimelinessCommittees = computePayloadTimelinessCommitteesForEpoch(
459
- state,
460
- currentEpoch,
461
- currentShuffling.committees,
462
- effectiveBalanceIncrements
463
- );
464
-
465
- if (!isGenesis && previousEpoch >= config.GLOAS_FORK_EPOCH) {
466
- previousPayloadTimelinessCommittees = computePayloadTimelinessCommitteesForEpoch(
467
- state,
468
- previousEpoch,
469
- previousShuffling.committees,
470
- effectiveBalanceIncrements
471
- );
472
- }
462
+ ({previousPayloadTimelinessCommittees, payloadTimelinessCommittees, nextPayloadTimelinessCommittees} =
463
+ getPtcWindowEpochCacheData(state as CachedBeaconStateGloas));
473
464
  }
474
465
 
475
466
  // Precompute churnLimit for efficient initiateValidatorExit() during block proposing MUST be recompute everytime the
@@ -546,6 +537,7 @@ export class EpochCache {
546
537
  nextSyncCommitteeIndexed,
547
538
  previousPayloadTimelinessCommittees,
548
539
  payloadTimelinessCommittees,
540
+ nextPayloadTimelinessCommittees,
549
541
  epoch: currentEpoch,
550
542
  syncPeriod: computeSyncPeriodAtEpoch(currentEpoch),
551
543
  });
@@ -592,6 +584,7 @@ export class EpochCache {
592
584
  nextSyncCommitteeIndexed: this.nextSyncCommitteeIndexed,
593
585
  previousPayloadTimelinessCommittees: this.previousPayloadTimelinessCommittees,
594
586
  payloadTimelinessCommittees: this.payloadTimelinessCommittees,
587
+ nextPayloadTimelinessCommittees: this.nextPayloadTimelinessCommittees,
595
588
  epoch: this.epoch,
596
589
  syncPeriod: this.syncPeriod,
597
590
  });
@@ -695,21 +688,26 @@ export class EpochCache {
695
688
  /**
696
689
  * At fork boundary, this runs post-fork logic and it happens after `upgradeState*` is called.
697
690
  */
698
- finalProcessEpoch(state: CachedBeaconStateAllForks): void {
691
+ finalProcessEpoch(state: CachedBeaconStateAllForks, epochTransitionCache: EpochTransitionCache): void {
699
692
  // this.epoch was updated at the end of afterProcessEpoch()
700
693
  const upcomingEpoch = this.epoch;
701
694
  const epochAfterUpcoming = upcomingEpoch + 1;
702
695
 
703
696
  this.proposersPrevEpoch = this.proposers;
704
697
  if (upcomingEpoch >= this.config.GLOAS_FORK_EPOCH) {
705
- // Shift and compute current epoch PTC eagerly for all slots
706
- this.previousPayloadTimelinessCommittees = this.payloadTimelinessCommittees;
707
- this.payloadTimelinessCommittees = computePayloadTimelinessCommitteesForEpoch(
708
- state,
709
- upcomingEpoch,
710
- this.currentShuffling.committees,
711
- this.effectiveBalanceIncrements
712
- );
698
+ if (epochTransitionCache.nextEpochPayloadTimelinessCommittees) {
699
+ // shift arrays from transition cache
700
+ this.previousPayloadTimelinessCommittees = this.payloadTimelinessCommittees;
701
+ this.payloadTimelinessCommittees = this.nextPayloadTimelinessCommittees;
702
+ this.nextPayloadTimelinessCommittees = epochTransitionCache.nextEpochPayloadTimelinessCommittees;
703
+ } else {
704
+ // Fork boundary: processPtcWindow didn't run, read from freshly initialized state.ptcWindow
705
+ ({
706
+ previousPayloadTimelinessCommittees: this.previousPayloadTimelinessCommittees,
707
+ payloadTimelinessCommittees: this.payloadTimelinessCommittees,
708
+ nextPayloadTimelinessCommittees: this.nextPayloadTimelinessCommittees,
709
+ } = getPtcWindowEpochCacheData(state as CachedBeaconStateGloas));
710
+ }
713
711
  }
714
712
  if (upcomingEpoch >= this.config.FULU_FORK_EPOCH) {
715
713
  // Populate proposer cache with lookahead from state
@@ -1034,12 +1032,16 @@ export class EpochCache {
1034
1032
  throw new Error("Payload Timeliness Committee is not available before gloas fork");
1035
1033
  }
1036
1034
 
1035
+ if (epoch === this.epoch - 1) {
1036
+ return this.previousPayloadTimelinessCommittees[slot % SLOTS_PER_EPOCH];
1037
+ }
1038
+
1037
1039
  if (epoch === this.epoch) {
1038
1040
  return this.payloadTimelinessCommittees[slot % SLOTS_PER_EPOCH];
1039
1041
  }
1040
1042
 
1041
- if (epoch === this.epoch - 1 && this.previousPayloadTimelinessCommittees.length > 0) {
1042
- return this.previousPayloadTimelinessCommittees[slot % SLOTS_PER_EPOCH];
1043
+ if (epoch === this.epoch + 1) {
1044
+ return this.nextPayloadTimelinessCommittees[slot % SLOTS_PER_EPOCH];
1043
1045
  }
1044
1046
 
1045
1047
  throw new Error(`Payload Timeliness Committee is not available for slot=${slot}`);
@@ -158,6 +158,12 @@ export interface EpochTransitionCache {
158
158
  */
159
159
  nextShuffling: EpochShuffling | null;
160
160
 
161
+ /**
162
+ * Pre-computed PTC for epoch N + MIN_SEED_LOOKAHEAD + 1, populated by processPtcWindow (Gloas+).
163
+ * Used by finalProcessEpoch to shift PTC arrays in epoch cache without reading from state.
164
+ */
165
+ nextEpochPayloadTimelinessCommittees: Uint32Array[] | null;
166
+
161
167
  /**
162
168
  * Altair specific, this is total active balances for the next epoch.
163
169
  * This is only used in `afterProcessEpoch` to compute base reward and sync participant reward.
@@ -502,6 +508,7 @@ export function beforeProcessEpoch(
502
508
  indicesToEject,
503
509
  nextShufflingActiveIndices,
504
510
  nextShuffling: null,
511
+ nextEpochPayloadTimelinessCommittees: null,
505
512
  // to be updated in processEffectiveBalanceUpdates
506
513
  nextEpochTotalActiveBalanceByIncrement: 0,
507
514
  isActivePrevEpoch,
@@ -28,6 +28,7 @@ import {processParticipationRecordUpdates} from "./processParticipationRecordUpd
28
28
  import {processPendingConsolidations} from "./processPendingConsolidations.js";
29
29
  import {processPendingDeposits} from "./processPendingDeposits.js";
30
30
  import {processProposerLookahead} from "./processProposerLookahead.js";
31
+ import {processPtcWindow} from "./processPtcWindow.js";
31
32
  import {processRandaoMixesReset} from "./processRandaoMixesReset.js";
32
33
  import {processRegistryUpdates} from "./processRegistryUpdates.js";
33
34
  import {processRewardsAndPenalties} from "./processRewardsAndPenalties.js";
@@ -55,6 +56,7 @@ export {
55
56
  processPendingDeposits,
56
57
  processPendingConsolidations,
57
58
  processProposerLookahead,
59
+ processPtcWindow,
58
60
  processBuilderPendingPayments,
59
61
  };
60
62
 
@@ -81,6 +83,7 @@ export enum EpochTransitionStep {
81
83
  processPendingDeposits = "processPendingDeposits",
82
84
  processPendingConsolidations = "processPendingConsolidations",
83
85
  processProposerLookahead = "processProposerLookahead",
86
+ processPtcWindow = "processPtcWindow",
84
87
  processBuilderPendingPayments = "processBuilderPendingPayments",
85
88
  }
86
89
 
@@ -211,4 +214,10 @@ export function processEpoch(
211
214
  processProposerLookahead(fork, state as CachedBeaconStateFulu, cache);
212
215
  timer?.();
213
216
  }
217
+
218
+ if (fork >= ForkSeq.gloas) {
219
+ const timer = metrics?.epochTransitionStepTime.startTimer({step: EpochTransitionStep.processPtcWindow});
220
+ processPtcWindow(state as CachedBeaconStateGloas, cache);
221
+ timer?.();
222
+ }
214
223
  }
@@ -0,0 +1,38 @@
1
+ import {MIN_SEED_LOOKAHEAD} from "@lodestar/params";
2
+ import {ssz} from "@lodestar/types";
3
+ import {CachedBeaconStateGloas, EpochTransitionCache} from "../types.js";
4
+ import {computeEpochShuffling} from "../util/epochShuffling.js";
5
+ import {computePayloadTimelinessCommitteesForEpoch} from "../util/seed.js";
6
+
7
+ /**
8
+ * Update the `ptc_window` field in the beacon state by shifting out the oldest epoch's
9
+ * PTC entries and appending newly computed entries for the next lookahead epoch.
10
+ * Stashes the computed PTCs in the transition cache for finalProcessEpoch to shift
11
+ * into the epoch cache without reading from state.
12
+ *
13
+ * Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.4/specs/gloas/beacon-chain.md#new-process_ptc_window
14
+ */
15
+ export function processPtcWindow(state: CachedBeaconStateGloas, cache: EpochTransitionCache): void {
16
+ const nextEpoch = state.epochCtx.epoch + MIN_SEED_LOOKAHEAD + 1;
17
+ const nextEpochShuffling =
18
+ cache.nextShuffling ?? computeEpochShuffling(state, cache.nextShufflingActiveIndices, nextEpoch);
19
+ cache.nextShuffling = nextEpochShuffling;
20
+
21
+ const newNextPayloadTimelinessCommittees = computePayloadTimelinessCommitteesForEpoch(
22
+ state,
23
+ nextEpoch,
24
+ nextEpochShuffling.committees,
25
+ state.epochCtx.effectiveBalanceIncrements
26
+ );
27
+
28
+ // Stash for finalProcessEpoch to shift into epoch cache
29
+ cache.nextEpochPayloadTimelinessCommittees = newNextPayloadTimelinessCommittees;
30
+
31
+ // Write shifted window to state: current(N) + next(N+1) + newlyComputed(N+2)
32
+ // From the perspective of upcoming epoch N+1, this is previous + current + next
33
+ state.ptcWindow = ssz.gloas.PtcWindow.toViewDU([
34
+ ...state.epochCtx.payloadTimelinessCommittees,
35
+ ...state.epochCtx.nextPayloadTimelinessCommittees,
36
+ ...newNextPayloadTimelinessCommittees,
37
+ ]);
38
+ }
@@ -11,7 +11,7 @@ export function getExecutionPayloadEnvelopeSigningRoot(
11
11
  config: BeaconConfig,
12
12
  envelope: gloas.ExecutionPayloadEnvelope
13
13
  ): Uint8Array {
14
- const domain = config.getDomain(envelope.slot, DOMAIN_BEACON_BUILDER);
14
+ const domain = config.getDomain(envelope.payload.slotNumber, DOMAIN_BEACON_BUILDER);
15
15
 
16
16
  return computeSigningRoot(ssz.gloas.ExecutionPayloadEnvelope, envelope, domain);
17
17
  }
@@ -5,7 +5,7 @@ import {isValidDepositSignature} from "../block/processDeposit.js";
5
5
  import {applyDepositForBuilder} from "../block/processDepositRequest.js";
6
6
  import {getCachedBeaconState} from "../cache/stateCache.js";
7
7
  import {CachedBeaconStateFulu, CachedBeaconStateGloas} from "../types.js";
8
- import {isBuilderWithdrawalCredential} from "../util/gloas.js";
8
+ import {initializePtcWindow, isBuilderWithdrawalCredential} from "../util/gloas.js";
9
9
  import {isValidatorKnown} from "../util/index.js";
10
10
 
11
11
  /**
@@ -61,6 +61,7 @@ export function upgradeStateToGloas(stateFulu: CachedBeaconStateFulu): CachedBea
61
61
  stateGloasView.pendingPartialWithdrawals = stateGloasCloned.pendingPartialWithdrawals;
62
62
  stateGloasView.pendingConsolidations = stateGloasCloned.pendingConsolidations;
63
63
  stateGloasView.proposerLookahead = stateGloasCloned.proposerLookahead;
64
+ stateGloasView.ptcWindow = ssz.gloas.PtcWindow.toViewDU(initializePtcWindow(stateFulu));
64
65
 
65
66
  for (let i = 0; i < SLOTS_PER_HISTORICAL_ROOT; i++) {
66
67
  stateGloasView.executionPayloadAvailability.set(i, true);
@@ -76,7 +76,6 @@ export enum StateHashTreeRootSource {
76
76
  prepareNextEpoch = "prepare_next_epoch",
77
77
  regenState = "regen_state",
78
78
  computeNewStateRoot = "compute_new_state_root",
79
- computePayloadEnvelopeStateRoot = "compute_payload_envelope_state_root",
80
79
  }
81
80
 
82
81
  /**
@@ -283,7 +282,7 @@ function processSlotsWithTransientCache(
283
282
  {
284
283
  const timer = metrics?.epochTransitionStepTime.startTimer({step: EpochTransitionStep.finalProcessEpoch});
285
284
  // last step to prepare epoch data that depends on the upgraded state, for example proposerLookahead of BeaconStateFulu
286
- postState.epochCtx.finalProcessEpoch(postState);
285
+ postState.epochCtx.finalProcessEpoch(postState, epochTransitionCache);
287
286
  timer?.();
288
287
  }
289
288
 
@@ -59,7 +59,12 @@ import {getBlockRootAtSlot} from "../util/blockRoot.js";
59
59
  import {computeAnchorCheckpoint} from "../util/computeAnchorCheckpoint.js";
60
60
  import {computeEpochAtSlot, computeStartSlotAtEpoch} from "../util/epoch.js";
61
61
  import {EpochShuffling} from "../util/epochShuffling.js";
62
- import {isExecutionEnabled, isExecutionStateType, isMergeTransitionComplete} from "../util/execution.js";
62
+ import {
63
+ isExecutionEnabled,
64
+ isExecutionStateType,
65
+ isGloasStateType,
66
+ isMergeTransitionComplete,
67
+ } from "../util/execution.js";
63
68
  import {canBuilderCoverBid} from "../util/gloas.js";
64
69
  import {loadState} from "../util/loadState/loadState.js";
65
70
  import {getRandaoMix} from "../util/seed.js";
@@ -79,8 +84,6 @@ export class BeaconStateView implements IBeaconStateViewLatestFork {
79
84
  private _currentEpochParticipation: Uint8Array | null = null;
80
85
  // bellatrix
81
86
  private _latestExecutionPayloadHeader: ExecutionPayloadHeader | null = null;
82
- // Caches the cross-fork latestBlockHash value
83
- private _latestBlockHash: Bytes32 | null = null;
84
87
  // capella
85
88
  private _historicalSummaries: capella.HistoricalSummaries | null = null;
86
89
  // electra
@@ -213,9 +216,13 @@ export class BeaconStateView implements IBeaconStateViewLatestFork {
213
216
  // bellatrix
214
217
 
215
218
  get latestExecutionPayloadHeader(): ExecutionPayloadHeader {
216
- if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.bellatrix) {
219
+ const forkSeq = this.config.getForkSeq(this.cachedState.slot);
220
+ if (forkSeq < ForkSeq.bellatrix) {
217
221
  throw new Error("latestExecutionPayloadHeader is not available before Bellatrix");
218
222
  }
223
+ if (forkSeq >= ForkSeq.gloas) {
224
+ throw new Error("latestExecutionPayloadHeader is not available after Gloas");
225
+ }
219
226
 
220
227
  if (this._latestExecutionPayloadHeader === null) {
221
228
  this._latestExecutionPayloadHeader = (
@@ -226,30 +233,6 @@ export class BeaconStateView implements IBeaconStateViewLatestFork {
226
233
  return this._latestExecutionPayloadHeader;
227
234
  }
228
235
 
229
- /**
230
- * Cross-fork accessor for the execution block hash of the most recently included payload.
231
- * Pre-gloas: reads from latestExecutionPayloadHeader.blockHash.
232
- * Gloas+: reads the dedicated latestBlockHash field (EIP-7732).
233
- */
234
- get latestBlockHash(): Bytes32 {
235
- const forkSeq = this.config.getForkSeq(this.cachedState.slot);
236
- if (forkSeq < ForkSeq.bellatrix) {
237
- throw new Error("latestBlockHash is not available before Bellatrix");
238
- }
239
-
240
- if (this._latestBlockHash === null) {
241
- if (forkSeq >= ForkSeq.gloas) {
242
- this._latestBlockHash = (this.cachedState as CachedBeaconStateGloas).latestBlockHash;
243
- } else {
244
- this._latestBlockHash = (
245
- this.cachedState as CachedBeaconStateExecutions
246
- ).latestExecutionPayloadHeader.blockHash;
247
- }
248
- }
249
-
250
- return this._latestBlockHash;
251
- }
252
-
253
236
  /**
254
237
  * The execution block number of the most recently included payload.
255
238
  * Named payloadBlockNumber (not latestBlockNumber) to mirror ExecutionPayloadHeader.blockNumber pre-gloas.
@@ -360,6 +343,13 @@ export class BeaconStateView implements IBeaconStateViewLatestFork {
360
343
 
361
344
  // gloas
362
345
 
346
+ get latestBlockHash(): Bytes32 {
347
+ if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.gloas) {
348
+ throw new Error("latestBlockHash is not available before Gloas");
349
+ }
350
+ return (this.cachedState as CachedBeaconStateGloas).latestBlockHash;
351
+ }
352
+
363
353
  get executionPayloadAvailability(): BitArray {
364
354
  if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.gloas) {
365
355
  throw new Error("executionPayloadAvailability is not available before Gloas");
@@ -589,7 +579,10 @@ export class BeaconStateView implements IBeaconStateViewLatestFork {
589
579
  }
590
580
 
591
581
  get isMergeTransitionComplete(): boolean {
592
- return isExecutionStateType(this.cachedState) && isMergeTransitionComplete(this.cachedState);
582
+ return (
583
+ (isExecutionStateType(this.cachedState) || isGloasStateType(this.cachedState)) &&
584
+ isMergeTransitionComplete(this.cachedState)
585
+ );
593
586
  }
594
587
 
595
588
  // Block production
@@ -711,7 +704,11 @@ export class BeaconStateView implements IBeaconStateViewLatestFork {
711
704
 
712
705
  // Serialization
713
706
 
714
- loadOtherState(stateBytes: Uint8Array, seedValidatorsBytes?: Uint8Array): IBeaconStateView {
707
+ loadOtherState(
708
+ stateBytes: Uint8Array,
709
+ seedValidatorsBytes?: Uint8Array,
710
+ opts?: {preloadValidatorsAndBalances?: boolean}
711
+ ): IBeaconStateView {
715
712
  const {state} = loadState(this.config, this.cachedState, stateBytes, seedValidatorsBytes);
716
713
 
717
714
  const cachedState = createCachedBeaconState(
@@ -726,9 +723,10 @@ export class BeaconStateView implements IBeaconStateViewLatestFork {
726
723
  }
727
724
  );
728
725
 
729
- // load all cache in order for consumers (usually regen.getState()) to process blocks faster
730
- cachedState.validators.getAllReadonlyValues();
731
- cachedState.balances.getAll();
726
+ if (opts?.preloadValidatorsAndBalances) {
727
+ cachedState.validators.getAllReadonlyValues();
728
+ cachedState.balances.getAll();
729
+ }
732
730
 
733
731
  return new BeaconStateView(cachedState);
734
732
  }
@@ -138,7 +138,13 @@ export interface IBeaconStateView {
138
138
  isStateValidatorsNodesPopulated(): boolean;
139
139
 
140
140
  // Serialization
141
- loadOtherState(stateBytes: Uint8Array, seedValidatorsBytes?: Uint8Array): IBeaconStateView;
141
+ /** Set `preloadValidatorsAndBalances` only when the whole state will be consumed
142
+ * immediately (e.g. CP reload before block replay). */
143
+ loadOtherState(
144
+ stateBytes: Uint8Array,
145
+ seedValidatorsBytes?: Uint8Array,
146
+ opts?: {preloadValidatorsAndBalances?: boolean}
147
+ ): IBeaconStateView;
142
148
  toValue(): BeaconState;
143
149
  serialize(): Uint8Array;
144
150
  serializedSize(): number;
@@ -187,13 +193,6 @@ export interface IBeaconStateViewAltair extends IBeaconStateView {
187
193
  export interface IBeaconStateViewBellatrix extends IBeaconStateViewAltair {
188
194
  forkName: ForkPostBellatrix;
189
195
  latestExecutionPayloadHeader: ExecutionPayloadHeader;
190
- /**
191
- * Cross-fork accessor for the execution block hash of the most recently included payload.
192
- * Pre-gloas: returns latestExecutionPayloadHeader.blockHash (bellatrix–fulu).
193
- * Gloas+: returns the dedicated latestBlockHash state field (EIP-7732).
194
- * Throws before bellatrix.
195
- */
196
- latestBlockHash: Bytes32;
197
196
  /**
198
197
  * The execution block number of the most recently included payload.
199
198
  * Named payloadBlockNumber (not latestBlockNumber) to mirror ExecutionPayloadHeader.blockNumber pre-gloas.
@@ -244,6 +243,11 @@ export interface IBeaconStateViewFulu extends IBeaconStateViewElectra {
244
243
  /** Gloas+ state fields — use isStatePostGloas() guard */
245
244
  export interface IBeaconStateViewGloas extends IBeaconStateViewFulu {
246
245
  forkName: ForkPostGloas;
246
+ /** Removed from BeaconState in gloas. Use `latestBlockHash` instead. */
247
+ latestExecutionPayloadHeader: never;
248
+ /** Removed from BeaconState in gloas. */
249
+ payloadBlockNumber: never;
250
+ latestBlockHash: Bytes32;
247
251
  executionPayloadAvailability: BitArray;
248
252
  latestExecutionPayloadBid: ExecutionPayloadBid;
249
253
  payloadExpectedWithdrawals: capella.Withdrawal[];
@@ -262,7 +266,14 @@ export interface IBeaconStateViewGloas extends IBeaconStateViewFulu {
262
266
  * forkName as ForkName since the class wraps any fork's state.
263
267
  * Sub-interfaces retain their narrowed forkName discriminants for caller-side type guards.
264
268
  */
265
- export type IBeaconStateViewLatestFork = Omit<IBeaconStateViewGloas, "forkName"> & {forkName: ForkName};
269
+ export type IBeaconStateViewLatestFork = Omit<
270
+ IBeaconStateViewGloas,
271
+ "forkName" | "latestExecutionPayloadHeader" | "payloadBlockNumber"
272
+ > & {
273
+ forkName: ForkName;
274
+ latestExecutionPayloadHeader: ExecutionPayloadHeader;
275
+ payloadBlockNumber: number;
276
+ };
266
277
  export function isStatePostAltair(state: IBeaconStateView): state is IBeaconStateViewAltair {
267
278
  return isForkPostAltair(state.forkName);
268
279
  }
@@ -18,6 +18,7 @@ import {
18
18
  BeaconStateBellatrix,
19
19
  BeaconStateCapella,
20
20
  BeaconStateExecutions,
21
+ BeaconStateGloas,
21
22
  CachedBeaconStateAllForks,
22
23
  CachedBeaconStateExecutions,
23
24
  } from "../types.js";
@@ -46,7 +47,11 @@ export function isExecutionEnabled(state: BeaconStateExecutions, block: BeaconBl
46
47
  * Merge is complete when the state includes execution layer data:
47
48
  * state.latestExecutionPayloadHeader NOT EMPTY or state is post-capella
48
49
  */
49
- export function isMergeTransitionComplete(state: BeaconStateExecutions): boolean {
50
+ export function isMergeTransitionComplete(state: BeaconStateExecutions | BeaconStateGloas): boolean {
51
+ if (isGloasStateType(state)) {
52
+ return true;
53
+ }
54
+
50
55
  if (isCapellaStateType(state)) {
51
56
  // All networks have completed the merge transition before capella
52
57
  return true;
@@ -71,6 +76,11 @@ export function isCapellaStateType(state: BeaconStateAllForks): state is BeaconS
71
76
  );
72
77
  }
73
78
 
79
+ /** Type guard for gloas.BeaconState */
80
+ export function isGloasStateType(state: BeaconStateAllForks): state is BeaconStateGloas {
81
+ return (state as BeaconStateGloas).latestBlockHash !== undefined;
82
+ }
83
+
74
84
  /** Type guard for bellatrix.CachedBeaconState */
75
85
  export function isExecutionCachedStateType(state: CachedBeaconStateAllForks): state is CachedBeaconStateExecutions {
76
86
  return (state as CachedBeaconStateExecutions).latestExecutionPayloadHeader !== undefined;