@lodestar/state-transition 1.46.0-dev.e00bf67333 → 1.46.0-dev.eabf12abae

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 +14 -2
  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 +9 -9
  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 +14 -0
  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
@@ -4,11 +4,17 @@ import {
4
4
  WHISTLEBLOWER_REWARD_QUOTIENT,
5
5
  WHISTLEBLOWER_REWARD_QUOTIENT_ELECTRA,
6
6
  isForkPostElectra,
7
+ isForkPostGloas,
7
8
  } from "@lodestar/params";
8
- import {BeaconBlock, altair, phase0, rewards} from "@lodestar/types";
9
+ import {BeaconBlock, Slot, altair, phase0, rewards} from "@lodestar/types";
9
10
  import {processAttestationsAltair} from "../block/processAttestationsAltair.js";
10
11
  import {RewardCache} from "../cache/rewardCache.js";
11
- import {CachedBeaconStateAllForks, CachedBeaconStateAltair, CachedBeaconStatePhase0} from "../cache/stateCache.js";
12
+ import {
13
+ CachedBeaconStateAllForks,
14
+ CachedBeaconStateAltair,
15
+ CachedBeaconStateGloas,
16
+ CachedBeaconStatePhase0,
17
+ } from "../cache/stateCache.js";
12
18
  import {getAttesterSlashableIndices} from "../util/attestation.js";
13
19
 
14
20
  type SubRewardValue = number; // All reward values should be integer
