@lodestar/state-transition 1.35.0-dev.8ea34e52ba → 1.35.0-dev.901d719660

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 (283) hide show
  1. package/lib/block/externalData.d.ts.map +1 -0
  2. package/lib/block/index.d.ts +2 -2
  3. package/lib/block/index.d.ts.map +1 -0
  4. package/lib/block/index.js +2 -2
  5. package/lib/block/index.js.map +1 -1
  6. package/lib/block/initiateValidatorExit.d.ts.map +1 -0
  7. package/lib/block/isValidIndexedAttestation.d.ts.map +1 -0
  8. package/lib/block/processAttestationPhase0.d.ts.map +1 -0
  9. package/lib/block/processAttestationPhase0.js +1 -2
  10. package/lib/block/processAttestationPhase0.js.map +1 -1
  11. package/lib/block/processAttestations.d.ts.map +1 -0
  12. package/lib/block/processAttestationsAltair.d.ts +1 -1
  13. package/lib/block/processAttestationsAltair.d.ts.map +1 -0
  14. package/lib/block/processAttestationsAltair.js +1 -1
  15. package/lib/block/processAttestationsAltair.js.map +1 -1
  16. package/lib/block/processAttesterSlashing.d.ts.map +1 -0
  17. package/lib/block/processAttesterSlashing.js.map +1 -1
  18. package/lib/block/processBlobKzgCommitments.d.ts.map +1 -0
  19. package/lib/block/processBlockHeader.d.ts.map +1 -0
  20. package/lib/block/processBlsToExecutionChange.d.ts.map +1 -0
  21. package/lib/block/processBlsToExecutionChange.js.map +1 -1
  22. package/lib/block/processConsolidationRequest.d.ts.map +1 -0
  23. package/lib/block/processConsolidationRequest.js.map +1 -1
  24. package/lib/block/processDeposit.d.ts +2 -2
  25. package/lib/block/processDeposit.d.ts.map +1 -0
  26. package/lib/block/processDeposit.js +1 -1
  27. package/lib/block/processDeposit.js.map +1 -1
  28. package/lib/block/processDepositRequest.d.ts.map +1 -0
  29. package/lib/block/processDepositRequest.js.map +1 -1
  30. package/lib/block/processEth1Data.d.ts.map +1 -0
  31. package/lib/block/processExecutionPayload.d.ts.map +1 -0
  32. package/lib/block/processExecutionPayload.js +3 -3
  33. package/lib/block/processExecutionPayload.js.map +1 -1
  34. package/lib/block/processOperations.d.ts.map +1 -0
  35. package/lib/block/processOperations.js.map +1 -1
  36. package/lib/block/processProposerSlashing.d.ts.map +1 -0
  37. package/lib/block/processRandao.d.ts.map +1 -0
  38. package/lib/block/processSyncCommittee.d.ts.map +1 -0
  39. package/lib/block/processSyncCommittee.js +1 -2
  40. package/lib/block/processSyncCommittee.js.map +1 -1
  41. package/lib/block/processVoluntaryExit.d.ts.map +1 -0
  42. package/lib/block/processWithdrawalRequest.d.ts.map +1 -0
  43. package/lib/block/processWithdrawalRequest.js.map +1 -1
  44. package/lib/block/processWithdrawals.d.ts.map +1 -0
  45. package/lib/block/processWithdrawals.js.map +1 -1
  46. package/lib/block/slashValidator.d.ts.map +1 -0
  47. package/lib/block/slashValidator.js.map +1 -1
  48. package/lib/block/types.d.ts.map +1 -0
  49. package/lib/cache/effectiveBalanceIncrements.d.ts.map +1 -0
  50. package/lib/cache/epochCache.d.ts.map +1 -0
  51. package/lib/cache/epochTransitionCache.d.ts.map +1 -0
  52. package/lib/cache/epochTransitionCache.js.map +1 -1
  53. package/lib/cache/pubkeyCache.d.ts.map +1 -0
  54. package/lib/cache/rewardCache.d.ts.map +1 -0
  55. package/lib/cache/stateCache.d.ts.map +1 -0
  56. package/lib/cache/syncCommitteeCache.d.ts.map +1 -0
  57. package/lib/cache/types.d.ts +2 -2
  58. package/lib/cache/types.d.ts.map +1 -0
  59. package/lib/constants/constants.d.ts.map +1 -0
  60. package/lib/constants/index.d.ts.map +1 -0
  61. package/lib/epoch/computeUnrealizedCheckpoints.d.ts.map +1 -0
  62. package/lib/epoch/getAttestationDeltas.d.ts.map +1 -0
  63. package/lib/epoch/getRewardsAndPenalties.d.ts.map +1 -0
  64. package/lib/epoch/index.d.ts.map +1 -0
  65. package/lib/epoch/index.js.map +1 -1
  66. package/lib/epoch/processEffectiveBalanceUpdates.d.ts.map +1 -0
  67. package/lib/epoch/processEth1DataReset.d.ts.map +1 -0
  68. package/lib/epoch/processHistoricalRootsUpdate.d.ts.map +1 -0
  69. package/lib/epoch/processHistoricalSummariesUpdate.d.ts.map +1 -0
  70. package/lib/epoch/processInactivityUpdates.d.ts.map +1 -0
  71. package/lib/epoch/processJustificationAndFinalization.d.ts.map +1 -0
  72. package/lib/epoch/processParticipationFlagUpdates.d.ts.map +1 -0
  73. package/lib/epoch/processParticipationRecordUpdates.d.ts.map +1 -0
  74. package/lib/epoch/processPendingAttestations.d.ts.map +1 -0
  75. package/lib/epoch/processPendingConsolidations.d.ts.map +1 -0
  76. package/lib/epoch/processPendingDeposits.d.ts.map +1 -0
  77. package/lib/epoch/processProposerLookahead.d.ts.map +1 -0
  78. package/lib/epoch/processRandaoMixesReset.d.ts.map +1 -0
  79. package/lib/epoch/processRegistryUpdates.d.ts.map +1 -0
  80. package/lib/epoch/processRewardsAndPenalties.d.ts.map +1 -0
  81. package/lib/epoch/processSlashings.d.ts.map +1 -0
  82. package/lib/epoch/processSlashings.js.map +1 -1
  83. package/lib/epoch/processSlashingsReset.d.ts.map +1 -0
  84. package/lib/epoch/processSyncCommitteeUpdates.d.ts.map +1 -0
  85. package/lib/index.d.ts +17 -17
  86. package/lib/index.d.ts.map +1 -0
  87. package/lib/index.js +16 -16
  88. package/lib/index.js.map +1 -1
  89. package/lib/metrics.d.ts.map +1 -0
  90. package/lib/signatureSets/attesterSlashings.d.ts.map +1 -0
  91. package/lib/signatureSets/blsToExecutionChange.d.ts.map +1 -0
  92. package/lib/signatureSets/blsToExecutionChange.js.map +1 -1
  93. package/lib/signatureSets/index.d.ts +1 -1
  94. package/lib/signatureSets/index.d.ts.map +1 -0
  95. package/lib/signatureSets/index.js +1 -1
  96. package/lib/signatureSets/index.js.map +1 -1
  97. package/lib/signatureSets/indexedAttestation.d.ts.map +1 -0
  98. package/lib/signatureSets/proposer.d.ts.map +1 -0
  99. package/lib/signatureSets/proposerSlashings.d.ts.map +1 -0
  100. package/lib/signatureSets/randao.d.ts.map +1 -0
  101. package/lib/signatureSets/voluntaryExits.d.ts.map +1 -0
  102. package/lib/slot/index.d.ts.map +1 -0
  103. package/lib/slot/upgradeStateToAltair.d.ts.map +1 -0
  104. package/lib/slot/upgradeStateToBellatrix.d.ts.map +1 -0
  105. package/lib/slot/upgradeStateToCapella.d.ts.map +1 -0
  106. package/lib/slot/upgradeStateToDeneb.d.ts +1 -2
  107. package/lib/slot/upgradeStateToDeneb.d.ts.map +1 -0
  108. package/lib/slot/upgradeStateToDeneb.js.map +1 -1
  109. package/lib/slot/upgradeStateToElectra.d.ts.map +1 -0
  110. package/lib/slot/upgradeStateToFulu.d.ts.map +1 -0
  111. package/lib/slot/upgradeStateToGloas.d.ts.map +1 -0
  112. package/lib/stateTransition.d.ts.map +1 -0
  113. package/lib/types.d.ts +2 -2
  114. package/lib/types.d.ts.map +1 -0
  115. package/lib/util/aggregator.d.ts.map +1 -0
  116. package/lib/util/altair.d.ts.map +1 -0
  117. package/lib/util/array.d.ts.map +1 -0
  118. package/lib/util/attestation.d.ts.map +1 -0
  119. package/lib/util/attesterStatus.d.ts.map +1 -0
  120. package/lib/util/balance.d.ts.map +1 -0
  121. package/lib/util/blindedBlock.d.ts.map +1 -0
  122. package/lib/util/blindedBlock.js.map +1 -1
  123. package/lib/util/blockRoot.d.ts.map +1 -0
  124. package/lib/util/calculateCommitteeAssignments.d.ts.map +1 -0
  125. package/lib/util/capella.d.ts.map +1 -0
  126. package/lib/util/computeAnchorCheckpoint.d.ts.map +1 -0
  127. package/lib/util/deposit.d.ts.map +1 -0
  128. package/lib/util/domain.d.ts.map +1 -0
  129. package/lib/util/electra.d.ts.map +1 -0
  130. package/lib/util/epoch.d.ts.map +1 -0
  131. package/lib/util/epochShuffling.d.ts.map +1 -0
  132. package/lib/util/execution.d.ts.map +1 -0
  133. package/lib/util/execution.js.map +1 -1
  134. package/lib/util/finality.d.ts.map +1 -0
  135. package/lib/util/fulu.d.ts.map +1 -0
  136. package/lib/util/genesis.d.ts.map +1 -0
  137. package/lib/util/genesis.js +0 -3
  138. package/lib/util/genesis.js.map +1 -1
  139. package/lib/util/index.d.ts +5 -5
  140. package/lib/util/index.d.ts.map +1 -0
  141. package/lib/util/index.js +5 -5
  142. package/lib/util/index.js.map +1 -1
  143. package/lib/util/interop.d.ts.map +1 -0
  144. package/lib/util/interop.js +1 -1
  145. package/lib/util/interop.js.map +1 -1
  146. package/lib/util/loadState/findModifiedInactivityScores.d.ts.map +1 -0
  147. package/lib/util/loadState/findModifiedValidators.d.ts.map +1 -0
  148. package/lib/util/loadState/index.d.ts.map +1 -0
  149. package/lib/util/loadState/loadState.d.ts.map +1 -0
  150. package/lib/util/loadState/loadValidator.d.ts.map +1 -0
  151. package/lib/util/rootCache.d.ts.map +1 -0
  152. package/lib/util/seed.d.ts.map +1 -0
  153. package/lib/util/seed.js +1 -2
  154. package/lib/util/seed.js.map +1 -1
  155. package/lib/util/shufflingDecisionRoot.d.ts.map +1 -0
  156. package/lib/util/signatureSets.d.ts.map +1 -0
  157. package/lib/util/signingRoot.d.ts.map +1 -0
  158. package/lib/util/slot.d.ts +0 -1
  159. package/lib/util/slot.d.ts.map +1 -0
  160. package/lib/util/slot.js +3 -7
  161. package/lib/util/slot.js.map +1 -1
  162. package/lib/util/sszBytes.d.ts.map +1 -0
  163. package/lib/util/syncCommittee.d.ts.map +1 -0
  164. package/lib/util/targetUnslashedBalance.d.ts.map +1 -0
  165. package/lib/util/validator.d.ts.map +1 -0
  166. package/lib/util/weakSubjectivity.d.ts.map +1 -0
  167. package/lib/util/weakSubjectivity.js.map +1 -1
  168. package/package.json +13 -11
  169. package/src/block/externalData.ts +26 -0
  170. package/src/block/index.ts +81 -0
  171. package/src/block/initiateValidatorExit.ts +62 -0
  172. package/src/block/isValidIndexedAttestation.ts +70 -0
  173. package/src/block/processAttestationPhase0.ts +158 -0
  174. package/src/block/processAttestations.ts +25 -0
  175. package/src/block/processAttestationsAltair.ts +184 -0
  176. package/src/block/processAttesterSlashing.ts +59 -0
  177. package/src/block/processBlobKzgCommitments.ts +21 -0
  178. package/src/block/processBlockHeader.ts +54 -0
  179. package/src/block/processBlsToExecutionChange.ts +78 -0
  180. package/src/block/processConsolidationRequest.ts +147 -0
  181. package/src/block/processDeposit.ts +166 -0
  182. package/src/block/processDepositRequest.ts +19 -0
  183. package/src/block/processEth1Data.ts +86 -0
  184. package/src/block/processExecutionPayload.ts +84 -0
  185. package/src/block/processOperations.ts +83 -0
  186. package/src/block/processProposerSlashing.ts +66 -0
  187. package/src/block/processRandao.ts +27 -0
  188. package/src/block/processSyncCommittee.ts +117 -0
  189. package/src/block/processVoluntaryExit.ts +55 -0
  190. package/src/block/processWithdrawalRequest.ts +98 -0
  191. package/src/block/processWithdrawals.ts +207 -0
  192. package/src/block/slashValidator.ts +98 -0
  193. package/src/block/types.ts +9 -0
  194. package/src/cache/effectiveBalanceIncrements.ts +39 -0
  195. package/src/cache/epochCache.ts +1213 -0
  196. package/src/cache/epochTransitionCache.ts +542 -0
  197. package/src/cache/pubkeyCache.ts +33 -0
  198. package/src/cache/rewardCache.ts +19 -0
  199. package/src/cache/stateCache.ts +268 -0
  200. package/src/cache/syncCommitteeCache.ts +96 -0
  201. package/src/cache/types.ts +18 -0
  202. package/src/constants/constants.ts +12 -0
  203. package/src/constants/index.ts +1 -0
  204. package/src/epoch/computeUnrealizedCheckpoints.ts +55 -0
  205. package/src/epoch/getAttestationDeltas.ts +169 -0
  206. package/src/epoch/getRewardsAndPenalties.ts +137 -0
  207. package/src/epoch/index.ts +202 -0
  208. package/src/epoch/processEffectiveBalanceUpdates.ts +111 -0
  209. package/src/epoch/processEth1DataReset.ts +17 -0
  210. package/src/epoch/processHistoricalRootsUpdate.ts +25 -0
  211. package/src/epoch/processHistoricalSummariesUpdate.ts +23 -0
  212. package/src/epoch/processInactivityUpdates.ts +60 -0
  213. package/src/epoch/processJustificationAndFinalization.ts +90 -0
  214. package/src/epoch/processParticipationFlagUpdates.ts +27 -0
  215. package/src/epoch/processParticipationRecordUpdates.ts +14 -0
  216. package/src/epoch/processPendingAttestations.ts +75 -0
  217. package/src/epoch/processPendingConsolidations.ts +59 -0
  218. package/src/epoch/processPendingDeposits.ts +136 -0
  219. package/src/epoch/processProposerLookahead.ts +39 -0
  220. package/src/epoch/processRandaoMixesReset.ts +18 -0
  221. package/src/epoch/processRegistryUpdates.ts +65 -0
  222. package/src/epoch/processRewardsAndPenalties.ts +58 -0
  223. package/src/epoch/processSlashings.ts +97 -0
  224. package/src/epoch/processSlashingsReset.ts +20 -0
  225. package/src/epoch/processSyncCommitteeUpdates.ts +44 -0
  226. package/src/index.ts +67 -0
  227. package/src/metrics.ts +169 -0
  228. package/src/signatureSets/attesterSlashings.ts +39 -0
  229. package/src/signatureSets/blsToExecutionChange.ts +43 -0
  230. package/src/signatureSets/index.ts +73 -0
  231. package/src/signatureSets/indexedAttestation.ts +51 -0
  232. package/src/signatureSets/proposer.ts +47 -0
  233. package/src/signatureSets/proposerSlashings.ts +41 -0
  234. package/src/signatureSets/randao.ts +31 -0
  235. package/src/signatureSets/voluntaryExits.ts +44 -0
  236. package/src/slot/index.ts +32 -0
  237. package/src/slot/upgradeStateToAltair.ts +149 -0
  238. package/src/slot/upgradeStateToBellatrix.ts +63 -0
  239. package/src/slot/upgradeStateToCapella.ts +71 -0
  240. package/src/slot/upgradeStateToDeneb.ts +40 -0
  241. package/src/slot/upgradeStateToElectra.ts +126 -0
  242. package/src/slot/upgradeStateToFulu.ts +31 -0
  243. package/src/slot/upgradeStateToGloas.ts +29 -0
  244. package/src/stateTransition.ts +305 -0
  245. package/src/types.ts +26 -0
  246. package/src/util/aggregator.ts +33 -0
  247. package/src/util/altair.ts +13 -0
  248. package/src/util/array.ts +53 -0
  249. package/src/util/attestation.ts +36 -0
  250. package/src/util/attesterStatus.ts +83 -0
  251. package/src/util/balance.ts +83 -0
  252. package/src/util/blindedBlock.ts +144 -0
  253. package/src/util/blockRoot.ts +72 -0
  254. package/src/util/calculateCommitteeAssignments.ts +43 -0
  255. package/src/util/capella.ts +8 -0
  256. package/src/util/computeAnchorCheckpoint.ts +38 -0
  257. package/src/util/deposit.ts +22 -0
  258. package/src/util/domain.ts +31 -0
  259. package/src/util/electra.ts +68 -0
  260. package/src/util/epoch.ts +135 -0
  261. package/src/util/epochShuffling.ts +185 -0
  262. package/src/util/execution.ts +177 -0
  263. package/src/util/finality.ts +17 -0
  264. package/src/util/fulu.ts +43 -0
  265. package/src/util/genesis.ts +340 -0
  266. package/src/util/index.ts +29 -0
  267. package/src/util/interop.ts +22 -0
  268. package/src/util/loadState/findModifiedInactivityScores.ts +47 -0
  269. package/src/util/loadState/findModifiedValidators.ts +46 -0
  270. package/src/util/loadState/index.ts +2 -0
  271. package/src/util/loadState/loadState.ts +225 -0
  272. package/src/util/loadState/loadValidator.ts +77 -0
  273. package/src/util/rootCache.ts +37 -0
  274. package/src/util/seed.ts +381 -0
  275. package/src/util/shufflingDecisionRoot.ts +78 -0
  276. package/src/util/signatureSets.ts +65 -0
  277. package/src/util/signingRoot.ts +13 -0
  278. package/src/util/slot.ts +22 -0
  279. package/src/util/sszBytes.ts +52 -0
  280. package/src/util/syncCommittee.ts +69 -0
  281. package/src/util/targetUnslashedBalance.ts +30 -0
  282. package/src/util/validator.ts +105 -0
  283. package/src/util/weakSubjectivity.ts +186 -0
