@lodestar/state-transition 1.46.0-dev.1cd9a671ea → 1.46.0-dev.1dde9abaa6

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 (292) hide show
  1. package/lib/block/externalData.js +2 -4
  2. package/lib/block/externalData.js.map +1 -1
  3. package/lib/block/index.d.ts.map +1 -1
  4. package/lib/block/index.js +3 -2
  5. package/lib/block/index.js.map +1 -1
  6. package/lib/block/initiateValidatorExit.js.map +1 -1
  7. package/lib/block/isValidIndexedAttestation.js.map +1 -1
  8. package/lib/block/isValidIndexedPayloadAttestation.js.map +1 -1
  9. package/lib/block/processAttestationPhase0.js.map +1 -1
  10. package/lib/block/processAttestations.d.ts +2 -2
  11. package/lib/block/processAttestations.d.ts.map +1 -1
  12. package/lib/block/processAttestations.js +2 -2
  13. package/lib/block/processAttestations.js.map +1 -1
  14. package/lib/block/processAttestationsAltair.d.ts +3 -3
  15. package/lib/block/processAttestationsAltair.d.ts.map +1 -1
  16. package/lib/block/processAttestationsAltair.js +7 -4
  17. package/lib/block/processAttestationsAltair.js.map +1 -1
  18. package/lib/block/processAttesterSlashing.js.map +1 -1
  19. package/lib/block/processBlobKzgCommitments.js.map +1 -1
  20. package/lib/block/processBlockHeader.js.map +1 -1
  21. package/lib/block/processBlsToExecutionChange.js.map +1 -1
  22. package/lib/block/processBuilderDepositRequest.js.map +1 -1
  23. package/lib/block/processBuilderExitRequest.js.map +1 -1
  24. package/lib/block/processConsolidationRequest.js.map +1 -1
  25. package/lib/block/processDeposit.d.ts +15 -0
  26. package/lib/block/processDeposit.d.ts.map +1 -1
  27. package/lib/block/processDeposit.js +73 -1
  28. package/lib/block/processDeposit.js.map +1 -1
  29. package/lib/block/processDepositRequest.js.map +1 -1
  30. package/lib/block/processEth1Data.js.map +1 -1
  31. package/lib/block/processExecutionPayload.js.map +1 -1
  32. package/lib/block/processExecutionPayloadBid.d.ts +3 -3
  33. package/lib/block/processExecutionPayloadBid.d.ts.map +1 -1
  34. package/lib/block/processExecutionPayloadBid.js +10 -3
  35. package/lib/block/processExecutionPayloadBid.js.map +1 -1
  36. package/lib/block/processOperations.d.ts +2 -2
  37. package/lib/block/processOperations.d.ts.map +1 -1
  38. package/lib/block/processOperations.js +2 -2
  39. package/lib/block/processOperations.js.map +1 -1
  40. package/lib/block/processParentExecutionPayload.js.map +1 -1
  41. package/lib/block/processPayloadAttestation.js.map +1 -1
  42. package/lib/block/processProposerSlashing.js.map +1 -1
  43. package/lib/block/processRandao.js.map +1 -1
  44. package/lib/block/processSyncCommittee.js.map +1 -1
  45. package/lib/block/processVoluntaryExit.js +1 -2
  46. package/lib/block/processVoluntaryExit.js.map +1 -1
  47. package/lib/block/processWithdrawalRequest.d.ts.map +1 -1
  48. package/lib/block/processWithdrawalRequest.js +2 -2
  49. package/lib/block/processWithdrawalRequest.js.map +1 -1
  50. package/lib/block/processWithdrawals.js.map +1 -1
  51. package/lib/block/slashValidator.js.map +1 -1
  52. package/lib/block/types.js +1 -2
  53. package/lib/block/types.js.map +1 -1
  54. package/lib/cache/builderDepositSignatureCache.d.ts +48 -0
  55. package/lib/cache/builderDepositSignatureCache.d.ts.map +1 -0
  56. package/lib/cache/builderDepositSignatureCache.js +70 -0
  57. package/lib/cache/builderDepositSignatureCache.js.map +1 -0
  58. package/lib/cache/effectiveBalanceIncrements.js.map +1 -1
  59. package/lib/cache/epochCache.d.ts +9 -0
  60. package/lib/cache/epochCache.d.ts.map +1 -1
  61. package/lib/cache/epochCache.js +32 -21
  62. package/lib/cache/epochCache.js.map +1 -1
  63. package/lib/cache/epochTransitionCache.js.map +1 -1
  64. package/lib/cache/pubkeyCache.js.map +1 -1
  65. package/lib/cache/rewardCache.js.map +1 -1
  66. package/lib/cache/stateCache.d.ts +2 -1
  67. package/lib/cache/stateCache.d.ts.map +1 -1
  68. package/lib/cache/stateCache.js +3 -2
  69. package/lib/cache/stateCache.js.map +1 -1
  70. package/lib/cache/syncCommitteeCache.js.map +1 -1
  71. package/lib/cache/types.d.ts +1 -0
  72. package/lib/cache/types.d.ts.map +1 -1
  73. package/lib/epoch/computeUnrealizedCheckpoints.js.map +1 -1
  74. package/lib/epoch/getAttestationDeltas.js.map +1 -1
  75. package/lib/epoch/getRewardsAndPenalties.js.map +1 -1
  76. package/lib/epoch/index.js +1 -2
  77. package/lib/epoch/index.js.map +1 -1
  78. package/lib/epoch/processBuilderPendingPayments.js.map +1 -1
  79. package/lib/epoch/processEffectiveBalanceUpdates.js.map +1 -1
  80. package/lib/epoch/processEth1DataReset.js.map +1 -1
  81. package/lib/epoch/processHistoricalRootsUpdate.js.map +1 -1
  82. package/lib/epoch/processHistoricalSummariesUpdate.js.map +1 -1
  83. package/lib/epoch/processInactivityUpdates.js.map +1 -1
  84. package/lib/epoch/processJustificationAndFinalization.js.map +1 -1
  85. package/lib/epoch/processParticipationFlagUpdates.js.map +1 -1
  86. package/lib/epoch/processParticipationRecordUpdates.js.map +1 -1
  87. package/lib/epoch/processPendingAttestations.js.map +1 -1
  88. package/lib/epoch/processPendingConsolidations.js.map +1 -1
  89. package/lib/epoch/processPendingDeposits.js.map +1 -1
  90. package/lib/epoch/processProposerLookahead.js.map +1 -1
  91. package/lib/epoch/processPtcWindow.js.map +1 -1
  92. package/lib/epoch/processRandaoMixesReset.js.map +1 -1
  93. package/lib/epoch/processRegistryUpdates.js.map +1 -1
  94. package/lib/epoch/processRewardsAndPenalties.js.map +1 -1
  95. package/lib/epoch/processSlashings.js.map +1 -1
  96. package/lib/epoch/processSlashingsReset.js.map +1 -1
  97. package/lib/epoch/processSyncCommitteeUpdates.js.map +1 -1
  98. package/lib/index.d.ts +2 -2
  99. package/lib/index.d.ts.map +1 -1
  100. package/lib/index.js +1 -1
  101. package/lib/index.js.map +1 -1
  102. package/lib/lightClient/proofs.js.map +1 -1
  103. package/lib/lightClient/spec/index.js.map +1 -1
  104. package/lib/lightClient/spec/isBetterUpdate.js.map +1 -1
  105. package/lib/lightClient/spec/processLightClientUpdate.js.map +1 -1
  106. package/lib/lightClient/spec/store.js.map +1 -1
  107. package/lib/lightClient/spec/utils.d.ts +0 -2
  108. package/lib/lightClient/spec/utils.d.ts.map +1 -1
  109. package/lib/lightClient/spec/utils.js +8 -2
  110. package/lib/lightClient/spec/utils.js.map +1 -1
  111. package/lib/lightClient/spec/validateLightClientBootstrap.js.map +1 -1
  112. package/lib/lightClient/spec/validateLightClientUpdate.js.map +1 -1
  113. package/lib/metrics.d.ts.map +1 -1
  114. package/lib/metrics.js +3 -2
  115. package/lib/metrics.js.map +1 -1
  116. package/lib/rewards/attestationsRewards.js.map +1 -1
  117. package/lib/rewards/blockRewards.d.ts.map +1 -1
  118. package/lib/rewards/blockRewards.js +7 -4
  119. package/lib/rewards/blockRewards.js.map +1 -1
  120. package/lib/rewards/syncCommitteeRewards.js.map +1 -1
  121. package/lib/signatureSets/attesterSlashings.js.map +1 -1
  122. package/lib/signatureSets/blsToExecutionChange.js.map +1 -1
  123. package/lib/signatureSets/executionPayloadBid.d.ts +2 -2
  124. package/lib/signatureSets/executionPayloadBid.d.ts.map +1 -1
  125. package/lib/signatureSets/executionPayloadBid.js +7 -5
  126. package/lib/signatureSets/executionPayloadBid.js.map +1 -1
  127. package/lib/signatureSets/executionPayloadEnvelope.js.map +1 -1
  128. package/lib/signatureSets/index.js.map +1 -1
  129. package/lib/signatureSets/indexedAttestation.js.map +1 -1
  130. package/lib/signatureSets/indexedPayloadAttestation.js.map +1 -1
  131. package/lib/signatureSets/proposer.js.map +1 -1
  132. package/lib/signatureSets/proposerPreferences.js.map +1 -1
  133. package/lib/signatureSets/proposerSlashings.js.map +1 -1
  134. package/lib/signatureSets/randao.js.map +1 -1
  135. package/lib/signatureSets/voluntaryExits.js.map +1 -1
  136. package/lib/slot/index.d.ts +1 -0
  137. package/lib/slot/index.d.ts.map +1 -1
  138. package/lib/slot/index.js +1 -0
  139. package/lib/slot/index.js.map +1 -1
  140. package/lib/slot/upgradeStateToAltair.js +1 -1
  141. package/lib/slot/upgradeStateToAltair.js.map +1 -1
  142. package/lib/slot/upgradeStateToBellatrix.js.map +1 -1
  143. package/lib/slot/upgradeStateToCapella.js.map +1 -1
  144. package/lib/slot/upgradeStateToDeneb.js.map +1 -1
  145. package/lib/slot/upgradeStateToElectra.js.map +1 -1
  146. package/lib/slot/upgradeStateToFulu.js.map +1 -1
  147. package/lib/slot/upgradeStateToGloas.js +14 -8
  148. package/lib/slot/upgradeStateToGloas.js.map +1 -1
  149. package/lib/slot/upgradeStateToHeze.d.ts +7 -0
  150. package/lib/slot/upgradeStateToHeze.d.ts.map +1 -0
  151. package/lib/slot/upgradeStateToHeze.js +83 -0
  152. package/lib/slot/upgradeStateToHeze.js.map +1 -0
  153. package/lib/stateTransition.d.ts.map +1 -1
  154. package/lib/stateTransition.js +6 -5
  155. package/lib/stateTransition.js.map +1 -1
  156. package/lib/stateView/beaconStateView.d.ts +3 -0
  157. package/lib/stateView/beaconStateView.d.ts.map +1 -1
  158. package/lib/stateView/beaconStateView.js +7 -0
  159. package/lib/stateView/beaconStateView.js.map +1 -1
  160. package/lib/stateView/interface.d.ts +16 -3
  161. package/lib/stateView/interface.d.ts.map +1 -1
  162. package/lib/stateView/interface.js +4 -1
  163. package/lib/stateView/interface.js.map +1 -1
  164. package/lib/stateView/nativeBeaconStateView.d.ts +3 -0
  165. package/lib/stateView/nativeBeaconStateView.d.ts.map +1 -1
  166. package/lib/stateView/nativeBeaconStateView.js +6 -0
  167. package/lib/stateView/nativeBeaconStateView.js.map +1 -1
  168. package/lib/stateView/stateViewFactory.js.map +1 -1
  169. package/lib/testUtils/infura.js.map +1 -1
  170. package/lib/testUtils/interop.js.map +1 -1
  171. package/lib/testUtils/params.d.ts.map +1 -1
  172. package/lib/testUtils/state.js +1 -1
  173. package/lib/testUtils/state.js.map +1 -1
  174. package/lib/testUtils/testFileCache.js.map +1 -1
  175. package/lib/testUtils/util.d.ts +17 -2
  176. package/lib/testUtils/util.d.ts.map +1 -1
  177. package/lib/testUtils/util.js +57 -4
  178. package/lib/testUtils/util.js.map +1 -1
  179. package/lib/types.d.ts +2 -2
  180. package/lib/types.d.ts.map +1 -1
  181. package/lib/util/aggregator.js.map +1 -1
  182. package/lib/util/altair.js.map +1 -1
  183. package/lib/util/array.js.map +1 -1
  184. package/lib/util/attestation.js.map +1 -1
  185. package/lib/util/attesterStatus.js.map +1 -1
  186. package/lib/util/balance.js.map +1 -1
  187. package/lib/util/blindedBlock.js.map +1 -1
  188. package/lib/util/blockRoot.js.map +1 -1
  189. package/lib/util/capella.js.map +1 -1
  190. package/lib/util/clock.d.ts +61 -0
  191. package/lib/util/clock.d.ts.map +1 -0
  192. package/lib/util/clock.js +141 -0
  193. package/lib/util/clock.js.map +1 -0
  194. package/lib/util/computeAnchorCheckpoint.js.map +1 -1
  195. package/lib/util/deposit.d.ts.map +1 -1
  196. package/lib/util/deposit.js +10 -8
  197. package/lib/util/deposit.js.map +1 -1
  198. package/lib/util/domain.js.map +1 -1
  199. package/lib/util/electra.js.map +1 -1
  200. package/lib/util/epoch.js.map +1 -1
  201. package/lib/util/epochShuffling.js.map +1 -1
  202. package/lib/util/execution.js.map +1 -1
  203. package/lib/util/finality.js.map +1 -1
  204. package/lib/util/fulu.js.map +1 -1
  205. package/lib/util/genesis.d.ts.map +1 -1
  206. package/lib/util/genesis.js +7 -2
  207. package/lib/util/genesis.js.map +1 -1
  208. package/lib/util/gloas.d.ts +2 -1
  209. package/lib/util/gloas.d.ts.map +1 -1
  210. package/lib/util/gloas.js +7 -4
  211. package/lib/util/gloas.js.map +1 -1
  212. package/lib/util/index.d.ts +2 -0
  213. package/lib/util/index.d.ts.map +1 -1
  214. package/lib/util/index.js +2 -0
  215. package/lib/util/index.js.map +1 -1
  216. package/lib/util/interop.js.map +1 -1
  217. package/lib/util/loadState/findModifiedInactivityScores.js.map +1 -1
  218. package/lib/util/loadState/findModifiedValidators.js.map +1 -1
  219. package/lib/util/loadState/loadState.d.ts.map +1 -1
  220. package/lib/util/loadState/loadState.js +36 -5
  221. package/lib/util/loadState/loadState.js.map +1 -1
  222. package/lib/util/loadState/loadValidator.js.map +1 -1
  223. package/lib/util/pendingDepositsLookup.d.ts +7 -10
  224. package/lib/util/pendingDepositsLookup.d.ts.map +1 -1
  225. package/lib/util/pendingDepositsLookup.js +10 -19
  226. package/lib/util/pendingDepositsLookup.js.map +1 -1
  227. package/lib/util/preVerifyBuilderDeposits.d.ts +52 -0
  228. package/lib/util/preVerifyBuilderDeposits.d.ts.map +1 -0
  229. package/lib/util/preVerifyBuilderDeposits.js +124 -0
  230. package/lib/util/preVerifyBuilderDeposits.js.map +1 -0
  231. package/lib/util/rootCache.js.map +1 -1
  232. package/lib/util/seed.js.map +1 -1
  233. package/lib/util/shuffling.js +1 -2
  234. package/lib/util/shuffling.js.map +1 -1
  235. package/lib/util/signatureSets.js +1 -2
  236. package/lib/util/signatureSets.js.map +1 -1
  237. package/lib/util/signingRoot.js.map +1 -1
  238. package/lib/util/slot.js.map +1 -1
  239. package/lib/util/ssz.d.ts +5 -0
  240. package/lib/util/ssz.d.ts.map +1 -1
  241. package/lib/util/ssz.js +8 -1
  242. package/lib/util/ssz.js.map +1 -1
  243. package/lib/util/sszBytes.js.map +1 -1
  244. package/lib/util/syncCommittee.js.map +1 -1
  245. package/lib/util/targetUnslashedBalance.js.map +1 -1
  246. package/lib/util/validator.d.ts +5 -0
  247. package/lib/util/validator.d.ts.map +1 -1
  248. package/lib/util/validator.js +9 -0
  249. package/lib/util/validator.js.map +1 -1
  250. package/lib/util/weakSubjectivity.d.ts +1 -0
  251. package/lib/util/weakSubjectivity.d.ts.map +1 -1
  252. package/lib/util/weakSubjectivity.js +20 -8
  253. package/lib/util/weakSubjectivity.js.map +1 -1
  254. package/package.json +15 -15
  255. package/src/block/index.ts +4 -3
  256. package/src/block/processAttestations.ts +10 -2
  257. package/src/block/processAttestationsAltair.ts +10 -4
  258. package/src/block/processDeposit.ts +75 -1
  259. package/src/block/processExecutionPayloadBid.ts +22 -9
  260. package/src/block/processOperations.ts +3 -2
  261. package/src/block/processWithdrawalRequest.ts +6 -2
  262. package/src/cache/builderDepositSignatureCache.ts +81 -0
  263. package/src/cache/epochCache.ts +33 -22
  264. package/src/cache/stateCache.ts +5 -2
  265. package/src/cache/types.ts +1 -0
  266. package/src/index.ts +4 -0
  267. package/src/lightClient/spec/utils.ts +9 -2
  268. package/src/metrics.ts +3 -2
  269. package/src/rewards/blockRewards.ts +20 -5
  270. package/src/signatureSets/executionPayloadBid.ts +7 -9
  271. package/src/slot/index.ts +1 -0
  272. package/src/slot/upgradeStateToAltair.ts +1 -0
  273. package/src/slot/upgradeStateToGloas.ts +18 -11
  274. package/src/slot/upgradeStateToHeze.ts +91 -0
  275. package/src/stateTransition.ts +5 -0
  276. package/src/stateView/beaconStateView.ts +13 -0
  277. package/src/stateView/interface.ts +21 -2
  278. package/src/stateView/nativeBeaconStateView.ts +9 -0
  279. package/src/testUtils/state.ts +1 -1
  280. package/src/testUtils/util.ts +75 -5
  281. package/src/types.ts +2 -0
  282. package/src/util/clock.ts +183 -0
  283. package/src/util/deposit.ts +11 -9
  284. package/src/util/genesis.ts +8 -2
  285. package/src/util/gloas.ts +9 -5
  286. package/src/util/index.ts +2 -0
  287. package/src/util/loadState/loadState.ts +50 -11
  288. package/src/util/pendingDepositsLookup.ts +13 -24
  289. package/src/util/preVerifyBuilderDeposits.ts +153 -0
  290. package/src/util/ssz.ts +9 -1
  291. package/src/util/validator.ts +17 -0
  292. package/src/util/weakSubjectivity.ts +61 -22