@@ -36,10 +42,18 @@ export async function computeBlockRewards(
36
42
  let syncAggregateReward = cachedSyncAggregateReward;
37
43
 
38
44
  if (blockAttestationReward === 0) {
45
+ const parentSlot = isForkPostGloas(fork)
46
+ ? (preState as CachedBeaconStateGloas).latestExecutionPayloadBid.slot
47
+ : null;
39
48
  blockAttestationReward =
40
49
  fork === ForkName.phase0
41
50
  ? computeBlockAttestationRewardPhase0(block as phase0.BeaconBlock, preState as CachedBeaconStatePhase0)
42
- : computeBlockAttestationRewardAltair(config, block as altair.BeaconBlock, preState as CachedBeaconStateAltair);
51
+ : computeBlockAttestationRewardAltair(
52
+ config,
53
+ block as altair.BeaconBlock,
54
+ preState as CachedBeaconStateAltair,
55
+ parentSlot
56
+ );
43
57
  }
44
58
 
45
59
  if (syncAggregateReward === 0) {
@@ -79,12 +93,13 @@ function computeBlockAttestationRewardPhase0(
79
93
  function computeBlockAttestationRewardAltair(
80
94
  config: BeaconConfig,
81
95
  block: altair.BeaconBlock,
82
- preState: CachedBeaconStateAltair
96
+ preState: CachedBeaconStateAltair,
97
+ parentSlot: Slot | null
83
98
  ): SubRewardValue {
84
99
  const fork = config.getForkSeq(block.slot);
85
100
  const {attestations} = block.body;
86
101
 
87
- processAttestationsAltair(fork, preState, attestations, false);
102
+ processAttestationsAltair(fork, preState, attestations, parentSlot, false);
88
103
 
89
104
  return preState.proposerRewards.attestations;
90
105
  }
@@ -1,14 +1,12 @@
1
1
  import {BeaconConfig} from "@lodestar/config";
2
- import {DOMAIN_BEACON_BUILDER} from "@lodestar/params";
3
- import {Slot, gloas, ssz} from "@lodestar/types";
2
+ import {DOMAIN_BEACON_BUILDER, isForkPostGloas} from "@lodestar/params";
3
+ import {ExecutionPayloadBid, ssz, sszTypesFor} from "@lodestar/types";
4
4
  import {computeSigningRoot} from "../util/index.js";
5
5
 
6
- export function getExecutionPayloadBidSigningRoot(
7
- config: BeaconConfig,
8
- stateSlot: Slot,
9
- bid: gloas.ExecutionPayloadBid
10
- ): Uint8Array {
11
- const domain = config.getDomain(stateSlot, DOMAIN_BEACON_BUILDER);
6
+ export function getExecutionPayloadBidSigningRoot(config: BeaconConfig, bid: ExecutionPayloadBid): Uint8Array {
7
+ const fork = config.getForkName(bid.slot);
8
+ const domain = config.getDomain(bid.slot, DOMAIN_BEACON_BUILDER);
9
+ const sszType = isForkPostGloas(fork) ? sszTypesFor(fork).ExecutionPayloadBid : ssz.gloas.ExecutionPayloadBid;
12
10
 
13
- return computeSigningRoot(ssz.gloas.ExecutionPayloadBid, bid, domain);
11
+ return computeSigningRoot(sszType, bid, domain);
14
12
  }
package/src/slot/index.ts CHANGED
@@ -10,6 +10,7 @@ export {upgradeStateToDeneb} from "./upgradeStateToDeneb.js";
10
10
  export {upgradeStateToElectra} from "./upgradeStateToElectra.js";
11
11
  export {upgradeStateToFulu} from "./upgradeStateToFulu.js";
12
12
  export {upgradeStateToGloas} from "./upgradeStateToGloas.js";
13
+ export {upgradeStateToHeze} from "./upgradeStateToHeze.js";
13
14
 
14
15
  /**
15
16
  * Dial state to next slot. Common for all forks
@@ -137,6 +137,7 @@ function translateParticipation(
137
137
  attestation.inclusionDelay,
138
138
  epochCtx.epoch,
139
139
  rootCache,
140
+ null,
140
141
  null
141
142
  );
142
143
 
@@ -70,7 +70,7 @@ export function upgradeStateToGloas(stateFulu: CachedBeaconStateFulu): CachedBea
70
70
  stateGloasView.currentSyncCommittee = stateGloasCloned.currentSyncCommittee;
71
71
  stateGloasView.nextSyncCommittee = stateGloasCloned.nextSyncCommittee;
72
72
  stateGloasView.latestExecutionPayloadBid.blockHash = stateFulu.latestExecutionPayloadHeader.blockHash;
73
- stateGloasView.latestExecutionPayloadBid.gasLimit = stateFulu.latestExecutionPayloadHeader.gasLimit;
73
+ stateGloasView.latestExecutionPayloadBid.gasLimit = BigInt(stateFulu.latestExecutionPayloadHeader.gasLimit);
74
74
  stateGloasView.latestExecutionPayloadBid.executionRequestsRoot = ssz.gloas.ExecutionRequests.hashTreeRoot(
75
75
  ssz.gloas.ExecutionRequests.defaultValue()
76
76
  );
@@ -172,8 +172,8 @@ function onboardBuildersFromPendingDeposits(state: CachedBeaconStateGloas): void
172
172
  const pendingDeposits = ssz.gloas.PendingDeposits.defaultViewDU();
173
173
  const pendingDepositsLookup = PendingDepositsLookup.buildEmpty();
174
174
 
175
- for (let i = 0; i < state.pendingDeposits.length; i++) {
176
- const deposit = state.pendingDeposits.getReadonly(i);
175
+ for (const deposit of state.pendingDeposits.getAllReadonly()) {
176
+ const depositValue = deposit.toValue();
177
177
 
178
178
  const validatorIndex = state.epochCtx.getValidatorIndex(deposit.pubkey);
179
179
  const pubkeyHex = toPubkeyHex(deposit.pubkey);
@@ -181,7 +181,7 @@ function onboardBuildersFromPendingDeposits(state: CachedBeaconStateGloas): void
181
181
  // Deposits for existing validators stay in the pending queue
182
182
  if (isValidatorKnown(state, validatorIndex)) {
183
183
  pendingDeposits.push(deposit);
184
- pendingDepositsLookup.add(deposit, pubkeyHex);
184
+ pendingDepositsLookup.add(depositValue, pubkeyHex);
185
185
  continue;
186
186
  }
187
187
 
@@ -202,26 +202,33 @@ function onboardBuildersFromPendingDeposits(state: CachedBeaconStateGloas): void
202
202
  // can pick it up later.
203
203
  if (!isBuilderWithdrawalCredential(deposit.withdrawalCredentials)) {
204
204
  pendingDeposits.push(deposit);
205
- pendingDepositsLookup.add(deposit, pubkeyHex);
205
+ pendingDepositsLookup.add(depositValue, pubkeyHex);
206
206
  continue;
207
207
  }
208
- if (pendingDepositsLookup.hasPendingValidator(state.config, pubkeyHex)) {
208
+ if (
209
+ pendingDepositsLookup.hasPendingValidator(state.config, pubkeyHex, state.epochCtx.builderDepositSignatureCache)
210
+ ) {
209
211
  pendingDeposits.push(deposit);
210
- pendingDepositsLookup.add(deposit, pubkeyHex);
212
+ pendingDepositsLookup.add(depositValue, pubkeyHex);
211
213
  continue;
212
214
  }
213
215
 
214
216
  // Verify the deposit signature (proof of possession). If invalid the deposit is silently
215
217
  // dropped — stake is forfeited, matching the validator deposit contract behavior.
216
- if (
217
- !isValidDepositSignature(
218
+ //
219
+ // The prepareNextSlot scheduler pre-verifies these signatures in the epochs before the fork
220
+ // A cache miss falls back to verifying this one deposit — no worse than pre-cache.
221
+ const cached = state.epochCtx.builderDepositSignatureCache.getSignatureValidity(depositValue);
222
+ const isValid =
223
+ cached ??
224
+ isValidDepositSignature(
218
225
  state.config,
219
226
  deposit.pubkey,
220
227
  deposit.withdrawalCredentials,
221
228
  deposit.amount,
222
229
  deposit.signature
223
- )
224
- ) {
230
+ );
231
+ if (!isValid) {
225
232
  continue;
226
233
  }
227
234
 
@@ -0,0 +1,91 @@
1
+ import {ssz} from "@lodestar/types";
2
+ import {getCachedBeaconState} from "../cache/stateCache.js";
3
+ import {CachedBeaconStateGloas, CachedBeaconStateHeze} from "../types.js";
4
+
5
+ /**
6
+ * Upgrade a state from Gloas to Heze.
7
+ * Spec: heze/fork.md `upgrade_to_heze`.
8
+ */
9
+ export function upgradeStateToHeze(stateGloas: CachedBeaconStateGloas): CachedBeaconStateHeze {
10
+ const {config} = stateGloas;
11
+
12
+ ssz.gloas.BeaconState.commitViewDU(stateGloas);
13
+ const stateHezeCloned = stateGloas;
14
+
15
+ const stateHezeView = ssz.heze.BeaconState.defaultViewDU();
16
+
17
+ stateHezeView.genesisTime = stateHezeCloned.genesisTime;
18
+ stateHezeView.genesisValidatorsRoot = stateHezeCloned.genesisValidatorsRoot;
19
+ stateHezeView.slot = stateHezeCloned.slot;
20
+ stateHezeView.fork = ssz.phase0.Fork.toViewDU({
21
+ previousVersion: stateGloas.fork.currentVersion,
22
+ currentVersion: config.HEZE_FORK_VERSION,
23
+ epoch: stateGloas.epochCtx.epoch,
24
+ });
25
+ stateHezeView.latestBlockHeader = stateHezeCloned.latestBlockHeader;
26
+ stateHezeView.blockRoots = stateHezeCloned.blockRoots;
27
+ stateHezeView.stateRoots = stateHezeCloned.stateRoots;
28
+ stateHezeView.historicalRoots = stateHezeCloned.historicalRoots;
29
+ stateHezeView.eth1Data = stateHezeCloned.eth1Data;
30
+ stateHezeView.eth1DataVotes = stateHezeCloned.eth1DataVotes;
31
+ stateHezeView.eth1DepositIndex = stateHezeCloned.eth1DepositIndex;
32
+ stateHezeView.validators = stateHezeCloned.validators;
33
+ stateHezeView.balances = stateHezeCloned.balances;
34
+ stateHezeView.randaoMixes = stateHezeCloned.randaoMixes;
35
+ stateHezeView.slashings = stateHezeCloned.slashings;
36
+ stateHezeView.previousEpochParticipation = stateHezeCloned.previousEpochParticipation;
37
+ stateHezeView.currentEpochParticipation = stateHezeCloned.currentEpochParticipation;
38
+ stateHezeView.justificationBits = stateHezeCloned.justificationBits;
39
+ stateHezeView.previousJustifiedCheckpoint = stateHezeCloned.previousJustifiedCheckpoint;
40
+ stateHezeView.currentJustifiedCheckpoint = stateHezeCloned.currentJustifiedCheckpoint;
41
+ stateHezeView.finalizedCheckpoint = stateHezeCloned.finalizedCheckpoint;
42
+ stateHezeView.inactivityScores = stateHezeCloned.inactivityScores;
43
+ stateHezeView.currentSyncCommittee = stateHezeCloned.currentSyncCommittee;
44
+ stateHezeView.nextSyncCommittee = stateHezeCloned.nextSyncCommittee;
45
+ stateHezeView.latestBlockHash = stateHezeCloned.latestBlockHash;
46
+ stateHezeView.nextWithdrawalIndex = stateHezeCloned.nextWithdrawalIndex;
47
+ stateHezeView.nextWithdrawalValidatorIndex = stateHezeCloned.nextWithdrawalValidatorIndex;
48
+ stateHezeView.historicalSummaries = stateHezeCloned.historicalSummaries;
49
+ stateHezeView.depositRequestsStartIndex = stateHezeCloned.depositRequestsStartIndex;
50
+ stateHezeView.depositBalanceToConsume = stateHezeCloned.depositBalanceToConsume;
51
+ stateHezeView.exitBalanceToConsume = stateHezeCloned.exitBalanceToConsume;
52
+ stateHezeView.earliestExitEpoch = stateHezeCloned.earliestExitEpoch;
53
+ stateHezeView.consolidationBalanceToConsume = stateHezeCloned.consolidationBalanceToConsume;
54
+ stateHezeView.earliestConsolidationEpoch = stateHezeCloned.earliestConsolidationEpoch;
55
+ stateHezeView.pendingDeposits = stateHezeCloned.pendingDeposits;
56
+ stateHezeView.pendingPartialWithdrawals = stateHezeCloned.pendingPartialWithdrawals;
57
+ stateHezeView.pendingConsolidations = stateHezeCloned.pendingConsolidations;
58
+ stateHezeView.proposerLookahead = stateHezeCloned.proposerLookahead;
59
+ stateHezeView.builders = stateHezeCloned.builders;
60
+ stateHezeView.nextWithdrawalBuilderIndex = stateHezeCloned.nextWithdrawalBuilderIndex;
61
+ stateHezeView.executionPayloadAvailability = stateHezeCloned.executionPayloadAvailability;
62
+ stateHezeView.builderPendingPayments = stateHezeCloned.builderPendingPayments;
63
+ stateHezeView.builderPendingWithdrawals = stateHezeCloned.builderPendingWithdrawals;
64
+
65
+ // [Modified in Heze:EIP7805] inclusion_list_bits = Bitvector[INCLUSION_LIST_COMMITTEE_SIZE]() (default zero)
66
+ const oldBid = stateHezeCloned.latestExecutionPayloadBid;
67
+ const newBid = ssz.heze.ExecutionPayloadBid.defaultViewDU();
68
+ newBid.parentBlockHash = oldBid.parentBlockHash;
69
+ newBid.parentBlockRoot = oldBid.parentBlockRoot;
70
+ newBid.blockHash = oldBid.blockHash;
71
+ newBid.prevRandao = oldBid.prevRandao;
72
+ newBid.feeRecipient = oldBid.feeRecipient;
73
+ newBid.gasLimit = oldBid.gasLimit;
74
+ newBid.builderIndex = oldBid.builderIndex;
75
+ newBid.slot = oldBid.slot;
76
+ newBid.value = oldBid.value;
77
+ newBid.executionPayment = oldBid.executionPayment;
78
+ newBid.blobKzgCommitments = oldBid.blobKzgCommitments;
79
+ newBid.executionRequestsRoot = oldBid.executionRequestsRoot;
80
+ stateHezeView.latestExecutionPayloadBid = newBid;
81
+
82
+ stateHezeView.payloadExpectedWithdrawals = stateHezeCloned.payloadExpectedWithdrawals;
83
+ stateHezeView.ptcWindow = stateHezeCloned.ptcWindow;
84
+
85
+ const stateHeze = getCachedBeaconState(stateHezeView, stateGloas);
86
+ stateHeze.commit();
87
+ // biome-ignore lint/complexity/useLiteralKeys: It is a protected attribute
88
+ stateHeze["clearCache"]();
89
+
90
+ return stateHeze;
91
+ }
@@ -16,6 +16,7 @@ import {
16
16
  upgradeStateToDeneb,
17
17
  upgradeStateToElectra,
18
18
  upgradeStateToGloas,
19
+ upgradeStateToHeze,
19
20
  } from "./slot/index.js";
20
21
  import {upgradeStateToFulu} from "./slot/upgradeStateToFulu.js";
21
22
  import {
@@ -26,6 +27,7 @@ import {
26
27
  CachedBeaconStateDeneb,
27
28
  CachedBeaconStateElectra,
28
29
  CachedBeaconStateFulu,
30
+ CachedBeaconStateGloas,
29
31
  CachedBeaconStatePhase0,
30
32
  } from "./types.js";
31
33
  import {computeEpochAtSlot} from "./util/index.js";
@@ -278,6 +280,9 @@ function processSlotsWithTransientCache(
278
280
  if (stateEpoch === config.GLOAS_FORK_EPOCH) {
279
281
  postState = upgradeStateToGloas(postState as CachedBeaconStateFulu) as CachedBeaconStateAllForks;
280
282
  }
283
+ if (stateEpoch === config.HEZE_FORK_EPOCH) {
284
+ postState = upgradeStateToHeze(postState as CachedBeaconStateGloas) as CachedBeaconStateAllForks;
285
+ }
281
286
 
282
287
  {
283
288
  const timer = metrics?.epochTransitionStepTime.startTimer({step: EpochTransitionStep.finalProcessEpoch});
@@ -67,6 +67,7 @@ import {
67
67
  } from "../util/execution.js";
68
68
  import {canBuilderCoverBid} from "../util/gloas.js";
69
69
  import {loadState} from "../util/loadState/loadState.js";
70
+ import {PreVerifyBuilderDepositsResult, preVerifyBuilderDepositsPreGloas} from "../util/preVerifyBuilderDeposits.js";
70
71
  import {getRandaoMix} from "../util/seed.js";
71
72
  import {getLatestWeakSubjectivityCheckpointEpoch} from "../util/weakSubjectivity.js";
72
73
  import {IBeaconStateView, IBeaconStateViewGloas, IBeaconStateViewLatestFork, isStatePostGloas} from "./interface.js";
@@ -341,6 +342,18 @@ export class BeaconStateView implements IBeaconStateViewLatestFork {
341
342
  return this._proposerLookahead;
342
343
  }
343
344
 
345
+ preVerifyBuilderDepositsPreGloas(maxBuilderDeposits: number, maxDurationMs: number): PreVerifyBuilderDepositsResult {
346
+ return preVerifyBuilderDepositsPreGloas(
347
+ this.cachedState as CachedBeaconStateFulu,
348
+ maxBuilderDeposits,
349
+ maxDurationMs
350
+ );
351
+ }
352
+
353
+ clearPreGloasBuilderDepositCache(): void {
354
+ this.cachedState.epochCtx.builderDepositSignatureCache.clear();
355
+ }
356
+
344
357
  // gloas
345
358
 
346
359
  get latestBlockHash(): Bytes32 {
@@ -9,6 +9,7 @@ import {
9
9
  ForkPostElectra,
10
10
  ForkPostFulu,
11
11
  ForkPostGloas,
12
+ ForkPostHeze,
12
13
  isForkPostAltair,
13
14
  isForkPostBellatrix,
14
15
  isForkPostCapella,
@@ -16,6 +17,7 @@ import {
16
17
  isForkPostElectra,
17
18
  isForkPostFulu,
18
19
  isForkPostGloas,
20
+ isForkPostHeze,
19
21
  } from "@lodestar/params";
20
22
  import {
21
23
  BeaconBlock,
@@ -50,6 +52,7 @@ import {SyncCommitteeCache} from "../cache/syncCommitteeCache.js";
50
52
  import {SyncCommitteeWitness} from "../lightClient/types.js";
51
53
  import {StateTransitionModules, StateTransitionOpts} from "../stateTransition.js";
52
54
  import {EpochShuffling} from "../util/epochShuffling.js";
55
+ import {PreVerifyBuilderDepositsResult} from "../util/preVerifyBuilderDeposits.js";
53
56
 
54
57
  /**
55
58
  * A read-only view of the BeaconState.
@@ -240,6 +243,13 @@ export interface IBeaconStateViewElectra extends IBeaconStateViewDeneb {
240
243
  export interface IBeaconStateViewFulu extends IBeaconStateViewElectra {
241
244
  forkName: ForkPostFulu;
242
245
  proposerLookahead: fulu.ProposerLookahead;
246
+ /**
247
+ * Pre-verify a slice of builder-prefix pending deposits and cache the results on the underlying
248
+ * `BuilderDepositSignatureCache` (Fulu is the fork immediately before Gloas).
249
+ */
250
+ preVerifyBuilderDepositsPreGloas(maxBuilderDeposits: number, maxDurationMs: number): PreVerifyBuilderDepositsResult;
251
+ /** Drop the pre-Gloas builder-deposit signature cache (called once the Gloas fork is finalized). */
252
+ clearPreGloasBuilderDepositCache(): void;
243
253
  }
244
254
 
245
255
  /** Gloas+ state fields — use isStatePostGloas() guard */
@@ -267,14 +277,19 @@ export interface IBeaconStateViewGloas extends IBeaconStateViewFulu {
267
277
  withParentPayloadApplied(executionRequests: gloas.ExecutionRequests): IBeaconStateViewGloas;
268
278
  }
269
279
 
280
+ /** Heze+ state fields — use isStatePostHeze() guard */
281
+ export interface IBeaconStateViewHeze extends IBeaconStateViewGloas {
282
+ forkName: ForkPostHeze;
283
+ }
284
+
270
285
  /**
271
286
  * Type constraint for the concrete BeaconStateView class.
272
- * Requires all fields from the latest fork interface (IBeaconStateViewGloas) but keeps
287
+ * Requires all fields from the latest fork interface (IBeaconStateViewHeze) but keeps
273
288
  * forkName as ForkName since the class wraps any fork's state.
274
289
  * Sub-interfaces retain their narrowed forkName discriminants for caller-side type guards.
275
290
  */
276
291
  export type IBeaconStateViewLatestFork = Omit<
277
- IBeaconStateViewGloas,
292
+ IBeaconStateViewHeze,
278
293
  "forkName" | "latestExecutionPayloadHeader" | "payloadBlockNumber"
279
294
  > & {
280
295
  forkName: ForkName;
@@ -337,3 +352,7 @@ export function isStatePostFulu(state: IBeaconStateView): state is IBeaconStateV
337
352
  export function isStatePostGloas(state: IBeaconStateView): state is IBeaconStateViewGloas {
338
353
  return isForkPostGloas(state.forkName);
339
354
  }
355
+
356
+ export function isStatePostHeze(state: IBeaconStateView): state is IBeaconStateViewHeze {
357
+ return isForkPostHeze(state.forkName);
358
+ }
@@ -35,6 +35,7 @@ import {SyncCommitteeCache} from "../cache/syncCommitteeCache.js";
35
35
  import {SyncCommitteeWitness} from "../lightClient/types.js";
36
36
  import {StateTransitionModules, StateTransitionOpts} from "../stateTransition.js";
37
37
  import {EpochShuffling} from "../util/epochShuffling.js";
38
+ import {PreVerifyBuilderDepositsResult} from "../util/preVerifyBuilderDeposits.js";
38
39
  import {
39
40
  IBeaconStateView,
40
41
  IBeaconStateViewGloas,
@@ -845,6 +846,14 @@ export class NativeBeaconStateView implements IBeaconStateViewLatestFork {
845
846
  return this._proposerLookahead;
846
847
  }
847
848
 
849
+ preVerifyBuilderDepositsPreGloas(maxBuilderDeposits: number, maxDurationMs: number): PreVerifyBuilderDepositsResult {
850
+ return this.binding.preVerifyBuilderDepositsPreGloas(maxBuilderDeposits, maxDurationMs);
851
+ }
852
+
853
+ clearPreGloasBuilderDepositCache(): void {
854
+ this.binding.clearPreGloasBuilderDepositCache();
855
+ }
856
+
848
857
  // ─── gloas ───────────────────────────────────────────────────────────────
849
858
 
850
859
  get latestBlockHash(): Bytes32 {
@@ -54,7 +54,7 @@ export function generateState(opts?: TestBeaconState): BeaconStatePhase0 {
54
54
  eth1Data: {
55
55
  depositRoot: Buffer.alloc(32),
56
56
  blockHash: Buffer.alloc(32),
57
- depositCount: 0,
57
+ depositCount: 0n,
58
58
  },
59
59
  eth1DataVotes: [],
60
60
  eth1DepositIndex: 0,
@@ -1,25 +1,28 @@
1
1
  import {PublicKey, SecretKey} from "@chainsafe/blst";
2
2
  import {BitArray, fromHexString} from "@chainsafe/ssz";
3
- import {createBeaconConfig, createChainForkConfig} from "@lodestar/config";
3
+ import {BeaconConfig, createBeaconConfig, createChainForkConfig} from "@lodestar/config";
4
4
  import {config} from "@lodestar/config/default";
5
5
  import {
6
+ BUILDER_WITHDRAWAL_PREFIX,
7
+ DOMAIN_DEPOSIT,
6
8
  EPOCHS_PER_ETH1_VOTING_PERIOD,
7
9
  EPOCHS_PER_HISTORICAL_VECTOR,
8
10
  ForkName,
9
11
  ForkSeq,
12
+ GENESIS_SLOT,
10
13
  MAX_ATTESTATIONS,
11
14
  MAX_EFFECTIVE_BALANCE,
12
15
  SLOTS_PER_EPOCH,
13
16
  SLOTS_PER_HISTORICAL_ROOT,
14
17
  } from "@lodestar/params";
15
- import {BeaconState, Slot, phase0, ssz} from "@lodestar/types";
18
+ import {BeaconState, Slot, electra, phase0, ssz} from "@lodestar/types";
16
19
  import {getEffectiveBalanceIncrements} from "../cache/effectiveBalanceIncrements.js";
20
+ import {ZERO_HASH} from "../constants/index.js";
17
21
  import {
18
22
  computeCommitteeCount,
19
23
  computeEpochAtSlot,
20
24
  createCachedBeaconState,
21
25
  createPubkeyCache,
22
- interopSecretKey,
23
26
  newFilledArray,
24
27
  processSlots,
25
28
  } from "../index.js";
@@ -32,6 +35,9 @@ import {
32
35
  CachedBeaconStateElectra,
33
36
  CachedBeaconStatePhase0,
34
37
  } from "../types.js";
38
+ import {computeDomain} from "../util/domain.js";
39
+ import {interopSecretKey} from "../util/interop.js";
40
+ import {computeSigningRoot} from "../util/signingRoot.js";
35
41
  import {getNextSyncCommittee} from "../util/syncCommittee.js";
36
42
  import {getActiveValidatorIndices} from "../util/validator.js";
37
43
  import {interopPubkeysCached} from "./interop.js";
@@ -437,13 +443,13 @@ function buildPerformanceStatePhase0(pubkeysArg?: Uint8Array[]): phase0.BeaconSt
437
443
  historicalRoots: [],
438
444
  // Eth1
439
445
  eth1Data: {
440
- depositCount: pubkeys.length,
446
+ depositCount: BigInt(pubkeys.length),
441
447
  depositRoot: fromHexString("0xcb1f89a924cfd31224823db5a41b1643f10faa7aedf231f1e28887f6ee98c047"),
442
448
  blockHash: fromHexString("0x701fb2869ce16d0f1d14f6705725adb0dec6799da29006dfc6fff83960298f21"),
443
449
  },
444
450
  // minus one so that inserting 1 from block works
445
451
  eth1DataVotes: newFilledArray(EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH - 1, {
446
- depositCount: 1,
452
+ depositCount: 1n,
447
453
  depositRoot: Buffer.alloc(32, 1),
448
454
  blockHash: Buffer.alloc(32, 1),
449
455
  }),
@@ -541,3 +547,67 @@ export function generateTestCachedBeaconStateOnlyValidators({
541
547
  {skipSyncPubkeys: true}
542
548
  );
543
549
  }
550
+
551
+ /**
552
+ * Generate `count` validly-signed builder pending deposits with distinct interop pubkeys
553
+ * [startIndex, startIndex + count). Withdrawal credentials carry the BUILDER_WITHDRAWAL_PREFIX so
554
+ * `isBuilderWithdrawalCredential` recognizes them. Used to exercise the pre-Gloas builder-deposit
555
+ * pre-verify scanner and the fork-transition onboarding path.
556
+ */
557
+ export function generateBuilderPendingDeposits(
558
+ config: BeaconConfig,
559
+ count: number,
560
+ startIndex: number
561
+ ): electra.PendingDeposit[] {
562
+ // Deposits use a fork-agnostic domain, see `isValidDepositSignature`
563
+ const domain = computeDomain(DOMAIN_DEPOSIT, config.GENESIS_FORK_VERSION, ZERO_HASH);
564
+ const amount = 1_000_000_000; // 1 ETH in Gwei
565
+ const deposits: electra.PendingDeposit[] = [];
566
+
567
+ for (let i = 0; i < count; i++) {
568
+ const sk = interopSecretKey(startIndex + i);
569
+ const pubkey = sk.toPublicKey().toBytes();
570
+
571
+ const withdrawalCredentials = Buffer.alloc(32, 0);
572
+ withdrawalCredentials[0] = BUILDER_WITHDRAWAL_PREFIX;
573
+ // bytes [12, 32) hold the 20-byte builder execution address
574
+ withdrawalCredentials.fill((startIndex + i) & 0xff, 12, 32);
575
+
576
+ const signingRoot = computeSigningRoot(ssz.phase0.DepositMessage, {pubkey, withdrawalCredentials, amount}, domain);
577
+
578
+ deposits.push({
579
+ pubkey,
580
+ withdrawalCredentials,
581
+ amount,
582
+ signature: sk.sign(signingRoot).toBytes(),
583
+ slot: GENESIS_SLOT,
584
+ });
585
+ }
586
+
587
+ return deposits;
588
+ }
589
+
590
+ /**
591
+ * Generate a validly-signed *validator* (0x00-prefix) pending deposit for interop key `keyIndex`.
592
+ * Shares its pubkey with `generateBuilderPendingDeposits(config, 1, keyIndex)`, so it stands in for a
593
+ * validator deposit competing with a builder deposit for the same pubkey (the `hasPendingValidator`
594
+ * path). `amount` lets callers build otherwise-identical-but-distinct deposit value objects.
595
+ */
596
+ export function generateValidatorPendingDeposit(
597
+ config: BeaconConfig,
598
+ keyIndex: number,
599
+ amount = 32_000_000_000
600
+ ): electra.PendingDeposit {
601
+ const domain = computeDomain(DOMAIN_DEPOSIT, config.GENESIS_FORK_VERSION, ZERO_HASH);
602
+ const sk = interopSecretKey(keyIndex);
603
+ const pubkey = sk.toPublicKey().toBytes();
604
+ const withdrawalCredentials = Buffer.alloc(32, 0); // 0x00 prefix → validator, not a builder
605
+ const signingRoot = computeSigningRoot(ssz.phase0.DepositMessage, {pubkey, withdrawalCredentials, amount}, domain);
606
+ return {
607
+ pubkey,
608
+ withdrawalCredentials,
609
+ amount,
610
+ signature: sk.sign(signingRoot).toBytes(),
611
+ slot: GENESIS_SLOT,
612
+ };
613
+ }
package/src/types.ts CHANGED
@@ -10,6 +10,7 @@ export type {
10
10
  CachedBeaconStateExecutions,
11
11
  CachedBeaconStateFulu,
12
12
  CachedBeaconStateGloas,
13
+ CachedBeaconStateHeze,
13
14
  CachedBeaconStatePhase0,
14
15
  } from "./cache/stateCache.js";
15
16
  export type {
@@ -22,6 +23,7 @@ export type {
22
23
  BeaconStateExecutions,
23
24
  BeaconStateFulu,
24
25
  BeaconStateGloas,
26
+ BeaconStateHeze,
25
27
  BeaconStatePhase0,
26
28
  ShufflingGetter,
27
29
  } from "./cache/types.js";