@@ -0,0 +1,185 @@
1
+ import {asyncUnshuffleList, unshuffleList} from "@chainsafe/swap-or-not-shuffle";
2
+ import {BeaconConfig} from "@lodestar/config";
3
+ import {
4
+ DOMAIN_BEACON_ATTESTER,
5
+ GENESIS_SLOT,
6
+ MAX_COMMITTEES_PER_SLOT,
7
+ SHUFFLE_ROUND_COUNT,
8
+ SLOTS_PER_EPOCH,
9
+ TARGET_COMMITTEE_SIZE,
10
+ } from "@lodestar/params";
11
+ import {Epoch, RootHex, ValidatorIndex, ssz} from "@lodestar/types";
12
+ import {GaugeExtra, Logger, NoLabels, intDiv, toRootHex} from "@lodestar/utils";
13
+ import {BeaconStateAllForks} from "../types.js";
14
+ import {getBlockRootAtSlot} from "./blockRoot.js";
15
+ import {computeAnchorCheckpoint} from "./computeAnchorCheckpoint.js";
16
+ import {computeStartSlotAtEpoch} from "./epoch.js";
17
+ import {getSeed} from "./seed.js";
18
+
19
+ export interface ShufflingBuildProps {
20
+ state: BeaconStateAllForks;
21
+ activeIndices: Uint32Array;
22
+ }
23
+
24
+ export interface PublicShufflingCacheMetrics {
25
+ shufflingCache: {
26
+ nextShufflingNotOnEpochCache: GaugeExtra<NoLabels>;
27
+ };
28
+ }
29
+ export interface IShufflingCache {
30
+ metrics: PublicShufflingCacheMetrics | null;
31
+ logger: Logger | null;
32
+ /**
33
+ * Gets a cached shuffling via the epoch and decision root. If the state and
34
+ * activeIndices are passed and a shuffling is not available it will be built
35
+ * synchronously. If the state is not passed and the shuffling is not available
36
+ * nothing will be returned.
37
+ *
38
+ * NOTE: If a shuffling is already queued and not calculated it will build and resolve
39
+ * the promise but the already queued build will happen at some later time
40
+ */
41
+ getSync<T extends ShufflingBuildProps | undefined>(
42
+ epoch: Epoch,
43
+ decisionRoot: RootHex,
44
+ buildProps?: T
45
+ ): T extends ShufflingBuildProps ? EpochShuffling : EpochShuffling | null;
46
+
47
+ /**
48
+ * Gets a cached shuffling via the epoch and decision root. Returns a promise
49
+ * for the shuffling if it hs not calculated yet. Returns null if a build has
50
+ * not been queued nor a shuffling was calculated.
51
+ */
52
+ get(epoch: Epoch, decisionRoot: RootHex): Promise<EpochShuffling | null>;
53
+
54
+ /**
55
+ * Queue asynchronous build for an EpochShuffling
56
+ */
57
+ build(epoch: Epoch, decisionRoot: RootHex, state: BeaconStateAllForks, activeIndices: Uint32Array): void;
58
+ }
59
+
60
+ /**
61
+ * Readonly interface for EpochShuffling.
62
+ */
63
+ export type ReadonlyEpochShuffling = {
64
+ readonly epoch: Epoch;
65
+ readonly committees: Readonly<ValidatorIndex[][][]>;
66
+ };
67
+
68
+ export type EpochShuffling = {
69
+ /**
70
+ * Epoch being shuffled
71
+ */
72
+ epoch: Epoch;
73
+
74
+ /**
75
+ * Non-shuffled active validator indices
76
+ */
77
+ activeIndices: Uint32Array;
78
+
79
+ /**
80
+ * The active validator indices, shuffled into their committee
81
+ */
82
+ shuffling: Uint32Array;
83
+
84
+ /**
85
+ * List of list of committees Committees
86
+ *
87
+ * Committees by index, by slot
88
+ *
89
+ * Note: With a high amount of shards, or low amount of validators,
90
+ * some shards may not have a committee this epoch
91
+ */
92
+ committees: Uint32Array[][];
93
+
94
+ /**
95
+ * Committees per slot, for fast attestation verification
96
+ */
97
+ committeesPerSlot: number;
98
+ };
99
+
100
+ export function computeCommitteeCount(activeValidatorCount: number): number {
101
+ const validatorsPerSlot = intDiv(activeValidatorCount, SLOTS_PER_EPOCH);
102
+ const committeesPerSlot = intDiv(validatorsPerSlot, TARGET_COMMITTEE_SIZE);
103
+ return Math.max(1, Math.min(MAX_COMMITTEES_PER_SLOT, committeesPerSlot));
104
+ }
105
+
106
+ function buildCommitteesFromShuffling(shuffling: Uint32Array): Uint32Array[][] {
107
+ const activeValidatorCount = shuffling.length;
108
+ const committeesPerSlot = computeCommitteeCount(activeValidatorCount);
109
+ const committeeCount = committeesPerSlot * SLOTS_PER_EPOCH;
110
+
111
+ const committees = new Array<Uint32Array[]>(SLOTS_PER_EPOCH);
112
+ for (let slot = 0; slot < SLOTS_PER_EPOCH; slot++) {
113
+ const slotCommittees = new Array<Uint32Array>(committeesPerSlot);
114
+
115
+ for (let committeeIndex = 0; committeeIndex < committeesPerSlot; committeeIndex++) {
116
+ const index = slot * committeesPerSlot + committeeIndex;
117
+ const startOffset = Math.floor((activeValidatorCount * index) / committeeCount);
118
+ const endOffset = Math.floor((activeValidatorCount * (index + 1)) / committeeCount);
119
+ if (!(startOffset <= endOffset)) {
120
+ throw new Error(`Invalid offsets: start ${startOffset} must be less than or equal end ${endOffset}`);
121
+ }
122
+ slotCommittees[committeeIndex] = shuffling.subarray(startOffset, endOffset);
123
+ }
124
+
125
+ committees[slot] = slotCommittees;
126
+ }
127
+
128
+ return committees;
129
+ }
130
+
131
+ export function computeEpochShuffling(
132
+ // TODO: (@matthewkeil) remove state/epoch and pass in seed to clean this up
133
+ state: BeaconStateAllForks,
134
+ activeIndices: Uint32Array,
135
+ epoch: Epoch
136
+ ): EpochShuffling {
137
+ const seed = getSeed(state, epoch, DOMAIN_BEACON_ATTESTER);
138
+ const shuffling = unshuffleList(activeIndices, seed, SHUFFLE_ROUND_COUNT);
139
+ const committees = buildCommitteesFromShuffling(shuffling);
140
+ return {
141
+ epoch,
142
+ activeIndices,
143
+ shuffling,
144
+ committees,
145
+ committeesPerSlot: committees[0].length,
146
+ };
147
+ }
148
+
149
+ export async function computeEpochShufflingAsync(
150
+ // TODO: (@matthewkeil) remove state/epoch and pass in seed to clean this up
151
+ state: BeaconStateAllForks,
152
+ activeIndices: Uint32Array,
153
+ epoch: Epoch
154
+ ): Promise<EpochShuffling> {
155
+ const seed = getSeed(state, epoch, DOMAIN_BEACON_ATTESTER);
156
+ const shuffling = await asyncUnshuffleList(activeIndices, seed, SHUFFLE_ROUND_COUNT);
157
+ const committees = buildCommitteesFromShuffling(shuffling);
158
+ return {
159
+ epoch,
160
+ activeIndices,
161
+ shuffling,
162
+ committees,
163
+ committeesPerSlot: committees[0].length,
164
+ };
165
+ }
166
+
167
+ function calculateDecisionRoot(state: BeaconStateAllForks, epoch: Epoch): RootHex {
168
+ const pivotSlot = computeStartSlotAtEpoch(epoch - 1) - 1;
169
+ return toRootHex(getBlockRootAtSlot(state, pivotSlot));
170
+ }
171
+
172
+ /**
173
+ * Get the shuffling decision block root for the given epoch of given state
174
+ * - Special case close to genesis block, return the genesis block root
175
+ * - This is similar to forkchoice.getDependentRoot() function, otherwise we cannot get cached shuffing in attestation verification when syncing from genesis.
176
+ */
177
+ export function calculateShufflingDecisionRoot(
178
+ config: BeaconConfig,
179
+ state: BeaconStateAllForks,
180
+ epoch: Epoch
181
+ ): RootHex {
182
+ return state.slot > GENESIS_SLOT
183
+ ? calculateDecisionRoot(state, epoch)
184
+ : toRootHex(ssz.phase0.BeaconBlockHeader.hashTreeRoot(computeAnchorCheckpoint(config, state).blockHeader));
185
+ }
@@ -0,0 +1,177 @@
1
+ import {ForkName, ForkPostBellatrix, ForkSeq} from "@lodestar/params";
2
+ import {
3
+ BeaconBlock,
4
+ BeaconBlockBody,
5
+ BlindedBeaconBlock,
6
+ BlindedBeaconBlockBody,
7
+ ExecutionPayload,
8
+ ExecutionPayloadHeader,
9
+ bellatrix,
10
+ capella,
11
+ deneb,
12
+ isBlindedBeaconBlockBody,
13
+ isExecutionPayload,
14
+ ssz,
15
+ } from "@lodestar/types";
16
+ import {
17
+ BeaconStateAllForks,
18
+ BeaconStateBellatrix,
19
+ BeaconStateCapella,
20
+ BeaconStateExecutions,
21
+ CachedBeaconStateAllForks,
22
+ CachedBeaconStateExecutions,
23
+ } from "../types.js";
24
+
25
+ /**
26
+ * Execution enabled = merge is done.
27
+ * When (A) state has execution data OR (B) block has execution data
28
+ */
29
+ export function isExecutionEnabled(state: BeaconStateExecutions, block: BeaconBlock | BlindedBeaconBlock): boolean {
30
+ if (isMergeTransitionComplete(state)) {
31
+ return true;
32
+ }
33
+
34
+ // Throws if not post-bellatrix block. A fork-guard in isExecutionEnabled() prevents this from happening
35
+ const payload = getFullOrBlindedPayload(block);
36
+ // Note: spec says to check all payload is zero-ed. However a state-root cannot be zero for any non-empty payload
37
+ // TODO: Consider comparing with the payload root if this assumption is not correct.
38
+ // return !byteArrayEquals(payload.stateRoot, ZERO_HASH);
39
+
40
+ // UPDATE: stateRoot comparision should have been enough with zero hash, but spec tests were failing
41
+ // Revisit this later to fix specs and make this efficient
42
+ return isExecutionPayload(payload)
43
+ ? !ssz.bellatrix.ExecutionPayload.equals(payload, ssz.bellatrix.ExecutionPayload.defaultValue())
44
+ : !ssz.bellatrix.ExecutionPayloadHeader.equals(
45
+ state.latestExecutionPayloadHeader,
46
+ // TODO: Performance
47
+ ssz.bellatrix.ExecutionPayloadHeader.defaultValue()
48
+ );
49
+ }
50
+
51
+ /**
52
+ * Merge block is the SINGLE block that transitions from POW to POS.
53
+ * state has no execution data AND this block has execution data
54
+ */
55
+ export function isMergeTransitionBlock(state: BeaconStateExecutions, body: bellatrix.BeaconBlockBody): boolean {
56
+ return (
57
+ !isMergeTransitionComplete(state) &&
58
+ !ssz.bellatrix.ExecutionPayload.equals(body.executionPayload, ssz.bellatrix.ExecutionPayload.defaultValue())
59
+ );
60
+ }
61
+
62
+ /**
63
+ * Merge is complete when the state includes execution layer data:
64
+ * state.latestExecutionPayloadHeader NOT EMPTY
65
+ */
66
+ export function isMergeTransitionComplete(state: BeaconStateExecutions): boolean {
67
+ if (!isCapellaStateType(state)) {
68
+ return !ssz.bellatrix.ExecutionPayloadHeader.equals(
69
+ (state as BeaconStateBellatrix).latestExecutionPayloadHeader,
70
+ // TODO: Performance
71
+ ssz.bellatrix.ExecutionPayloadHeader.defaultValue()
72
+ );
73
+ }
74
+
75
+ return !ssz.capella.ExecutionPayloadHeader.equals(
76
+ state.latestExecutionPayloadHeader,
77
+ // TODO: Performance
78
+ ssz.capella.ExecutionPayloadHeader.defaultValue()
79
+ );
80
+ }
81
+
82
+ /** Type guard for bellatrix.BeaconState */
83
+ export function isExecutionStateType(state: BeaconStateAllForks): state is BeaconStateExecutions {
84
+ return (state as BeaconStateExecutions).latestExecutionPayloadHeader !== undefined;
85
+ }
86
+
87
+ /** Type guard for capella.BeaconState */
88
+ export function isCapellaStateType(state: BeaconStateAllForks): state is BeaconStateCapella {
89
+ return (
90
+ (state as BeaconStateCapella).latestExecutionPayloadHeader !== undefined &&
91
+ (state as BeaconStateCapella).latestExecutionPayloadHeader.withdrawalsRoot !== undefined
92
+ );
93
+ }
94
+
95
+ /** Type guard for bellatrix.CachedBeaconState */
96
+ export function isExecutionCachedStateType(state: CachedBeaconStateAllForks): state is CachedBeaconStateExecutions {
97
+ return (state as CachedBeaconStateExecutions).latestExecutionPayloadHeader !== undefined;
98
+ }
99
+
100
+ /** Type guard for ExecutionBlockBody */
101
+ export function isExecutionBlockBodyType(blockBody: BeaconBlockBody): blockBody is BeaconBlockBody<ForkPostBellatrix> {
102
+ return (blockBody as BeaconBlockBody<ForkPostBellatrix>).executionPayload !== undefined;
103
+ }
104
+
105
+ export function getFullOrBlindedPayload(block: BeaconBlock): ExecutionPayload | ExecutionPayloadHeader {
106
+ return getFullOrBlindedPayloadFromBody(block.body);
107
+ }
108
+
109
+ export function getFullOrBlindedPayloadFromBody(
110
+ body: BeaconBlockBody | BlindedBeaconBlockBody
111
+ ): ExecutionPayload | ExecutionPayloadHeader {
112
+ if (isBlindedBeaconBlockBody(body)) {
113
+ return body.executionPayloadHeader;
114
+ }
115
+
116
+ if ((body as bellatrix.BeaconBlockBody).executionPayload !== undefined) {
117
+ return (body as bellatrix.BeaconBlockBody).executionPayload;
118
+ }
119
+
120
+ throw Error("Not full or blinded beacon block");
121
+ }
122
+
123
+ export function isCapellaPayload(
124
+ payload: ExecutionPayload | ExecutionPayloadHeader
125
+ ): payload is ExecutionPayload<ForkName.capella> | ExecutionPayloadHeader<ForkName.capella> {
126
+ return (
127
+ (payload as ExecutionPayload<ForkName.capella>).withdrawals !== undefined ||
128
+ (payload as ExecutionPayloadHeader<ForkName.capella>).withdrawalsRoot !== undefined
129
+ );
130
+ }
131
+
132
+ export function isCapellaPayloadHeader(
133
+ payload: capella.FullOrBlindedExecutionPayload
134
+ ): payload is capella.ExecutionPayloadHeader {
135
+ return (payload as capella.ExecutionPayloadHeader).withdrawalsRoot !== undefined;
136
+ }
137
+
138
+ export function executionPayloadToPayloadHeader(fork: ForkSeq, payload: ExecutionPayload): ExecutionPayloadHeader {
139
+ const transactionsRoot = ssz.bellatrix.Transactions.hashTreeRoot(payload.transactions);
140
+
141
+ const bellatrixPayloadFields: ExecutionPayloadHeader = {
142
+ parentHash: payload.parentHash,
143
+ feeRecipient: payload.feeRecipient,
144
+ stateRoot: payload.stateRoot,
145
+ receiptsRoot: payload.receiptsRoot,
146
+ logsBloom: payload.logsBloom,
147
+ prevRandao: payload.prevRandao,
148
+ blockNumber: payload.blockNumber,
149
+ gasLimit: payload.gasLimit,
150
+ gasUsed: payload.gasUsed,
151
+ timestamp: payload.timestamp,
152
+ extraData: payload.extraData,
153
+ baseFeePerGas: payload.baseFeePerGas,
154
+ blockHash: payload.blockHash,
155
+ transactionsRoot,
156
+ };
157
+
158
+ if (fork >= ForkSeq.capella) {
159
+ (bellatrixPayloadFields as capella.ExecutionPayloadHeader).withdrawalsRoot = ssz.capella.Withdrawals.hashTreeRoot(
160
+ (payload as capella.ExecutionPayload).withdrawals
161
+ );
162
+ }
163
+
164
+ if (fork >= ForkSeq.deneb) {
165
+ // https://github.com/ethereum/consensus-specs/blob/dev/specs/eip4844/beacon-chain.md#process_execution_payload
166
+ (bellatrixPayloadFields as deneb.ExecutionPayloadHeader).blobGasUsed = (
167
+ payload as deneb.ExecutionPayloadHeader | deneb.ExecutionPayload
168
+ ).blobGasUsed;
169
+ (bellatrixPayloadFields as deneb.ExecutionPayloadHeader).excessBlobGas = (
170
+ payload as deneb.ExecutionPayloadHeader | deneb.ExecutionPayload
171
+ ).excessBlobGas;
172
+ }
173
+
174
+ // No change in Electra
175
+
176
+ return bellatrixPayloadFields;
177
+ }
@@ -0,0 +1,17 @@
1
+ import {MIN_EPOCHS_TO_INACTIVITY_PENALTY} from "@lodestar/params";
2
+ import {CachedBeaconStateAllForks} from "../types.js";
3
+
4
+ export function getFinalityDelay(state: CachedBeaconStateAllForks): number {
5
+ // previousEpoch = epoch - 1
6
+ return state.epochCtx.epoch - 1 - state.finalizedCheckpoint.epoch;
7
+ }
8
+
9
+ /**
10
+ * If the chain has not been finalized for >4 epochs, the chain enters an "inactivity leak" mode,
11
+ * where inactive validators get progressively penalized more and more, to reduce their influence
12
+ * until blocks get finalized again. See here (https://github.com/ethereum/annotated-spec/blob/master/phase0/beacon-chain.md#inactivity-quotient) for what the inactivity leak is, what it's for and how
13
+ * it works.
14
+ */
15
+ export function isInInactivityLeak(state: CachedBeaconStateAllForks): boolean {
16
+ return getFinalityDelay(state) > MIN_EPOCHS_TO_INACTIVITY_PENALTY;
17
+ }
@@ -0,0 +1,43 @@
1
+ import {ForkSeq, MIN_SEED_LOOKAHEAD} from "@lodestar/params";
2
+ import {ValidatorIndex} from "@lodestar/types";
3
+ import {CachedBeaconStateElectra} from "../types.js";
4
+ import {computeEpochShuffling} from "./epochShuffling.js";
5
+ import {computeProposerIndices} from "./seed.js";
6
+ import {getActiveValidatorIndices} from "./validator.js";
7
+
8
+ /**
9
+ * Return the proposer indices for the full available lookahead starting from current epoch.
10
+ * Used to initialize the `proposer_lookahead` field in the beacon state at genesis and after forks.
11
+ */
12
+ export function initializeProposerLookahead(state: CachedBeaconStateElectra): ValidatorIndex[] {
13
+ const currentEpoch = state.epochCtx.epoch;
14
+
15
+ const lookahead: ValidatorIndex[] = [];
16
+
17
+ for (let i = 0; i <= MIN_SEED_LOOKAHEAD; i++) {
18
+ const epoch = currentEpoch + i;
19
+
20
+ // Try to pull cached shuffling first
21
+ let shuffling = state.epochCtx.getShufflingAtEpochOrNull(epoch);
22
+
23
+ if (!shuffling) {
24
+ // Only compute epoch shuffling if cache is not yet populated
25
+ let activeIndices: Uint32Array;
26
+ if (epoch === currentEpoch) {
27
+ // This should never happen as current shuffling will always be cached
28
+ activeIndices = state.epochCtx.currentShuffling.activeIndices;
29
+ } else if (epoch === currentEpoch + 1) {
30
+ activeIndices = state.epochCtx.nextActiveIndices;
31
+ } else {
32
+ // This will never be reached with current spec as `MIN_SEED_LOOKAHEAD == 1`
33
+ activeIndices = getActiveValidatorIndices(state, epoch);
34
+ }
35
+
36
+ shuffling = computeEpochShuffling(state, activeIndices, epoch);
37
+ }
38
+
39
+ lookahead.push(...computeProposerIndices(ForkSeq.fulu, state, shuffling, epoch));
40
+ }
41
+
42
+ return lookahead;
43
+ }