package/package.json CHANGED
@@ -11,36 +11,36 @@
11
11
  "bugs": {
12
12
  "url": "https://github.com/ChainSafe/lodestar/issues"
13
13
  },
14
- "version": "1.46.0-dev.1cd9a671ea",
14
+ "version": "1.46.0-dev.1dde9abaa6",
15
15
  "type": "module",
16
16
  "exports": {
17
17
  ".": {
18
- "bun": "./src/index.ts",
18
+ "typescript": "./src/index.ts",
19
19
  "types": "./lib/index.d.ts",
20
20
  "import": "./lib/index.js"
21
21
  },
22
22
  "./block": {
23
- "bun": "./src/block/index.ts",
23
+ "typescript": "./src/block/index.ts",
24
24
  "types": "./lib/block/index.d.ts",
25
25
  "import": "./lib/block/index.js"
26
26
  },
27
27
  "./epoch": {
28
- "bun": "./src/epoch/index.ts",
28
+ "typescript": "./src/epoch/index.ts",
29
29
  "types": "./lib/epoch/index.d.ts",
30
30
  "import": "./lib/epoch/index.js"
31
31
  },
32
32
  "./slot": {
33
- "bun": "./src/slot/index.ts",
33
+ "typescript": "./src/slot/index.ts",
34
34
  "types": "./lib/slot/index.d.ts",
35
35
  "import": "./lib/slot/index.js"
36
36
  },
37
37
  "./light-client": {
38
- "bun": "./src/lightClient/spec/index.ts",
38
+ "typescript": "./src/lightClient/spec/index.ts",
39
39
  "types": "./lib/lightClient/spec/index.d.ts",
40
40
  "import": "./lib/lightClient/spec/index.js"
41
41
  },
42
42
  "./test-utils": {
43
- "bun": "./src/testUtils/index.ts",
43
+ "typescript": "./src/testUtils/index.ts",
44
44
  "types": "./lib/testUtils/index.d.ts",
45
45
  "import": "./lib/testUtils/index.js"
46
46
  }
@@ -52,11 +52,11 @@
52
52
  ],
