@lodestar/state-transition 1.35.0-dev.fcf8d024ea → 1.35.0-dev.feed916580

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 (237) hide show
  1. package/lib/cache/types.d.ts +2 -2
  2. package/lib/util/genesis.js +3 -0
  3. package/lib/util/genesis.js.map +1 -1
  4. package/lib/util/slot.d.ts +1 -0
  5. package/lib/util/slot.js +5 -1
  6. package/lib/util/slot.js.map +1 -1
  7. package/package.json +11 -13
  8. package/lib/block/externalData.d.ts.map +0 -1
  9. package/lib/block/index.d.ts.map +0 -1
  10. package/lib/block/initiateValidatorExit.d.ts.map +0 -1
  11. package/lib/block/isValidIndexedAttestation.d.ts.map +0 -1
  12. package/lib/block/processAttestationPhase0.d.ts.map +0 -1
  13. package/lib/block/processAttestations.d.ts.map +0 -1
  14. package/lib/block/processAttestationsAltair.d.ts.map +0 -1
  15. package/lib/block/processAttesterSlashing.d.ts.map +0 -1
  16. package/lib/block/processBlobKzgCommitments.d.ts.map +0 -1
  17. package/lib/block/processBlockHeader.d.ts.map +0 -1
  18. package/lib/block/processBlsToExecutionChange.d.ts.map +0 -1
  19. package/lib/block/processConsolidationRequest.d.ts.map +0 -1
  20. package/lib/block/processDeposit.d.ts.map +0 -1
  21. package/lib/block/processDepositRequest.d.ts.map +0 -1
  22. package/lib/block/processEth1Data.d.ts.map +0 -1
  23. package/lib/block/processExecutionPayload.d.ts.map +0 -1
  24. package/lib/block/processOperations.d.ts.map +0 -1
  25. package/lib/block/processProposerSlashing.d.ts.map +0 -1
  26. package/lib/block/processRandao.d.ts.map +0 -1
  27. package/lib/block/processSyncCommittee.d.ts.map +0 -1
  28. package/lib/block/processVoluntaryExit.d.ts.map +0 -1
  29. package/lib/block/processWithdrawalRequest.d.ts.map +0 -1
  30. package/lib/block/processWithdrawals.d.ts.map +0 -1
  31. package/lib/block/slashValidator.d.ts.map +0 -1
  32. package/lib/block/types.d.ts.map +0 -1
  33. package/lib/cache/effectiveBalanceIncrements.d.ts.map +0 -1
  34. package/lib/cache/epochCache.d.ts.map +0 -1
  35. package/lib/cache/epochTransitionCache.d.ts.map +0 -1
  36. package/lib/cache/pubkeyCache.d.ts.map +0 -1
  37. package/lib/cache/rewardCache.d.ts.map +0 -1
  38. package/lib/cache/stateCache.d.ts.map +0 -1
  39. package/lib/cache/syncCommitteeCache.d.ts.map +0 -1
  40. package/lib/cache/types.d.ts.map +0 -1
  41. package/lib/constants/constants.d.ts.map +0 -1
  42. package/lib/constants/index.d.ts.map +0 -1
  43. package/lib/epoch/computeUnrealizedCheckpoints.d.ts.map +0 -1
  44. package/lib/epoch/getAttestationDeltas.d.ts.map +0 -1
  45. package/lib/epoch/getRewardsAndPenalties.d.ts.map +0 -1
  46. package/lib/epoch/index.d.ts.map +0 -1
  47. package/lib/epoch/processEffectiveBalanceUpdates.d.ts.map +0 -1
  48. package/lib/epoch/processEth1DataReset.d.ts.map +0 -1
  49. package/lib/epoch/processHistoricalRootsUpdate.d.ts.map +0 -1
  50. package/lib/epoch/processHistoricalSummariesUpdate.d.ts.map +0 -1
  51. package/lib/epoch/processInactivityUpdates.d.ts.map +0 -1
  52. package/lib/epoch/processJustificationAndFinalization.d.ts.map +0 -1
  53. package/lib/epoch/processParticipationFlagUpdates.d.ts.map +0 -1
  54. package/lib/epoch/processParticipationRecordUpdates.d.ts.map +0 -1
  55. package/lib/epoch/processPendingAttestations.d.ts.map +0 -1
  56. package/lib/epoch/processPendingConsolidations.d.ts.map +0 -1
  57. package/lib/epoch/processPendingDeposits.d.ts.map +0 -1
  58. package/lib/epoch/processProposerLookahead.d.ts.map +0 -1
  59. package/lib/epoch/processRandaoMixesReset.d.ts.map +0 -1
  60. package/lib/epoch/processRegistryUpdates.d.ts.map +0 -1
  61. package/lib/epoch/processRewardsAndPenalties.d.ts.map +0 -1
  62. package/lib/epoch/processSlashings.d.ts.map +0 -1
  63. package/lib/epoch/processSlashingsReset.d.ts.map +0 -1
  64. package/lib/epoch/processSyncCommitteeUpdates.d.ts.map +0 -1
  65. package/lib/index.d.ts.map +0 -1
  66. package/lib/metrics.d.ts.map +0 -1
  67. package/lib/signatureSets/attesterSlashings.d.ts.map +0 -1
  68. package/lib/signatureSets/blsToExecutionChange.d.ts.map +0 -1
  69. package/lib/signatureSets/index.d.ts.map +0 -1
  70. package/lib/signatureSets/indexedAttestation.d.ts.map +0 -1
  71. package/lib/signatureSets/proposer.d.ts.map +0 -1
  72. package/lib/signatureSets/proposerSlashings.d.ts.map +0 -1
  73. package/lib/signatureSets/randao.d.ts.map +0 -1
  74. package/lib/signatureSets/voluntaryExits.d.ts.map +0 -1
  75. package/lib/slot/index.d.ts.map +0 -1
  76. package/lib/slot/upgradeStateToAltair.d.ts.map +0 -1
  77. package/lib/slot/upgradeStateToBellatrix.d.ts.map +0 -1
  78. package/lib/slot/upgradeStateToCapella.d.ts.map +0 -1
  79. package/lib/slot/upgradeStateToDeneb.d.ts.map +0 -1
  80. package/lib/slot/upgradeStateToElectra.d.ts.map +0 -1
  81. package/lib/slot/upgradeStateToFulu.d.ts.map +0 -1
  82. package/lib/slot/upgradeStateToGloas.d.ts.map +0 -1
  83. package/lib/stateTransition.d.ts.map +0 -1
  84. package/lib/types.d.ts.map +0 -1
  85. package/lib/util/aggregator.d.ts.map +0 -1
  86. package/lib/util/altair.d.ts.map +0 -1
  87. package/lib/util/array.d.ts.map +0 -1
  88. package/lib/util/attestation.d.ts.map +0 -1
  89. package/lib/util/attesterStatus.d.ts.map +0 -1
  90. package/lib/util/balance.d.ts.map +0 -1
  91. package/lib/util/blindedBlock.d.ts.map +0 -1
  92. package/lib/util/blockRoot.d.ts.map +0 -1
  93. package/lib/util/calculateCommitteeAssignments.d.ts.map +0 -1
  94. package/lib/util/capella.d.ts.map +0 -1
  95. package/lib/util/computeAnchorCheckpoint.d.ts.map +0 -1
  96. package/lib/util/deposit.d.ts.map +0 -1
  97. package/lib/util/domain.d.ts.map +0 -1
  98. package/lib/util/electra.d.ts.map +0 -1
  99. package/lib/util/epoch.d.ts.map +0 -1
  100. package/lib/util/epochShuffling.d.ts.map +0 -1
  101. package/lib/util/execution.d.ts.map +0 -1
  102. package/lib/util/finality.d.ts.map +0 -1
  103. package/lib/util/fulu.d.ts.map +0 -1
  104. package/lib/util/genesis.d.ts.map +0 -1
  105. package/lib/util/index.d.ts.map +0 -1
  106. package/lib/util/interop.d.ts.map +0 -1
  107. package/lib/util/loadState/findModifiedInactivityScores.d.ts.map +0 -1
  108. package/lib/util/loadState/findModifiedValidators.d.ts.map +0 -1
  109. package/lib/util/loadState/index.d.ts.map +0 -1
  110. package/lib/util/loadState/loadState.d.ts.map +0 -1
  111. package/lib/util/loadState/loadValidator.d.ts.map +0 -1
  112. package/lib/util/rootCache.d.ts.map +0 -1
  113. package/lib/util/seed.d.ts.map +0 -1
  114. package/lib/util/shufflingDecisionRoot.d.ts.map +0 -1
  115. package/lib/util/signatureSets.d.ts.map +0 -1
  116. package/lib/util/signingRoot.d.ts.map +0 -1
  117. package/lib/util/slot.d.ts.map +0 -1
  118. package/lib/util/sszBytes.d.ts.map +0 -1
  119. package/lib/util/syncCommittee.d.ts.map +0 -1
  120. package/lib/util/targetUnslashedBalance.d.ts.map +0 -1
  121. package/lib/util/validator.d.ts.map +0 -1
  122. package/lib/util/weakSubjectivity.d.ts.map +0 -1
  123. package/src/block/externalData.ts +0 -26
  124. package/src/block/index.ts +0 -81
  125. package/src/block/initiateValidatorExit.ts +0 -62
  126. package/src/block/isValidIndexedAttestation.ts +0 -70
  127. package/src/block/processAttestationPhase0.ts +0 -158
  128. package/src/block/processAttestations.ts +0 -25
  129. package/src/block/processAttestationsAltair.ts +0 -184
  130. package/src/block/processAttesterSlashing.ts +0 -59
  131. package/src/block/processBlobKzgCommitments.ts +0 -21
  132. package/src/block/processBlockHeader.ts +0 -54
  133. package/src/block/processBlsToExecutionChange.ts +0 -78
  134. package/src/block/processConsolidationRequest.ts +0 -147
  135. package/src/block/processDeposit.ts +0 -166
  136. package/src/block/processDepositRequest.ts +0 -19
  137. package/src/block/processEth1Data.ts +0 -86
  138. package/src/block/processExecutionPayload.ts +0 -84
  139. package/src/block/processOperations.ts +0 -83
  140. package/src/block/processProposerSlashing.ts +0 -66
  141. package/src/block/processRandao.ts +0 -27
  142. package/src/block/processSyncCommittee.ts +0 -117
  143. package/src/block/processVoluntaryExit.ts +0 -55
  144. package/src/block/processWithdrawalRequest.ts +0 -98
  145. package/src/block/processWithdrawals.ts +0 -207
  146. package/src/block/slashValidator.ts +0 -98
  147. package/src/block/types.ts +0 -9
  148. package/src/cache/effectiveBalanceIncrements.ts +0 -39
  149. package/src/cache/epochCache.ts +0 -1213
  150. package/src/cache/epochTransitionCache.ts +0 -542
  151. package/src/cache/pubkeyCache.ts +0 -33
  152. package/src/cache/rewardCache.ts +0 -19
  153. package/src/cache/stateCache.ts +0 -268
  154. package/src/cache/syncCommitteeCache.ts +0 -96
  155. package/src/cache/types.ts +0 -18
  156. package/src/constants/constants.ts +0 -12
  157. package/src/constants/index.ts +0 -1
  158. package/src/epoch/computeUnrealizedCheckpoints.ts +0 -55
  159. package/src/epoch/getAttestationDeltas.ts +0 -169
  160. package/src/epoch/getRewardsAndPenalties.ts +0 -137
  161. package/src/epoch/index.ts +0 -202
  162. package/src/epoch/processEffectiveBalanceUpdates.ts +0 -111
  163. package/src/epoch/processEth1DataReset.ts +0 -17
  164. package/src/epoch/processHistoricalRootsUpdate.ts +0 -25
  165. package/src/epoch/processHistoricalSummariesUpdate.ts +0 -23
  166. package/src/epoch/processInactivityUpdates.ts +0 -60
  167. package/src/epoch/processJustificationAndFinalization.ts +0 -90
  168. package/src/epoch/processParticipationFlagUpdates.ts +0 -27
  169. package/src/epoch/processParticipationRecordUpdates.ts +0 -14
  170. package/src/epoch/processPendingAttestations.ts +0 -75
  171. package/src/epoch/processPendingConsolidations.ts +0 -59
  172. package/src/epoch/processPendingDeposits.ts +0 -136
  173. package/src/epoch/processProposerLookahead.ts +0 -39
  174. package/src/epoch/processRandaoMixesReset.ts +0 -18
  175. package/src/epoch/processRegistryUpdates.ts +0 -65
  176. package/src/epoch/processRewardsAndPenalties.ts +0 -58
  177. package/src/epoch/processSlashings.ts +0 -97
  178. package/src/epoch/processSlashingsReset.ts +0 -20
  179. package/src/epoch/processSyncCommitteeUpdates.ts +0 -44
  180. package/src/index.ts +0 -67
  181. package/src/metrics.ts +0 -169
  182. package/src/signatureSets/attesterSlashings.ts +0 -39
  183. package/src/signatureSets/blsToExecutionChange.ts +0 -43
  184. package/src/signatureSets/index.ts +0 -73
  185. package/src/signatureSets/indexedAttestation.ts +0 -51
  186. package/src/signatureSets/proposer.ts +0 -47
  187. package/src/signatureSets/proposerSlashings.ts +0 -41
  188. package/src/signatureSets/randao.ts +0 -31
  189. package/src/signatureSets/voluntaryExits.ts +0 -44
  190. package/src/slot/index.ts +0 -32
  191. package/src/slot/upgradeStateToAltair.ts +0 -149
  192. package/src/slot/upgradeStateToBellatrix.ts +0 -63
  193. package/src/slot/upgradeStateToCapella.ts +0 -71
  194. package/src/slot/upgradeStateToDeneb.ts +0 -40
  195. package/src/slot/upgradeStateToElectra.ts +0 -126
  196. package/src/slot/upgradeStateToFulu.ts +0 -31
  197. package/src/slot/upgradeStateToGloas.ts +0 -29
  198. package/src/stateTransition.ts +0 -305
  199. package/src/types.ts +0 -26
  200. package/src/util/aggregator.ts +0 -33
  201. package/src/util/altair.ts +0 -13
  202. package/src/util/array.ts +0 -53
  203. package/src/util/attestation.ts +0 -36
  204. package/src/util/attesterStatus.ts +0 -83
  205. package/src/util/balance.ts +0 -83
  206. package/src/util/blindedBlock.ts +0 -144
  207. package/src/util/blockRoot.ts +0 -72
  208. package/src/util/calculateCommitteeAssignments.ts +0 -43
  209. package/src/util/capella.ts +0 -8
  210. package/src/util/computeAnchorCheckpoint.ts +0 -38
  211. package/src/util/deposit.ts +0 -22
  212. package/src/util/domain.ts +0 -31
  213. package/src/util/electra.ts +0 -68
  214. package/src/util/epoch.ts +0 -135
  215. package/src/util/epochShuffling.ts +0 -185
  216. package/src/util/execution.ts +0 -177
  217. package/src/util/finality.ts +0 -17
  218. package/src/util/fulu.ts +0 -43
  219. package/src/util/genesis.ts +0 -340
  220. package/src/util/index.ts +0 -29
  221. package/src/util/interop.ts +0 -22
  222. package/src/util/loadState/findModifiedInactivityScores.ts +0 -47
  223. package/src/util/loadState/findModifiedValidators.ts +0 -46
  224. package/src/util/loadState/index.ts +0 -2
  225. package/src/util/loadState/loadState.ts +0 -225
  226. package/src/util/loadState/loadValidator.ts +0 -77
  227. package/src/util/rootCache.ts +0 -37
  228. package/src/util/seed.ts +0 -381
  229. package/src/util/shufflingDecisionRoot.ts +0 -78
  230. package/src/util/signatureSets.ts +0 -65
  231. package/src/util/signingRoot.ts +0 -13
  232. package/src/util/slot.ts +0 -22
  233. package/src/util/sszBytes.ts +0 -52
  234. package/src/util/syncCommittee.ts +0 -69
  235. package/src/util/targetUnslashedBalance.ts +0 -30
  236. package/src/util/validator.ts +0 -105
  237. package/src/util/weakSubjectivity.ts +0 -186
