@lodestar/state-transition 1.42.0 → 1.43.0-dev.07452fe3b7
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.
- package/lib/block/index.d.ts +2 -2
- package/lib/block/index.d.ts.map +1 -1
- package/lib/block/index.js +11 -4
- package/lib/block/index.js.map +1 -1
- package/lib/block/processDepositRequest.d.ts +11 -2
- package/lib/block/processDepositRequest.d.ts.map +1 -1
- package/lib/block/processDepositRequest.js +34 -4
- package/lib/block/processDepositRequest.js.map +1 -1
- package/lib/block/processParentExecutionPayload.d.ts +20 -0
- package/lib/block/processParentExecutionPayload.d.ts.map +1 -0
- package/lib/block/processParentExecutionPayload.js +100 -0
- package/lib/block/processParentExecutionPayload.js.map +1 -0
- package/lib/block/processWithdrawals.d.ts.map +1 -1
- package/lib/block/processWithdrawals.js +10 -4
- package/lib/block/processWithdrawals.js.map +1 -1
- package/lib/cache/epochCache.d.ts +3 -1
- package/lib/cache/epochCache.d.ts.map +1 -1
- package/lib/cache/epochCache.js +31 -13
- package/lib/cache/epochCache.js.map +1 -1
- package/lib/cache/epochTransitionCache.d.ts +5 -0
- package/lib/cache/epochTransitionCache.d.ts.map +1 -1
- package/lib/cache/epochTransitionCache.js +1 -0
- package/lib/cache/epochTransitionCache.js.map +1 -1
- package/lib/epoch/index.d.ts +3 -1
- package/lib/epoch/index.d.ts.map +1 -1
- package/lib/epoch/index.js +8 -1
- package/lib/epoch/index.js.map +1 -1
- package/lib/epoch/processPtcWindow.d.ts +11 -0
- package/lib/epoch/processPtcWindow.d.ts.map +1 -0
- package/lib/epoch/processPtcWindow.js +28 -0
- package/lib/epoch/processPtcWindow.js.map +1 -0
- package/lib/index.d.ts +4 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +4 -1
- package/lib/index.js.map +1 -1
- package/lib/signatureSets/executionPayloadEnvelope.d.ts.map +1 -1
- package/lib/signatureSets/executionPayloadEnvelope.js +5 -1
- package/lib/signatureSets/executionPayloadEnvelope.js.map +1 -1
- package/lib/signatureSets/index.d.ts +1 -0
- package/lib/signatureSets/index.d.ts.map +1 -1
- package/lib/signatureSets/index.js +1 -0
- package/lib/signatureSets/index.js.map +1 -1
- package/lib/signatureSets/proposerPreferences.d.ts +4 -0
- package/lib/signatureSets/proposerPreferences.d.ts.map +1 -0
- package/lib/signatureSets/proposerPreferences.js +8 -0
- package/lib/signatureSets/proposerPreferences.js.map +1 -0
- package/lib/signatureSets/voluntaryExits.d.ts +2 -2
- package/lib/signatureSets/voluntaryExits.d.ts.map +1 -1
- package/lib/signatureSets/voluntaryExits.js +4 -0
- package/lib/signatureSets/voluntaryExits.js.map +1 -1
- package/lib/slot/upgradeStateToGloas.d.ts.map +1 -1
- package/lib/slot/upgradeStateToGloas.js +3 -1
- package/lib/slot/upgradeStateToGloas.js.map +1 -1
- package/lib/stateTransition.d.ts +1 -2
- package/lib/stateTransition.d.ts.map +1 -1
- package/lib/stateTransition.js +1 -2
- package/lib/stateTransition.js.map +1 -1
- package/lib/stateView/beaconStateView.d.ts +18 -12
- package/lib/stateView/beaconStateView.d.ts.map +1 -1
- package/lib/stateView/beaconStateView.js +69 -42
- package/lib/stateView/beaconStateView.js.map +1 -1
- package/lib/stateView/interface.d.ts +111 -54
- package/lib/stateView/interface.d.ts.map +1 -1
- package/lib/stateView/interface.js +22 -1
- package/lib/stateView/interface.js.map +1 -1
- package/lib/util/attestation.d.ts +12 -1
- package/lib/util/attestation.d.ts.map +1 -1
- package/lib/util/attestation.js +23 -8
- package/lib/util/attestation.js.map +1 -1
- package/lib/util/computeAnchorCheckpoint.d.ts +1 -1
- package/lib/util/computeAnchorCheckpoint.d.ts.map +1 -1
- package/lib/util/computeAnchorCheckpoint.js +6 -19
- package/lib/util/computeAnchorCheckpoint.js.map +1 -1
- package/lib/util/execution.d.ts +4 -2
- package/lib/util/execution.d.ts.map +1 -1
- package/lib/util/execution.js +7 -0
- package/lib/util/execution.js.map +1 -1
- package/lib/util/gloas.d.ts +7 -2
- package/lib/util/gloas.d.ts.map +1 -1
- package/lib/util/gloas.js +25 -3
- package/lib/util/gloas.js.map +1 -1
- package/package.json +8 -8
- package/src/block/index.ts +12 -4
- package/src/block/processDepositRequest.ts +50 -5
- package/src/block/processParentExecutionPayload.ts +116 -0
- package/src/block/processWithdrawals.ts +12 -4
- package/src/cache/epochCache.ts +32 -30
- package/src/cache/epochTransitionCache.ts +7 -0
- package/src/epoch/index.ts +9 -0
- package/src/epoch/processPtcWindow.ts +38 -0
- package/src/index.ts +20 -2
- package/src/signatureSets/executionPayloadEnvelope.ts +6 -2
- package/src/signatureSets/index.ts +1 -0
- package/src/signatureSets/proposerPreferences.ts +12 -0
- package/src/signatureSets/voluntaryExits.ts +5 -2
- package/src/slot/upgradeStateToGloas.ts +5 -1
- package/src/stateTransition.ts +1 -2
- package/src/stateView/beaconStateView.ts +91 -56
- package/src/stateView/interface.ts +163 -79
- package/src/util/attestation.ts +37 -8
- package/src/util/computeAnchorCheckpoint.ts +6 -19
- package/src/util/execution.ts +11 -1
- package/src/util/gloas.ts +46 -3
- package/lib/block/processExecutionPayloadEnvelope.d.ts +0 -9
- package/lib/block/processExecutionPayloadEnvelope.d.ts.map +0 -1
- package/lib/block/processExecutionPayloadEnvelope.js +0 -102
- package/lib/block/processExecutionPayloadEnvelope.js.map +0 -1
- package/src/block/processExecutionPayloadEnvelope.ts +0 -170
|
@@ -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
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -35,14 +35,32 @@ export {
|
|
|
35
35
|
isStateValidatorsNodesPopulated,
|
|
36
36
|
loadCachedBeaconState,
|
|
37
37
|
} from "./cache/stateCache.js";
|
|
38
|
-
export {type SyncCommitteeCache} from "./cache/syncCommitteeCache.js";
|
|
38
|
+
export {type SyncCommitteeCache, SyncCommitteeCacheEmpty} from "./cache/syncCommitteeCache.js";
|
|
39
39
|
export * from "./constants/index.js";
|
|
40
40
|
export type {EpochTransitionStep} from "./epoch/index.js";
|
|
41
41
|
export {type BeaconStateTransitionMetrics, getMetrics} from "./metrics.js";
|
|
42
42
|
export * from "./rewards/index.js";
|
|
43
43
|
export * from "./signatureSets/index.js";
|
|
44
44
|
export * from "./stateTransition.js";
|
|
45
|
-
export
|
|
45
|
+
export {BeaconStateView} from "./stateView/beaconStateView.js";
|
|
46
|
+
export {
|
|
47
|
+
type IBeaconStateView,
|
|
48
|
+
type IBeaconStateViewAltair,
|
|
49
|
+
type IBeaconStateViewBellatrix,
|
|
50
|
+
type IBeaconStateViewCapella,
|
|
51
|
+
type IBeaconStateViewDeneb,
|
|
52
|
+
type IBeaconStateViewElectra,
|
|
53
|
+
type IBeaconStateViewFulu,
|
|
54
|
+
type IBeaconStateViewGloas,
|
|
55
|
+
isStatePostAltair,
|
|
56
|
+
isStatePostBellatrix,
|
|
57
|
+
isStatePostCapella,
|
|
58
|
+
isStatePostDeneb,
|
|
59
|
+
isStatePostElectra,
|
|
60
|
+
isStatePostFulu,
|
|
61
|
+
isStatePostGloas,
|
|
62
|
+
} from "./stateView/interface.js";
|
|
63
|
+
export {createBeaconStateView, createBeaconStateViewForHistoricalRegen} from "./stateView/stateViewFactory.js";
|
|
46
64
|
export type {
|
|
47
65
|
BeaconStateAllForks,
|
|
48
66
|
BeaconStateAltair,
|
|
@@ -3,7 +3,7 @@ import {BeaconConfig} from "@lodestar/config";
|
|
|
3
3
|
import {BUILDER_INDEX_SELF_BUILD, DOMAIN_BEACON_BUILDER} from "@lodestar/params";
|
|
4
4
|
import {ValidatorIndex, gloas, ssz} from "@lodestar/types";
|
|
5
5
|
import {PubkeyCache} from "../cache/pubkeyCache.js";
|
|
6
|
-
import {IBeaconStateView} from "../stateView/interface.js";
|
|
6
|
+
import {IBeaconStateView, isStatePostGloas} from "../stateView/interface.js";
|
|
7
7
|
import {computeSigningRoot} from "../util/index.js";
|
|
8
8
|
import {type SingleSignatureSet, createSingleSignatureSetFromComponents} from "../util/signatureSets.js";
|
|
9
9
|
|
|
@@ -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.
|
|
14
|
+
const domain = config.getDomain(envelope.payload.slotNumber, DOMAIN_BEACON_BUILDER);
|
|
15
15
|
|
|
16
16
|
return computeSigningRoot(ssz.gloas.ExecutionPayloadEnvelope, envelope, domain);
|
|
17
17
|
}
|
|
@@ -23,6 +23,10 @@ export function getExecutionPayloadEnvelopeSignatureSet(
|
|
|
23
23
|
signedEnvelope: gloas.SignedExecutionPayloadEnvelope,
|
|
24
24
|
proposerIndex: ValidatorIndex
|
|
25
25
|
): SingleSignatureSet {
|
|
26
|
+
if (!isStatePostGloas(state)) {
|
|
27
|
+
throw new Error(`Expected gloas+ state for execution payload envelope signature, got fork=${state.forkName}`);
|
|
28
|
+
}
|
|
29
|
+
|
|
26
30
|
const envelope = signedEnvelope.message;
|
|
27
31
|
const pubkey =
|
|
28
32
|
envelope.builderIndex === BUILDER_INDEX_SELF_BUILD
|
|
@@ -20,6 +20,7 @@ export * from "./executionPayloadEnvelope.js";
|
|
|
20
20
|
export * from "./indexedAttestation.js";
|
|
21
21
|
export * from "./indexedPayloadAttestation.js";
|
|
22
22
|
export * from "./proposer.js";
|
|
23
|
+
export * from "./proposerPreferences.js";
|
|
23
24
|
export * from "./proposerSlashings.js";
|
|
24
25
|
export * from "./randao.js";
|
|
25
26
|
export * from "./voluntaryExits.js";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {BeaconConfig} from "@lodestar/config";
|
|
2
|
+
import {DOMAIN_PROPOSER_PREFERENCES} from "@lodestar/params";
|
|
3
|
+
import {gloas, ssz} from "@lodestar/types";
|
|
4
|
+
import {computeSigningRoot} from "../util/index.js";
|
|
5
|
+
|
|
6
|
+
export function getProposerPreferencesSigningRoot(
|
|
7
|
+
config: BeaconConfig,
|
|
8
|
+
preferences: gloas.ProposerPreferences
|
|
9
|
+
): Uint8Array {
|
|
10
|
+
const domain = config.getDomain(preferences.proposalSlot, DOMAIN_PROPOSER_PREFERENCES);
|
|
11
|
+
return computeSigningRoot(ssz.gloas.ProposerPreferences, preferences, domain);
|
|
12
|
+
}
|
|
@@ -3,7 +3,7 @@ import {BeaconConfig} from "@lodestar/config";
|
|
|
3
3
|
import {ForkSeq} from "@lodestar/params";
|
|
4
4
|
import {SignedBeaconBlock, Slot, phase0, ssz} from "@lodestar/types";
|
|
5
5
|
import {PubkeyCache} from "../cache/pubkeyCache.js";
|
|
6
|
-
import {IBeaconStateView} from "../stateView/interface.js";
|
|
6
|
+
import {IBeaconStateView, IBeaconStateViewGloas, isStatePostGloas} from "../stateView/interface.js";
|
|
7
7
|
import {
|
|
8
8
|
ISignatureSet,
|
|
9
9
|
SignatureSetType,
|
|
@@ -34,6 +34,9 @@ export function getVoluntaryExitSignatureSet(
|
|
|
34
34
|
const fork = config.getForkSeq(state.slot);
|
|
35
35
|
|
|
36
36
|
if (fork >= ForkSeq.gloas && isBuilderVoluntaryExit(signedVoluntaryExit)) {
|
|
37
|
+
if (!isStatePostGloas(state)) {
|
|
38
|
+
throw new Error(`Expected gloas+ state for builder voluntary exit signature, got fork=${state.forkName}`);
|
|
39
|
+
}
|
|
37
40
|
return getBuilderVoluntaryExitSignatureSet(config, state, signedVoluntaryExit);
|
|
38
41
|
}
|
|
39
42
|
|
|
@@ -68,7 +71,7 @@ export function getValidatorVoluntaryExitSignatureSet(
|
|
|
68
71
|
|
|
69
72
|
export function getBuilderVoluntaryExitSignatureSet(
|
|
70
73
|
config: BeaconConfig,
|
|
71
|
-
state:
|
|
74
|
+
state: IBeaconStateViewGloas,
|
|
72
75
|
signedVoluntaryExit: phase0.SignedVoluntaryExit
|
|
73
76
|
): ISignatureSet {
|
|
74
77
|
const messageSlot = computeStartSlotAtEpoch(signedVoluntaryExit.message.epoch);
|
|
@@ -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
|
/**
|
|
@@ -48,6 +48,9 @@ export function upgradeStateToGloas(stateFulu: CachedBeaconStateFulu): CachedBea
|
|
|
48
48
|
stateGloasView.currentSyncCommittee = stateGloasCloned.currentSyncCommittee;
|
|
49
49
|
stateGloasView.nextSyncCommittee = stateGloasCloned.nextSyncCommittee;
|
|
50
50
|
stateGloasView.latestExecutionPayloadBid.blockHash = stateFulu.latestExecutionPayloadHeader.blockHash;
|
|
51
|
+
stateGloasView.latestExecutionPayloadBid.executionRequestsRoot = ssz.electra.ExecutionRequests.hashTreeRoot(
|
|
52
|
+
ssz.electra.ExecutionRequests.defaultValue()
|
|
53
|
+
);
|
|
51
54
|
stateGloasView.nextWithdrawalIndex = stateGloasCloned.nextWithdrawalIndex;
|
|
52
55
|
stateGloasView.nextWithdrawalValidatorIndex = stateGloasCloned.nextWithdrawalValidatorIndex;
|
|
53
56
|
stateGloasView.historicalSummaries = stateGloasCloned.historicalSummaries;
|
|
@@ -61,6 +64,7 @@ export function upgradeStateToGloas(stateFulu: CachedBeaconStateFulu): CachedBea
|
|
|
61
64
|
stateGloasView.pendingPartialWithdrawals = stateGloasCloned.pendingPartialWithdrawals;
|
|
62
65
|
stateGloasView.pendingConsolidations = stateGloasCloned.pendingConsolidations;
|
|
63
66
|
stateGloasView.proposerLookahead = stateGloasCloned.proposerLookahead;
|
|
67
|
+
stateGloasView.ptcWindow = ssz.gloas.PtcWindow.toViewDU(initializePtcWindow(stateFulu));
|
|
64
68
|
|
|
65
69
|
for (let i = 0; i < SLOTS_PER_HISTORICAL_ROOT; i++) {
|
|
66
70
|
stateGloasView.executionPayloadAvailability.set(i, true);
|
package/src/stateTransition.ts
CHANGED
|
@@ -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
|
-
computeEnvelopeStateRoot = "compute_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
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {CompactMultiProof, ProofType, Tree, createProof} from "@chainsafe/persistent-merkle-tree";
|
|
2
2
|
import {BitArray, ByteViews} from "@chainsafe/ssz";
|
|
3
3
|
import {BeaconConfig} from "@lodestar/config";
|
|
4
|
-
import {ForkSeq, SLOTS_PER_HISTORICAL_ROOT
|
|
4
|
+
import {ForkName, ForkSeq, SLOTS_PER_HISTORICAL_ROOT} from "@lodestar/params";
|
|
5
5
|
import {
|
|
6
6
|
BeaconBlock,
|
|
7
7
|
BeaconState,
|
|
@@ -28,8 +28,7 @@ import {
|
|
|
28
28
|
rewards,
|
|
29
29
|
} from "@lodestar/types";
|
|
30
30
|
import {Checkpoint, Fork} from "@lodestar/types/phase0";
|
|
31
|
-
import {
|
|
32
|
-
import {ProcessExecutionPayloadEnvelopeOpts} from "../block/processExecutionPayloadEnvelope.js";
|
|
31
|
+
import {applyParentExecutionPayload} from "../block/processParentExecutionPayload.js";
|
|
33
32
|
import {VoluntaryExitValidity, getVoluntaryExitValidity} from "../block/processVoluntaryExit.js";
|
|
34
33
|
import {getExpectedWithdrawals} from "../block/processWithdrawals.js";
|
|
35
34
|
import {EffectiveBalanceIncrements} from "../cache/effectiveBalanceIncrements.js";
|
|
@@ -59,14 +58,19 @@ import {getBlockRootAtSlot} from "../util/blockRoot.js";
|
|
|
59
58
|
import {computeAnchorCheckpoint} from "../util/computeAnchorCheckpoint.js";
|
|
60
59
|
import {computeEpochAtSlot, computeStartSlotAtEpoch} from "../util/epoch.js";
|
|
61
60
|
import {EpochShuffling} from "../util/epochShuffling.js";
|
|
62
|
-
import {
|
|
61
|
+
import {
|
|
62
|
+
isExecutionEnabled,
|
|
63
|
+
isExecutionStateType,
|
|
64
|
+
isGloasStateType,
|
|
65
|
+
isMergeTransitionComplete,
|
|
66
|
+
} from "../util/execution.js";
|
|
63
67
|
import {canBuilderCoverBid} from "../util/gloas.js";
|
|
64
68
|
import {loadState} from "../util/loadState/loadState.js";
|
|
65
69
|
import {getRandaoMix} from "../util/seed.js";
|
|
66
70
|
import {getLatestWeakSubjectivityCheckpointEpoch} from "../util/weakSubjectivity.js";
|
|
67
|
-
import {IBeaconStateView} from "./interface.js";
|
|
71
|
+
import {IBeaconStateView, IBeaconStateViewGloas, IBeaconStateViewLatestFork, isStatePostGloas} from "./interface.js";
|
|
68
72
|
|
|
69
|
-
export class BeaconStateView implements
|
|
73
|
+
export class BeaconStateView implements IBeaconStateViewLatestFork {
|
|
70
74
|
private readonly config: BeaconConfig;
|
|
71
75
|
// Cached values extracted from the tree
|
|
72
76
|
// phase0
|
|
@@ -79,8 +83,6 @@ export class BeaconStateView implements IBeaconStateView {
|
|
|
79
83
|
private _currentEpochParticipation: Uint8Array | null = null;
|
|
80
84
|
// bellatrix
|
|
81
85
|
private _latestExecutionPayloadHeader: ExecutionPayloadHeader | null = null;
|
|
82
|
-
// Caches the cross-fork latestBlockHash value
|
|
83
|
-
private _latestBlockHash: Bytes32 | null = null;
|
|
84
86
|
// capella
|
|
85
87
|
private _historicalSummaries: capella.HistoricalSummaries | null = null;
|
|
86
88
|
// electra
|
|
@@ -92,6 +94,7 @@ export class BeaconStateView implements IBeaconStateView {
|
|
|
92
94
|
// gloas
|
|
93
95
|
private _executionPayloadAvailability: BitArray | null = null;
|
|
94
96
|
private _latestExecutionPayloadBid: ExecutionPayloadBid | null = null;
|
|
97
|
+
private _payloadExpectedWithdrawals: capella.Withdrawal[] | null = null;
|
|
95
98
|
|
|
96
99
|
constructor(readonly cachedState: CachedBeaconStateAllForks) {
|
|
97
100
|
this.config = cachedState.config;
|
|
@@ -99,6 +102,10 @@ export class BeaconStateView implements IBeaconStateView {
|
|
|
99
102
|
|
|
100
103
|
// phase0
|
|
101
104
|
|
|
105
|
+
get forkName(): ForkName {
|
|
106
|
+
return this.config.getForkName(this.cachedState.slot);
|
|
107
|
+
}
|
|
108
|
+
|
|
102
109
|
get slot(): number {
|
|
103
110
|
return this.cachedState.slot;
|
|
104
111
|
}
|
|
@@ -208,9 +215,13 @@ export class BeaconStateView implements IBeaconStateView {
|
|
|
208
215
|
// bellatrix
|
|
209
216
|
|
|
210
217
|
get latestExecutionPayloadHeader(): ExecutionPayloadHeader {
|
|
211
|
-
|
|
218
|
+
const forkSeq = this.config.getForkSeq(this.cachedState.slot);
|
|
219
|
+
if (forkSeq < ForkSeq.bellatrix) {
|
|
212
220
|
throw new Error("latestExecutionPayloadHeader is not available before Bellatrix");
|
|
213
221
|
}
|
|
222
|
+
if (forkSeq >= ForkSeq.gloas) {
|
|
223
|
+
throw new Error("latestExecutionPayloadHeader is not available after Gloas");
|
|
224
|
+
}
|
|
214
225
|
|
|
215
226
|
if (this._latestExecutionPayloadHeader === null) {
|
|
216
227
|
this._latestExecutionPayloadHeader = (
|
|
@@ -221,30 +232,6 @@ export class BeaconStateView implements IBeaconStateView {
|
|
|
221
232
|
return this._latestExecutionPayloadHeader;
|
|
222
233
|
}
|
|
223
234
|
|
|
224
|
-
/**
|
|
225
|
-
* Cross-fork accessor for the execution block hash of the most recently included payload.
|
|
226
|
-
* Pre-gloas: reads from latestExecutionPayloadHeader.blockHash.
|
|
227
|
-
* Gloas+: reads the dedicated latestBlockHash field (EIP-7732).
|
|
228
|
-
*/
|
|
229
|
-
get latestBlockHash(): Bytes32 {
|
|
230
|
-
const forkSeq = this.config.getForkSeq(this.cachedState.slot);
|
|
231
|
-
if (forkSeq < ForkSeq.bellatrix) {
|
|
232
|
-
throw new Error("latestBlockHash is not available before Bellatrix");
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
if (this._latestBlockHash === null) {
|
|
236
|
-
if (forkSeq >= ForkSeq.gloas) {
|
|
237
|
-
this._latestBlockHash = (this.cachedState as CachedBeaconStateGloas).latestBlockHash;
|
|
238
|
-
} else {
|
|
239
|
-
this._latestBlockHash = (
|
|
240
|
-
this.cachedState as CachedBeaconStateExecutions
|
|
241
|
-
).latestExecutionPayloadHeader.blockHash;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
return this._latestBlockHash;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
235
|
/**
|
|
249
236
|
* The execution block number of the most recently included payload.
|
|
250
237
|
* Named payloadBlockNumber (not latestBlockNumber) to mirror ExecutionPayloadHeader.blockNumber pre-gloas.
|
|
@@ -355,9 +342,16 @@ export class BeaconStateView implements IBeaconStateView {
|
|
|
355
342
|
|
|
356
343
|
// gloas
|
|
357
344
|
|
|
345
|
+
get latestBlockHash(): Bytes32 {
|
|
346
|
+
if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.gloas) {
|
|
347
|
+
throw new Error("latestBlockHash is not available before Gloas");
|
|
348
|
+
}
|
|
349
|
+
return (this.cachedState as CachedBeaconStateGloas).latestBlockHash;
|
|
350
|
+
}
|
|
351
|
+
|
|
358
352
|
get executionPayloadAvailability(): BitArray {
|
|
359
353
|
if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.gloas) {
|
|
360
|
-
throw new Error("executionPayloadAvailability is not available before
|
|
354
|
+
throw new Error("executionPayloadAvailability is not available before Gloas");
|
|
361
355
|
}
|
|
362
356
|
|
|
363
357
|
if (this._executionPayloadAvailability === null) {
|
|
@@ -371,7 +365,7 @@ export class BeaconStateView implements IBeaconStateView {
|
|
|
371
365
|
|
|
372
366
|
get latestExecutionPayloadBid(): ExecutionPayloadBid {
|
|
373
367
|
if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.gloas) {
|
|
374
|
-
throw new Error("latestExecutionPayloadBid is not available before
|
|
368
|
+
throw new Error("latestExecutionPayloadBid is not available before Gloas");
|
|
375
369
|
}
|
|
376
370
|
|
|
377
371
|
if (this._latestExecutionPayloadBid === null) {
|
|
@@ -382,9 +376,22 @@ export class BeaconStateView implements IBeaconStateView {
|
|
|
382
376
|
return this._latestExecutionPayloadBid;
|
|
383
377
|
}
|
|
384
378
|
|
|
379
|
+
get payloadExpectedWithdrawals(): capella.Withdrawal[] {
|
|
380
|
+
if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.gloas) {
|
|
381
|
+
throw new Error("payloadExpectedWithdrawals is not available before Gloas");
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
if (this._payloadExpectedWithdrawals === null) {
|
|
385
|
+
this._payloadExpectedWithdrawals = (
|
|
386
|
+
this.cachedState as CachedBeaconStateGloas
|
|
387
|
+
).payloadExpectedWithdrawals.toValue();
|
|
388
|
+
}
|
|
389
|
+
return this._payloadExpectedWithdrawals;
|
|
390
|
+
}
|
|
391
|
+
|
|
385
392
|
getBuilder(index: BuilderIndex): gloas.Builder {
|
|
386
393
|
if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.gloas) {
|
|
387
|
-
throw new Error("Builders are not supported before
|
|
394
|
+
throw new Error("Builders are not supported before Gloas");
|
|
388
395
|
}
|
|
389
396
|
|
|
390
397
|
return (this.cachedState as CachedBeaconStateGloas).builders.getReadonly(index);
|
|
@@ -392,19 +399,36 @@ export class BeaconStateView implements IBeaconStateView {
|
|
|
392
399
|
|
|
393
400
|
canBuilderCoverBid(builderIndex: BuilderIndex, bidAmount: number): boolean {
|
|
394
401
|
if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.gloas) {
|
|
395
|
-
throw new Error("Builders are not supported before
|
|
402
|
+
throw new Error("Builders are not supported before Gloas");
|
|
396
403
|
}
|
|
397
404
|
|
|
398
405
|
return canBuilderCoverBid(this.cachedState as CachedBeaconStateGloas, builderIndex, bidAmount);
|
|
399
406
|
}
|
|
400
407
|
|
|
408
|
+
/**
|
|
409
|
+
* Return the PTCs for an epoch
|
|
410
|
+
*/
|
|
411
|
+
getEpochPTCs(epoch: Epoch): Uint32Array[] {
|
|
412
|
+
if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.gloas) {
|
|
413
|
+
throw new Error("PTC committees are not supported before Gloas");
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
const epochCtx = (this.cachedState as CachedBeaconStateGloas).epochCtx;
|
|
417
|
+
if (epoch === epochCtx.epoch) {
|
|
418
|
+
return epochCtx.payloadTimelinessCommittees;
|
|
419
|
+
}
|
|
420
|
+
if (epoch === epochCtx.nextEpoch) {
|
|
421
|
+
return epochCtx.nextPayloadTimelinessCommittees;
|
|
422
|
+
}
|
|
423
|
+
throw new Error(`PTC committees are not available for epoch=${epoch}`);
|
|
424
|
+
}
|
|
401
425
|
/**
|
|
402
426
|
* Return the index of the validator in the PTC committee for the given slot.
|
|
403
427
|
* return -1 if validator is not in the PTC committee for the given slot.
|
|
404
428
|
*/
|
|
405
429
|
getIndexInPayloadTimelinessCommittee(validatorIndex: ValidatorIndex, slot: Slot): number {
|
|
406
430
|
if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.gloas) {
|
|
407
|
-
throw new Error("PTC committees are not supported before
|
|
431
|
+
throw new Error("PTC committees are not supported before Gloas");
|
|
408
432
|
}
|
|
409
433
|
|
|
410
434
|
const ptcCommittee = (this.cachedState as CachedBeaconStateGloas).epochCtx.getPayloadTimelinessCommittee(slot);
|
|
@@ -571,7 +595,10 @@ export class BeaconStateView implements IBeaconStateView {
|
|
|
571
595
|
}
|
|
572
596
|
|
|
573
597
|
get isMergeTransitionComplete(): boolean {
|
|
574
|
-
return
|
|
598
|
+
return (
|
|
599
|
+
(isExecutionStateType(this.cachedState) || isGloasStateType(this.cachedState)) &&
|
|
600
|
+
isMergeTransitionComplete(this.cachedState)
|
|
601
|
+
);
|
|
575
602
|
}
|
|
576
603
|
|
|
577
604
|
// Block production
|
|
@@ -693,7 +720,11 @@ export class BeaconStateView implements IBeaconStateView {
|
|
|
693
720
|
|
|
694
721
|
// Serialization
|
|
695
722
|
|
|
696
|
-
loadOtherState(
|
|
723
|
+
loadOtherState(
|
|
724
|
+
stateBytes: Uint8Array,
|
|
725
|
+
seedValidatorsBytes?: Uint8Array,
|
|
726
|
+
opts?: {preloadValidatorsAndBalances?: boolean}
|
|
727
|
+
): IBeaconStateView {
|
|
697
728
|
const {state} = loadState(this.config, this.cachedState, stateBytes, seedValidatorsBytes);
|
|
698
729
|
|
|
699
730
|
const cachedState = createCachedBeaconState(
|
|
@@ -708,9 +739,10 @@ export class BeaconStateView implements IBeaconStateView {
|
|
|
708
739
|
}
|
|
709
740
|
);
|
|
710
741
|
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
742
|
+
if (opts?.preloadValidatorsAndBalances) {
|
|
743
|
+
cachedState.validators.getAllReadonlyValues();
|
|
744
|
+
cachedState.balances.getAll();
|
|
745
|
+
}
|
|
714
746
|
|
|
715
747
|
return new BeaconStateView(cachedState);
|
|
716
748
|
}
|
|
@@ -768,19 +800,22 @@ export class BeaconStateView implements IBeaconStateView {
|
|
|
768
800
|
return new BeaconStateView(newState);
|
|
769
801
|
}
|
|
770
802
|
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
):
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
throw Error(`processExecutionPayloadEnvelope is only available for gloas+ forks, got fork=${fork}`);
|
|
803
|
+
/**
|
|
804
|
+
* Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.5/specs/gloas/validator.md#executionpayload
|
|
805
|
+
*/
|
|
806
|
+
withParentPayloadApplied(executionRequests: electra.ExecutionRequests): IBeaconStateViewGloas {
|
|
807
|
+
if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.gloas) {
|
|
808
|
+
throw new Error("withParentPayloadApplied is not available before Gloas");
|
|
778
809
|
}
|
|
779
|
-
const
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
);
|
|
784
|
-
|
|
810
|
+
const stateCopy = this.cachedState.clone(true) as CachedBeaconStateGloas;
|
|
811
|
+
|
|
812
|
+
applyParentExecutionPayload(stateCopy, executionRequests);
|
|
813
|
+
|
|
814
|
+
const stateView = new BeaconStateView(stateCopy);
|
|
815
|
+
if (!isStatePostGloas(stateView)) {
|
|
816
|
+
throw new Error("Expected gloas state after clone");
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
return stateView;
|
|
785
820
|
}
|
|
786
821
|
}
|