53
53
  "scripts": {
54
54
  "clean": "rm -rf lib && rm -f *.tsbuildinfo",
55
- "build": "tsgo -p tsconfig.build.json",
55
+ "build": "tsc -p tsconfig.build.json",
56
56
  "build:watch": "pnpm run build --watch",
57
57
  "build:release": "pnpm clean && pnpm build",
58
58
  "check-build": "node -e \"(async function() { await import('./lib/index.js') })()\"",
59
- "check-types": "tsgo",
59
+ "check-types": "tsc",
60
60
  "lint": "biome check src/ test/",
61
61
  "lint:fix": "pnpm run lint --write",
62
62
  "test": "pnpm test:unit",
@@ -71,14 +71,14 @@
71
71
  "@chainsafe/pubkey-index-map": "^3.0.0",
72
72
  "@chainsafe/ssz": "^1.6.2",
73
73
  "@chainsafe/swap-or-not-shuffle": "^1.2.1",
74
- "@lodestar/config": "^1.46.0-dev.1cd9a671ea",
75
- "@lodestar/params": "^1.46.0-dev.1cd9a671ea",
76
- "@lodestar/types": "^1.46.0-dev.1cd9a671ea",
77
- "@lodestar/utils": "^1.46.0-dev.1cd9a671ea",
74
+ "@lodestar/config": "^1.46.0-dev.1dde9abaa6",
75
+ "@lodestar/params": "^1.46.0-dev.1dde9abaa6",
76
+ "@lodestar/types": "^1.46.0-dev.1dde9abaa6",
77
+ "@lodestar/utils": "^1.46.0-dev.1dde9abaa6",
78
78
  "@vekexasia/bigint-buffer2": "^1.1.1"
79
79
  },
