@lodestar/state-transition 1.35.0-dev.955e9f89ed → 1.35.0-dev.98d359db41

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 (284) hide show
  1. package/README.md +1 -1
  2. package/lib/block/externalData.d.ts.map +1 -0
  3. package/lib/block/index.d.ts +2 -2
  4. package/lib/block/index.d.ts.map +1 -0
  5. package/lib/block/index.js +2 -2
  6. package/lib/block/index.js.map +1 -1
  7. package/lib/block/initiateValidatorExit.d.ts.map +1 -0
  8. package/lib/block/isValidIndexedAttestation.d.ts.map +1 -0
  9. package/lib/block/processAttestationPhase0.d.ts.map +1 -0
  10. package/lib/block/processAttestationPhase0.js +1 -2
  11. package/lib/block/processAttestationPhase0.js.map +1 -1
  12. package/lib/block/processAttestations.d.ts.map +1 -0
  13. package/lib/block/processAttestationsAltair.d.ts +1 -1
  14. package/lib/block/processAttestationsAltair.d.ts.map +1 -0
  15. package/lib/block/processAttestationsAltair.js +1 -1
  16. package/lib/block/processAttestationsAltair.js.map +1 -1
  17. package/lib/block/processAttesterSlashing.d.ts.map +1 -0
  18. package/lib/block/processAttesterSlashing.js.map +1 -1
  19. package/lib/block/processBlobKzgCommitments.d.ts.map +1 -0
  20. package/lib/block/processBlockHeader.d.ts.map +1 -0
  21. package/lib/block/processBlsToExecutionChange.d.ts.map +1 -0
  22. package/lib/block/processBlsToExecutionChange.js.map +1 -1
  23. package/lib/block/processConsolidationRequest.d.ts.map +1 -0
  24. package/lib/block/processConsolidationRequest.js.map +1 -1
  25. package/lib/block/processDeposit.d.ts +2 -2
  26. package/lib/block/processDeposit.d.ts.map +1 -0
  27. package/lib/block/processDeposit.js +1 -1
  28. package/lib/block/processDeposit.js.map +1 -1
  29. package/lib/block/processDepositRequest.d.ts.map +1 -0
  30. package/lib/block/processDepositRequest.js.map +1 -1
  31. package/lib/block/processEth1Data.d.ts.map +1 -0
  32. package/lib/block/processExecutionPayload.d.ts.map +1 -0
  33. package/lib/block/processOperations.d.ts.map +1 -0
  34. package/lib/block/processOperations.js.map +1 -1
  35. package/lib/block/processProposerSlashing.d.ts.map +1 -0
  36. package/lib/block/processRandao.d.ts.map +1 -0
  37. package/lib/block/processSyncCommittee.d.ts.map +1 -0
  38. package/lib/block/processSyncCommittee.js +1 -2
  39. package/lib/block/processSyncCommittee.js.map +1 -1
  40. package/lib/block/processVoluntaryExit.d.ts.map +1 -0
  41. package/lib/block/processWithdrawalRequest.d.ts.map +1 -0
  42. package/lib/block/processWithdrawalRequest.js.map +1 -1
  43. package/lib/block/processWithdrawals.d.ts.map +1 -0
  44. package/lib/block/processWithdrawals.js.map +1 -1
  45. package/lib/block/slashValidator.d.ts.map +1 -0
  46. package/lib/block/slashValidator.js.map +1 -1
  47. package/lib/block/types.d.ts.map +1 -0
  48. package/lib/cache/effectiveBalanceIncrements.d.ts.map +1 -0
  49. package/lib/cache/epochCache.d.ts.map +1 -0
  50. package/lib/cache/epochCache.js +130 -0
  51. package/lib/cache/epochCache.js.map +1 -1
  52. package/lib/cache/epochTransitionCache.d.ts.map +1 -0
  53. package/lib/cache/epochTransitionCache.js.map +1 -1
  54. package/lib/cache/pubkeyCache.d.ts.map +1 -0
  55. package/lib/cache/rewardCache.d.ts.map +1 -0
  56. package/lib/cache/stateCache.d.ts.map +1 -0
  57. package/lib/cache/syncCommitteeCache.d.ts.map +1 -0
  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/slot/upgradeStateToGloas.js +2 -2
  113. package/lib/slot/upgradeStateToGloas.js.map +1 -1
  114. package/lib/stateTransition.d.ts.map +1 -0
  115. package/lib/types.d.ts +2 -2
  116. package/lib/types.d.ts.map +1 -0
  117. package/lib/util/aggregator.d.ts.map +1 -0
  118. package/lib/util/altair.d.ts.map +1 -0
  119. package/lib/util/array.d.ts.map +1 -0
  120. package/lib/util/attestation.d.ts.map +1 -0
  121. package/lib/util/attesterStatus.d.ts.map +1 -0
  122. package/lib/util/balance.d.ts.map +1 -0
  123. package/lib/util/blindedBlock.d.ts.map +1 -0
  124. package/lib/util/blindedBlock.js.map +1 -1
  125. package/lib/util/blockRoot.d.ts.map +1 -0
  126. package/lib/util/calculateCommitteeAssignments.d.ts.map +1 -0
  127. package/lib/util/capella.d.ts.map +1 -0
  128. package/lib/util/computeAnchorCheckpoint.d.ts.map +1 -0
  129. package/lib/util/deposit.d.ts.map +1 -0
  130. package/lib/util/domain.d.ts.map +1 -0
  131. package/lib/util/electra.d.ts.map +1 -0
  132. package/lib/util/epoch.d.ts.map +1 -0
  133. package/lib/util/epochShuffling.d.ts.map +1 -0
  134. package/lib/util/execution.d.ts.map +1 -0
  135. package/lib/util/execution.js.map +1 -1
  136. package/lib/util/finality.d.ts.map +1 -0
  137. package/lib/util/fulu.d.ts.map +1 -0
  138. package/lib/util/genesis.d.ts.map +1 -0
  139. package/lib/util/genesis.js +4 -4
  140. package/lib/util/genesis.js.map +1 -1
  141. package/lib/util/index.d.ts +5 -5
  142. package/lib/util/index.d.ts.map +1 -0
  143. package/lib/util/index.js +5 -5
  144. package/lib/util/index.js.map +1 -1
  145. package/lib/util/interop.d.ts.map +1 -0
  146. package/lib/util/interop.js +1 -1
  147. package/lib/util/interop.js.map +1 -1
  148. package/lib/util/loadState/findModifiedInactivityScores.d.ts.map +1 -0
  149. package/lib/util/loadState/findModifiedValidators.d.ts.map +1 -0
  150. package/lib/util/loadState/index.d.ts.map +1 -0
  151. package/lib/util/loadState/loadState.d.ts.map +1 -0
  152. package/lib/util/loadState/loadValidator.d.ts.map +1 -0
  153. package/lib/util/rootCache.d.ts.map +1 -0
  154. package/lib/util/rootCache.js +5 -2
  155. package/lib/util/rootCache.js.map +1 -1
  156. package/lib/util/seed.d.ts.map +1 -0
  157. package/lib/util/seed.js +1 -2
  158. package/lib/util/seed.js.map +1 -1
  159. package/lib/util/shufflingDecisionRoot.d.ts.map +1 -0
  160. package/lib/util/signatureSets.d.ts.map +1 -0
  161. package/lib/util/signingRoot.d.ts.map +1 -0
  162. package/lib/util/slot.d.ts.map +1 -0
  163. package/lib/util/sszBytes.d.ts.map +1 -0
  164. package/lib/util/syncCommittee.d.ts.map +1 -0
  165. package/lib/util/targetUnslashedBalance.d.ts.map +1 -0
  166. package/lib/util/validator.d.ts.map +1 -0
  167. package/lib/util/weakSubjectivity.d.ts.map +1 -0
  168. package/lib/util/weakSubjectivity.js.map +1 -1
  169. package/package.json +13 -11
  170. package/src/block/externalData.ts +26 -0
  171. package/src/block/index.ts +81 -0
  172. package/src/block/initiateValidatorExit.ts +62 -0
  173. package/src/block/isValidIndexedAttestation.ts +70 -0
  174. package/src/block/processAttestationPhase0.ts +158 -0
  175. package/src/block/processAttestations.ts +25 -0
  176. package/src/block/processAttestationsAltair.ts +184 -0
  177. package/src/block/processAttesterSlashing.ts +59 -0
  178. package/src/block/processBlobKzgCommitments.ts +21 -0
  179. package/src/block/processBlockHeader.ts +54 -0
  180. package/src/block/processBlsToExecutionChange.ts +78 -0
  181. package/src/block/processConsolidationRequest.ts +147 -0
  182. package/src/block/processDeposit.ts +166 -0
  183. package/src/block/processDepositRequest.ts +19 -0
  184. package/src/block/processEth1Data.ts +86 -0
  185. package/src/block/processExecutionPayload.ts +84 -0
  186. package/src/block/processOperations.ts +83 -0
  187. package/src/block/processProposerSlashing.ts +66 -0
  188. package/src/block/processRandao.ts +27 -0
  189. package/src/block/processSyncCommittee.ts +117 -0
  190. package/src/block/processVoluntaryExit.ts +55 -0
  191. package/src/block/processWithdrawalRequest.ts +98 -0
  192. package/src/block/processWithdrawals.ts +207 -0
  193. package/src/block/slashValidator.ts +98 -0
  194. package/src/block/types.ts +9 -0
  195. package/src/cache/effectiveBalanceIncrements.ts +39 -0
  196. package/src/cache/epochCache.ts +1213 -0
  197. package/src/cache/epochTransitionCache.ts +542 -0
  198. package/src/cache/pubkeyCache.ts +33 -0
  199. package/src/cache/rewardCache.ts +19 -0
  200. package/src/cache/stateCache.ts +268 -0
  201. package/src/cache/syncCommitteeCache.ts +96 -0
  202. package/src/cache/types.ts +18 -0
  203. package/src/constants/constants.ts +12 -0
  204. package/src/constants/index.ts +1 -0
  205. package/src/epoch/computeUnrealizedCheckpoints.ts +55 -0
  206. package/src/epoch/getAttestationDeltas.ts +169 -0
  207. package/src/epoch/getRewardsAndPenalties.ts +137 -0
  208. package/src/epoch/index.ts +202 -0
  209. package/src/epoch/processEffectiveBalanceUpdates.ts +111 -0
  210. package/src/epoch/processEth1DataReset.ts +17 -0
  211. package/src/epoch/processHistoricalRootsUpdate.ts +25 -0
  212. package/src/epoch/processHistoricalSummariesUpdate.ts +23 -0
  213. package/src/epoch/processInactivityUpdates.ts +60 -0
  214. package/src/epoch/processJustificationAndFinalization.ts +90 -0
  215. package/src/epoch/processParticipationFlagUpdates.ts +27 -0
  216. package/src/epoch/processParticipationRecordUpdates.ts +14 -0
  217. package/src/epoch/processPendingAttestations.ts +75 -0
  218. package/src/epoch/processPendingConsolidations.ts +59 -0
  219. package/src/epoch/processPendingDeposits.ts +136 -0
  220. package/src/epoch/processProposerLookahead.ts +39 -0
  221. package/src/epoch/processRandaoMixesReset.ts +18 -0
  222. package/src/epoch/processRegistryUpdates.ts +65 -0
  223. package/src/epoch/processRewardsAndPenalties.ts +58 -0
  224. package/src/epoch/processSlashings.ts +97 -0
  225. package/src/epoch/processSlashingsReset.ts +20 -0
  226. package/src/epoch/processSyncCommitteeUpdates.ts +44 -0
  227. package/src/index.ts +67 -0
  228. package/src/metrics.ts +169 -0
  229. package/src/signatureSets/attesterSlashings.ts +39 -0
  230. package/src/signatureSets/blsToExecutionChange.ts +43 -0
  231. package/src/signatureSets/index.ts +73 -0
  232. package/src/signatureSets/indexedAttestation.ts +51 -0
  233. package/src/signatureSets/proposer.ts +47 -0
  234. package/src/signatureSets/proposerSlashings.ts +41 -0
  235. package/src/signatureSets/randao.ts +31 -0
  236. package/src/signatureSets/voluntaryExits.ts +44 -0
  237. package/src/slot/index.ts +32 -0
  238. package/src/slot/upgradeStateToAltair.ts +149 -0
  239. package/src/slot/upgradeStateToBellatrix.ts +63 -0
  240. package/src/slot/upgradeStateToCapella.ts +71 -0
  241. package/src/slot/upgradeStateToDeneb.ts +40 -0
  242. package/src/slot/upgradeStateToElectra.ts +126 -0
  243. package/src/slot/upgradeStateToFulu.ts +31 -0
  244. package/src/slot/upgradeStateToGloas.ts +29 -0
  245. package/src/stateTransition.ts +305 -0
  246. package/src/types.ts +26 -0
  247. package/src/util/aggregator.ts +33 -0
  248. package/src/util/altair.ts +13 -0
  249. package/src/util/array.ts +53 -0
  250. package/src/util/attestation.ts +36 -0
  251. package/src/util/attesterStatus.ts +83 -0
  252. package/src/util/balance.ts +83 -0
  253. package/src/util/blindedBlock.ts +144 -0
  254. package/src/util/blockRoot.ts +72 -0
  255. package/src/util/calculateCommitteeAssignments.ts +43 -0
  256. package/src/util/capella.ts +8 -0
  257. package/src/util/computeAnchorCheckpoint.ts +38 -0
  258. package/src/util/deposit.ts +22 -0
  259. package/src/util/domain.ts +31 -0
  260. package/src/util/electra.ts +68 -0
  261. package/src/util/epoch.ts +135 -0
  262. package/src/util/epochShuffling.ts +185 -0
  263. package/src/util/execution.ts +177 -0
  264. package/src/util/finality.ts +17 -0
  265. package/src/util/fulu.ts +43 -0
  266. package/src/util/genesis.ts +343 -0
  267. package/src/util/index.ts +29 -0
  268. package/src/util/interop.ts +22 -0
  269. package/src/util/loadState/findModifiedInactivityScores.ts +47 -0
  270. package/src/util/loadState/findModifiedValidators.ts +46 -0
  271. package/src/util/loadState/index.ts +2 -0
  272. package/src/util/loadState/loadState.ts +225 -0
  273. package/src/util/loadState/loadValidator.ts +77 -0
  274. package/src/util/rootCache.ts +37 -0
  275. package/src/util/seed.ts +381 -0
  276. package/src/util/shufflingDecisionRoot.ts +78 -0
  277. package/src/util/signatureSets.ts +65 -0
  278. package/src/util/signingRoot.ts +13 -0
  279. package/src/util/slot.ts +27 -0
  280. package/src/util/sszBytes.ts +52 -0
  281. package/src/util/syncCommittee.ts +69 -0
  282. package/src/util/targetUnslashedBalance.ts +30 -0
  283. package/src/util/validator.ts +105 -0
  284. package/src/util/weakSubjectivity.ts +186 -0
