@lodestar/state-transition 1.50.0-dev.040a952dd7 → 1.50.0-dev.199b9d3a1f

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.
@@ -1,6 +1,5 @@
1
1
  import {CompactMultiProof} from "@chainsafe/persistent-merkle-tree";
2
2
  import {BitArray, ByteViews} from "@chainsafe/ssz";
3
- import type {BeaconConfig} from "@lodestar/config";
4
3
  import {ForkName, ForkSeq} from "@lodestar/params";
5
4
  import {
6
5
  BeaconBlock,
@@ -24,38 +23,38 @@ import {
24
23
  electra,
25
24
  fulu,
26
25
  gloas,
27
- isBlindedBeaconBlock,
28
26
  phase0,
29
27
  rewards,
30
- ssz,
31
28
  } from "@lodestar/types";
32
29
  import {Checkpoint, Fork} from "@lodestar/types/phase0";
33
30
  import {VoluntaryExitValidity} from "../block/processVoluntaryExit.js";
34
31
  import {EffectiveBalanceIncrements} from "../cache/effectiveBalanceIncrements.js";
35
32
  import {RewardCache} from "../cache/rewardCache.js";
36
33
  import {SyncCommitteeCache} from "../cache/syncCommitteeCache.js";
37
- import {EMPTY_SIGNATURE} from "../constants/constants.js";
38
34
  import {SyncCommitteeWitness} from "../lightClient/types.js";
39
35
  import {StateTransitionModules, StateTransitionOpts} from "../stateTransition.js";
40
36
  import {EpochShuffling} from "../util/epochShuffling.js";
41
37
  import {PreVerifyBuilderDepositsResult} from "../util/preVerifyBuilderDeposits.js";
42
38
  import {computeNewStateRootStateTransitionOpts, getComputeNewStateRootResult} from "./computeNewStateRoot.js";
43
39
  import {
44
- BlockSTFInput,
40
+ ComputeNewStateRootInput,
45
41
  ComputeNewStateRootResult,
46
42
  IBeaconStateView,
47
43
  IBeaconStateViewGloas,
48
44
  IBeaconStateViewLatestFork,
49
45
  IBeaconStateViewNative,
46
+ isStatePostGloas,
50
47
  } from "./interface.js";
51
48
 
52
49
  /**
53
50
  * Wraps a native binding (the auto-generated JS interface produced by a `.node`
54
51
  * file) and exposes it as a fully-conformant `IBeaconStateViewLatestFork`.
55
52
  *
56
- * The binding is typed `IBeaconStateViewNative`. This type models FFI-specific
57
- * inputs and outputs, such as serialized blocks and typed arrays. The wrapper
58
- * converts those values to the forms used by `IBeaconStateViewLatestFork`.
53
+ * The binding is typed `IBeaconStateViewNative` — identical to
54
+ * `IBeaconStateViewLatestFork` except `executionPayloadAvailability` is a raw
55
+ * `{uint8Array, bitLen}` POJO. The `executionPayloadAvailability` getter lifts
56
+ * that POJO back to a `BitArray` so beacon-node consumers see no difference from
57
+ * the TS-side `BeaconStateView`.
59
58
  *
60
59
  * Every getter that returns a value stable for the view's lifetime is cached so
61
60
  * the binding is hit at most once per field per view. Only mutable counters
@@ -65,97 +64,109 @@ import {
65
64
  */
66
65
  export class NativeBeaconStateView implements IBeaconStateViewLatestFork {
67
66
  // phase0
68
- private cachedForkName: ForkName | null = null;
69
- private cachedForkSeq: ForkSeq | null = null;
70
- private cachedSlot: Slot | null = null;
71
- private cachedFork: Fork | null = null;
72
- private cachedEpoch: Epoch | null = null;
73
- private cachedGenesisTime: number | null = null;
74
- private cachedGenesisValidatorsRoot: Root | null = null;
75
- private cachedEth1Data: phase0.Eth1Data | null = null;
76
- private cachedLatestBlockHeader: phase0.BeaconBlockHeader | null = null;
77
- private cachedPreviousJustifiedCheckpoint: Checkpoint | null = null;
78
- private cachedCurrentJustifiedCheckpoint: Checkpoint | null = null;
79
- private cachedFinalizedCheckpoint: Checkpoint | null = null;
67
+ private _forkName: ForkName | null = null;
68
+ private _forkSeq: ForkSeq | null = null;
69
+ private _slot: Slot | null = null;
70
+ private _fork: Fork | null = null;
71
+ private _epoch: Epoch | null = null;
72
+ private _genesisTime: number | null = null;
73
+ private _genesisValidatorsRoot: Root | null = null;
74
+ private _eth1Data: phase0.Eth1Data | null = null;
75
+ private _latestBlockHeader: phase0.BeaconBlockHeader | null = null;
76
+ private _previousJustifiedCheckpoint: Checkpoint | null = null;
77
+ private _currentJustifiedCheckpoint: Checkpoint | null = null;
78
+ private _finalizedCheckpoint: Checkpoint | null = null;
80
79
  // shuffling / decision roots / proposers
81
- private cachedPreviousDecisionRoot: RootHex | null = null;
82
- private cachedCurrentDecisionRoot: RootHex | null = null;
83
- private cachedNextDecisionRoot: RootHex | null = null;
80
+ private _previousDecisionRoot: RootHex | null = null;
81
+ private _currentDecisionRoot: RootHex | null = null;
82
+ private _nextDecisionRoot: RootHex | null = null;
84
83
  // previousProposers can be null, so use undefined as the "not loaded" sentinel
85
- private cachedPreviousProposers: ValidatorIndex[] | null | undefined = undefined;
86
- private cachedCurrentProposers: ValidatorIndex[] | null = null;
87
- private cachedNextProposers: ValidatorIndex[] | null = null;
84
+ private _previousProposers: ValidatorIndex[] | null | undefined = undefined;
85
+ private _currentProposers: ValidatorIndex[] | null = null;
86
+ private _nextProposers: ValidatorIndex[] | null = null;
88
87
  // validators / balances
89
- private cachedEffectiveBalanceIncrements: EffectiveBalanceIncrements | null = null;
90
- private cachedValidatorCount: number | null = null;
91
- private cachedActiveValidatorCount: number | null = null;
88
+ private _effectiveBalanceIncrements: EffectiveBalanceIncrements | null = null;
89
+ private _validatorCount: number | null = null;
90
+ private _activeValidatorCount: number | null = null;
92
91
  // backward compat
93
- private cachedCreatedWithTransferCache: boolean | null = null;
92
+ private _createdWithTransferCache: boolean | null = null;
94
93
  // altair
95
- private cachedCurrentSyncCommittee: SyncCommittee | null = null;
96
- private cachedNextSyncCommittee: SyncCommittee | null = null;
97
- private cachedPreviousEpochParticipation: Uint8Array | null = null;
98
- private cachedCurrentEpochParticipation: Uint8Array | null = null;
99
- private cachedCurrentSyncCommitteeIndexed: SyncCommitteeCache | null = null;
100
- private cachedSyncProposerReward: number | null = null;
94
+ private _currentSyncCommittee: SyncCommittee | null = null;
95
+ private _nextSyncCommittee: SyncCommittee | null = null;
96
+ private _previousEpochParticipation: Uint8Array | null = null;
97
+ private _currentEpochParticipation: Uint8Array | null = null;
98
+ private _currentSyncCommitteeIndexed: SyncCommitteeCache | null = null;
99
+ private _syncProposerReward: number | null = null;
101
100
  // bellatrix
102
- private cachedLatestExecutionPayloadHeader: ExecutionPayloadHeader | null = null;
103
- private cachedPayloadBlockNumber: number | null = null;
104
- private cachedIsExecutionStateType: boolean | null = null;
105
- private cachedIsMergeTransitionComplete: boolean | null = null;
101
+ private _latestExecutionPayloadHeader: ExecutionPayloadHeader | null = null;
102
+ private _payloadBlockNumber: number | null = null;
103
+ private _isExecutionStateType: boolean | null = null;
104
+ private _isMergeTransitionComplete: boolean | null = null;
106
105
  // capella
107
- private cachedHistoricalSummaries: capella.HistoricalSummaries | null = null;
106
+ private _historicalSummaries: capella.HistoricalSummaries | null = null;
108
107
  // electra
109
- private cachedPendingPartialWithdrawals: electra.PendingPartialWithdrawals | null = null;
110
- private cachedPendingConsolidations: electra.PendingConsolidations | null = null;
111
- private cachedPendingDeposits: electra.PendingDeposits | null = null;
112
- private cachedPendingDepositsCount: number | null = null;
113
- private cachedPendingPartialWithdrawalsCount: number | null = null;
114
- private cachedPendingConsolidationsCount: number | null = null;
108
+ private _pendingPartialWithdrawals: electra.PendingPartialWithdrawals | null = null;
109
+ private _pendingConsolidations: electra.PendingConsolidations | null = null;
110
+ private _pendingDeposits: electra.PendingDeposits | null = null;
111
+ private _pendingDepositsCount: number | null = null;
112
+ private _pendingPartialWithdrawalsCount: number | null = null;
113
+ private _pendingConsolidationsCount: number | null = null;
115
114
  // fulu
116
- private cachedProposerLookahead: fulu.ProposerLookahead | null = null;
115
+ private _proposerLookahead: fulu.ProposerLookahead | null = null;
116
+ // gloas
117
+ private _executionPayloadAvailability: BitArray | null = null;
118
+ private _latestBlockHash: Bytes32 | null = null;
119
+ private _latestExecutionPayloadBid: ExecutionPayloadBid | null = null;
120
+ private _payloadExpectedWithdrawals: capella.Withdrawal[] | null = null;
121
+ private _builderPendingPayments: gloas.BuilderPendingPayments | null = null;
122
+ private _builderPendingWithdrawals: gloas.BuilderPendingWithdrawals | null = null;
123
+
117
124
  // Per-argument caches for argument-taking methods. The binding is treated as
118
125
  // immutable for the view's lifetime, so a given argument always yields the
119
126
  // same result. Maps grow only with touched arguments — typical call patterns
120
127
  // (e.g. a handful of slots per attestation pool scan) keep them tiny.
121
- private readonly cachedBlockRootAtSlot = new Map<Slot, Root>();
122
- private readonly cachedBlockRootAtEpoch = new Map<Epoch, Root>();
123
- private readonly cachedStateRootAtSlot = new Map<Slot, Root>();
124
- private readonly cachedRandaoMix = new Map<Epoch, Bytes32>();
125
- private readonly cachedShufflingAtEpoch = new Map<Epoch, EpochShuffling>();
126
- private readonly cachedBeaconCommittee = new Map<string, Uint32Array>();
127
- private readonly cachedBeaconCommitteeCountPerSlot = new Map<Epoch, number>();
128
- private readonly cachedShufflingDecisionRoot = new Map<Epoch, RootHex>();
129
- private readonly cachedBeaconProposer = new Map<Slot, ValidatorIndex>();
130
- private readonly cachedValidator = new Map<ValidatorIndex, phase0.Validator>();
131
- private readonly cachedBalance = new Map<number, number>();
132
- private readonly cachedIndexedSyncCommitteeAtEpoch = new Map<Epoch, SyncCommitteeCache>();
133
- private readonly cachedIndexedSyncCommittee = new Map<Slot, SyncCommitteeCache>();
134
- private readonly cachedSingleProof = new Map<bigint, Uint8Array[]>();
128
+ private readonly _getBlockRootAtSlot = new Map<Slot, Root>();
129
+ private readonly _getBlockRootAtEpoch = new Map<Epoch, Root>();
130
+ private readonly _getStateRootAtSlot = new Map<Slot, Root>();
131
+ private readonly _getRandaoMix = new Map<Epoch, Bytes32>();
132
+ private readonly _getShufflingAtEpoch = new Map<Epoch, EpochShuffling>();
133
+ private readonly _getBeaconCommittee = new Map<string, Uint32Array>();
134
+ private readonly _getBeaconCommitteeCountPerSlot = new Map<Epoch, number>();
135
+ private readonly _getShufflingDecisionRoot = new Map<Epoch, RootHex>();
136
+ private readonly _getBeaconProposer = new Map<Slot, ValidatorIndex>();
137
+ private readonly _getValidator = new Map<ValidatorIndex, phase0.Validator>();
138
+ private readonly _getBalance = new Map<number, number>();
139
+ private readonly _getIndexedSyncCommitteeAtEpoch = new Map<Epoch, SyncCommitteeCache>();
140
+ private readonly _getIndexedSyncCommittee = new Map<Slot, SyncCommitteeCache>();
141
+ private readonly _getSingleProof = new Map<bigint, Uint8Array[]>();
142
+ private readonly _getEpochPTCs = new Map<Epoch, Uint32Array[]>();
143
+ private readonly _getBuilder = new Map<BuilderIndex, gloas.Builder>();
135
144
 
136
145
  // No-arg method caches
137
- private cachedPreviousShuffling: EpochShuffling | null = null;
138
- private cachedCurrentShuffling: EpochShuffling | null = null;
139
- private cachedNextShuffling: EpochShuffling | null = null;
140
- private cachedEffectiveBalanceIncrementsZeroInactive: EffectiveBalanceIncrements | null = null;
141
- private cachedAllValidators: phase0.Validator[] | null = null;
142
- private cachedAllBalances: number[] | null = null;
143
- private cachedLatestWeakSubjectivityCheckpointEpoch: Epoch | null = null;
144
- private cachedFinalizedRootProof: Uint8Array[] | null = null;
145
- private cachedUnrealizedCheckpoints: {
146
+ private _getPreviousShuffling: EpochShuffling | null = null;
147
+ private _getCurrentShuffling: EpochShuffling | null = null;
148
+ private _getNextShuffling: EpochShuffling | null = null;
149
+ private _getEffectiveBalanceIncrementsZeroInactive: EffectiveBalanceIncrements | null = null;
150
+ private _getAllValidators: phase0.Validator[] | null = null;
151
+ private _getBuildersLength: number | null = null;
152
+ private _getAllBalances: number[] | null = null;
153
+ private _getLatestWeakSubjectivityCheckpointEpoch: Epoch | null = null;
154
+ private _getFinalizedRootProof: Uint8Array[] | null = null;
155
+ private _computeUnrealizedCheckpoints: {
146
156
  justifiedCheckpoint: phase0.Checkpoint;
147
157
  finalizedCheckpoint: phase0.Checkpoint;
148
158
  } | null = null;
149
- private cachedAnchorCheckpoint: {checkpoint: phase0.Checkpoint; blockHeader: phase0.BeaconBlockHeader} | null = null;
150
- private cachedIsStateValidatorsNodesPopulated: boolean | null = null;
151
- private cachedValue: BeaconState | null = null;
152
- private cachedSerialized: Uint8Array | null = null;
153
- private cachedSerializedSize: number | null = null;
154
- private cachedSerializedValidators: Uint8Array | null = null;
155
- private cachedSerializedValidatorsSize: number | null = null;
156
- private cachedHashTreeRoot: Uint8Array | null = null;
157
- private cachedSyncCommitteesWitness: SyncCommitteeWitness | null = null;
158
- private cachedExpectedWithdrawals: {
159
+ private _computeAnchorCheckpoint: {checkpoint: phase0.Checkpoint; blockHeader: phase0.BeaconBlockHeader} | null =
160
+ null;
161
+ private _isStateValidatorsNodesPopulated: boolean | null = null;
162
+ private _toValue: BeaconState | null = null;
163
+ private _serialize: Uint8Array | null = null;
164
+ private _serializedSize: number | null = null;
165
+ private _serializeValidators: Uint8Array | null = null;
166
+ private _serializedValidatorsSize: number | null = null;
167
+ private _hashTreeRoot: Uint8Array | null = null;
168
+ private _getSyncCommitteesWitness: SyncCommitteeWitness | null = null;
169
+ private _getExpectedWithdrawals: {
159
170
  expectedWithdrawals: capella.Withdrawal[];
160
171
  processedBuilderWithdrawalsCount: number;
161
172
  processedPartialWithdrawalsCount: number;
@@ -163,137 +174,137 @@ export class NativeBeaconStateView implements IBeaconStateViewLatestFork {
163
174
  processedValidatorSweepCount: number;
164
175
  } | null = null;
165
176
 
166
- constructor(
167
- private readonly config: BeaconConfig,
168
- readonly binding: IBeaconStateViewNative
169
- ) {}
170
-
171
- release(): void {
172
- this.binding.release();
173
- }
177
+ constructor(readonly binding: IBeaconStateViewNative) {}
174
178
 
179
+ // Binding returns pojo object {uint8Array: Uint8Array; bitLen: number}
180
+ // this class wrap it with BitArray to conform to the api
175
181
  get executionPayloadAvailability(): BitArray {
176
- throw new Error("NativeBeaconStateView does not support Gloas");
182
+ if (this._executionPayloadAvailability === null) {
183
+ const pojo = this.binding.executionPayloadAvailability;
184
+ this._executionPayloadAvailability = new BitArray(pojo.uint8Array, pojo.bitLen);
185
+ }
186
+
187
+ return this._executionPayloadAvailability;
177
188
  }
178
189
 
179
190
  // ─── phase0 ──────────────────────────────────────────────────────────────
180
191
 
181
192
  get forkName(): ForkName {
182
- if (this.cachedForkName === null) {
183
- this.cachedForkName = this.binding.forkName;
193
+ if (this._forkName === null) {
194
+ this._forkName = this.binding.forkName;
184
195
  }
185
- return this.cachedForkName;
196
+ return this._forkName;
186
197
  }
187
198
 
188
199
  get forkSeq(): ForkSeq {
189
- if (this.cachedForkSeq === null) {
190
- this.cachedForkSeq = this.binding.forkSeq;
200
+ if (this._forkSeq === null) {
201
+ this._forkSeq = this.binding.forkSeq;
191
202
  }
192
- return this.cachedForkSeq;
203
+ return this._forkSeq;
193
204
  }
194
205
 
195
206
  get slot(): Slot {
196
- if (this.cachedSlot === null) {
197
- this.cachedSlot = this.binding.slot;
207
+ if (this._slot === null) {
208
+ this._slot = this.binding.slot;
198
209
  }
199
- return this.cachedSlot;
210
+ return this._slot;
200
211
  }
201
212
 
202
213
  get fork(): Fork {
203
- if (this.cachedFork === null) {
204
- this.cachedFork = this.binding.fork;
214
+ if (this._fork === null) {
215
+ this._fork = this.binding.fork;
205
216
  }
206
- return this.cachedFork;
217
+ return this._fork;
207
218
  }
208
219
 
209
220
  get epoch(): Epoch {
210
- if (this.cachedEpoch === null) {
211
- this.cachedEpoch = this.binding.epoch;
221
+ if (this._epoch === null) {
222
+ this._epoch = this.binding.epoch;
212
223
  }
213
- return this.cachedEpoch;
224
+ return this._epoch;
214
225
  }
215
226
 
216
227
  get genesisTime(): number {
217
- if (this.cachedGenesisTime === null) {
218
- this.cachedGenesisTime = this.binding.genesisTime;
228
+ if (this._genesisTime === null) {
229
+ this._genesisTime = this.binding.genesisTime;
219
230
  }
220
- return this.cachedGenesisTime;
231
+ return this._genesisTime;
221
232
  }
222
233
 
223
234
  get genesisValidatorsRoot(): Root {
224
- if (this.cachedGenesisValidatorsRoot === null) {
225
- this.cachedGenesisValidatorsRoot = this.binding.genesisValidatorsRoot;
235
+ if (this._genesisValidatorsRoot === null) {
236
+ this._genesisValidatorsRoot = this.binding.genesisValidatorsRoot;
226
237
  }
227
- return this.cachedGenesisValidatorsRoot;
238
+ return this._genesisValidatorsRoot;
228
239
  }
229
240
 
230
241
  get eth1Data(): phase0.Eth1Data {
231
- if (this.cachedEth1Data === null) {
232
- this.cachedEth1Data = this.binding.eth1Data;
242
+ if (this._eth1Data === null) {
243
+ this._eth1Data = this.binding.eth1Data;
233
244
  }
234
- return this.cachedEth1Data;
245
+ return this._eth1Data;
235
246
  }
236
247
 
237
248
  get latestBlockHeader(): phase0.BeaconBlockHeader {
238
- if (this.cachedLatestBlockHeader === null) {
239
- this.cachedLatestBlockHeader = this.binding.latestBlockHeader;
249
+ if (this._latestBlockHeader === null) {
250
+ this._latestBlockHeader = this.binding.latestBlockHeader;
240
251
  }
241
- return this.cachedLatestBlockHeader;
252
+ return this._latestBlockHeader;
242
253
  }
243
254
 
244
255
  get previousJustifiedCheckpoint(): Checkpoint {
245
- if (this.cachedPreviousJustifiedCheckpoint === null) {
246
- this.cachedPreviousJustifiedCheckpoint = this.binding.previousJustifiedCheckpoint;
256
+ if (this._previousJustifiedCheckpoint === null) {
257
+ this._previousJustifiedCheckpoint = this.binding.previousJustifiedCheckpoint;
247
258
  }
248
- return this.cachedPreviousJustifiedCheckpoint;
259
+ return this._previousJustifiedCheckpoint;
249
260
  }
250
261
 
251
262
  get currentJustifiedCheckpoint(): Checkpoint {
252
- if (this.cachedCurrentJustifiedCheckpoint === null) {
253
- this.cachedCurrentJustifiedCheckpoint = this.binding.currentJustifiedCheckpoint;
263
+ if (this._currentJustifiedCheckpoint === null) {
264
+ this._currentJustifiedCheckpoint = this.binding.currentJustifiedCheckpoint;
254
265
  }
255
- return this.cachedCurrentJustifiedCheckpoint;
266
+ return this._currentJustifiedCheckpoint;
256
267
  }
257
268
 
258
269
  get finalizedCheckpoint(): Checkpoint {
259
- if (this.cachedFinalizedCheckpoint === null) {
260
- this.cachedFinalizedCheckpoint = this.binding.finalizedCheckpoint;
270
+ if (this._finalizedCheckpoint === null) {
271
+ this._finalizedCheckpoint = this.binding.finalizedCheckpoint;
261
272
  }
262
- return this.cachedFinalizedCheckpoint;
273
+ return this._finalizedCheckpoint;
263
274
  }
264
275
 
265
276
  getBlockRootAtSlot(slot: Slot): Root {
266
- let cached = this.cachedBlockRootAtSlot.get(slot);
277
+ let cached = this._getBlockRootAtSlot.get(slot);
267
278
  if (cached === undefined) {
268
279
  cached = this.binding.getBlockRootAtSlot(slot);
269
- this.cachedBlockRootAtSlot.set(slot, cached);
280
+ this._getBlockRootAtSlot.set(slot, cached);
270
281
  }
271
282
  return cached;
272
283
  }
273
284
 
274
285
  getBlockRootAtEpoch(epoch: Epoch): Root {
275
- let cached = this.cachedBlockRootAtEpoch.get(epoch);
286
+ let cached = this._getBlockRootAtEpoch.get(epoch);
276
287
  if (cached === undefined) {
277
288
  cached = this.binding.getBlockRootAtEpoch(epoch);
278
- this.cachedBlockRootAtEpoch.set(epoch, cached);
289
+ this._getBlockRootAtEpoch.set(epoch, cached);
279
290
  }
280
291
  return cached;
281
292
  }
282
293
 
283
294
  getStateRootAtSlot(slot: Slot): Root {
284
- let cached = this.cachedStateRootAtSlot.get(slot);
295
+ let cached = this._getStateRootAtSlot.get(slot);
285
296
  if (cached === undefined) {
286
297
  cached = this.binding.getStateRootAtSlot(slot);
287
- this.cachedStateRootAtSlot.set(slot, cached);
298
+ this._getStateRootAtSlot.set(slot, cached);
288
299
  }
289
300
  return cached;
290
301
  }
291
302
 
292
303
  getRandaoMix(epoch: Epoch): Bytes32 {
293
- let cached = this.cachedRandaoMix.get(epoch);
304
+ let cached = this._getRandaoMix.get(epoch);
294
305
  if (cached === undefined) {
295
306
  cached = this.binding.getRandaoMix(epoch);
296
- this.cachedRandaoMix.set(epoch, cached);
307
+ this._getRandaoMix.set(epoch, cached);
297
308
  }
298
309
  return cached;
299
310
  }
@@ -301,112 +312,112 @@ export class NativeBeaconStateView implements IBeaconStateViewLatestFork {
301
312
  // Shuffling and committees
302
313
 
303
314
  getShufflingAtEpoch(epoch: Epoch): EpochShuffling {
304
- let cached = this.cachedShufflingAtEpoch.get(epoch);
315
+ let cached = this._getShufflingAtEpoch.get(epoch);
305
316
  if (cached === undefined) {
306
317
  cached = this.binding.getShufflingAtEpoch(epoch);
307
- this.cachedShufflingAtEpoch.set(epoch, cached);
318
+ this._getShufflingAtEpoch.set(epoch, cached);
308
319
  }
309
320
  return cached;
310
321
  }
311
322
 
312
323
  getBeaconCommittee(slot: Slot, index: CommitteeIndex): Uint32Array {
313
324
  const key = `${slot}:${index}`;
314
- let cached = this.cachedBeaconCommittee.get(key);
325
+ let cached = this._getBeaconCommittee.get(key);
315
326
  if (cached === undefined) {
316
327
  cached = this.binding.getBeaconCommittee(slot, index);
317
- this.cachedBeaconCommittee.set(key, cached);
328
+ this._getBeaconCommittee.set(key, cached);
318
329
  }
319
330
  return cached;
320
331
  }
321
332
 
322
333
  getBeaconCommitteeCountPerSlot(epoch: Epoch): number {
323
- let cached = this.cachedBeaconCommitteeCountPerSlot.get(epoch);
334
+ let cached = this._getBeaconCommitteeCountPerSlot.get(epoch);
324
335
  if (cached === undefined) {
325
336
  cached = this.binding.getBeaconCommitteeCountPerSlot(epoch);
326
- this.cachedBeaconCommitteeCountPerSlot.set(epoch, cached);
337
+ this._getBeaconCommitteeCountPerSlot.set(epoch, cached);
327
338
  }
328
339
  return cached;
329
340
  }
330
341
 
331
342
  get previousDecisionRoot(): RootHex {
332
- if (this.cachedPreviousDecisionRoot === null) {
333
- this.cachedPreviousDecisionRoot = this.binding.previousDecisionRoot;
343
+ if (this._previousDecisionRoot === null) {
344
+ this._previousDecisionRoot = this.binding.previousDecisionRoot;
334
345
  }
335
- return this.cachedPreviousDecisionRoot;
346
+ return this._previousDecisionRoot;
336
347
  }
337
348
 
338
349
  get currentDecisionRoot(): RootHex {
339
- if (this.cachedCurrentDecisionRoot === null) {
340
- this.cachedCurrentDecisionRoot = this.binding.currentDecisionRoot;
350
+ if (this._currentDecisionRoot === null) {
351
+ this._currentDecisionRoot = this.binding.currentDecisionRoot;
341
352
  }
342
- return this.cachedCurrentDecisionRoot;
353
+ return this._currentDecisionRoot;
343
354
  }
344
355
 
345
356
  get nextDecisionRoot(): RootHex {
346
- if (this.cachedNextDecisionRoot === null) {
347
- this.cachedNextDecisionRoot = this.binding.nextDecisionRoot;
357
+ if (this._nextDecisionRoot === null) {
358
+ this._nextDecisionRoot = this.binding.nextDecisionRoot;
348
359
  }
349
- return this.cachedNextDecisionRoot;
360
+ return this._nextDecisionRoot;
350
361
  }
351
362
 
352
363
  getShufflingDecisionRoot(epoch: Epoch): RootHex {
353
- let cached = this.cachedShufflingDecisionRoot.get(epoch);
364
+ let cached = this._getShufflingDecisionRoot.get(epoch);
354
365
  if (cached === undefined) {
355
366
  cached = this.binding.getShufflingDecisionRoot(epoch);
356
- this.cachedShufflingDecisionRoot.set(epoch, cached);
367
+ this._getShufflingDecisionRoot.set(epoch, cached);
357
368
  }
358
369
  return cached;
359
370
  }
360
371
 
361
372
  getPreviousShuffling(): EpochShuffling {
362
- if (this.cachedPreviousShuffling === null) {
363
- this.cachedPreviousShuffling = this.binding.getPreviousShuffling();
373
+ if (this._getPreviousShuffling === null) {
374
+ this._getPreviousShuffling = this.binding.getPreviousShuffling();
364
375
  }
365
- return this.cachedPreviousShuffling;
376
+ return this._getPreviousShuffling;
366
377
  }
367
378
 
368
379
  getCurrentShuffling(): EpochShuffling {
369
- if (this.cachedCurrentShuffling === null) {
370
- this.cachedCurrentShuffling = this.binding.getCurrentShuffling();
380
+ if (this._getCurrentShuffling === null) {
381
+ this._getCurrentShuffling = this.binding.getCurrentShuffling();
371
382
  }
372
- return this.cachedCurrentShuffling;
383
+ return this._getCurrentShuffling;
373
384
  }
374
385
 
375
386
  getNextShuffling(): EpochShuffling {
376
- if (this.cachedNextShuffling === null) {
377
- this.cachedNextShuffling = this.binding.getNextShuffling();
387
+ if (this._getNextShuffling === null) {
388
+ this._getNextShuffling = this.binding.getNextShuffling();
378
389
  }
379
- return this.cachedNextShuffling;
390
+ return this._getNextShuffling;
380
391
  }
381
392
 
382
393
  // Proposer shuffling
383
394
 
384
395
  get previousProposers(): ValidatorIndex[] | null {
385
- if (this.cachedPreviousProposers === undefined) {
386
- this.cachedPreviousProposers = this.binding.previousProposers;
396
+ if (this._previousProposers === undefined) {
397
+ this._previousProposers = this.binding.previousProposers;
387
398
  }
388
- return this.cachedPreviousProposers;
399
+ return this._previousProposers;
389
400
  }
390
401
 
391
402
  get currentProposers(): ValidatorIndex[] {
392
- if (this.cachedCurrentProposers === null) {
393
- this.cachedCurrentProposers = this.binding.currentProposers;
403
+ if (this._currentProposers === null) {
404
+ this._currentProposers = this.binding.currentProposers;
394
405
  }
395
- return this.cachedCurrentProposers;
406
+ return this._currentProposers;
396
407
  }
397
408
 
398
409
  get nextProposers(): ValidatorIndex[] {
399
- if (this.cachedNextProposers === null) {
400
- this.cachedNextProposers = this.binding.nextProposers;
410
+ if (this._nextProposers === null) {
411
+ this._nextProposers = this.binding.nextProposers;
401
412
  }
402
- return this.cachedNextProposers;
413
+ return this._nextProposers;
403
414
  }
404
415
 
405
416
  getBeaconProposer(slot: Slot): ValidatorIndex {
406
- let cached = this.cachedBeaconProposer.get(slot);
417
+ let cached = this._getBeaconProposer.get(slot);
407
418
  if (cached === undefined) {
408
419
  cached = this.binding.getBeaconProposer(slot);
409
- this.cachedBeaconProposer.set(slot, cached);
420
+ this._getBeaconProposer.set(slot, cached);
410
421
  }
411
422
  return cached;
412
423
  }
@@ -414,33 +425,33 @@ export class NativeBeaconStateView implements IBeaconStateViewLatestFork {
414
425
  // Validators and balances
415
426
 
416
427
  get effectiveBalanceIncrements(): EffectiveBalanceIncrements {
417
- if (this.cachedEffectiveBalanceIncrements === null) {
418
- this.cachedEffectiveBalanceIncrements = this.binding.effectiveBalanceIncrements;
428
+ if (this._effectiveBalanceIncrements === null) {
429
+ this._effectiveBalanceIncrements = this.binding.effectiveBalanceIncrements;
419
430
  }
420
- return this.cachedEffectiveBalanceIncrements;
431
+ return this._effectiveBalanceIncrements;
421
432
  }
422
433
 
423
434
  getEffectiveBalanceIncrementsZeroInactive(): EffectiveBalanceIncrements {
424
- if (this.cachedEffectiveBalanceIncrementsZeroInactive === null) {
425
- this.cachedEffectiveBalanceIncrementsZeroInactive = this.binding.getEffectiveBalanceIncrementsZeroInactive();
435
+ if (this._getEffectiveBalanceIncrementsZeroInactive === null) {
436
+ this._getEffectiveBalanceIncrementsZeroInactive = this.binding.getEffectiveBalanceIncrementsZeroInactive();
426
437
  }
427
- return this.cachedEffectiveBalanceIncrementsZeroInactive;
438
+ return this._getEffectiveBalanceIncrementsZeroInactive;
428
439
  }
429
440
 
430
441
  getBalance(index: number): number {
431
- let cached = this.cachedBalance.get(index);
442
+ let cached = this._getBalance.get(index);
432
443
  if (cached === undefined) {
433
444
  cached = this.binding.getBalance(index);
434
- this.cachedBalance.set(index, cached);
445
+ this._getBalance.set(index, cached);
435
446
  }
436
447
  return cached;
437
448
  }
438
449
 
439
450
  getValidator(index: ValidatorIndex): phase0.Validator {
440
- let cached = this.cachedValidator.get(index);
451
+ let cached = this._getValidator.get(index);
441
452
  if (cached === undefined) {
442
453
  cached = this.binding.getValidator(index);
443
- this.cachedValidator.set(index, cached);
454
+ this._getValidator.set(index, cached);
444
455
  }
445
456
  return cached;
446
457
  }
@@ -450,31 +461,31 @@ export class NativeBeaconStateView implements IBeaconStateViewLatestFork {
450
461
  }
451
462
 
452
463
  get validatorCount(): number {
453
- if (this.cachedValidatorCount === null) {
454
- this.cachedValidatorCount = this.binding.validatorCount;
464
+ if (this._validatorCount === null) {
465
+ this._validatorCount = this.binding.validatorCount;
455
466
  }
456
- return this.cachedValidatorCount;
467
+ return this._validatorCount;
457
468
  }
458
469
 
459
470
  get activeValidatorCount(): number {
460
- if (this.cachedActiveValidatorCount === null) {
461
- this.cachedActiveValidatorCount = this.binding.activeValidatorCount;
471
+ if (this._activeValidatorCount === null) {
472
+ this._activeValidatorCount = this.binding.activeValidatorCount;
462
473
  }
463
- return this.cachedActiveValidatorCount;
474
+ return this._activeValidatorCount;
464
475
  }
465
476
 
466
477
  getAllValidators(): phase0.Validator[] {
467
- if (this.cachedAllValidators === null) {
468
- this.cachedAllValidators = this.binding.getAllValidators();
478
+ if (this._getAllValidators === null) {
479
+ this._getAllValidators = this.binding.getAllValidators();
469
480
  }
470
- return this.cachedAllValidators;
481
+ return this._getAllValidators;
471
482
  }
472
483
 
473
484
  getAllBalances(): number[] {
474
- if (this.cachedAllBalances === null) {
475
- this.cachedAllBalances = this.binding.getAllBalances();
485
+ if (this._getAllBalances === null) {
486
+ this._getAllBalances = this.binding.getAllBalances();
476
487
  }
477
- return this.cachedAllBalances;
488
+ return this._getAllBalances;
478
489
  }
479
490
 
480
491
  // API
@@ -483,30 +494,19 @@ export class NativeBeaconStateView implements IBeaconStateViewLatestFork {
483
494
  return this.binding.proposerRewards;
484
495
  }
485
496
 
486
- async computeBlockRewards(block: BeaconBlock, proposerRewards?: RewardCache): Promise<rewards.BlockRewards> {
487
- const isBlinded = isBlindedBeaconBlock(block);
488
- const signedBlockBytes = isBlinded
489
- ? this.config.getPostBellatrixForkTypes(block.slot).SignedBlindedBeaconBlock.serialize({
490
- message: block as BlindedBeaconBlock,
491
- signature: EMPTY_SIGNATURE,
492
- } as SignedBlindedBeaconBlock)
493
- : this.config.getForkTypes(block.slot).SignedBeaconBlock.serialize({
494
- message: block,
495
- signature: EMPTY_SIGNATURE,
496
- } as SignedBeaconBlock);
497
-
498
- return this.binding.computeBlockRewards(signedBlockBytes, isBlinded, proposerRewards);
497
+ computeBlockRewards(block: BeaconBlock, proposerRewards?: RewardCache): Promise<rewards.BlockRewards> {
498
+ return this.binding.computeBlockRewards(block, proposerRewards);
499
499
  }
500
500
 
501
- async computeAttestationsRewards(validatorIds?: (ValidatorIndex | string)[]): Promise<rewards.AttestationsRewards> {
501
+ computeAttestationsRewards(validatorIds?: (ValidatorIndex | string)[]): Promise<rewards.AttestationsRewards> {
502
502
  return this.binding.computeAttestationsRewards(validatorIds);
503
503
  }
504
504
 
505
505
  getLatestWeakSubjectivityCheckpointEpoch(): Epoch {
506
- if (this.cachedLatestWeakSubjectivityCheckpointEpoch === null) {
507
- this.cachedLatestWeakSubjectivityCheckpointEpoch = this.binding.getLatestWeakSubjectivityCheckpointEpoch();
506
+ if (this._getLatestWeakSubjectivityCheckpointEpoch === null) {
507
+ this._getLatestWeakSubjectivityCheckpointEpoch = this.binding.getLatestWeakSubjectivityCheckpointEpoch();
508
508
  }
509
- return this.cachedLatestWeakSubjectivityCheckpointEpoch;
509
+ return this._getLatestWeakSubjectivityCheckpointEpoch;
510
510
  }
511
511
 
512
512
  // Validation
@@ -525,17 +525,17 @@ export class NativeBeaconStateView implements IBeaconStateViewLatestFork {
525
525
  // Proofs
526
526
 
527
527
  getFinalizedRootProof(): Uint8Array[] {
528
- if (this.cachedFinalizedRootProof === null) {
529
- this.cachedFinalizedRootProof = this.binding.getFinalizedRootProof();
528
+ if (this._getFinalizedRootProof === null) {
529
+ this._getFinalizedRootProof = this.binding.getFinalizedRootProof();
530
530
  }
531
- return this.cachedFinalizedRootProof;
531
+ return this._getFinalizedRootProof;
532
532
  }
533
533
 
534
534
  getSingleProof(gindex: bigint): Uint8Array[] {
535
- let cached = this.cachedSingleProof.get(gindex);
535
+ let cached = this._getSingleProof.get(gindex);
536
536
  if (cached === undefined) {
537
537
  cached = this.binding.getSingleProof(gindex);
538
- this.cachedSingleProof.set(gindex, cached);
538
+ this._getSingleProof.set(gindex, cached);
539
539
  }
540
540
  return cached;
541
541
  }
@@ -550,17 +550,17 @@ export class NativeBeaconStateView implements IBeaconStateViewLatestFork {
550
550
  justifiedCheckpoint: phase0.Checkpoint;
551
551
  finalizedCheckpoint: phase0.Checkpoint;
552
552
  } {
553
- if (this.cachedUnrealizedCheckpoints === null) {
554
- this.cachedUnrealizedCheckpoints = this.binding.computeUnrealizedCheckpoints();
553
+ if (this._computeUnrealizedCheckpoints === null) {
554
+ this._computeUnrealizedCheckpoints = this.binding.computeUnrealizedCheckpoints();
555
555
  }
556
- return this.cachedUnrealizedCheckpoints;
556
+ return this._computeUnrealizedCheckpoints;
557
557
  }
558
558
 
559
559
  computeAnchorCheckpoint(): {checkpoint: phase0.Checkpoint; blockHeader: phase0.BeaconBlockHeader} {
560
- if (this.cachedAnchorCheckpoint === null) {
561
- this.cachedAnchorCheckpoint = this.binding.computeAnchorCheckpoint();
560
+ if (this._computeAnchorCheckpoint === null) {
561
+ this._computeAnchorCheckpoint = this.binding.computeAnchorCheckpoint();
562
562
  }
563
- return this.cachedAnchorCheckpoint;
563
+ return this._computeAnchorCheckpoint;
564
564
  }
565
565
 
566
566
  // Backward compatibility
@@ -574,17 +574,17 @@ export class NativeBeaconStateView implements IBeaconStateViewLatestFork {
574
574
  }
575
575
 
576
576
  get createdWithTransferCache(): boolean {
577
- if (this.cachedCreatedWithTransferCache === null) {
578
- this.cachedCreatedWithTransferCache = this.binding.createdWithTransferCache;
577
+ if (this._createdWithTransferCache === null) {
578
+ this._createdWithTransferCache = this.binding.createdWithTransferCache;
579
579
  }
580
- return this.cachedCreatedWithTransferCache;
580
+ return this._createdWithTransferCache;
581
581
  }
582
582
 
583
583
  isStateValidatorsNodesPopulated(): boolean {
584
- if (this.cachedIsStateValidatorsNodesPopulated === null) {
585
- this.cachedIsStateValidatorsNodesPopulated = this.binding.isStateValidatorsNodesPopulated();
584
+ if (this._isStateValidatorsNodesPopulated === null) {
585
+ this._isStateValidatorsNodesPopulated = this.binding.isStateValidatorsNodesPopulated();
586
586
  }
587
- return this.cachedIsStateValidatorsNodesPopulated;
587
+ return this._isStateValidatorsNodesPopulated;
588
588
  }
589
589
 
590
590
  // Serialization
@@ -594,28 +594,28 @@ export class NativeBeaconStateView implements IBeaconStateViewLatestFork {
594
594
  seedValidatorsBytes?: Uint8Array,
595
595
  opts?: {preloadValidatorsAndBalances?: boolean}
596
596
  ): IBeaconStateView {
597
- return new NativeBeaconStateView(this.config, this.binding.loadOtherState(stateBytes, seedValidatorsBytes, opts));
597
+ return new NativeBeaconStateView(this.binding.loadOtherState(stateBytes, seedValidatorsBytes, opts));
598
598
  }
599
599
 
600
600
  toValue(): BeaconState {
601
- if (this.cachedValue === null) {
602
- this.cachedValue = this.binding.toValue();
601
+ if (this._toValue === null) {
602
+ this._toValue = this.binding.toValue();
603
603
  }
604
- return this.cachedValue;
604
+ return this._toValue;
605
605
  }
606
606
 
607
607
  serialize(): Uint8Array {
608
- if (this.cachedSerialized === null) {
609
- this.cachedSerialized = this.binding.serialize();
608
+ if (this._serialize === null) {
609
+ this._serialize = this.binding.serialize();
610
610
  }
611
- return this.cachedSerialized;
611
+ return this._serialize;
612
612
  }
613
613
 
614
614
  serializedSize(): number {
615
- if (this.cachedSerializedSize === null) {
616
- this.cachedSerializedSize = this.binding.serializedSize();
615
+ if (this._serializedSize === null) {
616
+ this._serializedSize = this.binding.serializedSize();
617
617
  }
618
- return this.cachedSerializedSize;
618
+ return this._serializedSize;
619
619
  }
620
620
 
621
621
  serializeToBytes(output: ByteViews, offset: number): number {
@@ -623,17 +623,17 @@ export class NativeBeaconStateView implements IBeaconStateViewLatestFork {
623
623
  }
624
624
 
625
625
  serializeValidators(): Uint8Array {
626
- if (this.cachedSerializedValidators === null) {
627
- this.cachedSerializedValidators = this.binding.serializeValidators();
626
+ if (this._serializeValidators === null) {
627
+ this._serializeValidators = this.binding.serializeValidators();
628
628
  }
629
- return this.cachedSerializedValidators;
629
+ return this._serializeValidators;
630
630
  }
631
631
 
632
632
  serializedValidatorsSize(): number {
633
- if (this.cachedSerializedValidatorsSize === null) {
634
- this.cachedSerializedValidatorsSize = this.binding.serializedValidatorsSize();
633
+ if (this._serializedValidatorsSize === null) {
634
+ this._serializedValidatorsSize = this.binding.serializedValidatorsSize();
635
635
  }
636
- return this.cachedSerializedValidatorsSize;
636
+ return this._serializedValidatorsSize;
637
637
  }
638
638
 
639
639
  serializeValidatorsToBytes(output: ByteViews, offset: number): number {
@@ -641,53 +641,47 @@ export class NativeBeaconStateView implements IBeaconStateViewLatestFork {
641
641
  }
642
642
 
643
643
  hashTreeRoot(): Uint8Array {
644
- if (this.cachedHashTreeRoot === null) {
645
- this.cachedHashTreeRoot = this.binding.hashTreeRoot();
644
+ if (this._hashTreeRoot === null) {
645
+ this._hashTreeRoot = this.binding.hashTreeRoot();
646
646
  }
647
- return this.cachedHashTreeRoot;
647
+ return this._hashTreeRoot;
648
648
  }
649
649
 
650
650
  // State transition
651
651
 
652
- computeNewStateRoot(input: BlockSTFInput, modules: StateTransitionModules): ComputeNewStateRootResult {
653
- const postState = this.stateTransition(input, computeNewStateRootStateTransitionOpts, modules);
652
+ computeNewStateRoot(input: ComputeNewStateRootInput, modules: StateTransitionModules): ComputeNewStateRootResult {
653
+ const postState = new NativeBeaconStateView(
654
+ this.binding.stateTransition(input.block, computeNewStateRootStateTransitionOpts, modules)
655
+ );
654
656
  return getComputeNewStateRootResult(postState);
655
657
  }
656
658
 
657
659
  stateTransition(
658
- {block, ssz}: BlockSTFInput,
660
+ signedBlock: SignedBeaconBlock | SignedBlindedBeaconBlock,
659
661
  options: StateTransitionOpts,
660
- _modules: StateTransitionModules
662
+ modules: StateTransitionModules
661
663
  ): IBeaconStateView {
662
- const isBlinded = isBlindedBeaconBlock(block.message);
663
- const signedBlockBytes =
664
- ssz ??
665
- (isBlinded
666
- ? this.config
667
- .getPostBellatrixForkTypes(block.message.slot)
668
- .SignedBlindedBeaconBlock.serialize(block as SignedBlindedBeaconBlock)
669
- : this.config.getForkTypes(block.message.slot).SignedBeaconBlock.serialize(block as SignedBeaconBlock));
670
- return new NativeBeaconStateView(this.config, this.binding.stateTransition(signedBlockBytes, isBlinded, options));
664
+ return new NativeBeaconStateView(this.binding.stateTransition(signedBlock, options, modules));
671
665
  }
672
666
 
673
- processSlots(slot: Slot, opts?: {dontTransferCache?: boolean}, _modules?: StateTransitionModules): IBeaconStateView {
674
- return new NativeBeaconStateView(this.config, this.binding.processSlots(slot, opts));
667
+ processSlots(slot: Slot, opts?: {dontTransferCache?: boolean}, modules?: StateTransitionModules): IBeaconStateView {
668
+ return new NativeBeaconStateView(this.binding.processSlots(slot, opts, modules));
675
669
  }
676
670
 
677
671
  // ─── altair ──────────────────────────────────────────────────────────────
678
672
 
679
673
  get previousEpochParticipation(): Uint8Array {
680
- if (this.cachedPreviousEpochParticipation === null) {
681
- this.cachedPreviousEpochParticipation = this.binding.previousEpochParticipation;
674
+ if (this._previousEpochParticipation === null) {
675
+ this._previousEpochParticipation = this.binding.previousEpochParticipation;
682
676
  }
683
- return this.cachedPreviousEpochParticipation;
677
+ return this._previousEpochParticipation;
684
678
  }
685
679
 
686
680
  get currentEpochParticipation(): Uint8Array {
687
- if (this.cachedCurrentEpochParticipation === null) {
688
- this.cachedCurrentEpochParticipation = this.binding.currentEpochParticipation;
681
+ if (this._currentEpochParticipation === null) {
682
+ this._currentEpochParticipation = this.binding.currentEpochParticipation;
689
683
  }
690
- return this.cachedCurrentEpochParticipation;
684
+ return this._currentEpochParticipation;
691
685
  }
692
686
 
693
687
  getPreviousEpochParticipation(validatorIndex: ValidatorIndex): number {
@@ -699,52 +693,52 @@ export class NativeBeaconStateView implements IBeaconStateViewLatestFork {
699
693
  }
700
694
 
701
695
  get currentSyncCommittee(): altair.SyncCommittee {
702
- if (this.cachedCurrentSyncCommittee === null) {
703
- this.cachedCurrentSyncCommittee = this.binding.currentSyncCommittee;
696
+ if (this._currentSyncCommittee === null) {
697
+ this._currentSyncCommittee = this.binding.currentSyncCommittee;
704
698
  }
705
- return this.cachedCurrentSyncCommittee;
699
+ return this._currentSyncCommittee;
706
700
  }
707
701
 
708
702
  get nextSyncCommittee(): altair.SyncCommittee {
709
- if (this.cachedNextSyncCommittee === null) {
710
- this.cachedNextSyncCommittee = this.binding.nextSyncCommittee;
703
+ if (this._nextSyncCommittee === null) {
704
+ this._nextSyncCommittee = this.binding.nextSyncCommittee;
711
705
  }
712
- return this.cachedNextSyncCommittee;
706
+ return this._nextSyncCommittee;
713
707
  }
714
708
 
715
709
  get currentSyncCommitteeIndexed(): SyncCommitteeCache {
716
- if (this.cachedCurrentSyncCommitteeIndexed === null) {
717
- this.cachedCurrentSyncCommitteeIndexed = this.binding.currentSyncCommitteeIndexed;
710
+ if (this._currentSyncCommitteeIndexed === null) {
711
+ this._currentSyncCommitteeIndexed = this.binding.currentSyncCommitteeIndexed;
718
712
  }
719
- return this.cachedCurrentSyncCommitteeIndexed;
713
+ return this._currentSyncCommitteeIndexed;
720
714
  }
721
715
 
722
716
  get syncProposerReward(): number {
723
- if (this.cachedSyncProposerReward === null) {
724
- this.cachedSyncProposerReward = this.binding.syncProposerReward;
717
+ if (this._syncProposerReward === null) {
718
+ this._syncProposerReward = this.binding.syncProposerReward;
725
719
  }
726
- return this.cachedSyncProposerReward;
720
+ return this._syncProposerReward;
727
721
  }
728
722
 
729
723
  getIndexedSyncCommitteeAtEpoch(epoch: Epoch): SyncCommitteeCache {
730
- let cached = this.cachedIndexedSyncCommitteeAtEpoch.get(epoch);
724
+ let cached = this._getIndexedSyncCommitteeAtEpoch.get(epoch);
731
725
  if (cached === undefined) {
732
726
  cached = this.binding.getIndexedSyncCommitteeAtEpoch(epoch);
733
- this.cachedIndexedSyncCommitteeAtEpoch.set(epoch, cached);
727
+ this._getIndexedSyncCommitteeAtEpoch.set(epoch, cached);
734
728
  }
735
729
  return cached;
736
730
  }
737
731
 
738
732
  getIndexedSyncCommittee(slot: Slot): SyncCommitteeCache {
739
- let cached = this.cachedIndexedSyncCommittee.get(slot);
733
+ let cached = this._getIndexedSyncCommittee.get(slot);
740
734
  if (cached === undefined) {
741
735
  cached = this.binding.getIndexedSyncCommittee(slot);
742
- this.cachedIndexedSyncCommittee.set(slot, cached);
736
+ this._getIndexedSyncCommittee.set(slot, cached);
743
737
  }
744
738
  return cached;
745
739
  }
746
740
 
747
- async computeSyncCommitteeRewards(
741
+ computeSyncCommitteeRewards(
748
742
  block: BeaconBlock,
749
743
  validatorIds: (ValidatorIndex | string)[]
750
744
  ): Promise<rewards.SyncCommitteeRewards> {
@@ -752,40 +746,40 @@ export class NativeBeaconStateView implements IBeaconStateViewLatestFork {
752
746
  }
753
747
 
754
748
  getSyncCommitteesWitness(): SyncCommitteeWitness {
755
- if (this.cachedSyncCommitteesWitness === null) {
756
- this.cachedSyncCommitteesWitness = this.binding.getSyncCommitteesWitness();
749
+ if (this._getSyncCommitteesWitness === null) {
750
+ this._getSyncCommitteesWitness = this.binding.getSyncCommitteesWitness();
757
751
  }
758
- return this.cachedSyncCommitteesWitness;
752
+ return this._getSyncCommitteesWitness;
759
753
  }
760
754
 
761
755
  // ─── bellatrix ───────────────────────────────────────────────────────────
762
756
 
763
757
  get latestExecutionPayloadHeader(): ExecutionPayloadHeader {
764
- if (this.cachedLatestExecutionPayloadHeader === null) {
765
- this.cachedLatestExecutionPayloadHeader = this.binding.latestExecutionPayloadHeader;
758
+ if (this._latestExecutionPayloadHeader === null) {
759
+ this._latestExecutionPayloadHeader = this.binding.latestExecutionPayloadHeader;
766
760
  }
767
- return this.cachedLatestExecutionPayloadHeader;
761
+ return this._latestExecutionPayloadHeader;
768
762
  }
769
763
 
770
764
  get payloadBlockNumber(): number {
771
- if (this.cachedPayloadBlockNumber === null) {
772
- this.cachedPayloadBlockNumber = this.binding.payloadBlockNumber;
765
+ if (this._payloadBlockNumber === null) {
766
+ this._payloadBlockNumber = this.binding.payloadBlockNumber;
773
767
  }
774
- return this.cachedPayloadBlockNumber;
768
+ return this._payloadBlockNumber;
775
769
  }
776
770
 
777
771
  get isExecutionStateType(): boolean {
778
- if (this.cachedIsExecutionStateType === null) {
779
- this.cachedIsExecutionStateType = this.binding.isExecutionStateType;
772
+ if (this._isExecutionStateType === null) {
773
+ this._isExecutionStateType = this.binding.isExecutionStateType;
780
774
  }
781
- return this.cachedIsExecutionStateType;
775
+ return this._isExecutionStateType;
782
776
  }
783
777
 
784
778
  get isMergeTransitionComplete(): boolean {
785
- if (this.cachedIsMergeTransitionComplete === null) {
786
- this.cachedIsMergeTransitionComplete = this.binding.isMergeTransitionComplete;
779
+ if (this._isMergeTransitionComplete === null) {
780
+ this._isMergeTransitionComplete = this.binding.isMergeTransitionComplete;
787
781
  }
788
- return this.cachedIsMergeTransitionComplete;
782
+ return this._isMergeTransitionComplete;
789
783
  }
790
784
 
791
785
  isExecutionEnabled(block: BeaconBlock | BlindedBeaconBlock): boolean {
@@ -795,10 +789,10 @@ export class NativeBeaconStateView implements IBeaconStateViewLatestFork {
795
789
  // ─── capella ─────────────────────────────────────────────────────────────
796
790
 
797
791
  get historicalSummaries(): capella.HistoricalSummaries {
798
- if (this.cachedHistoricalSummaries === null) {
799
- this.cachedHistoricalSummaries = this.binding.historicalSummaries;
792
+ if (this._historicalSummaries === null) {
793
+ this._historicalSummaries = this.binding.historicalSummaries;
800
794
  }
801
- return this.cachedHistoricalSummaries;
795
+ return this._historicalSummaries;
802
796
  }
803
797
 
804
798
  getExpectedWithdrawals(): {
@@ -808,127 +802,154 @@ export class NativeBeaconStateView implements IBeaconStateViewLatestFork {
808
802
  processedBuildersSweepCount: number;
809
803
  processedValidatorSweepCount: number;
810
804
  } {
811
- if (this.cachedExpectedWithdrawals === null) {
812
- this.cachedExpectedWithdrawals = this.binding.getExpectedWithdrawals();
805
+ if (this._getExpectedWithdrawals === null) {
806
+ this._getExpectedWithdrawals = this.binding.getExpectedWithdrawals();
813
807
  }
814
- return this.cachedExpectedWithdrawals;
808
+ return this._getExpectedWithdrawals;
815
809
  }
816
810
 
817
811
  // ─── electra ─────────────────────────────────────────────────────────────
818
812
 
819
813
  get pendingDeposits(): electra.PendingDeposits {
820
- if (this.cachedPendingDeposits === null) {
821
- this.cachedPendingDeposits = ssz.electra.PendingDeposits.deserialize(this.binding.pendingDeposits);
814
+ if (this._pendingDeposits === null) {
815
+ this._pendingDeposits = this.binding.pendingDeposits;
822
816
  }
823
- return this.cachedPendingDeposits;
817
+ return this._pendingDeposits;
824
818
  }
825
819
 
826
820
  get pendingDepositsCount(): number {
827
- if (this.cachedPendingDepositsCount === null) {
828
- this.cachedPendingDepositsCount = this.binding.pendingDepositsCount;
821
+ if (this._pendingDepositsCount === null) {
822
+ this._pendingDepositsCount = this.binding.pendingDepositsCount;
829
823
  }
830
- return this.cachedPendingDepositsCount;
824
+ return this._pendingDepositsCount;
831
825
  }
832
826
 
833
827
  get pendingPartialWithdrawals(): electra.PendingPartialWithdrawals {
834
- if (this.cachedPendingPartialWithdrawals === null) {
835
- this.cachedPendingPartialWithdrawals = ssz.electra.PendingPartialWithdrawals.deserialize(
836
- this.binding.pendingPartialWithdrawals
837
- );
828
+ if (this._pendingPartialWithdrawals === null) {
829
+ this._pendingPartialWithdrawals = this.binding.pendingPartialWithdrawals;
838
830
  }
839
- return this.cachedPendingPartialWithdrawals;
831
+ return this._pendingPartialWithdrawals;
840
832
  }
841
833
 
842
834
  get pendingPartialWithdrawalsCount(): number {
843
- if (this.cachedPendingPartialWithdrawalsCount === null) {
844
- this.cachedPendingPartialWithdrawalsCount = this.binding.pendingPartialWithdrawalsCount;
835
+ if (this._pendingPartialWithdrawalsCount === null) {
836
+ this._pendingPartialWithdrawalsCount = this.binding.pendingPartialWithdrawalsCount;
845
837
  }
846
- return this.cachedPendingPartialWithdrawalsCount;
838
+ return this._pendingPartialWithdrawalsCount;
847
839
  }
848
840
 
849
841
  get pendingConsolidations(): electra.PendingConsolidations {
850
- if (this.cachedPendingConsolidations === null) {
851
- this.cachedPendingConsolidations = ssz.electra.PendingConsolidations.deserialize(
852
- this.binding.pendingConsolidations
853
- );
842
+ if (this._pendingConsolidations === null) {
843
+ this._pendingConsolidations = this.binding.pendingConsolidations;
854
844
  }
855
- return this.cachedPendingConsolidations;
845
+ return this._pendingConsolidations;
856
846
  }
857
847
 
858
848
  get pendingConsolidationsCount(): number {
859
- if (this.cachedPendingConsolidationsCount === null) {
860
- this.cachedPendingConsolidationsCount = this.binding.pendingConsolidationsCount;
849
+ if (this._pendingConsolidationsCount === null) {
850
+ this._pendingConsolidationsCount = this.binding.pendingConsolidationsCount;
861
851
  }
862
- return this.cachedPendingConsolidationsCount;
852
+ return this._pendingConsolidationsCount;
863
853
  }
864
854
 
865
855
  // ─── fulu ────────────────────────────────────────────────────────────────
866
856
 
867
857
  get proposerLookahead(): fulu.ProposerLookahead {
868
- if (this.cachedProposerLookahead === null) {
869
- this.cachedProposerLookahead = Array.from(this.binding.proposerLookahead);
858
+ if (this._proposerLookahead === null) {
859
+ this._proposerLookahead = this.binding.proposerLookahead;
870
860
  }
871
- return this.cachedProposerLookahead;
861
+ return this._proposerLookahead;
872
862
  }
873
863
 
874
- preVerifyBuilderDepositsPreGloas(
875
- _maxBuilderDeposits: number,
876
- _maxDurationMs: number
877
- ): PreVerifyBuilderDepositsResult {
878
- throw new Error("NativeBeaconStateView does not support Gloas");
864
+ preVerifyBuilderDepositsPreGloas(maxBuilderDeposits: number, maxDurationMs: number): PreVerifyBuilderDepositsResult {
865
+ return this.binding.preVerifyBuilderDepositsPreGloas(maxBuilderDeposits, maxDurationMs);
879
866
  }
880
867
 
881
868
  clearPreGloasBuilderDepositCache(): void {
882
- throw new Error("NativeBeaconStateView does not support Gloas");
869
+ this.binding.clearPreGloasBuilderDepositCache();
883
870
  }
884
871
 
885
872
  // ─── gloas ───────────────────────────────────────────────────────────────
886
873
 
887
874
  get latestBlockHash(): Bytes32 {
888
- throw new Error("NativeBeaconStateView does not support Gloas");
875
+ if (this._latestBlockHash === null) {
876
+ this._latestBlockHash = this.binding.latestBlockHash;
877
+ }
878
+ return this._latestBlockHash;
889
879
  }
890
880
 
881
+ // executionPayloadAvailability getter is defined near the top of the class.
882
+
891
883
  get latestExecutionPayloadBid(): ExecutionPayloadBid {
892
- throw new Error("NativeBeaconStateView does not support Gloas");
884
+ if (this._latestExecutionPayloadBid === null) {
885
+ this._latestExecutionPayloadBid = this.binding.latestExecutionPayloadBid;
886
+ }
887
+ return this._latestExecutionPayloadBid;
893
888
  }
894
889
 
895
890
  get payloadExpectedWithdrawals(): capella.Withdrawal[] {
896
- throw new Error("NativeBeaconStateView does not support Gloas");
891
+ if (this._payloadExpectedWithdrawals === null) {
892
+ this._payloadExpectedWithdrawals = this.binding.payloadExpectedWithdrawals;
893
+ }
894
+ return this._payloadExpectedWithdrawals;
897
895
  }
898
896
 
899
897
  get builderPendingPayments(): gloas.BuilderPendingPayments {
900
- throw new Error("NativeBeaconStateView does not support Gloas");
898
+ if (this._builderPendingPayments === null) {
899
+ this._builderPendingPayments = this.binding.builderPendingPayments;
900
+ }
901
+ return this._builderPendingPayments;
901
902
  }
902
903
 
903
904
  get builderPendingWithdrawals(): gloas.BuilderPendingWithdrawals {
904
- throw new Error("NativeBeaconStateView does not support Gloas");
905
+ if (this._builderPendingWithdrawals === null) {
906
+ this._builderPendingWithdrawals = this.binding.builderPendingWithdrawals;
907
+ }
908
+ return this._builderPendingWithdrawals;
905
909
  }
906
910
 
907
- getBuilder(_index: BuilderIndex): gloas.Builder {
908
- throw new Error("NativeBeaconStateView does not support Gloas");
911
+ getBuilder(index: BuilderIndex): gloas.Builder {
912
+ let cached = this._getBuilder.get(index);
913
+ if (cached === undefined) {
914
+ cached = this.binding.getBuilder(index);
915
+ this._getBuilder.set(index, cached);
916
+ }
917
+ return cached;
909
918
  }
910
919
 
911
920
  getBuildersLength(): number {
912
- throw new Error("NativeBeaconStateView does not support Gloas");
921
+ if (this._getBuildersLength === null) {
922
+ this._getBuildersLength = this.binding.getBuildersLength();
923
+ }
924
+ return this._getBuildersLength;
913
925
  }
914
926
 
915
- canBuilderCoverBid(_builderIndex: BuilderIndex, _bidAmount: number): boolean {
916
- throw new Error("NativeBeaconStateView does not support Gloas");
927
+ canBuilderCoverBid(builderIndex: BuilderIndex, bidAmount: number): boolean {
928
+ return this.binding.canBuilderCoverBid(builderIndex, bidAmount);
917
929
  }
918
930
 
919
- getEpochPTCs(_epoch: Epoch): Uint32Array[] {
920
- throw new Error("NativeBeaconStateView does not support Gloas");
931
+ getEpochPTCs(epoch: Epoch): Uint32Array[] {
932
+ let cached = this._getEpochPTCs.get(epoch);
933
+ if (cached === undefined) {
934
+ cached = this.binding.getEpochPTCs(epoch);
935
+ this._getEpochPTCs.set(epoch, cached);
936
+ }
937
+ return cached;
921
938
  }
922
939
 
923
- getPayloadTimelinessCommittee(_slot: Slot): Uint32Array {
924
- throw new Error("NativeBeaconStateView does not support Gloas");
940
+ getPayloadTimelinessCommittee(slot: Slot): Uint32Array {
941
+ return this.binding.getPayloadTimelinessCommittee(slot);
925
942
  }
926
943
 
927
- getIndicesInPayloadTimelinessCommittee(_validatorIndex: ValidatorIndex, _slot: Slot): number[] {
928
- throw new Error("NativeBeaconStateView does not support Gloas");
944
+ getIndicesInPayloadTimelinessCommittee(validatorIndex: ValidatorIndex, slot: Slot): number[] {
945
+ return this.binding.getIndicesInPayloadTimelinessCommittee(validatorIndex, slot);
929
946
  }
930
947
 
931
- withParentPayloadApplied(_executionRequests: gloas.ExecutionRequests): IBeaconStateViewGloas {
932
- throw new Error("NativeBeaconStateView does not support Gloas");
948
+ withParentPayloadApplied(executionRequests: gloas.ExecutionRequests): IBeaconStateViewGloas {
949
+ const view = new NativeBeaconStateView(this.binding.withParentPayloadApplied(executionRequests));
950
+ if (!isStatePostGloas(view)) {
951
+ throw new Error("Expected gloas state from withParentPayloadApplied");
952
+ }
953
+ return view;
933
954
  }
934
955
  }