80
80
  "devDependencies": {
81
- "@lodestar/api": "^1.46.0-dev.1cd9a671ea"
81
+ "@lodestar/api": "^1.46.0-dev.1dde9abaa6"
82
82
  },
83
83
  "keywords": [
84
84
  "ethereum",
@@ -86,5 +86,5 @@
86
86
  "beacon",
87
87
  "blockchain"
88
88
  ],
89
- "gitHead": "4b927ade924253bac78cab64f9ffc45862b91682"
89
+ "gitHead": "c4cd3268c1c86a757880db46afe78e3f76c8abc9"
90
90
  }
@@ -1,5 +1,5 @@
1
1
  import {ForkPostGloas, ForkSeq} from "@lodestar/params";
2
- import {BeaconBlock, BlindedBeaconBlock, altair, capella} from "@lodestar/types";
2
+ import {BeaconBlock, BlindedBeaconBlock, Slot, altair, capella} from "@lodestar/types";
3
3
  import {BeaconStateTransitionMetrics} from "../metrics.js";
4
4
  import {
5
5
  CachedBeaconStateAllForks,
@@ -86,8 +86,9 @@ export function processBlock(
86
86
  processExecutionPayload(fork, state as CachedBeaconStateBellatrix, block.body, externalData);
87
87
  }
88
88
 
89
+ let parentSlot: Slot | null = null;
89
90
  if (fork >= ForkSeq.gloas) {
90
- processExecutionPayloadBid(
91
+ parentSlot = processExecutionPayloadBid(
91
92
  state as CachedBeaconStateGloas,
92
93
  (block as BeaconBlock<ForkPostGloas>).body.signedExecutionPayloadBid
93
94
  );
@@ -95,7 +96,7 @@ export function processBlock(
95
96
 
96
97
  processRandao(state, block, verifySignatures);
97
98
  processEth1Data(state, block.body.eth1Data);
98
- processOperations(fork, state, block.body, opts, metrics);
99
+ processOperations(fork, state, block.body, parentSlot, opts, metrics);
99
100
  if (fork >= ForkSeq.altair) {
100
101
  processSyncAggregate(state, block as altair.BeaconBlock, verifySignatures);
101
102
  }
@@ -1,5 +1,5 @@
1
1
  import {ForkSeq} from "@lodestar/params";
2
- import {Attestation} from "@lodestar/types";
2
+ import {Attestation, Slot} from "@lodestar/types";
3
3
  import {BeaconStateTransitionMetrics} from "../metrics.js";
4
4
  import {CachedBeaconStateAllForks, CachedBeaconStateAltair, CachedBeaconStatePhase0} from "../types.js";
5
5
  import {processAttestationPhase0} from "./processAttestationPhase0.js";
@@ -12,6 +12,7 @@ export function processAttestations(
12
12
  fork: ForkSeq,
13
13
  state: CachedBeaconStateAllForks,
14
14
  attestations: Attestation[],
15
+ parentSlot: Slot | null,
15
16
  verifySignatures = true,
16
17
  metrics?: BeaconStateTransitionMetrics | null
17
18
  ): void {
@@ -20,6 +21,13 @@ export function processAttestations(
20
21
  processAttestationPhase0(state as CachedBeaconStatePhase0, attestation, verifySignatures);
21
22
  }
22
23
  } else {
23
- processAttestationsAltair(fork, state as CachedBeaconStateAltair, attestations, verifySignatures, metrics);
24
+ processAttestationsAltair(
25
+ fork,
26
+ state as CachedBeaconStateAltair,
27
+ attestations,
28
+ parentSlot,
29
+ verifySignatures,
30
+ metrics
31
+ );
24
32
  }
25
33
  }
@@ -14,7 +14,7 @@ import {
14
14
  TIMELY_TARGET_WEIGHT,
15
15
  WEIGHT_DENOMINATOR,
16
16
  } from "@lodestar/params";
17
- import {Attestation, Epoch, phase0} from "@lodestar/types";
17
+ import {Attestation, Epoch, Slot, phase0} from "@lodestar/types";
18
18
  import {byteArrayEquals, intSqrt} from "@lodestar/utils";
19
19
  import {BeaconStateTransitionMetrics} from "../metrics.js";
20
20
  import {getAttestationWithIndicesSignatureSet} from "../signatureSets/indexedAttestation.js";
@@ -37,6 +37,7 @@ export function processAttestationsAltair(
37
37
  fork: ForkSeq,
38
38
  state: CachedBeaconStateAltair | CachedBeaconStateGloas,
39
39
  attestations: Attestation[],
40
+ parentSlot: Slot | null,
40
41
  verifySignature = true,
41
42
  metrics?: BeaconStateTransitionMetrics | null
42
43
  ): void {
@@ -82,7 +83,8 @@ export function processAttestationsAltair(
82
83
  stateSlot - data.slot,
83
84
  epochCtx.epoch,
84
85
  rootCache,
85
- fork >= ForkSeq.gloas ? (state as CachedBeaconStateGloas).executionPayloadAvailability : null
86
+ fork >= ForkSeq.gloas ? (state as CachedBeaconStateGloas).executionPayloadAvailability : null,
87
+ parentSlot
86
88
  );
87
89
 
88
90
  // For each participant, update their participation
@@ -179,7 +181,8 @@ export function getAttestationParticipationStatus(
179
181
  inclusionDelay: number,
180
182
  currentEpoch: Epoch,
181
183
  rootCache: RootCache,
182
- executionPayloadAvailability: BitArray | null
184
+ executionPayloadAvailability: BitArray | null,
185
+ parentSlot: Slot | null
183
186
  ): {flags: number; isSameSlotAttestation: boolean} {
184
187
  const justifiedCheckpoint =
185
188
  data.target.epoch === currentEpoch ? rootCache.currentJustifiedCheckpoint : rootCache.previousJustifiedCheckpoint;
@@ -221,13 +224,16 @@ export function getAttestationParticipationStatus(
221
224
  if (executionPayloadAvailability === null) {
222
225
  throw new Error("Must supply executionPayloadAvailability post-gloas");
223
226
  }
227
+ if (parentSlot === null) {
228
+ throw new Error("Must supply parentSlot post-gloas");
229
+ }
224
230
 
225
231
  if (data.index !== 0 && data.index !== 1) {
226
232
  throw new Error(`data index must be 0 or 1 index=${data.index}`);
227
233
  }
228
234
 
229
235
  isMatchingPayload =
230
- Boolean(data.index) === executionPayloadAvailability.get(data.slot % SLOTS_PER_HISTORICAL_ROOT);
236
+ Boolean(data.index) === executionPayloadAvailability.get(parentSlot % SLOTS_PER_HISTORICAL_ROOT);
231
237
  }
232
238
 
233
239
  isMatchingHead = isMatchingHead && isMatchingPayload;
@@ -1,4 +1,4 @@
1
- import {PublicKey, Signature, verify} from "@chainsafe/blst";
1
+ import {PublicKey, Signature, verify, verifyMultipleAggregateSignatures} from "@chainsafe/blst";
2
2
  import {BeaconConfig} from "@lodestar/config";
3
3
  import {
4
4
  DEPOSIT_CONTRACT_TREE_DEPTH,
@@ -138,6 +138,10 @@ export function addValidatorToRegistry(
138
138
  state.balances.push(amount);
139
139
  }
140
140
 
141
+ /**
142
+ * Verify a single deposit signature (proof of possession). See {@link verifyDepositSignatures} for
143
+ * the batch equivalent — the two MUST stay consistent (same domain, signing root, and checks).
144
+ */
141
145
  export function isValidDepositSignature(
142
146
  config: BeaconConfig,
143
147
  pubkey: Uint8Array,
@@ -164,3 +168,73 @@ export function isValidDepositSignature(
164
168
  return false; // Catch all BLS errors: failed key validation, failed signature validation, invalid signature
165
169
  }
166
170
  }
171
+
172
+ /**
173
+ * Batch equivalent of {@link isValidDepositSignature} — verify many deposit signatures at once.
174
+ * MUST stay consistent with `isValidDepositSignature`: same fork-agnostic deposit domain, same
175
+ * `DepositMessage` signing root, same group + infinity checks. Tries a single aggregate verify and,
176
+ * on failure, falls back to verifying each deposit individually so the valid deposits in a batch
177
+ * containing an invalid one are still identified. Returns a boolean per input deposit; `slot` is not
178
+ * part of the signature check.
179
+ *
180
+ * Used by the pre-Gloas builder-deposit pre-verify scanner (see `preVerifyBuilderDeposits.ts`).
181
+ */
182
+ export function verifyDepositSignatures(config: BeaconConfig, deposits: electra.PendingDeposit[]): boolean[] {
183
+ const results = new Array<boolean>(deposits.length).fill(false);
184
+ // fork-agnostic domain since deposits are valid across forks, matching isValidDepositSignature
185
+ const domain = computeDomain(DOMAIN_DEPOSIT, config.GENESIS_FORK_VERSION, ZERO_HASH);
186
+
187
+ const signatureSets: {pk: PublicKey; msg: Uint8Array; sig: Signature}[] = [];
188
+ const signatureSetDepositIndices: number[] = [];
189
+ for (let i = 0; i < deposits.length; i++) {
190
+ const {pubkey, withdrawalCredentials, amount, signature} = deposits[i];
191
+ let pk: PublicKey;
192
+ let sig: Signature;
193
+ try {
194
+ // Parse without group/infinity checks; deferred to the verify call below so it can be
195
+ // batched across all sets.
196
+ pk = PublicKey.fromBytes(pubkey);
197
+ sig = Signature.fromBytes(signature);
198
+ } catch (_) {
199
+ // Malformed pubkey or signature bytes - invalid deposit, results[i] stays false
200
+ continue;
201
+ }
202
+ const msg = computeSigningRoot(ssz.phase0.DepositMessage, {pubkey, withdrawalCredentials, amount}, domain);
203
+ signatureSets.push({pk, msg, sig});
204
+ signatureSetDepositIndices.push(i);
205
+ }
206
+
207
+ if (signatureSets.length === 0) {
208
+ return results;
209
+ }
210
+
211
+ // Deposit pubkeys and signatures are untrusted, so group + infinity checks are required.
212
+ // The trailing (true, true) args delegate those checks to blst, amortized across the batch.
213
+ let batchValid: boolean;
214
+ try {
215
+ batchValid =
216
+ signatureSets.length >= 2
217
+ ? verifyMultipleAggregateSignatures(signatureSets, true, true)
218
+ : verify(signatureSets[0].msg, signatureSets[0].pk, signatureSets[0].sig, true, true);
219
+ } catch (_) {
220
+ batchValid = false;
221
+ }
222
+
223
+ if (batchValid) {
224
+ for (const depositIndex of signatureSetDepositIndices) {
225
+ results[depositIndex] = true;
226
+ }
227
+ } else {
228
+ for (let s = 0; s < signatureSets.length; s++) {
229
+ try {
230
+ if (verify(signatureSets[s].msg, signatureSets[s].pk, signatureSets[s].sig, true, true)) {
231
+ results[signatureSetDepositIndices[s]] = true;
232
+ }
233
+ } catch (_) {
234
+ // invalid point / malformed → invalid signature, results[i] stays false
235
+ }
236
+ }
237
+ }
238
+
239
+ return results;
240
+ }
@@ -1,17 +1,23 @@
1
1
  import {PublicKey, Signature, verify} from "@chainsafe/blst";
2
- import {BUILDER_INDEX_SELF_BUILD, GENESIS_SLOT, PAYLOAD_BUILDER_VERSION, SLOTS_PER_EPOCH} from "@lodestar/params";
3
- import {gloas, ssz} from "@lodestar/types";
2
+ import {
3
+ BUILDER_INDEX_SELF_BUILD,
4
+ ForkSeq,
5
+ GENESIS_SLOT,
6
+ PAYLOAD_BUILDER_VERSION,
7
+ SLOTS_PER_EPOCH,
8
+ } from "@lodestar/params";
9
+ import {Slot, gloas, heze, ssz} from "@lodestar/types";
4
10
  import {byteArrayEquals, toHex, toRootHex} from "@lodestar/utils";
5
11
  import {G2_POINT_AT_INFINITY} from "../constants/constants.js";
6
12
  import {getExecutionPayloadBidSigningRoot} from "../signatureSets/executionPayloadBid.js";
7
- import {CachedBeaconStateGloas} from "../types.js";
13
+ import {CachedBeaconStateGloas, CachedBeaconStateHeze} from "../types.js";
8
14
  import {canBuilderCoverBid, isActiveBuilder} from "../util/gloas.js";
9
15
  import {getBlockRootAtSlot, getCurrentEpoch, getRandaoMix} from "../util/index.js";
10
16
 
11
17
  export function processExecutionPayloadBid(
12
- state: CachedBeaconStateGloas,
18
+ state: CachedBeaconStateGloas | CachedBeaconStateHeze,
13
19
  signedBid: gloas.SignedExecutionPayloadBid
14
- ): void {
20
+ ): Slot {
15
21
  const bid = signedBid.message;
16
22
  const {builderIndex, value: amount} = bid;
17
23
 
@@ -41,7 +47,7 @@ export function processExecutionPayloadBid(
41
47
  }
42
48
 
43
49
  // Verify that the builder has funds to cover the bid
44
- if (!canBuilderCoverBid(state, builderIndex, amount)) {
50
+ if (!canBuilderCoverBid(state as CachedBeaconStateGloas, builderIndex, amount)) {
45
51
  throw Error(`Invalid execution payload bid: builder ${builderIndex} has insufficient balance`);
46
52
  }
47
53
 
@@ -99,15 +105,22 @@ export function processExecutionPayloadBid(
99
105
  state.builderPendingPayments.set(SLOTS_PER_EPOCH + (bid.slot % SLOTS_PER_EPOCH), pendingPaymentView);
100
106
  }
101
107
 
102
- state.latestExecutionPayloadBid = ssz.gloas.ExecutionPayloadBid.toViewDU(bid);
108
+ const parentSlot = state.latestExecutionPayloadBid.slot;
109
+ if (state.config.getForkSeq(state.slot) >= ForkSeq.heze) {
110
+ state.latestExecutionPayloadBid = ssz.heze.ExecutionPayloadBid.toViewDU(bid as heze.ExecutionPayloadBid);
111
+ } else {
112
+ state.latestExecutionPayloadBid = ssz.gloas.ExecutionPayloadBid.toViewDU(bid);
113
+ }
114
+
115
+ return parentSlot;
103
116
  }
104
117
 
105
118
  function verifyExecutionPayloadBidSignature(
106
- state: CachedBeaconStateGloas,
119
+ state: CachedBeaconStateGloas | CachedBeaconStateHeze,
107
120
  pubkey: Uint8Array,
108
121
  signedBid: gloas.SignedExecutionPayloadBid
109
122
  ): boolean {
110
- const signingRoot = getExecutionPayloadBidSigningRoot(state.config, state.slot, signedBid.message);
123
+ const signingRoot = getExecutionPayloadBidSigningRoot(state.config, signedBid.message);
111
124
 
112
125
  try {
113
126
  const publicKey = PublicKey.fromBytes(pubkey);
@@ -7,7 +7,7 @@ import {
7
7
  MAX_PROPOSER_SLASHINGS,
8
8
  MAX_VOLUNTARY_EXITS,
9
9
  } from "@lodestar/params";
10
- import {BeaconBlockBody, capella, electra, gloas} from "@lodestar/types";
10
+ import {BeaconBlockBody, Slot, capella, electra, gloas} from "@lodestar/types";
11
11
  import {BeaconStateTransitionMetrics} from "../metrics.js";
12
12
  import {
13
13
  CachedBeaconStateAllForks,
@@ -44,6 +44,7 @@ export function processOperations(
44
44
  fork: ForkSeq,
45
45
  state: CachedBeaconStateAllForks,
46
46
  body: BeaconBlockBody,
47
+ parentSlot: Slot | null,
47
48
  opts: ProcessBlockOpts = {verifySignatures: true},
48
49
  metrics?: BeaconStateTransitionMetrics | null
49
50
  ): void {
@@ -67,7 +68,7 @@ export function processOperations(
67
68
  processAttesterSlashing(fork, state, attesterSlashing, opts.verifySignatures);
68
69
  }
69
70
 
70
- processAttestations(fork, state, body.attestations, opts.verifySignatures, metrics);
71
+ processAttestations(fork, state, body.attestations, parentSlot, opts.verifySignatures, metrics);
71
72
 
72
73
  for (const deposit of body.deposits) {
73
74
  processDeposit(fork, state, deposit);
@@ -8,7 +8,11 @@ import {
8
8
  import {electra, phase0, ssz} from "@lodestar/types";
9
9
  import {toHex} from "@lodestar/utils";
10
10
  import {CachedBeaconStateElectra, CachedBeaconStateGloas} from "../types.js";
11
- import {hasCompoundingWithdrawalCredential, hasExecutionWithdrawalCredential} from "../util/electra.js";
11
+ import {
12
+ hasCompoundingWithdrawalCredential,
13
+ hasExecutionWithdrawalCredential,
14
+ isValidatorKnown,
15
+ } from "../util/electra.js";
12
16
  import {computeExitEpochAndUpdateChurn} from "../util/epoch.js";
13
17
  import {getPendingBalanceToWithdraw, isActiveValidator} from "../util/validator.js";
14
18
  import {initiateValidatorExit} from "./initiateValidatorExit.js";
@@ -32,7 +36,7 @@ export function processWithdrawalRequest(
32
36
  // bail out if validator is not in beacon state
33
37
  // note that we don't need to check for 6110 unfinalized vals as they won't be eligible for withdraw/exit anyway
34
38
  const validatorIndex = pubkeyCache.getIndex(withdrawalRequest.validatorPubkey);
35
- if (validatorIndex === null) {
39
+ if (!isValidatorKnown(state, validatorIndex)) {
36
40
  return;
37
41
  }
38
42
 
@@ -0,0 +1,81 @@
1
+ import {PubkeyHex, electra} from "@lodestar/types";
2
+
3
+ /**
4
+ * Caches deposit signature-verification results — passes (`true`) and failures (`false`) — so the
5
+ * Fulu → Gloas fork transition can skip the bulk verification cost AND skip re-verifying deposits
6
+ * already proven invalid. Covers both builder-prefix deposits (onboarding) and validator deposits
7
+ * that share a pubkey with a builder deposit (the ones `hasPendingValidator` checks at the fork).
8
+ *
9
+ * Keyed by the deposit's struct **value object** — `electra.PendingDeposit` is a
10
+ * `ContainerNodeStructType`, so its `node.value` is a stable object reused across
11
+ * prepareNextSlot-derived states and carried by reference through the gloas pendingDeposits
12
+ * migration. No merkle-root computation, no slot bucketing.
13
+ *
14
+ * Also tracks builder pubkeys seen so the scanner knows which validator deposits to pre-verify (only
15
+ * those sharing a pubkey with a builder deposit ever reach `hasPendingValidator`). The mapped boolean
16
+ * records whether a *valid* validator deposit for that pubkey has been found: once true, the scanner
17
+ * stops pre-verifying further validator deposits for it — `hasPendingValidator` short-circuits on the
18
+ * first valid signature at the fork, so the rest would never be read.
19
+ *
20
+ * Lifecycle owned by `prepareNextSlot`: filled during the pre-fork window, then `clear()`ed once the
21
+ * Gloas fork is finalized. `onboardBuildersFromPendingDeposits()` only reads it. A plain `Map` (not a
22
+ * `WeakMap`) is used so the drop is deterministic and the contents are inspectable for logging.
23
+ *
24
+ * Single instance across the application (created in `EpochCache.createFromState`, shared
25
+ * by-reference through `clone()`).
26
+ */
27
+ export class BuilderDepositSignatureCache {
28
+ private validityByDeposit = new Map<electra.PendingDeposit, boolean>();
29
+ /** builder pubkey → whether a valid validator deposit sharing it has already been pre-verified. */
30
+ private builderPubkeys = new Map<PubkeyHex, boolean>();
31
+
32
+ setSignatureValidity(deposit: electra.PendingDeposit, isValid: boolean): void {
33
+ this.validityByDeposit.set(deposit, isValid);
34
+ }
35
+
36
+ getSignatureValidity(deposit: electra.PendingDeposit): boolean | null {
37
+ return this.validityByDeposit.get(deposit) ?? null;
38
+ }
39
+
40
+ isVerified(deposit: electra.PendingDeposit): boolean {
41
+ return this.validityByDeposit.has(deposit);
42
+ }
43
+
44
+ /** Record a builder deposit's pubkey so the scanner pre-verifies validator deposits for it.
45
+ * Idempotent; never downgrades a pubkey already marked as having a valid validator deposit. */
46
+ addBuilderPubkey(pubkeyHex: PubkeyHex): void {
47
+ if (!this.builderPubkeys.has(pubkeyHex)) {
48
+ this.builderPubkeys.set(pubkeyHex, false);
49
+ }
50
+ }
51
+
52
+ isBuilderPubkey(pubkeyHex: PubkeyHex): boolean {
53
+ return this.builderPubkeys.has(pubkeyHex);
54
+ }
55
+
56
+ /** True once a valid validator deposit sharing this builder pubkey has been pre-verified — the
57
+ * scanner then skips this pubkey's remaining validator deposits (as `hasPendingValidator` would). */
58
+ hasValidValidatorDeposit(pubkeyHex: PubkeyHex): boolean {
59
+ return this.builderPubkeys.get(pubkeyHex) === true;
60
+ }
61
+
62
+ /** Mark that a valid validator deposit sharing this builder pubkey was found. */
63
+ setValidValidatorDeposit(pubkeyHex: PubkeyHex): void {
64
+ this.builderPubkeys.set(pubkeyHex, true);
65
+ }
66
+
67
+ /** Cumulative deposits verified & cached this window (pass + fail). */
68
+ get cachedDepositCount(): number {
69
+ return this.validityByDeposit.size;
70
+ }
71
+
72
+ /** Distinct builder pubkeys tracked this window. */
73
+ get builderPubkeyCount(): number {
74
+ return this.builderPubkeys.size;
75
+ }
76
+
77
+ clear(): void {
78
+ this.validityByDeposit.clear();
79
+ this.builderPubkeys.clear();
80
+ }
81
+ }
@@ -53,6 +53,7 @@ import {
53
53
  } from "../util/shuffling.js";
54
54
  import {computeBaseRewardPerIncrement, computeSyncParticipantReward} from "../util/syncCommittee.js";
55
55
  import {sumTargetUnslashedBalanceIncrements} from "../util/targetUnslashedBalance.js";
56
+ import {BuilderDepositSignatureCache} from "./builderDepositSignatureCache.js";
56
57
  import {EffectiveBalanceIncrements, getEffectiveBalanceIncrementsWithLen} from "./effectiveBalanceIncrements.js";
57
58
  import {EpochTransitionCache} from "./epochTransitionCache.js";
58
59
  import {PubkeyCache, createPubkeyCache, syncPubkeys} from "./pubkeyCache.js";
@@ -112,6 +113,13 @@ export class EpochCache {
112
113
  * Couples both index→pubkey and pubkey→index lookups, keeping them in sync atomically.
113
114
  */
114
115
  pubkeyCache: PubkeyCache;
116
+ /**
117
+ * Shared across all clones of the same chain head. Holds builder deposit signature validity
118
+ * pre-verified by the prepareForNextSlot scheduler in the `GLOAS_PREVERIFY_WINDOW_EPOCHS` epochs
119
+ * leading up to GLOAS_FORK_EPOCH, so `onboardBuildersFromPendingDeposits()` at the fork transition
120
+ * can skip the bulk verification cost. There should only exist one for the entire application.
121
+ */
122
+ builderDepositSignatureCache: BuilderDepositSignatureCache;
115
123
  /**
116
124
  * Indexes of the block proposers for the current epoch.
117
125
  * For pre-fulu, this is computed and cached from the current shuffling.
@@ -245,6 +253,7 @@ export class EpochCache {
245
253
  constructor(data: {
246
254
  config: BeaconConfig;
247
255
  pubkeyCache: PubkeyCache;
256
+ builderDepositSignatureCache: BuilderDepositSignatureCache;
248
257
  proposers: number[];
249
258
  proposersPrevEpoch: number[] | null;
250
259
  proposersNextEpoch: ProposersDeferred;
@@ -277,6 +286,7 @@ export class EpochCache {
277
286
  }) {
278
287
  this.config = data.config;
279
288
  this.pubkeyCache = data.pubkeyCache;
289
+ this.builderDepositSignatureCache = data.builderDepositSignatureCache;
280
290
  this.proposers = data.proposers;
281
291
  this.proposersPrevEpoch = data.proposersPrevEpoch;
282
292
  this.proposersNextEpoch = data.proposersNextEpoch;
@@ -408,12 +418,17 @@ export class EpochCache {
408
418
 
409
419
  const nextShuffling = cachedNextShuffling ?? computeEpochShuffling(state, nextActiveIndices, nextEpoch);
410
420
 
411
- const currentProposerSeed = getSeed(state, currentEpoch, DOMAIN_BEACON_PROPOSER);
412
-
413
- let proposers: number[];
421
+ let proposers: ValidatorIndex[];
422
+ let proposersNextEpoch: ProposersDeferred;
414
423
  if (currentEpoch >= config.FULU_FORK_EPOCH) {
415
- // Overwrite proposers with state.proposerLookahead
416
- proposers = (state as CachedBeaconStateFulu).proposerLookahead.getAll().slice(0, SLOTS_PER_EPOCH);
424
+ // After fulu, use state.proposerLookahead for current and next epoch proposers.
425
+ // Computing from the unfiltered active shuffling would include slashed validators in gloas.
426
+ const proposerLookahead = (state as CachedBeaconStateFulu).proposerLookahead.getAll();
427
+ proposers = proposerLookahead.slice(0, SLOTS_PER_EPOCH);
428
+ proposersNextEpoch = {
429
+ computed: true,
430
+ indexes: proposerLookahead.slice(SLOTS_PER_EPOCH, SLOTS_PER_EPOCH * 2),
431
+ };
417
432
  } else {
418
433
  // We need to calculate Pre-fulu
419
434
  // Allow to create CachedBeaconState for empty states, or no active validators
@@ -421,18 +436,17 @@ export class EpochCache {
421
436
  currentShuffling.activeIndices.length > 0
422
437
  ? computeProposers(
423
438
  config.getForkSeqAtEpoch(currentEpoch),
424
- currentProposerSeed,
439
+ getSeed(state, currentEpoch, DOMAIN_BEACON_PROPOSER),
425
440
  currentShuffling,
426
441
  effectiveBalanceIncrements
427
442
  )
428
443
  : [];
444
+ proposersNextEpoch = {
445
+ computed: false,
446
+ seed: getSeed(state, nextEpoch, DOMAIN_BEACON_PROPOSER),
447
+ };
429
448
  }
430
449
 
431
- const proposersNextEpoch: ProposersDeferred = {
432
- computed: false,
433
- seed: getSeed(state, nextEpoch, DOMAIN_BEACON_PROPOSER),
434
- };
435
-
436
450
  // Only after altair, compute the indices of the current sync committee
437
451
  const afterAltairFork = currentEpoch >= config.ALTAIR_FORK_EPOCH;
438
452
 
@@ -510,6 +524,8 @@ export class EpochCache {
510
524
  return new EpochCache({
511
525
  config,
512
526
  pubkeyCache,
527
+ // Created once per application (shared by-reference through clone()).
528
+ builderDepositSignatureCache: new BuilderDepositSignatureCache(),
513
529
  proposers,
514
530
  // On first epoch, set to null to prevent unnecessary work since this is only used for metrics
515
531
  proposersPrevEpoch: null,
@@ -554,6 +570,8 @@ export class EpochCache {
554
570
  config: this.config,
555
571
  // Common append-only structures shared with all states, no need to clone
556
572
  pubkeyCache: this.pubkeyCache,
573
+ // Singleton per application, shared by-reference across clones
574
+ builderDepositSignatureCache: this.builderDepositSignatureCache,
557
575
  // Immutable data
558
576
  proposers: this.proposers,
559
577
  proposersPrevEpoch: this.proposersPrevEpoch,
@@ -713,17 +731,10 @@ export class EpochCache {
713
731
  // Populate proposer cache with lookahead from state
714
732
  const proposerLookahead = (state as CachedBeaconStateFulu).proposerLookahead.getAll();
715
733
  this.proposers = proposerLookahead.slice(0, SLOTS_PER_EPOCH);
716
-
717
- if (proposerLookahead.length >= SLOTS_PER_EPOCH * 2) {
718
- this.proposersNextEpoch = {
719
- computed: true,
720
- indexes: proposerLookahead.slice(SLOTS_PER_EPOCH, SLOTS_PER_EPOCH * 2),
721
- };
722
- } else {
723
- // This should not happen unless MIN_SEED_LOOKAHEAD is set to 0
724
- // this ensures things don't break if the proposer lookahead is not long enough
725
- this.proposersNextEpoch = {computed: false, seed: getSeed(state, epochAfterUpcoming, DOMAIN_BEACON_PROPOSER)};
726
- }
734
+ this.proposersNextEpoch = {
735
+ computed: true,
736
+ indexes: proposerLookahead.slice(SLOTS_PER_EPOCH, SLOTS_PER_EPOCH * 2),
737
+ };
727
738
  } else {
728
739
  // Need to calculate proposers pre-fulu
729
740
  const upcomingProposerSeed = getSeed(state, upcomingEpoch, DOMAIN_BEACON_PROPOSER);
@@ -1,5 +1,6 @@
1
1
  import {BeaconConfig} from "@lodestar/config";
2
2
  import {loadState} from "../util/loadState/loadState.js";
3
+ import {isViewDUNodesPopulated} from "../util/ssz.js";
3
4
  import {EpochCache, EpochCacheImmutableData, EpochCacheOpts} from "./epochCache.js";
4
5
  import {RewardCache, createEmptyRewardCache} from "./rewardCache.js";
5
6
  import {
@@ -12,6 +13,7 @@ import {
12
13
  BeaconStateExecutions,
13
14
  BeaconStateFulu,
14
15
  BeaconStateGloas,
16
+ BeaconStateHeze,
15
17
  BeaconStatePhase0,
16
18
  } from "./types.js";
17
19
 
@@ -136,6 +138,7 @@ export type CachedBeaconStateDeneb = CachedBeaconState<BeaconStateDeneb>;
136
138
  export type CachedBeaconStateElectra = CachedBeaconState<BeaconStateElectra>;
137
139
  export type CachedBeaconStateFulu = CachedBeaconState<BeaconStateFulu>;
138
140
  export type CachedBeaconStateGloas = CachedBeaconState<BeaconStateGloas>;
141
+ export type CachedBeaconStateHeze = CachedBeaconState<BeaconStateHeze>;
139
142
 
140
143
  export type CachedBeaconStateAllForks = CachedBeaconState<BeaconStateAllForks>;
141
144
  export type CachedBeaconStateExecutions = CachedBeaconState<BeaconStateExecutions>;
@@ -254,9 +257,9 @@ export function isCachedBeaconState<T extends BeaconStateAllForks>(
254
257
  // This cache is populated during epoch transition, and should be preserved for performance.
255
258
  // If the cache is missing too often, means that our clone strategy is not working well.
256
259
  export function isStateValidatorsNodesPopulated(state: CachedBeaconStateAllForks): boolean {
257
- return (state.validators as unknown as {nodesPopulated?: boolean}).nodesPopulated === true;
260
+ return isViewDUNodesPopulated(state.validators);
258
261
  }
259
262
 
260
263
  export function isStateBalancesNodesPopulated(state: CachedBeaconStateAllForks): boolean {
261
- return (state.balances as unknown as {nodesPopulated?: boolean}).nodesPopulated === true;
264
+ return isViewDUNodesPopulated(state.balances);
262
265
  }
@@ -11,6 +11,7 @@ export type BeaconStateDeneb = CompositeViewDU<SSZTypesFor<ForkName.deneb, "Beac
11
11
  export type BeaconStateElectra = CompositeViewDU<SSZTypesFor<ForkName.electra, "BeaconState">>;
12
12
  export type BeaconStateFulu = CompositeViewDU<SSZTypesFor<ForkName.fulu, "BeaconState">>;
13
13
  export type BeaconStateGloas = CompositeViewDU<SSZTypesFor<ForkName.gloas, "BeaconState">>;
14
+ export type BeaconStateHeze = CompositeViewDU<SSZTypesFor<ForkName.heze, "BeaconState">>;
14
15
 
15
16
  export type BeaconStateAllForks = CompositeViewDU<SSZTypesFor<ForkAll, "BeaconState">>;
16
17
  export type BeaconStateExecutions = CompositeViewDU<SSZTypesFor<ForkPostBellatrix & ForkPreGloas, "BeaconState">>;