@lodestar/state-transition 1.49.0-rc.0 → 1.50.0-dev.01cc10ce70

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