@lodestar/state-transition 1.42.0-dev.1d50253953 → 1.42.0-dev.1e596a7422
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/isValidIndexedAttestation.d.ts.map +1 -1
- package/lib/block/isValidIndexedAttestation.js +2 -3
- package/lib/block/isValidIndexedAttestation.js.map +1 -1
- package/lib/block/processAttestationsAltair.d.ts +2 -1
- package/lib/block/processAttestationsAltair.d.ts.map +1 -1
- package/lib/block/processAttestationsAltair.js +5 -3
- package/lib/block/processAttestationsAltair.js.map +1 -1
- 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 +4 -0
- package/lib/signatureSets/executionPayloadEnvelope.js.map +1 -1
- package/lib/signatureSets/index.d.ts +2 -2
- package/lib/signatureSets/index.d.ts.map +1 -1
- package/lib/signatureSets/index.js +1 -2
- package/lib/signatureSets/index.js.map +1 -1
- 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/upgradeStateToAltair.d.ts.map +1 -1
- package/lib/slot/upgradeStateToAltair.js +2 -1
- package/lib/slot/upgradeStateToAltair.js.map +1 -1
- package/lib/stateTransition.d.ts +1 -1
- package/lib/stateTransition.d.ts.map +1 -1
- package/lib/stateTransition.js +1 -1
- package/lib/stateTransition.js.map +1 -1
- package/lib/stateView/beaconStateView.d.ts +12 -11
- package/lib/stateView/beaconStateView.d.ts.map +1 -1
- package/lib/stateView/beaconStateView.js +26 -37
- package/lib/stateView/beaconStateView.js.map +1 -1
- package/lib/stateView/index.d.ts +1 -0
- package/lib/stateView/index.d.ts.map +1 -1
- package/lib/stateView/index.js +1 -0
- package/lib/stateView/index.js.map +1 -1
- package/lib/stateView/interface.d.ts +105 -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/stateView/stateViewFactory.d.ts +40 -0
- package/lib/stateView/stateViewFactory.d.ts.map +1 -0
- package/lib/stateView/stateViewFactory.js +46 -0
- package/lib/stateView/stateViewFactory.js.map +1 -0
- package/lib/testUtils/cache.d.ts.map +1 -1
- package/lib/testUtils/cache.js +1 -1
- package/lib/testUtils/cache.js.map +1 -1
- package/lib/testUtils/util.d.ts +13 -1
- package/lib/testUtils/util.d.ts.map +1 -1
- package/lib/testUtils/util.js +119 -19
- package/lib/testUtils/util.js.map +1 -1
- package/lib/util/gloas.d.ts +2 -1
- package/lib/util/gloas.d.ts.map +1 -1
- package/lib/util/gloas.js.map +1 -1
- package/lib/util/rootCache.d.ts +2 -2
- package/lib/util/rootCache.d.ts.map +1 -1
- package/lib/util/rootCache.js +2 -3
- package/lib/util/rootCache.js.map +1 -1
- package/lib/util/shuffling.d.ts +2 -1
- package/lib/util/shuffling.d.ts.map +1 -1
- package/lib/util/shuffling.js +2 -2
- package/lib/util/shuffling.js.map +1 -1
- package/package.json +7 -7
- package/src/block/isValidIndexedAttestation.ts +2 -3
- package/src/block/processAttestationsAltair.ts +7 -4
- package/src/index.ts +20 -2
- package/src/signatureSets/executionPayloadEnvelope.ts +5 -1
- package/src/signatureSets/index.ts +3 -4
- package/src/signatureSets/voluntaryExits.ts +5 -2
- package/src/slot/upgradeStateToAltair.ts +2 -1
- package/src/stateTransition.ts +1 -1
- package/src/stateView/beaconStateView.ts +42 -56
- package/src/stateView/index.ts +1 -0
- package/src/stateView/interface.ts +148 -73
- package/src/stateView/stateViewFactory.ts +78 -0
- package/src/testUtils/cache.ts +1 -1
- package/src/testUtils/util.ts +136 -22
- package/src/util/gloas.ts +2 -1
- package/src/util/rootCache.ts +4 -5
- package/src/util/shuffling.ts +5 -4
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
|
|
|
@@ -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
|
|
@@ -3,8 +3,7 @@ import {ForkSeq} from "@lodestar/params";
|
|
|
3
3
|
import {IndexedAttestation, SignedBeaconBlock, altair, capella} from "@lodestar/types";
|
|
4
4
|
import {getSyncCommitteeSignatureSet} from "../block/processSyncCommittee.js";
|
|
5
5
|
import {SyncCommitteeCache} from "../cache/syncCommitteeCache.js";
|
|
6
|
-
import {
|
|
7
|
-
import {CachedBeaconStateAllForks} from "../types.js";
|
|
6
|
+
import {IBeaconStateView} from "../stateView/interface.js";
|
|
8
7
|
import {ISignatureSet} from "../util/index.js";
|
|
9
8
|
import {getAttesterSlashingsSignatureSets} from "./attesterSlashings.js";
|
|
10
9
|
import {getBlsToExecutionChangeSignatureSets} from "./blsToExecutionChange.js";
|
|
@@ -32,7 +31,7 @@ export * from "./voluntaryExits.js";
|
|
|
32
31
|
export function getBlockSignatureSets(
|
|
33
32
|
config: BeaconConfig,
|
|
34
33
|
currentSyncCommitteeIndexed: SyncCommitteeCache,
|
|
35
|
-
state:
|
|
34
|
+
state: IBeaconStateView,
|
|
36
35
|
signedBlock: SignedBeaconBlock,
|
|
37
36
|
indexedAttestations: IndexedAttestation[],
|
|
38
37
|
opts?: {
|
|
@@ -48,7 +47,7 @@ export function getBlockSignatureSets(
|
|
|
48
47
|
...getProposerSlashingsSignatureSets(config, signedBlock),
|
|
49
48
|
...getAttesterSlashingsSignatureSets(config, signedBlock),
|
|
50
49
|
...getAttestationsSignatureSets(config, signedBlock, indexedAttestations),
|
|
51
|
-
...getVoluntaryExitsSignatureSets(config,
|
|
50
|
+
...getVoluntaryExitsSignatureSets(config, state, signedBlock),
|
|
52
51
|
];
|
|
53
52
|
|
|
54
53
|
if (!opts?.skipProposerSignature) {
|
|
@@ -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);
|
|
@@ -3,6 +3,7 @@ import {ForkSeq} from "@lodestar/params";
|
|
|
3
3
|
import {ssz} from "@lodestar/types";
|
|
4
4
|
import {getAttestationParticipationStatus} from "../block/processAttestationsAltair.js";
|
|
5
5
|
import {getCachedBeaconState} from "../cache/stateCache.js";
|
|
6
|
+
import {BeaconStateView} from "../stateView/beaconStateView.js";
|
|
6
7
|
import {CachedBeaconStateAltair, CachedBeaconStatePhase0} from "../types.js";
|
|
7
8
|
import {RootCache, newZeroedArray} from "../util/index.js";
|
|
8
9
|
import {getNextSyncCommittee} from "../util/syncCommittee.js";
|
|
@@ -125,7 +126,7 @@ function translateParticipation(
|
|
|
125
126
|
pendingAttesations: CompositeViewDU<typeof ssz.phase0.EpochAttestations>
|
|
126
127
|
): void {
|
|
127
128
|
const {epochCtx} = state;
|
|
128
|
-
const rootCache = new RootCache(state);
|
|
129
|
+
const rootCache = new RootCache(new BeaconStateView(state));
|
|
129
130
|
const epochParticipation = state.previousEpochParticipation;
|
|
130
131
|
|
|
131
132
|
for (const attestation of pendingAttesations.getAllReadonly()) {
|
package/src/stateTransition.ts
CHANGED
|
@@ -76,7 +76,7 @@ export enum StateHashTreeRootSource {
|
|
|
76
76
|
prepareNextEpoch = "prepare_next_epoch",
|
|
77
77
|
regenState = "regen_state",
|
|
78
78
|
computeNewStateRoot = "compute_new_state_root",
|
|
79
|
-
|
|
79
|
+
computePayloadEnvelopeStateRoot = "compute_payload_envelope_state_root",
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
/**
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import {CompactMultiProof, ProofType, Tree, createProof} from "@chainsafe/persistent-merkle-tree";
|
|
2
|
-
import {ByteViews} from "@chainsafe/ssz";
|
|
2
|
+
import {BitArray, ByteViews} from "@chainsafe/ssz";
|
|
3
3
|
import {BeaconConfig} from "@lodestar/config";
|
|
4
|
-
import {ForkSeq, SLOTS_PER_HISTORICAL_ROOT, isForkPostGloas} from "@lodestar/params";
|
|
4
|
+
import {ForkName, ForkSeq, SLOTS_PER_HISTORICAL_ROOT, isForkPostGloas} from "@lodestar/params";
|
|
5
5
|
import {
|
|
6
6
|
BeaconBlock,
|
|
7
|
+
BeaconState,
|
|
7
8
|
BlindedBeaconBlock,
|
|
8
9
|
BuilderIndex,
|
|
9
10
|
Bytes32,
|
|
@@ -33,7 +34,6 @@ import {VoluntaryExitValidity, getVoluntaryExitValidity} from "../block/processV
|
|
|
33
34
|
import {getExpectedWithdrawals} from "../block/processWithdrawals.js";
|
|
34
35
|
import {EffectiveBalanceIncrements} from "../cache/effectiveBalanceIncrements.js";
|
|
35
36
|
import {EpochTransitionCacheOpts} from "../cache/epochTransitionCache.js";
|
|
36
|
-
import {PubkeyCache, createPubkeyCache} from "../cache/pubkeyCache.js";
|
|
37
37
|
import {RewardCache} from "../cache/rewardCache.js";
|
|
38
38
|
import {
|
|
39
39
|
CachedBeaconStateAllForks,
|
|
@@ -47,7 +47,6 @@ import {
|
|
|
47
47
|
isStateValidatorsNodesPopulated,
|
|
48
48
|
} from "../cache/stateCache.js";
|
|
49
49
|
import {SyncCommitteeCache} from "../cache/syncCommitteeCache.js";
|
|
50
|
-
import {BeaconStateAllForks} from "../cache/types.js";
|
|
51
50
|
import {computeUnrealizedCheckpoints} from "../epoch/computeUnrealizedCheckpoints.js";
|
|
52
51
|
import {getFinalizedRootProof, getSyncCommitteesWitness} from "../lightClient/proofs.js";
|
|
53
52
|
import {SyncCommitteeWitness} from "../lightClient/types.js";
|
|
@@ -64,11 +63,10 @@ import {isExecutionEnabled, isExecutionStateType, isMergeTransitionComplete} fro
|
|
|
64
63
|
import {canBuilderCoverBid} from "../util/gloas.js";
|
|
65
64
|
import {loadState} from "../util/loadState/loadState.js";
|
|
66
65
|
import {getRandaoMix} from "../util/seed.js";
|
|
67
|
-
import {getStateTypeFromBytes} from "../util/sszBytes.js";
|
|
68
66
|
import {getLatestWeakSubjectivityCheckpointEpoch} from "../util/weakSubjectivity.js";
|
|
69
|
-
import {IBeaconStateView} from "./interface.js";
|
|
67
|
+
import {IBeaconStateView, IBeaconStateViewLatestFork} from "./interface.js";
|
|
70
68
|
|
|
71
|
-
export class BeaconStateView implements
|
|
69
|
+
export class BeaconStateView implements IBeaconStateViewLatestFork {
|
|
72
70
|
private readonly config: BeaconConfig;
|
|
73
71
|
// Cached values extracted from the tree
|
|
74
72
|
// phase0
|
|
@@ -92,8 +90,9 @@ export class BeaconStateView implements IBeaconStateView {
|
|
|
92
90
|
// fulu
|
|
93
91
|
private _proposerLookahead: fulu.ProposerLookahead | null = null;
|
|
94
92
|
// gloas
|
|
95
|
-
private _executionPayloadAvailability:
|
|
93
|
+
private _executionPayloadAvailability: BitArray | null = null;
|
|
96
94
|
private _latestExecutionPayloadBid: ExecutionPayloadBid | null = null;
|
|
95
|
+
private _payloadExpectedWithdrawals: capella.Withdrawal[] | null = null;
|
|
97
96
|
|
|
98
97
|
constructor(readonly cachedState: CachedBeaconStateAllForks) {
|
|
99
98
|
this.config = cachedState.config;
|
|
@@ -101,6 +100,10 @@ export class BeaconStateView implements IBeaconStateView {
|
|
|
101
100
|
|
|
102
101
|
// phase0
|
|
103
102
|
|
|
103
|
+
get forkName(): ForkName {
|
|
104
|
+
return this.config.getForkName(this.cachedState.slot);
|
|
105
|
+
}
|
|
106
|
+
|
|
104
107
|
get slot(): number {
|
|
105
108
|
return this.cachedState.slot;
|
|
106
109
|
}
|
|
@@ -357,15 +360,15 @@ export class BeaconStateView implements IBeaconStateView {
|
|
|
357
360
|
|
|
358
361
|
// gloas
|
|
359
362
|
|
|
360
|
-
get executionPayloadAvailability():
|
|
363
|
+
get executionPayloadAvailability(): BitArray {
|
|
361
364
|
if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.gloas) {
|
|
362
|
-
throw new Error("executionPayloadAvailability is not available before
|
|
365
|
+
throw new Error("executionPayloadAvailability is not available before Gloas");
|
|
363
366
|
}
|
|
364
367
|
|
|
365
368
|
if (this._executionPayloadAvailability === null) {
|
|
366
|
-
this._executionPayloadAvailability = (
|
|
367
|
-
.
|
|
368
|
-
|
|
369
|
+
this._executionPayloadAvailability = (
|
|
370
|
+
this.cachedState as CachedBeaconStateGloas
|
|
371
|
+
).executionPayloadAvailability.toValue();
|
|
369
372
|
}
|
|
370
373
|
|
|
371
374
|
return this._executionPayloadAvailability;
|
|
@@ -373,7 +376,7 @@ export class BeaconStateView implements IBeaconStateView {
|
|
|
373
376
|
|
|
374
377
|
get latestExecutionPayloadBid(): ExecutionPayloadBid {
|
|
375
378
|
if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.gloas) {
|
|
376
|
-
throw new Error("latestExecutionPayloadBid is not available before
|
|
379
|
+
throw new Error("latestExecutionPayloadBid is not available before Gloas");
|
|
377
380
|
}
|
|
378
381
|
|
|
379
382
|
if (this._latestExecutionPayloadBid === null) {
|
|
@@ -384,9 +387,22 @@ export class BeaconStateView implements IBeaconStateView {
|
|
|
384
387
|
return this._latestExecutionPayloadBid;
|
|
385
388
|
}
|
|
386
389
|
|
|
390
|
+
get payloadExpectedWithdrawals(): capella.Withdrawal[] {
|
|
391
|
+
if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.gloas) {
|
|
392
|
+
throw new Error("payloadExpectedWithdrawals is not available before Gloas");
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
if (this._payloadExpectedWithdrawals === null) {
|
|
396
|
+
this._payloadExpectedWithdrawals = (
|
|
397
|
+
this.cachedState as CachedBeaconStateGloas
|
|
398
|
+
).payloadExpectedWithdrawals.toValue();
|
|
399
|
+
}
|
|
400
|
+
return this._payloadExpectedWithdrawals;
|
|
401
|
+
}
|
|
402
|
+
|
|
387
403
|
getBuilder(index: BuilderIndex): gloas.Builder {
|
|
388
404
|
if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.gloas) {
|
|
389
|
-
throw new Error("Builders are not supported before
|
|
405
|
+
throw new Error("Builders are not supported before Gloas");
|
|
390
406
|
}
|
|
391
407
|
|
|
392
408
|
return (this.cachedState as CachedBeaconStateGloas).builders.getReadonly(index);
|
|
@@ -394,7 +410,7 @@ export class BeaconStateView implements IBeaconStateView {
|
|
|
394
410
|
|
|
395
411
|
canBuilderCoverBid(builderIndex: BuilderIndex, bidAmount: number): boolean {
|
|
396
412
|
if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.gloas) {
|
|
397
|
-
throw new Error("Builders are not supported before
|
|
413
|
+
throw new Error("Builders are not supported before Gloas");
|
|
398
414
|
}
|
|
399
415
|
|
|
400
416
|
return canBuilderCoverBid(this.cachedState as CachedBeaconStateGloas, builderIndex, bidAmount);
|
|
@@ -404,9 +420,9 @@ export class BeaconStateView implements IBeaconStateView {
|
|
|
404
420
|
* Return the index of the validator in the PTC committee for the given slot.
|
|
405
421
|
* return -1 if validator is not in the PTC committee for the given slot.
|
|
406
422
|
*/
|
|
407
|
-
|
|
423
|
+
getIndexInPayloadTimelinessCommittee(validatorIndex: ValidatorIndex, slot: Slot): number {
|
|
408
424
|
if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.gloas) {
|
|
409
|
-
throw new Error("PTC committees are not supported before
|
|
425
|
+
throw new Error("PTC committees are not supported before Gloas");
|
|
410
426
|
}
|
|
411
427
|
|
|
412
428
|
const ptcCommittee = (this.cachedState as CachedBeaconStateGloas).epochCtx.getPayloadTimelinessCommittee(slot);
|
|
@@ -503,6 +519,10 @@ export class BeaconStateView implements IBeaconStateView {
|
|
|
503
519
|
return this.cachedState.epochCtx.syncProposerReward;
|
|
504
520
|
}
|
|
505
521
|
|
|
522
|
+
getIndexedSyncCommittee(slot: Slot): SyncCommitteeCache {
|
|
523
|
+
return this.cachedState.epochCtx.getIndexedSyncCommittee(slot);
|
|
524
|
+
}
|
|
525
|
+
|
|
506
526
|
getIndexedSyncCommitteeAtEpoch(epoch: Epoch): SyncCommitteeCache {
|
|
507
527
|
return this.cachedState.epochCtx.getIndexedSyncCommitteeAtEpoch(epoch);
|
|
508
528
|
}
|
|
@@ -713,6 +733,10 @@ export class BeaconStateView implements IBeaconStateView {
|
|
|
713
733
|
return new BeaconStateView(cachedState);
|
|
714
734
|
}
|
|
715
735
|
|
|
736
|
+
toValue(): BeaconState {
|
|
737
|
+
return this.cachedState.toValue();
|
|
738
|
+
}
|
|
739
|
+
|
|
716
740
|
serialize(): Uint8Array {
|
|
717
741
|
return this.cachedState.serialize();
|
|
718
742
|
}
|
|
@@ -778,41 +802,3 @@ export class BeaconStateView implements IBeaconStateView {
|
|
|
778
802
|
return new BeaconStateView(postPayloadState);
|
|
779
803
|
}
|
|
780
804
|
}
|
|
781
|
-
|
|
782
|
-
/**
|
|
783
|
-
* Create BeaconStateView for historical state regen, no need to sync pubkey cache there.
|
|
784
|
-
*/
|
|
785
|
-
export function createBeaconStateViewForHistoricalRegen(
|
|
786
|
-
config: BeaconConfig,
|
|
787
|
-
stateBytes: Uint8Array
|
|
788
|
-
): IBeaconStateView {
|
|
789
|
-
const state = getStateTypeFromBytes(config, stateBytes).deserializeToViewDU(stateBytes);
|
|
790
|
-
|
|
791
|
-
const pubkeyCache = createPubkeyCache();
|
|
792
|
-
syncPubkeyCache(state, pubkeyCache);
|
|
793
|
-
const cachedState = createCachedBeaconState(
|
|
794
|
-
state,
|
|
795
|
-
{
|
|
796
|
-
config,
|
|
797
|
-
pubkeyCache,
|
|
798
|
-
},
|
|
799
|
-
{
|
|
800
|
-
skipSyncPubkeys: true,
|
|
801
|
-
}
|
|
802
|
-
);
|
|
803
|
-
|
|
804
|
-
return new BeaconStateView(cachedState);
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
/**
|
|
808
|
-
* Populate a PubkeyIndexMap with any new entries based on a BeaconState
|
|
809
|
-
*/
|
|
810
|
-
function syncPubkeyCache(state: BeaconStateAllForks, pubkeyCache: PubkeyCache): void {
|
|
811
|
-
// Get the validators sub tree once for all the loop
|
|
812
|
-
|
|
813
|
-
const newCount = state.validators.length;
|
|
814
|
-
for (let i = pubkeyCache.size; i < newCount; i++) {
|
|
815
|
-
const pubkey = state.validators.getReadonly(i).pubkey;
|
|
816
|
-
pubkeyCache.set(i, pubkey);
|
|
817
|
-
}
|
|
818
|
-
}
|
package/src/stateView/index.ts
CHANGED
|
@@ -1,7 +1,25 @@
|
|
|
1
1
|
import {CompactMultiProof} from "@chainsafe/persistent-merkle-tree";
|
|
2
|
-
import {ByteViews} from "@chainsafe/ssz";
|
|
2
|
+
import {BitArray, ByteViews} from "@chainsafe/ssz";
|
|
3
|
+
import {
|
|
4
|
+
ForkName,
|
|
5
|
+
ForkPostAltair,
|
|
6
|
+
ForkPostBellatrix,
|
|
7
|
+
ForkPostCapella,
|
|
8
|
+
ForkPostDeneb,
|
|
9
|
+
ForkPostElectra,
|
|
10
|
+
ForkPostFulu,
|
|
11
|
+
ForkPostGloas,
|
|
12
|
+
isForkPostAltair,
|
|
13
|
+
isForkPostBellatrix,
|
|
14
|
+
isForkPostCapella,
|
|
15
|
+
isForkPostDeneb,
|
|
16
|
+
isForkPostElectra,
|
|
17
|
+
isForkPostFulu,
|
|
18
|
+
isForkPostGloas,
|
|
19
|
+
} from "@lodestar/params";
|
|
3
20
|
import {
|
|
4
21
|
BeaconBlock,
|
|
22
|
+
BeaconState,
|
|
5
23
|
BlindedBeaconBlock,
|
|
6
24
|
BuilderIndex,
|
|
7
25
|
Bytes32,
|
|
@@ -40,6 +58,7 @@ export interface IBeaconStateView {
|
|
|
40
58
|
// State access
|
|
41
59
|
|
|
42
60
|
// phase0
|
|
61
|
+
forkName: ForkName;
|
|
43
62
|
slot: Slot;
|
|
44
63
|
fork: Fork;
|
|
45
64
|
epoch: Epoch;
|
|
@@ -55,50 +74,6 @@ export interface IBeaconStateView {
|
|
|
55
74
|
getStateRootAtSlot(slot: Slot): Root;
|
|
56
75
|
getRandaoMix(epoch: Epoch): Bytes32;
|
|
57
76
|
|
|
58
|
-
// altair
|
|
59
|
-
previousEpochParticipation: Uint8Array;
|
|
60
|
-
currentEpochParticipation: Uint8Array;
|
|
61
|
-
getPreviousEpochParticipation(validatorIndex: ValidatorIndex): number;
|
|
62
|
-
getCurrentEpochParticipation(validatorIndex: ValidatorIndex): number;
|
|
63
|
-
|
|
64
|
-
// bellatrix
|
|
65
|
-
latestExecutionPayloadHeader: ExecutionPayloadHeader;
|
|
66
|
-
/**
|
|
67
|
-
* Cross-fork accessor for the execution block hash of the most recently included payload.
|
|
68
|
-
* Pre-gloas: returns latestExecutionPayloadHeader.blockHash (bellatrix–fulu).
|
|
69
|
-
* Gloas+: returns the dedicated latestBlockHash state field (EIP-7732).
|
|
70
|
-
* Throws before bellatrix.
|
|
71
|
-
*/
|
|
72
|
-
latestBlockHash: Bytes32;
|
|
73
|
-
/**
|
|
74
|
-
* The execution block number of the most recently included payload.
|
|
75
|
-
* Named payloadBlockNumber (not latestBlockNumber) to mirror ExecutionPayloadHeader.blockNumber pre-gloas.
|
|
76
|
-
* Only available from bellatrix through fulu — not tracked on BeaconState in gloas+ (EIP-7732).
|
|
77
|
-
* Throws before bellatrix and from gloas onwards.
|
|
78
|
-
*/
|
|
79
|
-
payloadBlockNumber: number;
|
|
80
|
-
|
|
81
|
-
// capella
|
|
82
|
-
historicalSummaries: capella.HistoricalSummaries;
|
|
83
|
-
|
|
84
|
-
// electra
|
|
85
|
-
pendingDeposits: electra.PendingDeposits;
|
|
86
|
-
pendingDepositsCount: number;
|
|
87
|
-
pendingPartialWithdrawals: electra.PendingPartialWithdrawals;
|
|
88
|
-
pendingPartialWithdrawalsCount: number;
|
|
89
|
-
pendingConsolidations: electra.PendingConsolidations;
|
|
90
|
-
pendingConsolidationsCount: number;
|
|
91
|
-
|
|
92
|
-
// fulu
|
|
93
|
-
proposerLookahead: fulu.ProposerLookahead;
|
|
94
|
-
|
|
95
|
-
// gloas
|
|
96
|
-
executionPayloadAvailability: boolean[];
|
|
97
|
-
latestExecutionPayloadBid: ExecutionPayloadBid;
|
|
98
|
-
getBuilder(index: BuilderIndex): gloas.Builder;
|
|
99
|
-
canBuilderCoverBid(builderIndex: BuilderIndex, bidAmount: number): boolean;
|
|
100
|
-
validatorPTCCommitteeIndex(validatorIndex: ValidatorIndex, slot: Slot): number;
|
|
101
|
-
|
|
102
77
|
// Shuffling and committees
|
|
103
78
|
getShufflingAtEpoch(epoch: Epoch): EpochShuffling;
|
|
104
79
|
// Decision roots
|
|
@@ -110,19 +85,11 @@ export interface IBeaconStateView {
|
|
|
110
85
|
getCurrentShuffling(): EpochShuffling;
|
|
111
86
|
getNextShuffling(): EpochShuffling;
|
|
112
87
|
|
|
113
|
-
//
|
|
88
|
+
// Proposer shuffling
|
|
114
89
|
previousProposers: ValidatorIndex[] | null;
|
|
115
90
|
currentProposers: ValidatorIndex[];
|
|
116
91
|
nextProposers: ValidatorIndex[];
|
|
117
92
|
getBeaconProposer(slot: Slot): ValidatorIndex;
|
|
118
|
-
computeAnchorCheckpoint(): {checkpoint: phase0.Checkpoint; blockHeader: phase0.BeaconBlockHeader};
|
|
119
|
-
|
|
120
|
-
// Sync committees
|
|
121
|
-
currentSyncCommittee: altair.SyncCommittee;
|
|
122
|
-
nextSyncCommittee: altair.SyncCommittee;
|
|
123
|
-
currentSyncCommitteeIndexed: SyncCommitteeCache;
|
|
124
|
-
syncProposerReward: number;
|
|
125
|
-
getIndexedSyncCommitteeAtEpoch(epoch: Epoch): SyncCommitteeCache;
|
|
126
93
|
|
|
127
94
|
// Validators and balances
|
|
128
95
|
effectiveBalanceIncrements: EffectiveBalanceIncrements;
|
|
@@ -138,28 +105,10 @@ export interface IBeaconStateView {
|
|
|
138
105
|
getAllValidators(): phase0.Validator[];
|
|
139
106
|
getAllBalances(): number[];
|
|
140
107
|
|
|
141
|
-
// Merge
|
|
142
|
-
isExecutionStateType: boolean;
|
|
143
|
-
isMergeTransitionComplete: boolean;
|
|
144
|
-
// TODO this should go away (or rather only need block)
|
|
145
|
-
isExecutionEnabled(block: BeaconBlock | BlindedBeaconBlock): boolean;
|
|
146
|
-
|
|
147
|
-
// Block production
|
|
148
|
-
getExpectedWithdrawals(): {
|
|
149
|
-
expectedWithdrawals: capella.Withdrawal[];
|
|
150
|
-
processedBuilderWithdrawalsCount: number;
|
|
151
|
-
processedPartialWithdrawalsCount: number;
|
|
152
|
-
processedValidatorSweepCount: number;
|
|
153
|
-
};
|
|
154
|
-
|
|
155
108
|
// API
|
|
156
109
|
proposerRewards: RewardCache;
|
|
157
110
|
computeBlockRewards(block: BeaconBlock, proposerRewards?: RewardCache): Promise<rewards.BlockRewards>;
|
|
158
111
|
computeAttestationsRewards(validatorIds?: (ValidatorIndex | string)[]): Promise<rewards.AttestationsRewards>;
|
|
159
|
-
computeSyncCommitteeRewards(
|
|
160
|
-
block: BeaconBlock,
|
|
161
|
-
validatorIds: (ValidatorIndex | string)[]
|
|
162
|
-
): Promise<rewards.SyncCommitteeRewards>;
|
|
163
112
|
getLatestWeakSubjectivityCheckpointEpoch(): Epoch;
|
|
164
113
|
|
|
165
114
|
// Validation
|
|
@@ -171,7 +120,6 @@ export interface IBeaconStateView {
|
|
|
171
120
|
|
|
172
121
|
// Proofs
|
|
173
122
|
getFinalizedRootProof(): Uint8Array[];
|
|
174
|
-
getSyncCommitteesWitness(): SyncCommitteeWitness;
|
|
175
123
|
getSingleProof(gindex: bigint): Uint8Array[];
|
|
176
124
|
createMultiProof(descriptor: Uint8Array): CompactMultiProof;
|
|
177
125
|
|
|
@@ -180,6 +128,7 @@ export interface IBeaconStateView {
|
|
|
180
128
|
justifiedCheckpoint: phase0.Checkpoint;
|
|
181
129
|
finalizedCheckpoint: phase0.Checkpoint;
|
|
182
130
|
};
|
|
131
|
+
computeAnchorCheckpoint(): {checkpoint: phase0.Checkpoint; blockHeader: phase0.BeaconBlockHeader};
|
|
183
132
|
|
|
184
133
|
// this is for backward compatible
|
|
185
134
|
clonedCount: number;
|
|
@@ -190,6 +139,7 @@ export interface IBeaconStateView {
|
|
|
190
139
|
|
|
191
140
|
// Serialization
|
|
192
141
|
loadOtherState(stateBytes: Uint8Array, seedValidatorsBytes?: Uint8Array): IBeaconStateView;
|
|
142
|
+
toValue(): BeaconState;
|
|
193
143
|
serialize(): Uint8Array;
|
|
194
144
|
serializedSize(): number;
|
|
195
145
|
serializeToBytes(output: ByteViews, offset: number): number;
|
|
@@ -210,8 +160,133 @@ export interface IBeaconStateView {
|
|
|
210
160
|
epochTransitionCacheOpts?: EpochTransitionCacheOpts & {dontTransferCache?: boolean},
|
|
211
161
|
modules?: StateTransitionModules
|
|
212
162
|
): IBeaconStateView;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** Altair+ state fields — use isStatePostAltair() guard */
|
|
166
|
+
export interface IBeaconStateViewAltair extends IBeaconStateView {
|
|
167
|
+
forkName: ForkPostAltair;
|
|
168
|
+
previousEpochParticipation: Uint8Array;
|
|
169
|
+
currentEpochParticipation: Uint8Array;
|
|
170
|
+
getPreviousEpochParticipation(validatorIndex: ValidatorIndex): number;
|
|
171
|
+
getCurrentEpochParticipation(validatorIndex: ValidatorIndex): number;
|
|
172
|
+
currentSyncCommittee: altair.SyncCommittee;
|
|
173
|
+
nextSyncCommittee: altair.SyncCommittee;
|
|
174
|
+
currentSyncCommitteeIndexed: SyncCommitteeCache;
|
|
175
|
+
syncProposerReward: number;
|
|
176
|
+
getIndexedSyncCommitteeAtEpoch(epoch: Epoch): SyncCommitteeCache;
|
|
177
|
+
/** Get indexed sync committee with slot+1 offset for duty lookups */
|
|
178
|
+
getIndexedSyncCommittee(slot: Slot): SyncCommitteeCache;
|
|
179
|
+
computeSyncCommitteeRewards(
|
|
180
|
+
block: BeaconBlock,
|
|
181
|
+
validatorIds: (ValidatorIndex | string)[]
|
|
182
|
+
): Promise<rewards.SyncCommitteeRewards>;
|
|
183
|
+
getSyncCommitteesWitness(): SyncCommitteeWitness;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** Bellatrix+ state fields — use isStatePostBellatrix() guard */
|
|
187
|
+
export interface IBeaconStateViewBellatrix extends IBeaconStateViewAltair {
|
|
188
|
+
forkName: ForkPostBellatrix;
|
|
189
|
+
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
|
+
/**
|
|
198
|
+
* The execution block number of the most recently included payload.
|
|
199
|
+
* Named payloadBlockNumber (not latestBlockNumber) to mirror ExecutionPayloadHeader.blockNumber pre-gloas.
|
|
200
|
+
* Only available from bellatrix through fulu — not tracked on BeaconState in gloas+ (EIP-7732).
|
|
201
|
+
* Throws before bellatrix and from gloas onwards.
|
|
202
|
+
*/
|
|
203
|
+
payloadBlockNumber: number;
|
|
204
|
+
isExecutionStateType: boolean;
|
|
205
|
+
isMergeTransitionComplete: boolean;
|
|
206
|
+
isExecutionEnabled(block: BeaconBlock | BlindedBeaconBlock): boolean;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/** Capella+ state fields — use isStatePostCapella() guard */
|
|
210
|
+
export interface IBeaconStateViewCapella extends IBeaconStateViewBellatrix {
|
|
211
|
+
forkName: ForkPostCapella;
|
|
212
|
+
historicalSummaries: capella.HistoricalSummaries;
|
|
213
|
+
getExpectedWithdrawals(): {
|
|
214
|
+
expectedWithdrawals: capella.Withdrawal[];
|
|
215
|
+
processedBuilderWithdrawalsCount: number;
|
|
216
|
+
processedPartialWithdrawalsCount: number;
|
|
217
|
+
processedBuildersSweepCount: number;
|
|
218
|
+
processedValidatorSweepCount: number;
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/** Deneb+ state — no new state-view fields; placeholder for fork completeness and isStatePostDeneb() narrowing */
|
|
223
|
+
export interface IBeaconStateViewDeneb extends IBeaconStateViewCapella {
|
|
224
|
+
forkName: ForkPostDeneb;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** Electra+ state fields — use isStatePostElectra() guard */
|
|
228
|
+
export interface IBeaconStateViewElectra extends IBeaconStateViewDeneb {
|
|
229
|
+
forkName: ForkPostElectra;
|
|
230
|
+
pendingDeposits: electra.PendingDeposits;
|
|
231
|
+
pendingDepositsCount: number;
|
|
232
|
+
pendingPartialWithdrawals: electra.PendingPartialWithdrawals;
|
|
233
|
+
pendingPartialWithdrawalsCount: number;
|
|
234
|
+
pendingConsolidations: electra.PendingConsolidations;
|
|
235
|
+
pendingConsolidationsCount: number;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/** Fulu+ state fields — use isStatePostFulu() guard */
|
|
239
|
+
export interface IBeaconStateViewFulu extends IBeaconStateViewElectra {
|
|
240
|
+
forkName: ForkPostFulu;
|
|
241
|
+
proposerLookahead: fulu.ProposerLookahead;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/** Gloas+ state fields — use isStatePostGloas() guard */
|
|
245
|
+
export interface IBeaconStateViewGloas extends IBeaconStateViewFulu {
|
|
246
|
+
forkName: ForkPostGloas;
|
|
247
|
+
executionPayloadAvailability: BitArray;
|
|
248
|
+
latestExecutionPayloadBid: ExecutionPayloadBid;
|
|
249
|
+
payloadExpectedWithdrawals: capella.Withdrawal[];
|
|
250
|
+
getBuilder(index: BuilderIndex): gloas.Builder;
|
|
251
|
+
canBuilderCoverBid(builderIndex: BuilderIndex, bidAmount: number): boolean;
|
|
252
|
+
getIndexInPayloadTimelinessCommittee(validatorIndex: ValidatorIndex, slot: Slot): number;
|
|
213
253
|
processExecutionPayloadEnvelope(
|
|
214
254
|
signedEnvelope: gloas.SignedExecutionPayloadEnvelope,
|
|
215
255
|
opts?: ProcessExecutionPayloadEnvelopeOpts
|
|
216
256
|
): IBeaconStateView;
|
|
217
257
|
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Type constraint for the concrete BeaconStateView class.
|
|
261
|
+
* Requires all fields from the latest fork interface (IBeaconStateViewGloas) but keeps
|
|
262
|
+
* forkName as ForkName since the class wraps any fork's state.
|
|
263
|
+
* Sub-interfaces retain their narrowed forkName discriminants for caller-side type guards.
|
|
264
|
+
*/
|
|
265
|
+
export type IBeaconStateViewLatestFork = Omit<IBeaconStateViewGloas, "forkName"> & {forkName: ForkName};
|
|
266
|
+
export function isStatePostAltair(state: IBeaconStateView): state is IBeaconStateViewAltair {
|
|
267
|
+
return isForkPostAltair(state.forkName);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export function isStatePostBellatrix(state: IBeaconStateView): state is IBeaconStateViewBellatrix {
|
|
271
|
+
return isForkPostBellatrix(state.forkName);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export function isStatePostCapella(state: IBeaconStateView): state is IBeaconStateViewCapella {
|
|
275
|
+
return isForkPostCapella(state.forkName);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export function isStatePostDeneb(state: IBeaconStateView): state is IBeaconStateViewDeneb {
|
|
279
|
+
return isForkPostDeneb(state.forkName);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export function isStatePostElectra(state: IBeaconStateView): state is IBeaconStateViewElectra {
|
|
283
|
+
return isForkPostElectra(state.forkName);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export function isStatePostFulu(state: IBeaconStateView): state is IBeaconStateViewFulu {
|
|
287
|
+
return isForkPostFulu(state.forkName);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export function isStatePostGloas(state: IBeaconStateView): state is IBeaconStateViewGloas {
|
|
291
|
+
return isForkPostGloas(state.forkName);
|
|
292
|
+
}
|