package/src/index.ts ADDED
@@ -0,0 +1,67 @@
1
+ export {
2
+ type BlockExternalData,
3
+ DataAvailabilityStatus,
4
+ ExecutionPayloadStatus,
5
+ } from "./block/externalData.js";
6
+ export {getAttestationParticipationStatus, processAttestationsAltair} from "./block/processAttestationsAltair.js";
7
+ export {assertValidAttesterSlashing} from "./block/processAttesterSlashing.js";
8
+ export {isValidBlsToExecutionChange} from "./block/processBlsToExecutionChange.js";
9
+ // BeaconChain, to prepare new blocks
10
+ export {becomesNewEth1Data} from "./block/processEth1Data.js";
11
+ export {assertValidProposerSlashing} from "./block/processProposerSlashing.js";
12
+ // BeaconChain validation
13
+ export {isValidVoluntaryExit} from "./block/processVoluntaryExit.js";
14
+ // Withdrawals for new blocks
15
+ export {getExpectedWithdrawals} from "./block/processWithdrawals.js";
16
+ export {ProposerRewardType} from "./block/types.js";
17
+ export {
18
+ type EffectiveBalanceIncrements,
19
+ getEffectiveBalanceIncrementsWithLen,
20
+ getEffectiveBalanceIncrementsZeroed,
21
+ } from "./cache/effectiveBalanceIncrements.js";
22
+ export {
23
+ EpochCache,
24
+ EpochCacheError,
25
+ EpochCacheErrorCode,
26
+ type EpochCacheImmutableData,
27
+ createEmptyEpochCacheImmutableData,
28
+ } from "./cache/epochCache.js";
29
+ export {type EpochTransitionCache, beforeProcessEpoch} from "./cache/epochTransitionCache.js";
30
+ // Aux data-structures
31
+ export {type Index2PubkeyCache} from "./cache/pubkeyCache.js";
32
+ // Main state caches
33
+ export {
34
+ type BeaconStateCache,
35
+ createCachedBeaconState,
36
+ isCachedBeaconState,
37
+ isStateBalancesNodesPopulated,
38
+ isStateValidatorsNodesPopulated,
39
+ loadCachedBeaconState,
40
+ } from "./cache/stateCache.js";
41
+ export * from "./constants/index.js";
42
+ export type {EpochTransitionStep} from "./epoch/index.js";
43
+ export {type BeaconStateTransitionMetrics, getMetrics} from "./metrics.js";
44
+ export * from "./signatureSets/index.js";
45
+ export * from "./stateTransition.js";
46
+ export type {
47
+ BeaconStateAllForks,
48
+ BeaconStateAltair,
49
+ BeaconStateBellatrix,
50
+ BeaconStateCapella,
51
+ BeaconStateDeneb,
52
+ BeaconStateElectra,
53
+ BeaconStateExecutions,
54
+ BeaconStateFulu,
55
+ // Non-cached states
56
+ BeaconStatePhase0,
57
+ CachedBeaconStateAllForks,
58
+ CachedBeaconStateAltair,
59
+ CachedBeaconStateBellatrix,
60
+ CachedBeaconStateCapella,
61
+ CachedBeaconStateDeneb,
62
+ CachedBeaconStateElectra,
63
+ CachedBeaconStateExecutions,
64
+ CachedBeaconStateFulu,
65
+ CachedBeaconStatePhase0,
66
+ } from "./types.js";
67
+ export * from "./util/index.js";
package/src/metrics.ts ADDED
@@ -0,0 +1,169 @@
1
+ import {MetricsRegister} from "@lodestar/utils";
2
+ import {ProposerRewardType} from "./block/types.js";
3
+ import {EpochTransitionStep} from "./epoch/index.js";
4
+ import {StateCloneSource, StateHashTreeRootSource} from "./stateTransition.js";
5
+ import {CachedBeaconStateAllForks} from "./types.js";
6
+
7
+ export type BeaconStateTransitionMetrics = ReturnType<typeof getMetrics>;
8
+
9
+ /**
10
+ * A collection of metrics used throughout the State Transition.
11
+ */
12
+ export function getMetrics(register: MetricsRegister) {
13
+ // Using function style instead of class to prevent having to re-declare all MetricsPrometheus types.
14
+
15
+ return {
16
+ epochTransitionTime: register.histogram({
17
+ name: "lodestar_stfn_epoch_transition_seconds",
18
+ help: "Time to process a single epoch transition in seconds",
19
+ // as of Sep 2025, on mainnet, epoch transition time of lodestar is never less than 0.5s, and it could be up to 3s
20
+ buckets: [0.2, 0.5, 0.75, 1, 1.25, 1.5, 2, 2.5, 3, 10],
21
+ }),
22
+ epochTransitionCommitTime: register.histogram({
23
+ name: "lodestar_stfn_epoch_transition_commit_seconds",
24
+ help: "Time to call commit after process a single epoch transition in seconds",
25
+ buckets: [0.01, 0.05, 0.1, 0.2, 0.5, 0.75, 1],
26
+ }),
27
+ epochTransitionStepTime: register.histogram<{step: EpochTransitionStep}>({
28
+ name: "lodestar_stfn_epoch_transition_step_seconds",
29
+ help: "Time to call each step of epoch transition in seconds",
30
+ labelNames: ["step"],
31
+ buckets: [0.01, 0.05, 0.1, 0.2, 0.5, 0.75, 1],
32
+ }),
33
+ processBlockTime: register.histogram({
34
+ name: "lodestar_stfn_process_block_seconds",
35
+ help: "Time to process a single block in seconds",
36
+ // TODO: Add metrics for each step
37
+ // Block processing can take 5-40ms, 100ms max
38
+ buckets: [0.005, 0.01, 0.02, 0.05, 0.1, 1],
39
+ }),
40
+ processBlockCommitTime: register.histogram({
41
+ name: "lodestar_stfn_process_block_commit_seconds",
42
+ help: "Time to call commit after process a single block in seconds",
43
+ buckets: [0.005, 0.01, 0.02, 0.05, 0.1, 1],
44
+ }),
45
+ stateHashTreeRootTime: register.histogram<{source: StateHashTreeRootSource}>({
46
+ name: "lodestar_stfn_hash_tree_root_seconds",
47
+ help: "Time to compute the hash tree root of a post state in seconds",
48
+ buckets: [0.05, 0.1, 0.2, 0.5, 1, 1.5],
49
+ labelNames: ["source"],
50
+ }),
51
+ numEffectiveBalanceUpdates: register.gauge({
52
+ name: "lodestar_stfn_effective_balance_updates_count",
53
+ help: "Total count of effective balance updates",
54
+ }),
55
+ validatorsInActivationQueue: register.gauge({
56
+ name: "lodestar_stfn_validators_in_activation_queue",
57
+ help: "Current number of validators in the activation queue",
58
+ }),
59
+ validatorsInExitQueue: register.gauge({
60
+ name: "lodestar_stfn_validators_in_exit_queue",
61
+ help: "Current number of validators in the exit queue",
62
+ }),
63
+ preStateBalancesNodesPopulatedMiss: register.gauge<{source: StateCloneSource}>({
64
+ name: "lodestar_stfn_balances_nodes_populated_miss_total",
65
+ help: "Total count state.balances nodesPopulated is false on stfn",
66
+ labelNames: ["source"],
67
+ }),
68
+ preStateBalancesNodesPopulatedHit: register.gauge<{source: StateCloneSource}>({
69
+ name: "lodestar_stfn_balances_nodes_populated_hit_total",
70
+ help: "Total count state.balances nodesPopulated is true on stfn",
71
+ labelNames: ["source"],
72
+ }),
73
+ preStateValidatorsNodesPopulatedMiss: register.gauge<{source: StateCloneSource}>({
74
+ name: "lodestar_stfn_validators_nodes_populated_miss_total",
75
+ help: "Total count state.validators nodesPopulated is false on stfn",
76
+ labelNames: ["source"],
77
+ }),
78
+ preStateValidatorsNodesPopulatedHit: register.gauge<{source: StateCloneSource}>({
79
+ name: "lodestar_stfn_validators_nodes_populated_hit_total",
80
+ help: "Total count state.validators nodesPopulated is true on stfn",
81
+ labelNames: ["source"],
82
+ }),
83
+ preStateClonedCount: register.histogram({
84
+ name: "lodestar_stfn_state_cloned_count",
85
+ help: "Histogram of cloned count per state every time state.clone() is called",
86
+ buckets: [1, 2, 5, 10, 50, 250],
87
+ }),
88
+ postStateBalancesNodesPopulatedHit: register.gauge({
89
+ name: "lodestar_stfn_post_state_balances_nodes_populated_hit_total",
90
+ help: "Total count state.validators nodesPopulated is true on stfn for post state",
91
+ }),
92
+ postStateBalancesNodesPopulatedMiss: register.gauge({
93
+ name: "lodestar_stfn_post_state_balances_nodes_populated_miss_total",
94
+ help: "Total count state.validators nodesPopulated is false on stfn for post state",
95
+ }),
96
+ postStateValidatorsNodesPopulatedHit: register.gauge({
97
+ name: "lodestar_stfn_post_state_validators_nodes_populated_hit_total",
98
+ help: "Total count state.validators nodesPopulated is true on stfn for post state",
99
+ }),
100
+ postStateValidatorsNodesPopulatedMiss: register.gauge({
101
+ name: "lodestar_stfn_post_state_validators_nodes_populated_miss_total",
102
+ help: "Total count state.validators nodesPopulated is false on stfn for post state",
103
+ }),
104
+ newSeenAttestersPerBlock: register.gauge({
105
+ name: "lodestar_stfn_new_seen_attesters_per_block_total",
106
+ help: "Total count of new seen attesters per block",
107
+ }),
108
+ newSeenAttestersEffectiveBalancePerBlock: register.gauge({
109
+ name: "lodestar_stfn_new_seen_attesters_effective_balance_per_block_total",
110
+ help: "Total effective balance increment of new seen attesters per block",
111
+ }),
112
+ attestationsPerBlock: register.gauge({
113
+ name: "lodestar_stfn_attestations_per_block_total",
114
+ help: "Total count of attestations per block",
115
+ }),
116
+ proposerRewards: register.gauge<{type: ProposerRewardType}>({
117
+ name: "lodestar_stfn_proposer_rewards_total",
118
+ help: "Proposer reward by type per block",
119
+ labelNames: ["type"],
120
+ }),
121
+ };
122
+ }
123
+
124
+ export function onStateCloneMetrics(
125
+ state: CachedBeaconStateAllForks,
126
+ metrics: BeaconStateTransitionMetrics,
127
+ source: StateCloneSource
128
+ ): void {
129
+ metrics.preStateClonedCount.observe(state.clonedCount);
130
+
131
+ if (isBalancesNodesPopulated(state)) {
132
+ metrics.preStateBalancesNodesPopulatedHit.inc({source});
133
+ } else {
134
+ metrics.preStateBalancesNodesPopulatedMiss.inc({source});
135
+ }
136
+
137
+ if (isValidatorsNodesPopulated(state)) {
138
+ metrics.preStateValidatorsNodesPopulatedHit.inc({source});
139
+ } else {
140
+ metrics.preStateValidatorsNodesPopulatedMiss.inc({source});
141
+ }
142
+ }
143
+
144
+ export function onPostStateMetrics(postState: CachedBeaconStateAllForks, metrics: BeaconStateTransitionMetrics): void {
145
+ if (isBalancesNodesPopulated(postState)) {
146
+ metrics.postStateBalancesNodesPopulatedHit.inc();
147
+ } else {
148
+ metrics.postStateBalancesNodesPopulatedMiss.inc();
149
+ }
150
+
151
+ if (isValidatorsNodesPopulated(postState)) {
152
+ metrics.postStateValidatorsNodesPopulatedHit.inc();
153
+ } else {
154
+ metrics.postStateValidatorsNodesPopulatedMiss.inc();
155
+ }
156
+ }
157
+
158
+ // Given a CachedBeaconState, check if validators array internal cache is populated.
159
+ // This cache is populated during epoch transition, and should be preserved for performance.
160
+ // If the cache is missing too often, means that our clone strategy is not working well.
161
+ function isValidatorsNodesPopulated(state: CachedBeaconStateAllForks): boolean {
162
+ // biome-ignore lint/complexity/useLiteralKeys: It is a private attribute
163
+ return state.validators["nodesPopulated"] === true;
164
+ }
165
+
166
+ function isBalancesNodesPopulated(state: CachedBeaconStateAllForks): boolean {
167
+ // biome-ignore lint/complexity/useLiteralKeys: It is a private attribute
168
+ return state.balances["nodesPopulated"] === true;
169
+ }
@@ -0,0 +1,39 @@
1
+ import {DOMAIN_BEACON_ATTESTER} from "@lodestar/params";
2
+ import {AttesterSlashing, IndexedAttestationBigint, SignedBeaconBlock, ssz} from "@lodestar/types";
3
+ import {CachedBeaconStateAllForks} from "../types.js";
4
+ import {ISignatureSet, SignatureSetType, computeSigningRoot, computeStartSlotAtEpoch} from "../util/index.js";
5
+
6
+ /** Get signature sets from all AttesterSlashing objects in a block */
7
+ export function getAttesterSlashingsSignatureSets(
8
+ state: CachedBeaconStateAllForks,
9
+ signedBlock: SignedBeaconBlock
10
+ ): ISignatureSet[] {
11
+ return signedBlock.message.body.attesterSlashings.flatMap((attesterSlashing) =>
12
+ getAttesterSlashingSignatureSets(state, attesterSlashing)
13
+ );
14
+ }
15
+
16
+ /** Get signature sets from a single AttesterSlashing object */
17
+ export function getAttesterSlashingSignatureSets(
18
+ state: CachedBeaconStateAllForks,
19
+ attesterSlashing: AttesterSlashing
20
+ ): ISignatureSet[] {
21
+ return [attesterSlashing.attestation1, attesterSlashing.attestation2].map((attestation) =>
22
+ getIndexedAttestationBigintSignatureSet(state, attestation)
23
+ );
24
+ }
25
+
26
+ export function getIndexedAttestationBigintSignatureSet(
27
+ state: CachedBeaconStateAllForks,
28
+ indexedAttestation: IndexedAttestationBigint
29
+ ): ISignatureSet {
30
+ const slot = computeStartSlotAtEpoch(Number(indexedAttestation.data.target.epoch as bigint));
31
+ const domain = state.config.getDomain(state.slot, DOMAIN_BEACON_ATTESTER, slot);
32
+
33
+ return {
34
+ type: SignatureSetType.aggregate,
35
+ pubkeys: indexedAttestation.attestingIndices.map((i) => state.epochCtx.index2pubkey[i]),
36
+ signingRoot: computeSigningRoot(ssz.phase0.AttestationDataBigint, indexedAttestation.data, domain),
37
+ signature: indexedAttestation.signature,
38
+ };
39
+ }
@@ -0,0 +1,43 @@
1
+ import {PublicKey} from "@chainsafe/blst";
2
+ import {BeaconConfig} from "@lodestar/config";
3
+ import {DOMAIN_BLS_TO_EXECUTION_CHANGE, ForkName} from "@lodestar/params";
4
+ import {capella, ssz} from "@lodestar/types";
5
+ import {CachedBeaconStateAllForks} from "../types.js";
6
+ import {ISignatureSet, SignatureSetType, computeSigningRoot, verifySignatureSet} from "../util/index.js";
7
+
8
+ export function verifyBlsToExecutionChangeSignature(
9
+ state: CachedBeaconStateAllForks,
10
+ signedBLSToExecutionChange: capella.SignedBLSToExecutionChange
11
+ ): boolean {
12
+ return verifySignatureSet(getBlsToExecutionChangeSignatureSet(state.config, signedBLSToExecutionChange));
13
+ }
14
+
15
+ /**
16
+ * Extract signatures to allow validating all block signatures at once
17
+ */
18
+ export function getBlsToExecutionChangeSignatureSet(
19
+ config: BeaconConfig,
20
+ signedBLSToExecutionChange: capella.SignedBLSToExecutionChange
21
+ ): ISignatureSet {
22
+ // signatureFork for signing domain is fixed
23
+ const signatureFork = ForkName.phase0;
24
+ const domain = config.getDomainAtFork(signatureFork, DOMAIN_BLS_TO_EXECUTION_CHANGE);
25
+
26
+ return {
27
+ type: SignatureSetType.single,
28
+ // The withdrawal pubkey is the same as signedBLSToExecutionChange's fromBlsPubkey as it should
29
+ // be validated against the withdrawal credentials digest
30
+ pubkey: PublicKey.fromBytes(signedBLSToExecutionChange.message.fromBlsPubkey, true),
31
+ signingRoot: computeSigningRoot(ssz.capella.BLSToExecutionChange, signedBLSToExecutionChange.message, domain),
32
+ signature: signedBLSToExecutionChange.signature,
33
+ };
34
+ }
35
+
36
+ export function getBlsToExecutionChangeSignatureSets(
37
+ config: BeaconConfig,
38
+ signedBlock: capella.SignedBeaconBlock
39
+ ): ISignatureSet[] {
40
+ return signedBlock.message.body.blsToExecutionChanges.map((blsToExecutionChange) =>
41
+ getBlsToExecutionChangeSignatureSet(config, blsToExecutionChange)
42
+ );
43
+ }
@@ -0,0 +1,73 @@
1
+ import {ForkSeq} from "@lodestar/params";
2
+ import {SignedBeaconBlock, altair, capella} from "@lodestar/types";
3
+ import {getSyncCommitteeSignatureSet} from "../block/processSyncCommittee.js";
4
+ import {CachedBeaconStateAllForks, CachedBeaconStateAltair} from "../types.js";
5
+ import {ISignatureSet} from "../util/index.js";
6
+ import {getAttesterSlashingsSignatureSets} from "./attesterSlashings.js";
7
+ import {getBlsToExecutionChangeSignatureSets} from "./blsToExecutionChange.js";
8
+ import {getAttestationsSignatureSets} from "./indexedAttestation.js";
9
+ import {getBlockProposerSignatureSet} from "./proposer.js";
10
+ import {getProposerSlashingsSignatureSets} from "./proposerSlashings.js";
11
+ import {getRandaoRevealSignatureSet} from "./randao.js";
12
+ import {getVoluntaryExitsSignatureSets} from "./voluntaryExits.js";
13
+
14
+ export * from "./attesterSlashings.js";
15
+ export * from "./blsToExecutionChange.js";
16
+ export * from "./indexedAttestation.js";
17
+ export * from "./proposer.js";
18
+ export * from "./proposerSlashings.js";
19
+ export * from "./randao.js";
20
+ export * from "./voluntaryExits.js";
21
+
22
+ /**
23
+ * Includes all signatures on the block (except the deposit signatures) for verification.
24
+ * Deposits are not included because they can legally have invalid signatures.
25
+ */
26
+ export function getBlockSignatureSets(
27
+ state: CachedBeaconStateAllForks,
28
+ signedBlock: SignedBeaconBlock,
29
+ opts?: {
30
+ /** Useful since block proposer signature is verified beforehand on gossip validation */
31
+ skipProposerSignature?: boolean;
32
+ }
33
+ ): ISignatureSet[] {
34
+ // fork based validations
35
+ const fork = state.config.getForkSeq(signedBlock.message.slot);
36
+
37
+ const signatureSets = [
38
+ getRandaoRevealSignatureSet(state, signedBlock.message),
39
+ ...getProposerSlashingsSignatureSets(state, signedBlock),
40
+ ...getAttesterSlashingsSignatureSets(state, signedBlock),
41
+ ...getAttestationsSignatureSets(state, signedBlock),
42
+ ...getVoluntaryExitsSignatureSets(state, signedBlock),
43
+ ];
44
+
45
+ if (!opts?.skipProposerSignature) {
46
+ signatureSets.push(getBlockProposerSignatureSet(state, signedBlock));
47
+ }
48
+
49
+ // Only after altair fork, validate tSyncCommitteeSignature
50
+ if (fork >= ForkSeq.altair) {
51
+ const syncCommitteeSignatureSet = getSyncCommitteeSignatureSet(
52
+ state as CachedBeaconStateAltair,
53
+ (signedBlock as altair.SignedBeaconBlock).message
54
+ );
55
+ // There may be no participants in this syncCommitteeSignature, so it must not be validated
56
+ if (syncCommitteeSignatureSet) {
57
+ signatureSets.push(syncCommitteeSignatureSet);
58
+ }
59
+ }
60
+
61
+ // only after capella fork
62
+ if (fork >= ForkSeq.capella) {
63
+ const blsToExecutionChangeSignatureSets = getBlsToExecutionChangeSignatureSets(
64
+ state.config,
65
+ signedBlock as capella.SignedBeaconBlock
66
+ );
67
+ if (blsToExecutionChangeSignatureSets.length > 0) {
68
+ signatureSets.push(...blsToExecutionChangeSignatureSets);
69
+ }
70
+ }
71
+
72
+ return signatureSets;
73
+ }
@@ -0,0 +1,51 @@
1
+ import {DOMAIN_BEACON_ATTESTER} from "@lodestar/params";
2
+ import {IndexedAttestation, SignedBeaconBlock, phase0, ssz} from "@lodestar/types";
3
+ import {CachedBeaconStateAllForks} from "../types.js";
4
+ import {
5
+ ISignatureSet,
6
+ computeSigningRoot,
7
+ computeStartSlotAtEpoch,
8
+ createAggregateSignatureSetFromComponents,
9
+ } from "../util/index.js";
10
+
11
+ export function getAttestationDataSigningRoot(
12
+ state: CachedBeaconStateAllForks,
13
+ data: phase0.AttestationData
14
+ ): Uint8Array {
15
+ const slot = computeStartSlotAtEpoch(data.target.epoch);
16
+ const domain = state.config.getDomain(state.slot, DOMAIN_BEACON_ATTESTER, slot);
17
+
18
+ return computeSigningRoot(ssz.phase0.AttestationData, data, domain);
19
+ }
20
+
21
+ export function getAttestationWithIndicesSignatureSet(
22
+ state: CachedBeaconStateAllForks,
23
+ attestation: Pick<phase0.Attestation, "data" | "signature">,
24
+ attestingIndices: number[]
25
+ ): ISignatureSet {
26
+ return createAggregateSignatureSetFromComponents(
27
+ attestingIndices.map((i) => state.epochCtx.index2pubkey[i]),
28
+ getAttestationDataSigningRoot(state, attestation.data),
29
+ attestation.signature
30
+ );
31
+ }
32
+
33
+ export function getIndexedAttestationSignatureSet(
34
+ state: CachedBeaconStateAllForks,
35
+ indexedAttestation: IndexedAttestation
36
+ ): ISignatureSet {
37
+ return getAttestationWithIndicesSignatureSet(state, indexedAttestation, indexedAttestation.attestingIndices);
38
+ }
39
+
40
+ export function getAttestationsSignatureSets(
41
+ state: CachedBeaconStateAllForks,
42
+ signedBlock: SignedBeaconBlock
43
+ ): ISignatureSet[] {
44
+ // TODO: figure how to get attesting indices of an attestation once per block processing
45
+ return signedBlock.message.body.attestations.map((attestation) =>
46
+ getIndexedAttestationSignatureSet(
47
+ state,
48
+ state.epochCtx.getIndexedAttestation(state.config.getForkSeq(signedBlock.message.slot), attestation)
49
+ )
50
+ );
51
+ }
@@ -0,0 +1,47 @@
1
+ import {DOMAIN_BEACON_PROPOSER} from "@lodestar/params";
2
+ import {SignedBeaconBlock, SignedBlindedBeaconBlock, isBlindedBeaconBlock, phase0, ssz} from "@lodestar/types";
3
+ import {CachedBeaconStateAllForks} from "../types.js";
4
+ import {computeSigningRoot} from "../util/index.js";
5
+ import {ISignatureSet, SignatureSetType, verifySignatureSet} from "../util/signatureSets.js";
6
+
7
+ export function verifyProposerSignature(
8
+ state: CachedBeaconStateAllForks,
9
+ signedBlock: SignedBeaconBlock | SignedBlindedBeaconBlock
10
+ ): boolean {
11
+ const signatureSet = getBlockProposerSignatureSet(state, signedBlock);
12
+ return verifySignatureSet(signatureSet);
13
+ }
14
+
15
+ export function getBlockProposerSignatureSet(
16
+ state: CachedBeaconStateAllForks,
17
+ signedBlock: SignedBeaconBlock | SignedBlindedBeaconBlock
18
+ ): ISignatureSet {
19
+ const {config, epochCtx} = state;
20
+ const domain = config.getDomain(state.slot, DOMAIN_BEACON_PROPOSER, signedBlock.message.slot);
21
+
22
+ const blockType = isBlindedBeaconBlock(signedBlock.message)
23
+ ? config.getPostBellatrixForkTypes(signedBlock.message.slot).BlindedBeaconBlock
24
+ : config.getForkTypes(signedBlock.message.slot).BeaconBlock;
25
+
26
+ return {
27
+ type: SignatureSetType.single,
28
+ pubkey: epochCtx.index2pubkey[signedBlock.message.proposerIndex],
29
+ signingRoot: computeSigningRoot(blockType, signedBlock.message, domain),
30
+ signature: signedBlock.signature,
31
+ };
32
+ }
33
+
34
+ export function getBlockHeaderProposerSignatureSet(
35
+ state: CachedBeaconStateAllForks,
36
+ signedBlockHeader: phase0.SignedBeaconBlockHeader
37
+ ): ISignatureSet {
38
+ const {config, epochCtx} = state;
39
+ const domain = config.getDomain(state.slot, DOMAIN_BEACON_PROPOSER, signedBlockHeader.message.slot);
40
+
41
+ return {
42
+ type: SignatureSetType.single,
43
+ pubkey: epochCtx.index2pubkey[signedBlockHeader.message.proposerIndex],
44
+ signingRoot: computeSigningRoot(ssz.phase0.BeaconBlockHeader, signedBlockHeader.message, domain),
45
+ signature: signedBlockHeader.signature,
46
+ };
47
+ }
@@ -0,0 +1,41 @@
1
+ import {DOMAIN_BEACON_PROPOSER} from "@lodestar/params";
2
+ import {SignedBeaconBlock, phase0, ssz} from "@lodestar/types";
3
+ import {CachedBeaconStateAllForks} from "../types.js";
4
+ import {ISignatureSet, SignatureSetType, computeSigningRoot} from "../util/index.js";
5
+
6
+ /**
7
+ * Extract signatures to allow validating all block signatures at once
8
+ */
9
+ export function getProposerSlashingSignatureSets(
10
+ state: CachedBeaconStateAllForks,
11
+ proposerSlashing: phase0.ProposerSlashing
12
+ ): ISignatureSet[] {
13
+ const {epochCtx} = state;
14
+ const pubkey = epochCtx.index2pubkey[proposerSlashing.signedHeader1.message.proposerIndex];
15
+
16
+ // In state transition, ProposerSlashing headers are only partially validated. Their slot could be higher than the
17
+ // clock and the slashing would still be valid. Must use bigint variants to hash correctly to all possible values
18
+ return [proposerSlashing.signedHeader1, proposerSlashing.signedHeader2].map((signedHeader): ISignatureSet => {
19
+ const domain = state.config.getDomain(
20
+ state.slot,
21
+ DOMAIN_BEACON_PROPOSER,
22
+ Number(signedHeader.message.slot as bigint)
23
+ );
24
+
25
+ return {
26
+ type: SignatureSetType.single,
27
+ pubkey,
28
+ signingRoot: computeSigningRoot(ssz.phase0.BeaconBlockHeaderBigint, signedHeader.message, domain),
29
+ signature: signedHeader.signature,
30
+ };
31
+ });
32
+ }
33
+
34
+ export function getProposerSlashingsSignatureSets(
35
+ state: CachedBeaconStateAllForks,
36
+ signedBlock: SignedBeaconBlock
37
+ ): ISignatureSet[] {
38
+ return signedBlock.message.body.proposerSlashings.flatMap((proposerSlashing) =>
39
+ getProposerSlashingSignatureSets(state, proposerSlashing)
40
+ );
41
+ }
@@ -0,0 +1,31 @@
1
+ import {DOMAIN_RANDAO} from "@lodestar/params";
2
+ import {BeaconBlock, ssz} from "@lodestar/types";
3
+ import {CachedBeaconStateAllForks} from "../types.js";
4
+ import {
5
+ ISignatureSet,
6
+ SignatureSetType,
7
+ computeEpochAtSlot,
8
+ computeSigningRoot,
9
+ verifySignatureSet,
10
+ } from "../util/index.js";
11
+
12
+ export function verifyRandaoSignature(state: CachedBeaconStateAllForks, block: BeaconBlock): boolean {
13
+ return verifySignatureSet(getRandaoRevealSignatureSet(state, block));
14
+ }
15
+
16
+ /**
17
+ * Extract signatures to allow validating all block signatures at once
18
+ */
19
+ export function getRandaoRevealSignatureSet(state: CachedBeaconStateAllForks, block: BeaconBlock): ISignatureSet {
20
+ const {epochCtx} = state;
21
+ // should not get epoch from epochCtx
22
+ const epoch = computeEpochAtSlot(block.slot);
23
+ const domain = state.config.getDomain(state.slot, DOMAIN_RANDAO, block.slot);
24
+
25
+ return {
26
+ type: SignatureSetType.single,
27
+ pubkey: epochCtx.index2pubkey[block.proposerIndex],
28
+ signingRoot: computeSigningRoot(ssz.Epoch, epoch, domain),
29
+ signature: block.body.randaoReveal,
30
+ };
31
+ }
@@ -0,0 +1,44 @@
1
+ import {SignedBeaconBlock, phase0, ssz} from "@lodestar/types";
2
+ import {CachedBeaconStateAllForks} from "../types.js";
3
+ import {
4
+ ISignatureSet,
5
+ SignatureSetType,
6
+ computeSigningRoot,
7
+ computeStartSlotAtEpoch,
8
+ verifySignatureSet,
9
+ } from "../util/index.js";
10
+
11
+ export function verifyVoluntaryExitSignature(
12
+ state: CachedBeaconStateAllForks,
13
+ signedVoluntaryExit: phase0.SignedVoluntaryExit
14
+ ): boolean {
15
+ return verifySignatureSet(getVoluntaryExitSignatureSet(state, signedVoluntaryExit));
16
+ }
17
+
18
+ /**
19
+ * Extract signatures to allow validating all block signatures at once
20
+ */
21
+ export function getVoluntaryExitSignatureSet(
22
+ state: CachedBeaconStateAllForks,
23
+ signedVoluntaryExit: phase0.SignedVoluntaryExit
24
+ ): ISignatureSet {
25
+ const {epochCtx} = state;
26
+ const slot = computeStartSlotAtEpoch(signedVoluntaryExit.message.epoch);
27
+ const domain = state.config.getDomainForVoluntaryExit(state.slot, slot);
28
+
29
+ return {
30
+ type: SignatureSetType.single,
31
+ pubkey: epochCtx.index2pubkey[signedVoluntaryExit.message.validatorIndex],
32
+ signingRoot: computeSigningRoot(ssz.phase0.VoluntaryExit, signedVoluntaryExit.message, domain),
33
+ signature: signedVoluntaryExit.signature,
34
+ };
35
+ }
36
+
37
+ export function getVoluntaryExitsSignatureSets(
38
+ state: CachedBeaconStateAllForks,
39
+ signedBlock: SignedBeaconBlock
40
+ ): ISignatureSet[] {
41
+ return signedBlock.message.body.voluntaryExits.map((voluntaryExit) =>
42
+ getVoluntaryExitSignatureSet(state, voluntaryExit)
43
+ );
44
+ }
@@ -0,0 +1,32 @@
1
+ import {byteArrayEquals} from "@chainsafe/ssz";
2
+ import {SLOTS_PER_HISTORICAL_ROOT} from "@lodestar/params";
3
+ import {ZERO_HASH} from "../constants/index.js";
4
+ import {CachedBeaconStateAllForks} from "../types.js";
5
+
6
+ export {upgradeStateToAltair} from "./upgradeStateToAltair.js";
7
+ export {upgradeStateToBellatrix} from "./upgradeStateToBellatrix.js";
8
+ export {upgradeStateToCapella} from "./upgradeStateToCapella.js";
9
+ export {upgradeStateToDeneb} from "./upgradeStateToDeneb.js";
10
+ export {upgradeStateToElectra} from "./upgradeStateToElectra.js";
11
+ export {upgradeStateToFulu} from "./upgradeStateToFulu.js";
12
+ export {upgradeStateToGloas} from "./upgradeStateToGloas.js";
13
+
14
+ /**
15
+ * Dial state to next slot. Common for all forks
16
+ */
17
+ export function processSlot(state: CachedBeaconStateAllForks): void {
18
+ // Cache state root
19
+ // Note: .hashTreeRoot() automatically commits() pending changes
20
+ const previousStateRoot = state.hashTreeRoot();
21
+ state.stateRoots.set(state.slot % SLOTS_PER_HISTORICAL_ROOT, previousStateRoot);
22
+
23
+ // Cache latest block header state root
24
+ if (byteArrayEquals(state.latestBlockHeader.stateRoot, ZERO_HASH)) {
25
+ state.latestBlockHeader.stateRoot = previousStateRoot;
26
+ }
27
+
28
+ // Cache block root
29
+ // Note: .hashTreeRoot() automatically commits() pending changes
30
+ const previousBlockRoot = state.latestBlockHeader.hashTreeRoot();
31
+ state.blockRoots.set(state.slot % SLOTS_PER_HISTORICAL_ROOT, previousBlockRoot);
32
+ }