@@ -1,542 +0,0 @@
1
- import {
2
- EPOCHS_PER_SLASHINGS_VECTOR,
3
- FAR_FUTURE_EPOCH,
4
- ForkSeq,
5
- MIN_ACTIVATION_BALANCE,
6
- SLOTS_PER_HISTORICAL_ROOT,
7
- } from "@lodestar/params";
8
- import {Epoch, RootHex, ValidatorIndex} from "@lodestar/types";
9
- import {intDiv, toRootHex} from "@lodestar/utils";
10
- import {processPendingAttestations} from "../epoch/processPendingAttestations.js";
11
- import {
12
- CachedBeaconStateAllForks,
13
- CachedBeaconStateAltair,
14
- CachedBeaconStatePhase0,
15
- hasCompoundingWithdrawalCredential,
16
- } from "../index.js";
17
- import {computeBaseRewardPerIncrement} from "../util/altair.js";
18
- import {
19
- FLAG_CURR_HEAD_ATTESTER,
20
- FLAG_CURR_SOURCE_ATTESTER,
21
- FLAG_CURR_TARGET_ATTESTER,
22
- FLAG_ELIGIBLE_ATTESTER,
23
- FLAG_PREV_HEAD_ATTESTER,
24
- FLAG_PREV_SOURCE_ATTESTER,
25
- FLAG_PREV_TARGET_ATTESTER,
26
- FLAG_UNSLASHED,
27
- hasMarkers,
28
- } from "../util/attesterStatus.js";
29
-
30
- export type EpochTransitionCacheOpts = {
31
- /**
32
- * Assert progressive balances the same to EpochTransitionCache
33
- */
34
- assertCorrectProgressiveBalances?: boolean;
35
- /**
36
- * Do not queue shuffling calculation async. Forces sync JIT calculation in afterProcessEpoch
37
- */
38
- asyncShufflingCalculation?: boolean;
39
- };
40
-
41
- /**
42
- * EpochTransitionCache is the parent object of:
43
- * - Any data-structures not part of the spec'ed BeaconState
44
- * - Necessary to only compute data once
45
- * - Only necessary for epoch processing, can be disposed immediately
46
- * - Not already part of `EpochCache` {@see} {@link EpochCache}
47
- *
48
- * EpochTransitionCache speeds up epoch processing as a whole at the cost of more memory temporarily. This is okay since
49
- * only epoch process is done at once, limiting the max total memory increase. In summary it helps:
50
- * - Only loop state.validators once for all `process_*` fns
51
- * - Only loop status array once
52
- */
53
- export interface EpochTransitionCache {
54
- prevEpoch: Epoch;
55
- currentEpoch: Epoch;
56
- /**
57
- * This is sum of active validators' balance in eth.
58
- */
59
- totalActiveStakeByIncrement: number;
60
- /** For altair */
61
- baseRewardPerIncrement: number;
62
- prevEpochUnslashedStake: {
63
- sourceStakeByIncrement: number;
64
- targetStakeByIncrement: number;
65
- headStakeByIncrement: number;
66
- };
67
- currEpochUnslashedTargetStakeByIncrement: number;
68
-
69
- /**
70
- * Indices which will receive the slashing penalty
71
- * ```
72
- * v.withdrawableEpoch === currentEpoch + EPOCHS_PER_SLASHINGS_VECTOR / 2
73
- * ```
74
- * There's a practical limitation in number of possible validators slashed by epoch, which would share the same
75
- * withdrawableEpoch. Note that after some count exitChurn would advance the withdrawableEpoch.
76
- * ```
77
- * maxSlashedPerSlot = SLOTS_PER_EPOCH * (MAX_PROPOSER_SLASHINGS + MAX_ATTESTER_SLASHINGS * bits)
78
- * ```
79
- * For current mainnet conditions (bits = 128) that's `maxSlashedPerSlot = 8704`.
80
- * For less than 327680 validators, churnLimit = 4 (minimum possible)
81
- * For exitChurn to overtake the slashing delay, there should be
82
- * ```
83
- * churnLimit * (EPOCHS_PER_SLASHINGS_VECTOR / 2 - 1 - MAX_SEED_LOOKAHEAD)
84
- * ```
85
- * For mainnet conditions that's 16364 validators. So the limiting factor is the max operations on the block. Note
86
- * that on average indicesToSlash must contain churnLimit validators (4), but it can spike to a max of 8704 in a
87
- * single epoch if there haven't been exits in a while and there's a massive attester slashing at once of validators
88
- * that happen to be in the same committee, which is very unlikely.
89
- */
90
- indicesToSlash: ValidatorIndex[];
91
-
92
- /**
93
- * Indices of validators that just joined and will be eligible for the active queue.
94
- * ```
95
- * v.activationEligibilityEpoch === FAR_FUTURE_EPOCH && v.effectiveBalance >= MAX_EFFECTIVE_BALANCE
96
- * ```
97
- * All validators in indicesEligibleForActivationQueue get activationEligibilityEpoch set. So it can only include
98
- * validators that have just joined the registry through a valid full deposit(s).
99
- * ```
100
- * max indicesEligibleForActivationQueue = SLOTS_PER_EPOCH * MAX_DEPOSITS
101
- * ```
102
- * For mainnet spec = 512
103
- */
104
- indicesEligibleForActivationQueue: ValidatorIndex[];
105
-
106
- /**
107
- * Indices of validators that may become active once churn and finaly allow.
108
- * ```
109
- * v.activationEpoch === FAR_FUTURE_EPOCH && v.activationEligibilityEpoch <= currentEpoch
110
- * ```
111
- * Many validators could be on indicesEligibleForActivation, but only up to churnLimit will be activated.
112
- * For less than 327680 validators, churnLimit = 4 (minimum possible), so max processed is 4.
113
- */
114
- indicesEligibleForActivation: ValidatorIndex[];
115
-
116
- /**
117
- * Indices of validators that will be ejected due to low balance.
118
- * ```
119
- * status.active && v.exitEpoch === FAR_FUTURE_EPOCH && v.effectiveBalance <= config.EJECTION_BALANCE
120
- * ```
121
- * Potentially the entire validator set could be added to indicesToEject, and all validators in the array will have
122
- * their validator object mutated. Exit queue churn delays exit, but the object is mutated immediately.
123
- */
124
- indicesToEject: ValidatorIndex[];
125
-
126
- /**
127
- * Pre-computes status flags for faster checking of statuses during epoch transition.
128
- * Spec requires some reward or penalty to apply to
129
- * - eligible validators
130
- * - un-slashed validators
131
- * - prev attester flag set
132
- * With a status flag to check this conditions at once we just have to mask with an OR of the conditions.
133
- * This is only for phase0 only.
134
- */
135
- proposerIndices: number[];
136
-
137
- /**
138
- * This is for phase0 only.
139
- */
140
- inclusionDelays: number[];
141
-
142
- flags: number[];
143
-
144
- isCompoundingValidatorArr: boolean[];
145
-
146
- /**
147
- * balances array will be populated by processRewardsAndPenalties() and consumed by processEffectiveBalanceUpdates().
148
- * processRewardsAndPenalties() already has a regular Javascript array of balances.
149
- * Then processEffectiveBalanceUpdates() needs to iterate all balances so it can re-use the array pre-computed previously.
150
- */
151
- balances?: number[];
152
-
153
- /**
154
- * Active validator indices for currentEpoch + 2.
155
- * This is only used in `afterProcessEpoch` to compute epoch shuffling, it's not efficient to calculate it at that time
156
- * since it requires 1 loop through validator.
157
- * | epoch process fn | nextEpochTotalActiveBalance action |
158
- * | -------------------------------- | ---------------------------------- |
159
- * | beforeProcessEpoch | calculate during the validator loop|
160
- * | afterEpochTransitionCache | read it |
161
- */
162
- nextShufflingActiveIndices: Uint32Array;
163
-
164
- /**
165
- * Shuffling decision root that gets set on the EpochCache in afterProcessEpoch
166
- */
167
- nextShufflingDecisionRoot: RootHex;
168
-
169
- /**
170
- * Altair specific, this is total active balances for the next epoch.
171
- * This is only used in `afterProcessEpoch` to compute base reward and sync participant reward.
172
- * It's not efficient to calculate it at that time since it requires looping through all active validators,
173
- * so we should calculate it during `processEffectiveBalancesUpdate` which gives us updated effective balance.
174
- * | epoch process fn | nextEpochTotalActiveBalance action |
175
- * | -------------------------------- | ---------------------------------- |
176
- * | beforeProcessEpoch | initialize as BigInt(0) |
177
- * | processEffectiveBalancesUpdate | calculate during the loop |
178
- * | afterEpochTransitionCache | read it |
179
- */
180
- nextEpochTotalActiveBalanceByIncrement: number;
181
-
182
- /**
183
- * Compute the shuffling sync or async. Defaults to synchronous. Need to pass `true` with the
184
- * `EpochTransitionCacheOpts`
185
- */
186
- asyncShufflingCalculation: boolean;
187
-
188
- /**
189
- * Track by validator index if it's active in the prev epoch.
190
- * Used in metrics
191
- */
192
- isActivePrevEpoch: boolean[];
193
-
194
- /**
195
- * Track by validator index if it's active in the current epoch.
196
- * Used in metrics
197
- */
198
- isActiveCurrEpoch: boolean[];
199
-
200
- /**
201
- * Track by validator index if it's active in the next epoch.
202
- * Used in `processEffectiveBalanceUpdates` to save one loop over validators after epoch process.
203
- */
204
- isActiveNextEpoch: boolean[];
205
- }
206
-
207
- // reuse arrays to avoid memory reallocation and gc
208
- // WARNING: this is not async safe
209
- /** WARNING: reused, never gc'd */
210
- const isActivePrevEpoch = new Array<boolean>();
211
- /** WARNING: reused, never gc'd */
212
- const isActiveCurrEpoch = new Array<boolean>();
213
- /** WARNING: reused, never gc'd */
214
- const isActiveNextEpoch = new Array<boolean>();
215
- /** WARNING: reused, never gc'd, from altair this is empty array */
216
- const proposerIndices = new Array<number>();
217
- /** WARNING: reused, never gc'd, from altair this is empty array */
218
- const inclusionDelays = new Array<number>();
219
- /** WARNING: reused, never gc'd */
220
- const flags = new Array<number>();
221
- /** WARNING: reused, never gc'd */
222
- const nextEpochShufflingActiveValidatorIndices = new Array<number>();
223
- /** WARNING: reused, never gc'd */
224
- const isCompoundingValidatorArr = new Array<boolean>();
225
-
226
- const previousEpochParticipation = new Array<number>();
227
- const currentEpochParticipation = new Array<number>();
228
-
229
- export function beforeProcessEpoch(
230
- state: CachedBeaconStateAllForks,
231
- opts?: EpochTransitionCacheOpts
232
- ): EpochTransitionCache {
233
- const {config, epochCtx} = state;
234
- const forkSeq = config.getForkSeq(state.slot);
235
- const currentEpoch = epochCtx.epoch;
236
- const prevEpoch = epochCtx.previousShuffling.epoch;
237
- const nextEpoch = currentEpoch + 1;
238
- // active validator indices for nextShuffling is ready, we want to precalculate for the one after that
239
- const nextEpoch2 = currentEpoch + 2;
240
-
241
- const slashingsEpoch = currentEpoch + intDiv(EPOCHS_PER_SLASHINGS_VECTOR, 2);
242
-
243
- const indicesToSlash: ValidatorIndex[] = [];
244
- const indicesEligibleForActivationQueue: ValidatorIndex[] = [];
245
- const indicesEligibleForActivation: {validatorIndex: ValidatorIndex; activationEligibilityEpoch: Epoch}[] = [];
246
- const indicesToEject: ValidatorIndex[] = [];
247
-
248
- let totalActiveStakeByIncrement = 0;
249
- const validatorCount = state.validators.length;
250
- nextEpochShufflingActiveValidatorIndices.length = validatorCount;
251
- let nextEpochShufflingActiveIndicesLength = 0;
252
- // pre-fill with true (most validators are active)
253
- isActivePrevEpoch.length = validatorCount;
254
- isActiveCurrEpoch.length = validatorCount;
255
- isActiveNextEpoch.length = validatorCount;
256
- isActivePrevEpoch.fill(true);
257
- isActiveCurrEpoch.fill(true);
258
- isActiveNextEpoch.fill(true);
259
-
260
- // During the epoch transition, additional data is precomputed to avoid traversing any state a second
261
- // time. Attestations are a big part of this, and each validator has a "status" to represent its
262
- // precomputed participation.
263
- // - proposerIndex: number; // -1 when not included by any proposer, for phase0 only so it's declared inside phase0 block below
264
- // - inclusionDelay: number;// for phase0 only so it's declared inside phase0 block below
265
- // - flags: number; // bitfield of AttesterFlags
266
- flags.length = validatorCount;
267
- // flags.fill(0);
268
- // flags will be zero'd out below
269
- // In the first loop, set slashed+eligibility
270
- // In the second loop, set participation flags
271
- // TODO: optimize by combining the two loops
272
- // likely will require splitting into phase0 and post-phase0 versions
273
-
274
- if (forkSeq >= ForkSeq.electra) {
275
- isCompoundingValidatorArr.length = validatorCount;
276
- }
277
-
278
- // Clone before being mutated in processEffectiveBalanceUpdates
279
- epochCtx.beforeEpochTransition();
280
-
281
- const effectiveBalancesByIncrements = epochCtx.effectiveBalanceIncrements;
282
-
283
- state.validators.forEachValue((validator, i) => {
284
- let flag = 0;
285
-
286
- if (validator.slashed) {
287
- if (slashingsEpoch === validator.withdrawableEpoch) {
288
- indicesToSlash.push(i);
289
- }
290
- } else {
291
- flag |= FLAG_UNSLASHED;
292
- }
293
-
294
- const {activationEpoch, exitEpoch} = validator;
295
- const isActivePrev = activationEpoch <= prevEpoch && prevEpoch < exitEpoch;
296
- const isActiveCurr = activationEpoch <= currentEpoch && currentEpoch < exitEpoch;
297
- const isActiveNext = activationEpoch <= nextEpoch && nextEpoch < exitEpoch;
298
- const isActiveNext2 = activationEpoch <= nextEpoch2 && nextEpoch2 < exitEpoch;
299
-
300
- if (!isActivePrev) {
301
- isActivePrevEpoch[i] = false;
302
- }
303
-
304
- // Both active validators and slashed-but-not-yet-withdrawn validators are eligible to receive penalties.
305
- // This is done to prevent self-slashing from being a way to escape inactivity leaks.
306
- // TODO: Consider using an array of `eligibleValidatorIndices: number[]`
307
- if (isActivePrev || (validator.slashed && prevEpoch + 1 < validator.withdrawableEpoch)) {
308
- flag |= FLAG_ELIGIBLE_ATTESTER;
309
- }
310
-
311
- flags[i] = flag;
312
-
313
- if (forkSeq >= ForkSeq.electra) {
314
- isCompoundingValidatorArr[i] = hasCompoundingWithdrawalCredential(validator.withdrawalCredentials);
315
- }
316
-
317
- if (isActiveCurr) {
318
- totalActiveStakeByIncrement += effectiveBalancesByIncrements[i];
319
- } else {
320
- isActiveCurrEpoch[i] = false;
321
- }
322
-
323
- // To optimize process_registry_updates():
324
- // ```python
325
- // def is_eligible_for_activation_queue(validator: Validator) -> bool:
326
- // return (
327
- // validator.activation_eligibility_epoch == FAR_FUTURE_EPOCH
328
- // and validator.effective_balance >= MAX_EFFECTIVE_BALANCE # [Modified in Electra]
329
- // )
330
- // ```
331
- if (
332
- validator.activationEligibilityEpoch === FAR_FUTURE_EPOCH &&
333
- validator.effectiveBalance >= MIN_ACTIVATION_BALANCE
334
- ) {
335
- indicesEligibleForActivationQueue.push(i);
336
- }
337
-
338
- // To optimize process_registry_updates():
339
- // ```python
340
- // def is_eligible_for_activation(state: BeaconState, validator: Validator) -> bool:
341
- // return (
342
- // validator.activation_eligibility_epoch <= state.finalized_checkpoint.epoch # Placement in queue is finalized
343
- // and validator.activation_epoch == FAR_FUTURE_EPOCH # Has not yet been activated
344
- // )
345
- // ```
346
- // Here we have to check if `activationEligibilityEpoch <= currentEpoch` instead of finalized checkpoint, because the finalized
347
- // checkpoint may change during epoch processing at processJustificationAndFinalization(), which is called before processRegistryUpdates().
348
- // Then in processRegistryUpdates() we will check `activationEligibilityEpoch <= finalityEpoch`. This is to keep the array small.
349
- //
350
- // Use `else` since indicesEligibleForActivationQueue + indicesEligibleForActivation are mutually exclusive
351
- else if (validator.activationEpoch === FAR_FUTURE_EPOCH && validator.activationEligibilityEpoch <= currentEpoch) {
352
- indicesEligibleForActivation.push({
353
- validatorIndex: i,
354
- activationEligibilityEpoch: validator.activationEligibilityEpoch,
355
- });
356
- }
357
-
358
- // To optimize process_registry_updates():
359
- // ```python
360
- // if is_active_validator(validator, get_current_epoch(state)) and validator.effective_balance <= EJECTION_BALANCE:
361
- // ```
362
- // Adding extra condition `exitEpoch === FAR_FUTURE_EPOCH` to keep the array as small as possible. initiateValidatorExit() will ignore them anyway
363
- //
364
- // Use `else` since indicesEligibleForActivationQueue + indicesEligibleForActivation + indicesToEject are mutually exclusive
365
- else if (
366
- isActiveCurr &&
367
- validator.exitEpoch === FAR_FUTURE_EPOCH &&
368
- validator.effectiveBalance <= config.EJECTION_BALANCE
369
- ) {
370
- indicesToEject.push(i);
371
- }
372
-
373
- if (!isActiveNext) {
374
- isActiveNextEpoch[i] = false;
375
- }
376
-
377
- if (isActiveNext2) {
378
- nextEpochShufflingActiveValidatorIndices[nextEpochShufflingActiveIndicesLength++] = i;
379
- }
380
- });
381
-
382
- // Trigger async build of shuffling for epoch after next (nextShuffling post epoch transition)
383
- const epochAfterNext = state.epochCtx.nextEpoch + 1;
384
- // cannot call calculateShufflingDecisionRoot here because spec prevent getting current slot
385
- // as a decision block. we are part way through the transition though and this was added in
386
- // process slot beforeProcessEpoch happens so it available and valid
387
- const nextShufflingDecisionRoot = toRootHex(state.blockRoots.get(state.slot % SLOTS_PER_HISTORICAL_ROOT));
388
- const nextShufflingActiveIndices = new Uint32Array(nextEpochShufflingActiveIndicesLength);
389
- if (nextEpochShufflingActiveIndicesLength > nextEpochShufflingActiveValidatorIndices.length) {
390
- throw new Error(
391
- `Invalid activeValidatorCount: ${nextEpochShufflingActiveIndicesLength} > ${nextEpochShufflingActiveValidatorIndices.length}`
392
- );
393
- }
394
- // only the first `activeValidatorCount` elements are copied to `activeIndices`
395
- for (let i = 0; i < nextEpochShufflingActiveIndicesLength; i++) {
396
- nextShufflingActiveIndices[i] = nextEpochShufflingActiveValidatorIndices[i];
397
- }
398
-
399
- const asyncShufflingCalculation = opts?.asyncShufflingCalculation ?? false;
400
- if (asyncShufflingCalculation) {
401
- state.epochCtx.shufflingCache?.build(epochAfterNext, nextShufflingDecisionRoot, state, nextShufflingActiveIndices);
402
- }
403
-
404
- if (totalActiveStakeByIncrement < 1) {
405
- totalActiveStakeByIncrement = 1;
406
- } else if (totalActiveStakeByIncrement >= Number.MAX_SAFE_INTEGER) {
407
- throw Error("totalActiveStakeByIncrement >= Number.MAX_SAFE_INTEGER. MAX_EFFECTIVE_BALANCE is too low.");
408
- }
409
-
410
- // SPEC: function getBaseRewardPerIncrement()
411
- const baseRewardPerIncrement = computeBaseRewardPerIncrement(totalActiveStakeByIncrement);
412
-
413
- // To optimize process_registry_updates():
414
- // order by sequence of activationEligibilityEpoch setting and then index
415
- indicesEligibleForActivation.sort(
416
- (a, b) => a.activationEligibilityEpoch - b.activationEligibilityEpoch || a.validatorIndex - b.validatorIndex
417
- );
418
-
419
- if (forkSeq === ForkSeq.phase0) {
420
- proposerIndices.length = validatorCount;
421
- proposerIndices.fill(-1);
422
- inclusionDelays.length = validatorCount;
423
- inclusionDelays.fill(0);
424
- processPendingAttestations(
425
- state as CachedBeaconStatePhase0,
426
- proposerIndices,
427
- inclusionDelays,
428
- flags,
429
- (state as CachedBeaconStatePhase0).previousEpochAttestations.getAllReadonly(),
430
- prevEpoch,
431
- FLAG_PREV_SOURCE_ATTESTER,
432
- FLAG_PREV_TARGET_ATTESTER,
433
- FLAG_PREV_HEAD_ATTESTER
434
- );
435
- processPendingAttestations(
436
- state as CachedBeaconStatePhase0,
437
- proposerIndices,
438
- inclusionDelays,
439
- flags,
440
- (state as CachedBeaconStatePhase0).currentEpochAttestations.getAllReadonly(),
441
- currentEpoch,
442
- FLAG_CURR_SOURCE_ATTESTER,
443
- FLAG_CURR_TARGET_ATTESTER,
444
- FLAG_CURR_HEAD_ATTESTER
445
- );
446
- } else {
447
- previousEpochParticipation.length = (state as CachedBeaconStateAltair).previousEpochParticipation.length;
448
- (state as CachedBeaconStateAltair).previousEpochParticipation.getAll(previousEpochParticipation);
449
- currentEpochParticipation.length = (state as CachedBeaconStateAltair).currentEpochParticipation.length;
450
- (state as CachedBeaconStateAltair).currentEpochParticipation.getAll(currentEpochParticipation);
451
- for (let i = 0; i < validatorCount; i++) {
452
- flags[i] |=
453
- // checking active status first is required to pass random spec tests in altair
454
- // in practice, inactive validators will have 0 participation
455
- // FLAG_PREV are indexes [0,1,2]
456
- (isActivePrevEpoch[i] ? previousEpochParticipation[i] : 0) |
457
- // FLAG_CURR are indexes [3,4,5], so shift by 3
458
- (isActiveCurrEpoch[i] ? currentEpochParticipation[i] << 3 : 0);
459
- }
460
- }
461
-
462
- let prevSourceUnslStake = 0;
463
- let prevTargetUnslStake = 0;
464
- let prevHeadUnslStake = 0;
465
-
466
- let currTargetUnslStake = 0;
467
-
468
- const FLAG_PREV_SOURCE_ATTESTER_UNSLASHED = FLAG_PREV_SOURCE_ATTESTER | FLAG_UNSLASHED;
469
- const FLAG_PREV_TARGET_ATTESTER_UNSLASHED = FLAG_PREV_TARGET_ATTESTER | FLAG_UNSLASHED;
470
- const FLAG_PREV_HEAD_ATTESTER_UNSLASHED = FLAG_PREV_HEAD_ATTESTER | FLAG_UNSLASHED;
471
- const FLAG_CURR_TARGET_UNSLASHED = FLAG_CURR_TARGET_ATTESTER | FLAG_UNSLASHED;
472
-
473
- for (let i = 0; i < validatorCount; i++) {
474
- const effectiveBalanceByIncrement = effectiveBalancesByIncrements[i];
475
- const flag = flags[i];
476
- if (hasMarkers(flag, FLAG_PREV_SOURCE_ATTESTER_UNSLASHED)) {
477
- prevSourceUnslStake += effectiveBalanceByIncrement;
478
- }
479
- if (hasMarkers(flag, FLAG_PREV_TARGET_ATTESTER_UNSLASHED)) {
480
- prevTargetUnslStake += effectiveBalanceByIncrement;
481
- }
482
- if (hasMarkers(flag, FLAG_PREV_HEAD_ATTESTER_UNSLASHED)) {
483
- prevHeadUnslStake += effectiveBalanceByIncrement;
484
- }
485
- if (hasMarkers(flag, FLAG_CURR_TARGET_UNSLASHED)) {
486
- currTargetUnslStake += effectiveBalanceByIncrement;
487
- }
488
- }
489
-
490
- if (opts?.assertCorrectProgressiveBalances && forkSeq >= ForkSeq.altair) {
491
- // TODO: describe issue. Compute progressive target balances
492
- if (epochCtx.currentTargetUnslashedBalanceIncrements !== currTargetUnslStake) {
493
- throw Error(
494
- `currentTargetUnslashedBalanceIncrements is wrong, expect ${currTargetUnslStake} got ${epochCtx.currentTargetUnslashedBalanceIncrements} epoch ${epochCtx.epoch}`
495
- );
496
- }
497
- if (epochCtx.previousTargetUnslashedBalanceIncrements !== prevTargetUnslStake) {
498
- throw Error(
499
- `previousTargetUnslashedBalanceIncrements is wrong, expect ${prevTargetUnslStake} got ${epochCtx.previousTargetUnslashedBalanceIncrements} epoch ${epochCtx.epoch}`
500
- );
501
- }
502
- }
503
-
504
- // As per spec of `get_total_balance`:
505
- // EFFECTIVE_BALANCE_INCREMENT Gwei minimum to avoid divisions by zero.
506
- // Math safe up to ~10B ETH, afterwhich this overflows uint64.
507
- if (prevSourceUnslStake < 1) prevSourceUnslStake = 1;
508
- if (prevTargetUnslStake < 1) prevTargetUnslStake = 1;
509
- if (prevHeadUnslStake < 1) prevHeadUnslStake = 1;
510
- if (currTargetUnslStake < 1) currTargetUnslStake = 1;
511
-
512
- return {
513
- prevEpoch,
514
- currentEpoch,
515
- totalActiveStakeByIncrement,
516
- baseRewardPerIncrement,
517
- prevEpochUnslashedStake: {
518
- sourceStakeByIncrement: prevSourceUnslStake,
519
- targetStakeByIncrement: prevTargetUnslStake,
520
- headStakeByIncrement: prevHeadUnslStake,
521
- },
522
- currEpochUnslashedTargetStakeByIncrement: currTargetUnslStake,
523
- indicesToSlash,
524
- indicesEligibleForActivationQueue,
525
- indicesEligibleForActivation: indicesEligibleForActivation.map(({validatorIndex}) => validatorIndex),
526
- indicesToEject,
527
- nextShufflingDecisionRoot,
528
- nextShufflingActiveIndices,
529
- asyncShufflingCalculation,
530
- // to be updated in processEffectiveBalanceUpdates
531
- nextEpochTotalActiveBalanceByIncrement: 0,
532
- isActivePrevEpoch,
533
- isActiveCurrEpoch,
534
- isActiveNextEpoch,
535
- proposerIndices,
536
- inclusionDelays,
537
- flags,
538
- isCompoundingValidatorArr,
539
- // Will be assigned in processRewardsAndPenalties()
540
- balances: undefined,
541
- };
542
- }
@@ -1,33 +0,0 @@
1
- import {PublicKey} from "@chainsafe/blst";
2
- import {PubkeyIndexMap} from "@chainsafe/pubkey-index-map";
3
- import {phase0} from "@lodestar/types";
4
-
5
- export type Index2PubkeyCache = PublicKey[];
6
-
7
- /**
8
- * Checks the pubkey indices against a state and adds missing pubkeys
9
- *
10
- * Mutates `pubkey2index` and `index2pubkey`
11
- *
12
- * If pubkey caches are empty: SLOW CODE - 🐢
13
- */
14
- export function syncPubkeys(
15
- validators: phase0.Validator[],
16
- pubkey2index: PubkeyIndexMap,
17
- index2pubkey: Index2PubkeyCache
18
- ): void {
19
- if (pubkey2index.size !== index2pubkey.length) {
20
- throw new Error(`Pubkey indices have fallen out of sync: ${pubkey2index.size} != ${index2pubkey.length}`);
21
- }
22
-
23
- const newCount = validators.length;
24
- index2pubkey.length = newCount;
25
- for (let i = pubkey2index.size; i < newCount; i++) {
26
- const pubkey = validators[i].pubkey;
27
- pubkey2index.set(pubkey, i);
28
- // Pubkeys must be checked for group + inf. This must be done only once when the validator deposit is processed.
29
- // Afterwards any public key is the state consider validated.
30
- // > Do not do any validation here
31
- index2pubkey[i] = PublicKey.fromBytes(pubkey); // Optimize for aggregation
32
- }
33
- }
@@ -1,19 +0,0 @@
1
- /**
2
- * A simple data structure to store rewards payable to block proposer in the memory.
3
- * Rewards are updated throughout the state transition
4
- * Should only hold info for one state transition
5
- * All values are in Gwei
6
- */
7
- export type RewardCache = {
8
- attestations: number;
9
- syncAggregate: number;
10
- slashing: number; // Sum of attester and proposer slashing reward
11
- };
12
-
13
- export function createEmptyRewardCache(): RewardCache {
14
- return {
15
- attestations: 0,
16
- syncAggregate: 0,
17
- slashing: 0,
18
- };
19
- }