-
-
Notifications
You must be signed in to change notification settings - Fork 457
feat: add cached PTC window to the state #9211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
27a2075
e80c801
613aa40
42c3077
4531a52
5517f57
000b21c
06d23f3
b4e9577
c4282b9
6f95833
e4aef42
d17ed83
c4d0dcf
94a5034
0517ca3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -32,10 +32,10 @@ import { | |
| calculateShufflingDecisionRoot, | ||
| computeEpochShuffling, | ||
| } from "../util/epochShuffling.js"; | ||
| import {getPtcWindowEpochCacheData} from "../util/gloas.js"; | ||
| import { | ||
| computeActivationExitEpoch, | ||
| computeEpochAtSlot, | ||
| computePayloadTimelinessCommitteesForEpoch, | ||
| computeProposers, | ||
| computeSyncPeriodAtEpoch, | ||
| getActivationChurnLimit, | ||
|
|
@@ -56,7 +56,7 @@ import {sumTargetUnslashedBalanceIncrements} from "../util/targetUnslashedBalanc | |
| import {EffectiveBalanceIncrements, getEffectiveBalanceIncrementsWithLen} from "./effectiveBalanceIncrements.js"; | ||
| import {EpochTransitionCache} from "./epochTransitionCache.js"; | ||
| import {PubkeyCache, createPubkeyCache, syncPubkeys} from "./pubkeyCache.js"; | ||
| import {CachedBeaconStateAllForks, CachedBeaconStateFulu} from "./stateCache.js"; | ||
| import {CachedBeaconStateAllForks, CachedBeaconStateFulu, CachedBeaconStateGloas} from "./stateCache.js"; | ||
| import { | ||
| SyncCommitteeCache, | ||
| SyncCommitteeCacheEmpty, | ||
|
|
@@ -226,11 +226,12 @@ export class EpochCache { | |
| /** TODO: Indexed SyncCommitteeCache */ | ||
| nextSyncCommitteeIndexed: SyncCommitteeCache; | ||
|
|
||
| // TODO GLOAS: See if we need to cache PTC for next epoch | ||
| // PTC for previous epoch, required for slot N block validating slot N-1 attestations | ||
| previousPayloadTimelinessCommittees: Uint32Array[]; | ||
| // PTC for current epoch, computed eagerly at epoch transition | ||
| payloadTimelinessCommittees: Uint32Array[]; | ||
| // PTC for next epoch, precomputed from the ptc window for future duty serving | ||
| nextPayloadTimelinessCommittees: Uint32Array[]; | ||
|
ensi321 marked this conversation as resolved.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is a fragile approach because spec says we now store But for now, it is fine.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah was thinking about that too, it seems fine as is for now, at least in the state-transition we should handle it like we do in |
||
|
|
||
| // TODO: Helper stats | ||
| syncPeriod: SyncPeriod; | ||
|
|
@@ -270,6 +271,7 @@ export class EpochCache { | |
| nextSyncCommitteeIndexed: SyncCommitteeCache; | ||
| previousPayloadTimelinessCommittees: Uint32Array[]; | ||
| payloadTimelinessCommittees: Uint32Array[]; | ||
| nextPayloadTimelinessCommittees: Uint32Array[]; | ||
| epoch: Epoch; | ||
| syncPeriod: SyncPeriod; | ||
| }) { | ||
|
|
@@ -301,6 +303,7 @@ export class EpochCache { | |
| this.nextSyncCommitteeIndexed = data.nextSyncCommitteeIndexed; | ||
| this.previousPayloadTimelinessCommittees = data.previousPayloadTimelinessCommittees; | ||
| this.payloadTimelinessCommittees = data.payloadTimelinessCommittees; | ||
| this.nextPayloadTimelinessCommittees = data.nextPayloadTimelinessCommittees; | ||
| this.epoch = data.epoch; | ||
| this.syncPeriod = data.syncPeriod; | ||
| } | ||
|
|
@@ -451,25 +454,13 @@ export class EpochCache { | |
| nextSyncCommitteeIndexed = new SyncCommitteeCacheEmpty(); | ||
| } | ||
|
|
||
| // Compute PTC for all slots in the prev/current epoch | ||
| // Copy previous/current epoch PTC slices from state.ptcWindow once, then serve hot-path lookups from epochCtx. | ||
| let previousPayloadTimelinessCommittees: Uint32Array[] = []; | ||
| let payloadTimelinessCommittees: Uint32Array[] = []; | ||
| let nextPayloadTimelinessCommittees: Uint32Array[] = []; | ||
| if (currentEpoch >= config.GLOAS_FORK_EPOCH) { | ||
| payloadTimelinessCommittees = computePayloadTimelinessCommitteesForEpoch( | ||
| state, | ||
| currentEpoch, | ||
| currentShuffling.committees, | ||
| effectiveBalanceIncrements | ||
| ); | ||
|
|
||
| if (!isGenesis && previousEpoch >= config.GLOAS_FORK_EPOCH) { | ||
| previousPayloadTimelinessCommittees = computePayloadTimelinessCommitteesForEpoch( | ||
| state, | ||
| previousEpoch, | ||
| previousShuffling.committees, | ||
| effectiveBalanceIncrements | ||
| ); | ||
| } | ||
| ({previousPayloadTimelinessCommittees, payloadTimelinessCommittees, nextPayloadTimelinessCommittees} = | ||
| getPtcWindowEpochCacheData(state as CachedBeaconStateGloas)); | ||
| } | ||
|
|
||
| // Precompute churnLimit for efficient initiateValidatorExit() during block proposing MUST be recompute everytime the | ||
|
|
@@ -546,6 +537,7 @@ export class EpochCache { | |
| nextSyncCommitteeIndexed, | ||
| previousPayloadTimelinessCommittees, | ||
| payloadTimelinessCommittees, | ||
| nextPayloadTimelinessCommittees, | ||
| epoch: currentEpoch, | ||
| syncPeriod: computeSyncPeriodAtEpoch(currentEpoch), | ||
| }); | ||
|
|
@@ -592,6 +584,7 @@ export class EpochCache { | |
| nextSyncCommitteeIndexed: this.nextSyncCommitteeIndexed, | ||
| previousPayloadTimelinessCommittees: this.previousPayloadTimelinessCommittees, | ||
| payloadTimelinessCommittees: this.payloadTimelinessCommittees, | ||
| nextPayloadTimelinessCommittees: this.nextPayloadTimelinessCommittees, | ||
| epoch: this.epoch, | ||
| syncPeriod: this.syncPeriod, | ||
| }); | ||
|
|
@@ -695,21 +688,26 @@ export class EpochCache { | |
| /** | ||
| * At fork boundary, this runs post-fork logic and it happens after `upgradeState*` is called. | ||
| */ | ||
| finalProcessEpoch(state: CachedBeaconStateAllForks): void { | ||
| finalProcessEpoch(state: CachedBeaconStateAllForks, epochTransitionCache: EpochTransitionCache): void { | ||
| // this.epoch was updated at the end of afterProcessEpoch() | ||
| const upcomingEpoch = this.epoch; | ||
| const epochAfterUpcoming = upcomingEpoch + 1; | ||
|
|
||
| this.proposersPrevEpoch = this.proposers; | ||
| if (upcomingEpoch >= this.config.GLOAS_FORK_EPOCH) { | ||
| // Shift and compute current epoch PTC eagerly for all slots | ||
| this.previousPayloadTimelinessCommittees = this.payloadTimelinessCommittees; | ||
| this.payloadTimelinessCommittees = computePayloadTimelinessCommitteesForEpoch( | ||
| state, | ||
| upcomingEpoch, | ||
| this.currentShuffling.committees, | ||
| this.effectiveBalanceIncrements | ||
| ); | ||
| if (epochTransitionCache.nextEpochPayloadTimelinessCommittees) { | ||
| // shift arrays from transition cache | ||
| this.previousPayloadTimelinessCommittees = this.payloadTimelinessCommittees; | ||
| this.payloadTimelinessCommittees = this.nextPayloadTimelinessCommittees; | ||
| this.nextPayloadTimelinessCommittees = epochTransitionCache.nextEpochPayloadTimelinessCommittees; | ||
| } else { | ||
| // Fork boundary: processPtcWindow didn't run, read from freshly initialized state.ptcWindow | ||
| ({ | ||
| previousPayloadTimelinessCommittees: this.previousPayloadTimelinessCommittees, | ||
| payloadTimelinessCommittees: this.payloadTimelinessCommittees, | ||
| nextPayloadTimelinessCommittees: this.nextPayloadTimelinessCommittees, | ||
| } = getPtcWindowEpochCacheData(state as CachedBeaconStateGloas)); | ||
| } | ||
| } | ||
| if (upcomingEpoch >= this.config.FULU_FORK_EPOCH) { | ||
| // Populate proposer cache with lookahead from state | ||
|
|
@@ -1034,12 +1032,16 @@ export class EpochCache { | |
| throw new Error("Payload Timeliness Committee is not available before gloas fork"); | ||
| } | ||
|
|
||
| if (epoch === this.epoch - 1) { | ||
| return this.previousPayloadTimelinessCommittees[slot % SLOTS_PER_EPOCH]; | ||
| } | ||
|
|
||
| if (epoch === this.epoch) { | ||
| return this.payloadTimelinessCommittees[slot % SLOTS_PER_EPOCH]; | ||
| } | ||
|
|
||
| if (epoch === this.epoch - 1 && this.previousPayloadTimelinessCommittees.length > 0) { | ||
| return this.previousPayloadTimelinessCommittees[slot % SLOTS_PER_EPOCH]; | ||
| if (epoch === this.epoch + 1) { | ||
| return this.nextPayloadTimelinessCommittees[slot % SLOTS_PER_EPOCH]; | ||
| } | ||
|
|
||
| throw new Error(`Payload Timeliness Committee is not available for slot=${slot}`); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is due to ChainSafe/ssz#503 which we aren't even making use of but this is not a big deal, we can revisit this later cc @wemeetagain