@lodestar/state-transition 1.44.0-dev.edb7c53fbc → 1.44.0-dev.f328dc3369

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