@lodestar/beacon-node 1.41.0 → 1.42.0-dev.04e52d162f

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 (474) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +36 -17
  3. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  4. package/lib/api/impl/beacon/pool/index.js +1 -1
  5. package/lib/api/impl/beacon/pool/index.js.map +1 -1
  6. package/lib/api/impl/beacon/state/index.d.ts.map +1 -1
  7. package/lib/api/impl/beacon/state/index.js +27 -32
  8. package/lib/api/impl/beacon/state/index.js.map +1 -1
  9. package/lib/api/impl/beacon/state/utils.d.ts +6 -6
  10. package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
  11. package/lib/api/impl/beacon/state/utils.js +7 -10
  12. package/lib/api/impl/beacon/state/utils.js.map +1 -1
  13. package/lib/api/impl/lodestar/index.d.ts.map +1 -1
  14. package/lib/api/impl/lodestar/index.js +4 -6
  15. package/lib/api/impl/lodestar/index.js.map +1 -1
  16. package/lib/api/impl/proof/index.d.ts.map +1 -1
  17. package/lib/api/impl/proof/index.js +2 -6
  18. package/lib/api/impl/proof/index.js.map +1 -1
  19. package/lib/api/impl/validator/index.d.ts.map +1 -1
  20. package/lib/api/impl/validator/index.js +32 -28
  21. package/lib/api/impl/validator/index.js.map +1 -1
  22. package/lib/api/impl/validator/utils.d.ts +2 -2
  23. package/lib/api/impl/validator/utils.d.ts.map +1 -1
  24. package/lib/api/impl/validator/utils.js +3 -3
  25. package/lib/api/impl/validator/utils.js.map +1 -1
  26. package/lib/chain/archiveStore/archiveStore.d.ts +0 -1
  27. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  28. package/lib/chain/archiveStore/archiveStore.js +1 -9
  29. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  30. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts +3 -7
  31. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
  32. package/lib/chain/archiveStore/historicalState/getHistoricalState.js +8 -26
  33. package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
  34. package/lib/chain/archiveStore/historicalState/historicalStateRegen.d.ts +2 -2
  35. package/lib/chain/archiveStore/historicalState/historicalStateRegen.d.ts.map +1 -1
  36. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js +1 -0
  37. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js.map +1 -1
  38. package/lib/chain/archiveStore/historicalState/types.d.ts +2 -0
  39. package/lib/chain/archiveStore/historicalState/types.d.ts.map +1 -1
  40. package/lib/chain/archiveStore/historicalState/types.js.map +1 -1
  41. package/lib/chain/archiveStore/historicalState/worker.js +1 -3
  42. package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
  43. package/lib/chain/archiveStore/interface.d.ts +5 -4
  44. package/lib/chain/archiveStore/interface.d.ts.map +1 -1
  45. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts +4 -4
  46. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts.map +1 -1
  47. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js +4 -1
  48. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js.map +1 -1
  49. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
  50. package/lib/chain/archiveStore/utils/archiveBlocks.js +38 -0
  51. package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
  52. package/lib/chain/balancesCache.d.ts +2 -2
  53. package/lib/chain/balancesCache.d.ts.map +1 -1
  54. package/lib/chain/balancesCache.js +4 -4
  55. package/lib/chain/balancesCache.js.map +1 -1
  56. package/lib/chain/blocks/blockInput/types.d.ts +4 -3
  57. package/lib/chain/blocks/blockInput/types.d.ts.map +1 -1
  58. package/lib/chain/blocks/blockInput/types.js +1 -0
  59. package/lib/chain/blocks/blockInput/types.js.map +1 -1
  60. package/lib/chain/blocks/importBlock.d.ts +3 -3
  61. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  62. package/lib/chain/blocks/importBlock.js +48 -28
  63. package/lib/chain/blocks/importBlock.js.map +1 -1
  64. package/lib/chain/blocks/importExecutionPayload.d.ts +48 -0
  65. package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -0
  66. package/lib/chain/blocks/importExecutionPayload.js +167 -0
  67. package/lib/chain/blocks/importExecutionPayload.js.map +1 -0
  68. package/lib/chain/blocks/index.d.ts.map +1 -1
  69. package/lib/chain/blocks/index.js +3 -2
  70. package/lib/chain/blocks/index.js.map +1 -1
  71. package/lib/chain/blocks/payloadEnvelopeInput/index.d.ts +3 -0
  72. package/lib/chain/blocks/payloadEnvelopeInput/index.d.ts.map +1 -0
  73. package/lib/chain/blocks/payloadEnvelopeInput/index.js +3 -0
  74. package/lib/chain/blocks/payloadEnvelopeInput/index.js.map +1 -0
  75. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +80 -0
  76. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -0
  77. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +248 -0
  78. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -0
  79. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +29 -0
  80. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -0
  81. package/lib/chain/blocks/payloadEnvelopeInput/types.js +11 -0
  82. package/lib/chain/blocks/payloadEnvelopeInput/types.js.map +1 -0
  83. package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts +15 -0
  84. package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts.map +1 -0
  85. package/lib/chain/blocks/payloadEnvelopeProcessor.js +46 -0
  86. package/lib/chain/blocks/payloadEnvelopeProcessor.js.map +1 -0
  87. package/lib/chain/blocks/types.d.ts +28 -15
  88. package/lib/chain/blocks/types.d.ts.map +1 -1
  89. package/lib/chain/blocks/types.js.map +1 -1
  90. package/lib/chain/blocks/utils/checkpoint.d.ts +2 -2
  91. package/lib/chain/blocks/utils/checkpoint.d.ts.map +1 -1
  92. package/lib/chain/blocks/utils/checkpoint.js.map +1 -1
  93. package/lib/chain/blocks/verifyBlock.d.ts +2 -2
  94. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  95. package/lib/chain/blocks/verifyBlock.js +4 -4
  96. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  97. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts +5 -5
  98. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
  99. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +4 -4
  100. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
  101. package/lib/chain/blocks/verifyBlocksSignatures.d.ts +2 -2
  102. package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
  103. package/lib/chain/blocks/verifyBlocksSignatures.js +2 -2
  104. package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
  105. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts +3 -3
  106. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
  107. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +3 -3
  108. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
  109. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts +12 -0
  110. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts.map +1 -0
  111. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js +40 -0
  112. package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js.map +1 -0
  113. package/lib/chain/chain.d.ts +22 -17
  114. package/lib/chain/chain.d.ts.map +1 -1
  115. package/lib/chain/chain.js +90 -48
  116. package/lib/chain/chain.js.map +1 -1
  117. package/lib/chain/emitter.d.ts +2 -2
  118. package/lib/chain/emitter.d.ts.map +1 -1
  119. package/lib/chain/errors/blockError.d.ts +4 -4
  120. package/lib/chain/errors/blockError.d.ts.map +1 -1
  121. package/lib/chain/errors/executionPayloadEnvelope.d.ts +12 -2
  122. package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
  123. package/lib/chain/errors/executionPayloadEnvelope.js +3 -1
  124. package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
  125. package/lib/chain/forkChoice/index.d.ts +4 -4
  126. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  127. package/lib/chain/forkChoice/index.js +27 -33
  128. package/lib/chain/forkChoice/index.js.map +1 -1
  129. package/lib/chain/initState.d.ts +2 -2
  130. package/lib/chain/initState.d.ts.map +1 -1
  131. package/lib/chain/initState.js +1 -1
  132. package/lib/chain/initState.js.map +1 -1
  133. package/lib/chain/interface.d.ts +19 -17
  134. package/lib/chain/interface.d.ts.map +1 -1
  135. package/lib/chain/lightClient/index.d.ts +2 -2
  136. package/lib/chain/lightClient/index.d.ts.map +1 -1
  137. package/lib/chain/lightClient/index.js +4 -4
  138. package/lib/chain/lightClient/index.js.map +1 -1
  139. package/lib/chain/opPools/aggregatedAttestationPool.d.ts +6 -6
  140. package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
  141. package/lib/chain/opPools/aggregatedAttestationPool.js +10 -13
  142. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  143. package/lib/chain/opPools/opPool.d.ts +3 -3
  144. package/lib/chain/opPools/opPool.d.ts.map +1 -1
  145. package/lib/chain/opPools/opPool.js +7 -7
  146. package/lib/chain/opPools/opPool.js.map +1 -1
  147. package/lib/chain/opPools/utils.d.ts +2 -2
  148. package/lib/chain/opPools/utils.d.ts.map +1 -1
  149. package/lib/chain/opPools/utils.js +2 -2
  150. package/lib/chain/opPools/utils.js.map +1 -1
  151. package/lib/chain/options.d.ts +1 -0
  152. package/lib/chain/options.d.ts.map +1 -1
  153. package/lib/chain/options.js +1 -0
  154. package/lib/chain/options.js.map +1 -1
  155. package/lib/chain/prepareNextSlot.d.ts +2 -2
  156. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  157. package/lib/chain/prepareNextSlot.js +9 -5
  158. package/lib/chain/prepareNextSlot.js.map +1 -1
  159. package/lib/chain/produceBlock/computeNewStateRoot.d.ts +4 -4
  160. package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
  161. package/lib/chain/produceBlock/computeNewStateRoot.js +8 -4
  162. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  163. package/lib/chain/produceBlock/produceBlockBody.d.ts +5 -5
  164. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  165. package/lib/chain/produceBlock/produceBlockBody.js +13 -17
  166. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  167. package/lib/chain/regen/errors.d.ts +11 -1
  168. package/lib/chain/regen/errors.d.ts.map +1 -1
  169. package/lib/chain/regen/errors.js +2 -0
  170. package/lib/chain/regen/errors.js.map +1 -1
  171. package/lib/chain/regen/interface.d.ts +22 -14
  172. package/lib/chain/regen/interface.d.ts.map +1 -1
  173. package/lib/chain/regen/interface.js +2 -0
  174. package/lib/chain/regen/interface.js.map +1 -1
  175. package/lib/chain/regen/queued.d.ts +20 -15
  176. package/lib/chain/regen/queued.d.ts.map +1 -1
  177. package/lib/chain/regen/queued.js +40 -8
  178. package/lib/chain/regen/queued.js.map +1 -1
  179. package/lib/chain/regen/regen.d.ts +11 -5
  180. package/lib/chain/regen/regen.d.ts.map +1 -1
  181. package/lib/chain/regen/regen.js +38 -11
  182. package/lib/chain/regen/regen.js.map +1 -1
  183. package/lib/chain/seenCache/index.d.ts +1 -1
  184. package/lib/chain/seenCache/index.d.ts.map +1 -1
  185. package/lib/chain/seenCache/index.js +1 -1
  186. package/lib/chain/seenCache/index.js.map +1 -1
  187. package/lib/chain/seenCache/seenGossipBlockInput.js +2 -2
  188. package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
  189. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +38 -0
  190. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -0
  191. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +76 -0
  192. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -0
  193. package/lib/chain/serializeState.d.ts +2 -2
  194. package/lib/chain/serializeState.d.ts.map +1 -1
  195. package/lib/chain/serializeState.js +1 -1
  196. package/lib/chain/serializeState.js.map +1 -1
  197. package/lib/chain/shufflingCache.d.ts +2 -2
  198. package/lib/chain/shufflingCache.d.ts.map +1 -1
  199. package/lib/chain/shufflingCache.js +3 -4
  200. package/lib/chain/shufflingCache.js.map +1 -1
  201. package/lib/chain/stateCache/datastore/db.d.ts +4 -5
  202. package/lib/chain/stateCache/datastore/db.d.ts.map +1 -1
  203. package/lib/chain/stateCache/datastore/db.js +32 -10
  204. package/lib/chain/stateCache/datastore/db.js.map +1 -1
  205. package/lib/chain/stateCache/datastore/file.d.ts +1 -1
  206. package/lib/chain/stateCache/datastore/file.d.ts.map +1 -1
  207. package/lib/chain/stateCache/datastore/file.js +5 -5
  208. package/lib/chain/stateCache/datastore/file.js.map +1 -1
  209. package/lib/chain/stateCache/datastore/types.d.ts +1 -1
  210. package/lib/chain/stateCache/datastore/types.d.ts.map +1 -1
  211. package/lib/chain/stateCache/fifoBlockStateCache.d.ts +13 -10
  212. package/lib/chain/stateCache/fifoBlockStateCache.d.ts.map +1 -1
  213. package/lib/chain/stateCache/fifoBlockStateCache.js +8 -3
  214. package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
  215. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +36 -17
  216. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  217. package/lib/chain/stateCache/persistentCheckpointsCache.js +228 -134
  218. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  219. package/lib/chain/stateCache/types.d.ts +23 -16
  220. package/lib/chain/stateCache/types.d.ts.map +1 -1
  221. package/lib/chain/stateCache/types.js.map +1 -1
  222. package/lib/chain/validation/attesterSlashing.js +3 -3
  223. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  224. package/lib/chain/validation/blobSidecar.js +1 -1
  225. package/lib/chain/validation/blobSidecar.js.map +1 -1
  226. package/lib/chain/validation/block.d.ts.map +1 -1
  227. package/lib/chain/validation/block.js +3 -3
  228. package/lib/chain/validation/block.js.map +1 -1
  229. package/lib/chain/validation/blsToExecutionChange.js +2 -2
  230. package/lib/chain/validation/blsToExecutionChange.js.map +1 -1
  231. package/lib/chain/validation/dataColumnSidecar.js +1 -1
  232. package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
  233. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
  234. package/lib/chain/validation/executionPayloadBid.js +4 -4
  235. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  236. package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
  237. package/lib/chain/validation/executionPayloadEnvelope.js +29 -19
  238. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
  239. package/lib/chain/validation/lightClientFinalityUpdate.js +1 -1
  240. package/lib/chain/validation/lightClientFinalityUpdate.js.map +1 -1
  241. package/lib/chain/validation/lightClientOptimisticUpdate.js +1 -1
  242. package/lib/chain/validation/lightClientOptimisticUpdate.js.map +1 -1
  243. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
  244. package/lib/chain/validation/payloadAttestationMessage.js +1 -2
  245. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  246. package/lib/chain/validation/proposerSlashing.js +1 -1
  247. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  248. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts +2 -2
  249. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts.map +1 -1
  250. package/lib/chain/validation/signatureSets/contributionAndProof.js +1 -1
  251. package/lib/chain/validation/signatureSets/contributionAndProof.js.map +1 -1
  252. package/lib/chain/validation/signatureSets/syncCommittee.d.ts +2 -2
  253. package/lib/chain/validation/signatureSets/syncCommittee.d.ts.map +1 -1
  254. package/lib/chain/validation/signatureSets/syncCommittee.js +1 -1
  255. package/lib/chain/validation/signatureSets/syncCommittee.js.map +1 -1
  256. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts +2 -2
  257. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts.map +1 -1
  258. package/lib/chain/validation/signatureSets/syncCommitteeContribution.js.map +1 -1
  259. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts +2 -2
  260. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts.map +1 -1
  261. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js +1 -1
  262. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js.map +1 -1
  263. package/lib/chain/validation/syncCommittee.d.ts +4 -4
  264. package/lib/chain/validation/syncCommittee.d.ts.map +1 -1
  265. package/lib/chain/validation/syncCommittee.js +13 -12
  266. package/lib/chain/validation/syncCommittee.js.map +1 -1
  267. package/lib/chain/validation/syncCommitteeContributionAndProof.d.ts.map +1 -1
  268. package/lib/chain/validation/syncCommitteeContributionAndProof.js +1 -1
  269. package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
  270. package/lib/chain/validation/voluntaryExit.d.ts.map +1 -1
  271. package/lib/chain/validation/voluntaryExit.js +3 -3
  272. package/lib/chain/validation/voluntaryExit.js.map +1 -1
  273. package/lib/chain/validatorMonitor.d.ts +5 -4
  274. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  275. package/lib/chain/validatorMonitor.js +13 -8
  276. package/lib/chain/validatorMonitor.js.map +1 -1
  277. package/lib/execution/engine/interface.d.ts +2 -2
  278. package/lib/metrics/metrics/lodestar.d.ts +40 -4
  279. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  280. package/lib/metrics/metrics/lodestar.js +93 -15
  281. package/lib/metrics/metrics/lodestar.js.map +1 -1
  282. package/lib/network/gossip/encoding.d.ts.map +1 -1
  283. package/lib/network/gossip/encoding.js +15 -0
  284. package/lib/network/gossip/encoding.js.map +1 -1
  285. package/lib/network/interface.d.ts +4 -2
  286. package/lib/network/interface.d.ts.map +1 -1
  287. package/lib/network/libp2p/index.d.ts.map +1 -1
  288. package/lib/network/libp2p/index.js +5 -0
  289. package/lib/network/libp2p/index.js.map +1 -1
  290. package/lib/network/network.d.ts +4 -2
  291. package/lib/network/network.d.ts.map +1 -1
  292. package/lib/network/network.js +11 -5
  293. package/lib/network/network.js.map +1 -1
  294. package/lib/network/processor/extractSlotRootFns.d.ts +1 -1
  295. package/lib/network/processor/extractSlotRootFns.d.ts.map +1 -1
  296. package/lib/network/processor/extractSlotRootFns.js +15 -5
  297. package/lib/network/processor/extractSlotRootFns.js.map +1 -1
  298. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  299. package/lib/network/processor/gossipHandlers.js +39 -9
  300. package/lib/network/processor/gossipHandlers.js.map +1 -1
  301. package/lib/network/processor/index.d.ts +12 -7
  302. package/lib/network/processor/index.d.ts.map +1 -1
  303. package/lib/network/processor/index.js +99 -78
  304. package/lib/network/processor/index.js.map +1 -1
  305. package/lib/network/reqresp/ReqRespBeaconNode.d.ts +1 -1
  306. package/lib/network/reqresp/ReqRespBeaconNode.d.ts.map +1 -1
  307. package/lib/network/reqresp/ReqRespBeaconNode.js +10 -1
  308. package/lib/network/reqresp/ReqRespBeaconNode.js.map +1 -1
  309. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts +8 -0
  310. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts.map +1 -0
  311. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +69 -0
  312. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -0
  313. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.d.ts +6 -0
  314. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.d.ts.map +1 -0
  315. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js +28 -0
  316. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js.map +1 -0
  317. package/lib/network/reqresp/handlers/index.d.ts.map +1 -1
  318. package/lib/network/reqresp/handlers/index.js +11 -1
  319. package/lib/network/reqresp/handlers/index.js.map +1 -1
  320. package/lib/network/reqresp/protocols.d.ts +2 -0
  321. package/lib/network/reqresp/protocols.d.ts.map +1 -1
  322. package/lib/network/reqresp/protocols.js +10 -0
  323. package/lib/network/reqresp/protocols.js.map +1 -1
  324. package/lib/network/reqresp/rateLimit.d.ts.map +1 -1
  325. package/lib/network/reqresp/rateLimit.js +8 -0
  326. package/lib/network/reqresp/rateLimit.js.map +1 -1
  327. package/lib/network/reqresp/score.d.ts.map +1 -1
  328. package/lib/network/reqresp/score.js +2 -0
  329. package/lib/network/reqresp/score.js.map +1 -1
  330. package/lib/network/reqresp/types.d.ts +8 -2
  331. package/lib/network/reqresp/types.d.ts.map +1 -1
  332. package/lib/network/reqresp/types.js +7 -1
  333. package/lib/network/reqresp/types.js.map +1 -1
  334. package/lib/node/nodejs.d.ts +2 -2
  335. package/lib/node/nodejs.d.ts.map +1 -1
  336. package/lib/node/nodejs.js +1 -4
  337. package/lib/node/nodejs.js.map +1 -1
  338. package/lib/node/notifier.d.ts.map +1 -1
  339. package/lib/node/notifier.js +3 -3
  340. package/lib/node/notifier.js.map +1 -1
  341. package/lib/sync/backfill/backfill.d.ts +3 -3
  342. package/lib/sync/backfill/backfill.d.ts.map +1 -1
  343. package/lib/sync/backfill/backfill.js +3 -3
  344. package/lib/sync/backfill/backfill.js.map +1 -1
  345. package/lib/sync/constants.d.ts +1 -1
  346. package/lib/sync/constants.js +1 -1
  347. package/lib/sync/unknownBlock.d.ts +3 -9
  348. package/lib/sync/unknownBlock.d.ts.map +1 -1
  349. package/lib/sync/unknownBlock.js +8 -41
  350. package/lib/sync/unknownBlock.js.map +1 -1
  351. package/lib/util/sszBytes.d.ts +4 -1
  352. package/lib/util/sszBytes.d.ts.map +1 -1
  353. package/lib/util/sszBytes.js +69 -12
  354. package/lib/util/sszBytes.js.map +1 -1
  355. package/lib/util/types.d.ts +2 -0
  356. package/lib/util/types.d.ts.map +1 -1
  357. package/lib/util/types.js +1 -0
  358. package/lib/util/types.js.map +1 -1
  359. package/package.json +16 -16
  360. package/src/api/impl/beacon/blocks/index.ts +37 -18
  361. package/src/api/impl/beacon/pool/index.ts +1 -1
  362. package/src/api/impl/beacon/state/index.ts +29 -41
  363. package/src/api/impl/beacon/state/utils.ts +13 -27
  364. package/src/api/impl/lodestar/index.ts +4 -8
  365. package/src/api/impl/proof/index.ts +2 -9
  366. package/src/api/impl/validator/index.ts +35 -43
  367. package/src/api/impl/validator/utils.ts +4 -7
  368. package/src/chain/archiveStore/archiveStore.ts +1 -10
  369. package/src/chain/archiveStore/historicalState/getHistoricalState.ts +10 -39
  370. package/src/chain/archiveStore/historicalState/historicalStateRegen.ts +2 -1
  371. package/src/chain/archiveStore/historicalState/types.ts +2 -0
  372. package/src/chain/archiveStore/historicalState/worker.ts +1 -4
  373. package/src/chain/archiveStore/interface.ts +5 -4
  374. package/src/chain/archiveStore/strategies/frequencyStateArchiveStrategy.ts +8 -5
  375. package/src/chain/archiveStore/utils/archiveBlocks.ts +59 -1
  376. package/src/chain/balancesCache.ts +5 -11
  377. package/src/chain/blocks/blockInput/types.ts +4 -3
  378. package/src/chain/blocks/importBlock.ts +69 -32
  379. package/src/chain/blocks/importExecutionPayload.ts +247 -0
  380. package/src/chain/blocks/index.ts +3 -2
  381. package/src/chain/blocks/payloadEnvelopeInput/index.ts +2 -0
  382. package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +336 -0
  383. package/src/chain/blocks/payloadEnvelopeInput/types.ts +33 -0
  384. package/src/chain/blocks/payloadEnvelopeProcessor.ts +61 -0
  385. package/src/chain/blocks/types.ts +34 -15
  386. package/src/chain/blocks/utils/checkpoint.ts +2 -2
  387. package/src/chain/blocks/verifyBlock.ts +5 -10
  388. package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +9 -14
  389. package/src/chain/blocks/verifyBlocksSignatures.ts +4 -4
  390. package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +6 -8
  391. package/src/chain/blocks/writePayloadEnvelopeInputToDb.ts +55 -0
  392. package/src/chain/chain.ts +134 -81
  393. package/src/chain/emitter.ts +2 -2
  394. package/src/chain/errors/blockError.ts +4 -4
  395. package/src/chain/errors/executionPayloadEnvelope.ts +6 -2
  396. package/src/chain/forkChoice/index.ts +33 -52
  397. package/src/chain/initState.ts +7 -2
  398. package/src/chain/interface.ts +20 -18
  399. package/src/chain/lightClient/index.ts +9 -22
  400. package/src/chain/opPools/aggregatedAttestationPool.ts +15 -21
  401. package/src/chain/opPools/opPool.ts +13 -14
  402. package/src/chain/opPools/utils.ts +4 -4
  403. package/src/chain/options.ts +2 -0
  404. package/src/chain/prepareNextSlot.ts +12 -10
  405. package/src/chain/produceBlock/computeNewStateRoot.ts +11 -10
  406. package/src/chain/produceBlock/produceBlockBody.ts +23 -50
  407. package/src/chain/regen/errors.ts +6 -1
  408. package/src/chain/regen/interface.ts +22 -18
  409. package/src/chain/regen/queued.ts +59 -27
  410. package/src/chain/regen/regen.ts +52 -23
  411. package/src/chain/seenCache/index.ts +1 -1
  412. package/src/chain/seenCache/seenGossipBlockInput.ts +2 -2
  413. package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +106 -0
  414. package/src/chain/serializeState.ts +3 -3
  415. package/src/chain/shufflingCache.ts +5 -7
  416. package/src/chain/stateCache/datastore/db.ts +33 -10
  417. package/src/chain/stateCache/datastore/file.ts +6 -5
  418. package/src/chain/stateCache/datastore/types.ts +3 -2
  419. package/src/chain/stateCache/fifoBlockStateCache.ts +17 -11
  420. package/src/chain/stateCache/persistentCheckpointsCache.ts +266 -172
  421. package/src/chain/stateCache/types.ts +22 -16
  422. package/src/chain/validation/attesterSlashing.ts +3 -3
  423. package/src/chain/validation/blobSidecar.ts +1 -1
  424. package/src/chain/validation/block.ts +2 -4
  425. package/src/chain/validation/blsToExecutionChange.ts +2 -2
  426. package/src/chain/validation/dataColumnSidecar.ts +1 -1
  427. package/src/chain/validation/executionPayloadBid.ts +3 -7
  428. package/src/chain/validation/executionPayloadEnvelope.ts +36 -29
  429. package/src/chain/validation/lightClientFinalityUpdate.ts +1 -1
  430. package/src/chain/validation/lightClientOptimisticUpdate.ts +1 -1
  431. package/src/chain/validation/payloadAttestationMessage.ts +2 -4
  432. package/src/chain/validation/proposerSlashing.ts +1 -1
  433. package/src/chain/validation/signatureSets/contributionAndProof.ts +2 -7
  434. package/src/chain/validation/signatureSets/syncCommittee.ts +2 -7
  435. package/src/chain/validation/signatureSets/syncCommitteeContribution.ts +2 -2
  436. package/src/chain/validation/signatureSets/syncCommitteeSelectionProof.ts +2 -7
  437. package/src/chain/validation/syncCommittee.ts +21 -20
  438. package/src/chain/validation/syncCommitteeContributionAndProof.ts +5 -10
  439. package/src/chain/validation/voluntaryExit.ts +3 -7
  440. package/src/chain/validatorMonitor.ts +23 -12
  441. package/src/execution/engine/interface.ts +2 -2
  442. package/src/metrics/metrics/lodestar.ts +100 -19
  443. package/src/network/gossip/encoding.ts +16 -0
  444. package/src/network/interface.ts +15 -2
  445. package/src/network/libp2p/index.ts +5 -0
  446. package/src/network/network.ts +34 -6
  447. package/src/network/processor/extractSlotRootFns.ts +19 -6
  448. package/src/network/processor/gossipHandlers.ts +45 -8
  449. package/src/network/processor/index.ts +110 -89
  450. package/src/network/reqresp/ReqRespBeaconNode.ts +14 -1
  451. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +94 -0
  452. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRoot.ts +43 -0
  453. package/src/network/reqresp/handlers/index.ts +12 -0
  454. package/src/network/reqresp/protocols.ts +12 -0
  455. package/src/network/reqresp/rateLimit.ts +18 -0
  456. package/src/network/reqresp/score.ts +2 -0
  457. package/src/network/reqresp/types.ts +13 -0
  458. package/src/node/nodejs.ts +3 -5
  459. package/src/node/notifier.ts +4 -10
  460. package/src/sync/backfill/backfill.ts +4 -4
  461. package/src/sync/constants.ts +1 -1
  462. package/src/sync/unknownBlock.ts +10 -50
  463. package/src/util/sszBytes.ts +90 -10
  464. package/src/util/types.ts +6 -0
  465. package/lib/chain/archiveStore/utils/archivePayloads.d.ts +0 -7
  466. package/lib/chain/archiveStore/utils/archivePayloads.d.ts.map +0 -1
  467. package/lib/chain/archiveStore/utils/archivePayloads.js +0 -10
  468. package/lib/chain/archiveStore/utils/archivePayloads.js.map +0 -1
  469. package/lib/chain/seenCache/seenExecutionPayloadEnvelope.d.ts +0 -15
  470. package/lib/chain/seenCache/seenExecutionPayloadEnvelope.d.ts.map +0 -1
  471. package/lib/chain/seenCache/seenExecutionPayloadEnvelope.js +0 -28
  472. package/lib/chain/seenCache/seenExecutionPayloadEnvelope.js.map +0 -1
  473. package/src/chain/archiveStore/utils/archivePayloads.ts +0 -15
  474. package/src/chain/seenCache/seenExecutionPayloadEnvelope.ts +0 -34
@@ -1,11 +1,7 @@
1
1
  import {routes} from "@lodestar/api";
2
2
  import {BeaconConfig} from "@lodestar/config";
3
- import {
4
- CachedBeaconStateAllForks,
5
- computeStartSlotAtEpoch,
6
- getBlockRootAtSlot,
7
- loadCachedBeaconState,
8
- } from "@lodestar/state-transition";
3
+ import {CheckpointWithPayloadStatus} from "@lodestar/fork-choice";
4
+ import {IBeaconStateView, computeStartSlotAtEpoch} from "@lodestar/state-transition";
9
5
  import {Epoch, RootHex, phase0} from "@lodestar/types";
10
6
  import {Logger, MapDef, fromHex, sleep, toHex, toRootHex} from "@lodestar/utils";
11
7
  import {Metrics} from "../../metrics/index.js";
@@ -14,7 +10,7 @@ import {IClock} from "../../util/clock.js";
14
10
  import {serializeState} from "../serializeState.js";
15
11
  import {CPStateDatastore, DatastoreKey} from "./datastore/index.js";
16
12
  import {MapTracker} from "./mapMetrics.js";
17
- import {BlockStateCache, CacheItemType, CheckpointHex, CheckpointStateCache} from "./types.js";
13
+ import {BlockStateCache, CacheItemType, CheckpointHexPayload, CheckpointStateCache} from "./types.js";
18
14
 
19
15
  export type PersistentCheckpointStateCacheOpts = {
20
16
  /** Keep max n state epochs in memory, persist the rest to disk */
@@ -39,7 +35,7 @@ type CacheKey = string;
39
35
 
40
36
  type InMemoryCacheItem = {
41
37
  type: CacheItemType.inMemory;
42
- state: CachedBeaconStateAllForks;
38
+ state: IBeaconStateView;
43
39
  // if a cp state is reloaded from disk, it'll keep track of persistedKey to allow us to remove it from disk later
44
40
  // it also helps not to persist it again
45
41
  persistedKey?: DatastoreKey;
@@ -54,6 +50,22 @@ type CacheItem = InMemoryCacheItem | PersistedCacheItem;
54
50
 
55
51
  type LoadedStateBytesData = {persistedKey: DatastoreKey; stateBytes: Uint8Array};
56
52
 
53
+ /** Bitmask for tracking which payload variants exist per root in the epochIndex */
54
+ enum PayloadAvailability {
55
+ NOT_PRESENT = 1,
56
+ PRESENT = 2,
57
+ }
58
+
59
+ const PAYLOAD_AVAILABILITY_ALL = [PayloadAvailability.NOT_PRESENT, PayloadAvailability.PRESENT] as const;
60
+
61
+ function toPayloadAvailability(payloadPresent: boolean): PayloadAvailability {
62
+ return payloadPresent ? PayloadAvailability.PRESENT : PayloadAvailability.NOT_PRESENT;
63
+ }
64
+
65
+ function fromPayloadAvailability(flag: PayloadAvailability): boolean {
66
+ return flag === PayloadAvailability.PRESENT;
67
+ }
68
+
57
69
  /**
58
70
  * Before n-historical states, lodestar keeps all checkpoint states since finalized
59
71
  * Since Sep 2024, lodestar stores 3 most recent checkpoint states in memory and the rest on disk. The finalized state
@@ -106,8 +118,8 @@ const PROCESS_CHECKPOINT_STATES_BPS = 6667;
106
118
  */
107
119
  export class PersistentCheckpointStateCache implements CheckpointStateCache {
108
120
  private readonly cache: MapTracker<CacheKey, CacheItem>;
109
- /** Epoch -> Set<blockRoot> */
110
- private readonly epochIndex = new MapDef<Epoch, Set<RootHex>>(() => new Set<string>());
121
+ /** Epoch -> Map<blockRoot, PayloadAvailability bitmask> */
122
+ private readonly epochIndex = new MapDef<Epoch, Map<RootHex, number>>(() => new Map());
111
123
  private readonly config: BeaconConfig;
112
124
  private readonly metrics: Metrics | null | undefined;
113
125
  private readonly logger: Logger;
@@ -203,19 +215,24 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
203
215
  * - Get block for processing
204
216
  * - Regen head state
205
217
  */
206
- async getOrReload(cp: CheckpointHex): Promise<CachedBeaconStateAllForks | null> {
218
+ async getOrReload(cp: CheckpointHexPayload): Promise<IBeaconStateView | null> {
207
219
  const stateOrStateBytesData = await this.getStateOrLoadDb(cp);
208
- if (stateOrStateBytesData === null || isCachedBeaconState(stateOrStateBytesData)) {
220
+ if (stateOrStateBytesData === null || isBeaconStateView(stateOrStateBytesData)) {
209
221
  return stateOrStateBytesData ?? null;
210
222
  }
211
223
  const {persistedKey, stateBytes} = stateOrStateBytesData;
212
- const logMeta = {persistedKey: toHex(persistedKey)};
224
+ const logMeta = {
225
+ epoch: cp.epoch,
226
+ rootHex: cp.rootHex,
227
+ payloadPresent: cp.payloadPresent,
228
+ persistedKey: toHex(persistedKey),
229
+ };
213
230
  this.logger.debug("Reload: read state successful", logMeta);
214
231
  this.metrics?.cpStateCache.stateReloadSecFromSlot.observe(
215
232
  this.clock?.secFromSlot(this.clock?.currentSlot ?? 0) ?? 0
216
233
  );
217
234
  const seedState = this.findSeedStateToReload(cp);
218
- this.metrics?.cpStateCache.stateReloadEpochDiff.observe(Math.abs(seedState.epochCtx.epoch - cp.epoch));
235
+ this.metrics?.cpStateCache.stateReloadEpochDiff.observe(Math.abs(seedState.epoch - cp.epoch));
219
236
  this.logger.debug("Reload: found seed state", {...logMeta, seedSlot: seedState.slot});
220
237
 
221
238
  try {
@@ -227,19 +244,16 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
227
244
  if (validatorsBytes == null) {
228
245
  // fallback logic in case we can't use the buffer pool
229
246
  this.metrics?.cpStateCache.stateReloadValidatorsSerializeAllocCount.inc();
230
- validatorsBytes = seedState.validators.serialize();
247
+ validatorsBytes = seedState.serializeValidators();
231
248
  }
232
249
  sszTimer?.();
233
250
  const timer = this.metrics?.cpStateCache.stateReloadDuration.startTimer();
234
- const newCachedState = loadCachedBeaconState(seedState, stateBytes, {}, validatorsBytes);
251
+ const newCachedState = seedState.loadOtherState(stateBytes, validatorsBytes);
235
252
  // hashTreeRoot() calls the commit() inside
236
253
  // there is no modification inside the state, it's just that we want to compute and cache all roots
237
254
  const stateRoot = toRootHex(newCachedState.hashTreeRoot());
238
255
  timer?.();
239
256
 
240
- // load all cache in order for consumers (usually regen.getState()) to process blocks faster
241
- newCachedState.validators.getAllReadonlyValues();
242
- newCachedState.balances.getAll();
243
257
  this.logger.debug("Reload: cached state load successful", {
244
258
  ...logMeta,
245
259
  stateSlot: newCachedState.slot,
@@ -250,7 +264,7 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
250
264
  // only remove persisted state once we reload successfully
251
265
  const cpKey = toCacheKey(cp);
252
266
  this.cache.set(cpKey, {type: CacheItemType.inMemory, state: newCachedState, persistedKey});
253
- this.epochIndex.getOrDefault(cp.epoch).add(cp.rootHex);
267
+ this.addToEpochIndex(cp.epoch, cp.rootHex, cp.payloadPresent);
254
268
  // don't prune from memory here, call it at the last 1/3 of slot 0 of an epoch
255
269
  return newCachedState;
256
270
  } catch (e) {
@@ -262,9 +276,9 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
262
276
  /**
263
277
  * Return either state or state bytes loaded from db.
264
278
  */
265
- async getStateOrBytes(cp: CheckpointHex): Promise<CachedBeaconStateAllForks | Uint8Array | null> {
279
+ async getStateOrBytes(cp: CheckpointHexPayload): Promise<IBeaconStateView | Uint8Array | null> {
266
280
  const stateOrLoadedState = await this.getStateOrLoadDb(cp);
267
- if (stateOrLoadedState === null || isCachedBeaconState(stateOrLoadedState)) {
281
+ if (stateOrLoadedState === null || isBeaconStateView(stateOrLoadedState)) {
268
282
  return stateOrLoadedState;
269
283
  }
270
284
  return stateOrLoadedState.stateBytes;
@@ -273,7 +287,7 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
273
287
  /**
274
288
  * Return either state or state bytes with persisted key loaded from db.
275
289
  */
276
- async getStateOrLoadDb(cp: CheckpointHex): Promise<CachedBeaconStateAllForks | LoadedStateBytesData | null> {
290
+ async getStateOrLoadDb(cp: CheckpointHexPayload): Promise<IBeaconStateView | LoadedStateBytesData | null> {
277
291
  const cpKey = toCacheKey(cp);
278
292
  const inMemoryState = this.get(cpKey);
279
293
  if (inMemoryState) {
@@ -304,7 +318,7 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
304
318
  /**
305
319
  * Similar to get() api without reloading from disk
306
320
  */
307
- get(cpOrKey: CheckpointHex | string): CachedBeaconStateAllForks | null {
321
+ get(cpOrKey: CheckpointHexPayload | CacheKey): IBeaconStateView | null {
308
322
  this.metrics?.cpStateCache.lookups.inc();
309
323
  const cpKey = typeof cpOrKey === "string" ? cpOrKey : toCacheKey(cpOrKey);
310
324
  const cacheItem = this.cache.get(cpKey);
@@ -330,9 +344,11 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
330
344
 
331
345
  /**
332
346
  * Add a state of a checkpoint to this cache, prune from memory if necessary.
347
+ * @param payloadPresent - For Gloas: true if this is payload state, false if block state.
348
+ * Always true for pre-Gloas.
333
349
  */
334
- add(cp: phase0.Checkpoint, state: CachedBeaconStateAllForks): void {
335
- const cpHex = toCheckpointHex(cp);
350
+ add(cp: phase0.Checkpoint, state: IBeaconStateView, payloadPresent: boolean): void {
351
+ const cpHex = toCheckpointHexPayload(cp, payloadPresent);
336
352
  const key = toCacheKey(cpHex);
337
353
  const cacheItem = this.cache.get(key);
338
354
  this.metrics?.cpStateCache.adds.inc();
@@ -343,27 +359,32 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
343
359
  this.logger.verbose("Added checkpoint state to memory but a persisted key existed", {
344
360
  epoch: cp.epoch,
345
361
  rootHex: cpHex.rootHex,
362
+ payloadPresent,
346
363
  persistedKey: toHex(persistedKey),
347
364
  });
348
365
  } else {
349
366
  this.cache.set(key, {type: CacheItemType.inMemory, state});
350
- this.logger.verbose("Added checkpoint state to memory", {epoch: cp.epoch, rootHex: cpHex.rootHex});
367
+ this.logger.verbose("Added checkpoint state to memory", {
368
+ epoch: cp.epoch,
369
+ rootHex: cpHex.rootHex,
370
+ payloadPresent,
371
+ });
351
372
  }
352
- this.epochIndex.getOrDefault(cp.epoch).add(cpHex.rootHex);
373
+ this.addToEpochIndex(cp.epoch, cpHex.rootHex, cpHex.payloadPresent);
353
374
  this.prunePersistedStates();
354
375
  }
355
376
 
356
377
  /**
357
378
  * Searches in-memory state for the latest cached state with a `root` without reload, starting with `epoch` and descending
358
379
  */
359
- getLatest(rootHex: RootHex, maxEpoch: Epoch): CachedBeaconStateAllForks | null {
380
+ getLatest(rootHex: RootHex, maxEpoch: Epoch, payloadPresent: boolean): IBeaconStateView | null {
360
381
  // sort epochs in descending order, only consider epochs lte `epoch`
361
382
  const epochs = Array.from(this.epochIndex.keys())
362
383
  .sort((a, b) => b - a)
363
384
  .filter((e) => e <= maxEpoch);
364
385
  for (const epoch of epochs) {
365
- if (this.epochIndex.get(epoch)?.has(rootHex)) {
366
- const inMemoryClonedState = this.get({rootHex, epoch});
386
+ if (this.hasPayloadVariant(epoch, rootHex, payloadPresent)) {
387
+ const inMemoryClonedState = this.get({rootHex, epoch, payloadPresent});
367
388
  if (inMemoryClonedState) {
368
389
  return inMemoryClonedState;
369
390
  }
@@ -379,20 +400,24 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
379
400
  * - Get block for processing
380
401
  * - Regen head state
381
402
  */
382
- async getOrReloadLatest(rootHex: RootHex, maxEpoch: Epoch): Promise<CachedBeaconStateAllForks | null> {
403
+ async getOrReloadLatest(
404
+ rootHex: RootHex,
405
+ maxEpoch: Epoch,
406
+ payloadPresent: boolean
407
+ ): Promise<IBeaconStateView | null> {
383
408
  // sort epochs in descending order, only consider epochs lte `epoch`
384
409
  const epochs = Array.from(this.epochIndex.keys())
385
410
  .sort((a, b) => b - a)
386
411
  .filter((e) => e <= maxEpoch);
387
412
  for (const epoch of epochs) {
388
- if (this.epochIndex.get(epoch)?.has(rootHex)) {
413
+ if (this.hasPayloadVariant(epoch, rootHex, payloadPresent)) {
389
414
  try {
390
- const state = await this.getOrReload({rootHex, epoch});
415
+ const state = await this.getOrReload({rootHex, epoch, payloadPresent});
391
416
  if (state) {
392
417
  return state;
393
418
  }
394
419
  } catch (e) {
395
- this.logger.debug("Error get or reload state", {epoch, rootHex}, e as Error);
420
+ this.logger.debug("Error get or reload state", {epoch, rootHex, payloadPresent}, e as Error);
396
421
  }
397
422
  }
398
423
  }
@@ -400,12 +425,14 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
400
425
  }
401
426
 
402
427
  /**
403
- * Update the precomputed checkpoint and return the number of his for the
428
+ * Update the precomputed checkpoint and return the number of hits for the
404
429
  * previous one (if any).
430
+ * @param payloadPresent - For Gloas: true if head block has FULL payload, false if EMPTY.
431
+ * Always true for pre-Gloas.
405
432
  */
406
- updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch): number | null {
433
+ updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch, payloadPresent: boolean): number | null {
407
434
  const previousHits = this.preComputedCheckpointHits;
408
- this.preComputedCheckpoint = toCacheKey({rootHex, epoch});
435
+ this.preComputedCheckpoint = toCacheKey({rootHex, epoch, payloadPresent});
409
436
  this.preComputedCheckpointHits = 0;
410
437
  return previousHits;
411
438
  }
@@ -479,8 +506,11 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
479
506
  * - 2 then we'll persist {root: b2, epoch n-2} checkpoint state to disk, there are also 2 checkpoint states in memory at epoch n, same to the above (maxEpochsInMemory=1)
480
507
  *
481
508
  * As of Mar 2024, it takes <=350ms to persist a holesky state on fast server
509
+ *
510
+ * For Gloas: Processes both block state and payload state variants together. The decision of which roots to persist/prune
511
+ * is based on root canonicality (from state's view), not payload presence. Both variants are managed as a unit.
482
512
  */
483
- async processState(blockRootHex: RootHex, state: CachedBeaconStateAllForks): Promise<number> {
513
+ async processState(blockRootHex: RootHex, state: IBeaconStateView): Promise<number> {
484
514
  let persistCount = 0;
485
515
  // it's important to sort the epochs in ascending order, in case of big reorg we always want to keep the most recent checkpoint states
486
516
  const sortedEpochs = Array.from(this.epochIndex.keys()).sort((a, b) => a - b);
@@ -549,10 +579,10 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
549
579
  *
550
580
  * Use seed state from the block cache if cannot find any seed states within this cache.
551
581
  */
552
- findSeedStateToReload(reloadedCp: CheckpointHex): CachedBeaconStateAllForks {
582
+ findSeedStateToReload(reloadedCp: CheckpointHexPayload): IBeaconStateView {
553
583
  const maxEpoch = Math.max(...Array.from(this.epochIndex.keys()));
554
584
  const reloadedCpSlot = computeStartSlotAtEpoch(reloadedCp.epoch);
555
- let firstState: CachedBeaconStateAllForks | null = null;
585
+ let firstState: IBeaconStateView | null = null;
556
586
  const logCtx = {reloadedCpEpoch: reloadedCp.epoch, reloadedCpRoot: reloadedCp.rootHex};
557
587
 
558
588
  // no need to check epochs before `maxEpoch - this.maxEpochsInMemory + 1` before they are all persisted
@@ -562,32 +592,35 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
562
592
  return firstState;
563
593
  }
564
594
 
565
- for (const rootHex of this.epochIndex.get(epoch) || []) {
566
- const cpKey = toCacheKey({rootHex, epoch});
567
- const cacheItem = this.cache.get(cpKey);
568
- if (cacheItem === undefined) {
569
- // should not happen
570
- continue;
571
- }
572
- if (isInMemoryCacheItem(cacheItem)) {
573
- const {state} = cacheItem;
574
- if (firstState === null) {
575
- firstState = state;
595
+ for (const [rootHex, bitmask] of this.epochIndex.get(epoch) || []) {
596
+ for (const flag of PAYLOAD_AVAILABILITY_ALL) {
597
+ if (!(bitmask & flag)) continue;
598
+ const payloadPresent = fromPayloadAvailability(flag);
599
+ const cpKey = toCacheKey({rootHex, epoch, payloadPresent});
600
+ const cacheItem = this.cache.get(cpKey);
601
+ if (cacheItem === undefined) {
602
+ continue;
576
603
  }
577
- const cpLog = {cpEpoch: epoch, cpRoot: rootHex};
578
-
579
- try {
580
- // amongst states of the same epoch, choose the one with the same view of reloadedCp
581
- if (
582
- reloadedCpSlot < state.slot &&
583
- toRootHex(getBlockRootAtSlot(state, reloadedCpSlot)) === reloadedCp.rootHex
584
- ) {
585
- this.logger.verbose("Reload: use checkpoint state as seed state", {...cpLog, ...logCtx});
586
- return state;
604
+ if (isInMemoryCacheItem(cacheItem)) {
605
+ const {state} = cacheItem;
606
+ if (firstState === null) {
607
+ firstState = state;
608
+ }
609
+ const cpLog = {cpEpoch: epoch, cpRoot: rootHex, payloadPresent};
610
+
611
+ try {
612
+ // amongst states of the same epoch, choose the one with the same view of reloadedCp
613
+ if (
614
+ reloadedCpSlot < state.slot &&
615
+ toRootHex(state.getBlockRootAtSlot(reloadedCpSlot)) === reloadedCp.rootHex
616
+ ) {
617
+ this.logger.verbose("Reload: use checkpoint state as seed state", {...cpLog, ...logCtx});
618
+ return state;
619
+ }
620
+ } catch (e) {
621
+ // getBlockRootAtSlot may throw error
622
+ this.logger.debug("Error finding checkpoint state to reload", {...cpLog, ...logCtx}, e as Error);
587
623
  }
588
- } catch (e) {
589
- // getBlockRootAtSlot may throw error
590
- this.logger.debug("Error finding checkpoint state to reload", {...cpLog, ...logCtx}, e as Error);
591
624
  }
592
625
  }
593
626
  }
@@ -604,6 +637,31 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
604
637
  this.epochIndex.clear();
605
638
  }
606
639
 
640
+ private addToEpochIndex(epoch: Epoch, rootHex: RootHex, payloadPresent: boolean): void {
641
+ const rootMap = this.epochIndex.getOrDefault(epoch);
642
+ rootMap.set(rootHex, (rootMap.get(rootHex) ?? 0) | toPayloadAvailability(payloadPresent));
643
+ }
644
+
645
+ private removeFromEpochIndex(epoch: Epoch, rootHex: RootHex, payloadPresent: boolean): void {
646
+ const rootMap = this.epochIndex.get(epoch);
647
+ if (rootMap === undefined) return;
648
+ const existing = rootMap.get(rootHex);
649
+ if (existing === undefined) return;
650
+ const updated = existing & ~toPayloadAvailability(payloadPresent);
651
+ if (updated === 0) {
652
+ rootMap.delete(rootHex);
653
+ if (rootMap.size === 0) {
654
+ this.epochIndex.delete(epoch);
655
+ }
656
+ } else {
657
+ rootMap.set(rootHex, updated);
658
+ }
659
+ }
660
+
661
+ private hasPayloadVariant(epoch: Epoch, rootHex: RootHex, payloadPresent: boolean): boolean {
662
+ return Boolean((this.epochIndex.get(epoch)?.get(rootHex) ?? 0) & toPayloadAvailability(payloadPresent));
663
+ }
664
+
607
665
  /** ONLY FOR DEBUGGING PURPOSES. For lodestar debug API */
608
666
  dumpSummary(): routes.lodestar.StateCacheItem[] {
609
667
  return Array.from(this.cache.keys()).map((key) => {
@@ -619,7 +677,7 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
619
677
  });
620
678
  }
621
679
 
622
- getStates(): IterableIterator<CachedBeaconStateAllForks> {
680
+ getStates(): IterableIterator<IBeaconStateView> {
623
681
  const items = Array.from(this.cache.values())
624
682
  .filter(isInMemoryCacheItem)
625
683
  .map((item) => item.state);
@@ -669,20 +727,16 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
669
727
  * - In normal condition, we persist 1 checkpoint state per epoch.
670
728
  * - In reorged condition, we may persist multiple (most likely 2) checkpoint states per epoch.
671
729
  */
672
- private async processPastEpoch(
673
- blockRootHex: RootHex,
674
- state: CachedBeaconStateAllForks,
675
- epoch: Epoch
676
- ): Promise<number> {
730
+ private async processPastEpoch(blockRootHex: RootHex, state: IBeaconStateView, epoch: Epoch): Promise<number> {
677
731
  let persistCount = 0;
678
732
  const epochBoundarySlot = computeStartSlotAtEpoch(epoch);
679
733
  const epochBoundaryRoot =
680
- epochBoundarySlot === state.slot ? fromHex(blockRootHex) : getBlockRootAtSlot(state, epochBoundarySlot);
734
+ epochBoundarySlot === state.slot ? fromHex(blockRootHex) : state.getBlockRootAtSlot(epochBoundarySlot);
681
735
  const epochBoundaryHex = toRootHex(epochBoundaryRoot);
682
- const prevEpochRoot = toRootHex(getBlockRootAtSlot(state, epochBoundarySlot - 1));
736
+ const prevEpochRoot = toRootHex(state.getBlockRootAtSlot(epochBoundarySlot - 1));
683
737
 
684
738
  // for each epoch, usually there are 2 rootHexes respective to the 2 checkpoint states: Previous Root Checkpoint State and Current Root Checkpoint State
685
- const cpRootHexes = this.epochIndex.get(epoch) ?? [];
739
+ const cpRootHexMap = this.epochIndex.get(epoch) ?? new Map<RootHex, number>();
686
740
  const persistedRootHexes = new Set<RootHex>();
687
741
 
688
742
  // 1) if there is no CRCS, persist PRCS (block 0 of epoch is skipped). In this case prevEpochRoot === epochBoundaryHex
@@ -691,76 +745,81 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
691
745
  persistedRootHexes.add(epochBoundaryHex);
692
746
 
693
747
  // 3) persist any states with unknown roots to this state
694
- for (const rootHex of cpRootHexes) {
748
+ for (const rootHex of cpRootHexMap.keys()) {
695
749
  if (rootHex !== epochBoundaryHex && rootHex !== prevEpochRoot) {
696
750
  persistedRootHexes.add(rootHex);
697
751
  }
698
752
  }
699
753
 
700
- for (const rootHex of cpRootHexes) {
701
- const cpKey = toCacheKey({epoch: epoch, rootHex});
702
- const cacheItem = this.cache.get(cpKey);
703
-
704
- if (cacheItem !== undefined && isInMemoryCacheItem(cacheItem)) {
705
- let {persistedKey} = cacheItem;
706
- const {state} = cacheItem;
707
- const logMeta = {
708
- stateSlot: state.slot,
709
- rootHex,
710
- epochBoundaryHex,
711
- persistedKey: persistedKey ? toHex(persistedKey) : "",
712
- };
713
-
714
- if (persistedRootHexes.has(rootHex)) {
715
- if (persistedKey) {
716
- // we don't care if the checkpoint state is already persisted
717
- this.logger.verbose("Pruned checkpoint state from memory but no need to persist", logMeta);
718
- } else {
719
- // persist and do not update epochIndex
720
- this.metrics?.cpStateCache.statePersistSecFromSlot.observe(
721
- this.clock?.secFromSlot(this.clock?.currentSlot ?? 0) ?? 0
722
- );
723
- const cpPersist = {epoch: epoch, root: fromHex(rootHex)};
724
- // It's not sustainable to allocate ~240MB for each state every epoch, so we use buffer pool to reuse the memory.
725
- // As monitored on holesky as of Jan 2024:
726
- // - This does not increase heap allocation while gc time is the same
727
- // - It helps stabilize persist time and save ~300ms in average (1.5s vs 1.2s)
728
- // - It also helps the state reload to save ~500ms in average (4.3s vs 3.8s)
729
- // - Also `serializeState.test.ts` perf test shows a lot of differences allocating ~240MB once vs per state serialization
730
- const timer = this.metrics?.stateSerializeDuration.startTimer({
731
- source: AllocSource.PERSISTENT_CHECKPOINTS_CACHE_STATE,
732
- });
733
- persistedKey = await serializeState(
734
- state,
735
- AllocSource.PERSISTENT_CHECKPOINTS_CACHE_STATE,
736
- (stateBytes) => {
737
- timer?.();
738
- return this.datastore.write(cpPersist, stateBytes);
739
- },
740
- this.bufferPool
741
- );
754
+ for (const [rootHex, bitmask] of cpRootHexMap) {
755
+ for (const flag of PAYLOAD_AVAILABILITY_ALL) {
756
+ if (!(bitmask & flag)) continue;
757
+ const payloadPresent = fromPayloadAvailability(flag);
758
+ const cpKey = toCacheKey({epoch: epoch, rootHex, payloadPresent});
759
+ const cacheItem = this.cache.get(cpKey);
742
760
 
743
- persistCount++;
744
- this.logger.verbose("Pruned checkpoint state from memory and persisted to disk", {
745
- ...logMeta,
746
- persistedKey: toHex(persistedKey),
747
- });
748
- }
749
- // overwrite cpKey, this means the state is deleted from memory
750
- this.cache.set(cpKey, {type: CacheItemType.persisted, value: persistedKey});
751
- } else {
752
- if (persistedKey) {
753
- // persisted file will be eventually deleted by the archive task
754
- // this also means the state is deleted from memory
761
+ if (cacheItem !== undefined && isInMemoryCacheItem(cacheItem)) {
762
+ let {persistedKey} = cacheItem;
763
+ const {state} = cacheItem;
764
+ const logMeta = {
765
+ stateSlot: state.slot,
766
+ rootHex,
767
+ payloadPresent,
768
+ epochBoundaryHex,
769
+ persistedKey: persistedKey ? toHex(persistedKey) : "",
770
+ };
771
+
772
+ if (persistedRootHexes.has(rootHex)) {
773
+ if (persistedKey) {
774
+ // we don't care if the checkpoint state is already persisted
775
+ this.logger.verbose("Pruned checkpoint state from memory but no need to persist", logMeta);
776
+ } else {
777
+ // persist and do not update epochIndex
778
+ this.metrics?.cpStateCache.statePersistSecFromSlot.observe(
779
+ this.clock?.secFromSlot(this.clock?.currentSlot ?? 0) ?? 0
780
+ );
781
+ const cpPersist = {epoch: epoch, root: fromHex(rootHex)};
782
+ // It's not sustainable to allocate ~240MB for each state every epoch, so we use buffer pool to reuse the memory.
783
+ // As monitored on holesky as of Jan 2024:
784
+ // - This does not increase heap allocation while gc time is the same
785
+ // - It helps stabilize persist time and save ~300ms in average (1.5s vs 1.2s)
786
+ // - It also helps the state reload to save ~500ms in average (4.3s vs 3.8s)
787
+ // - Also `serializeState.test.ts` perf test shows a lot of differences allocating ~240MB once vs per state serialization
788
+ const timer = this.metrics?.stateSerializeDuration.startTimer({
789
+ source: AllocSource.PERSISTENT_CHECKPOINTS_CACHE_STATE,
790
+ });
791
+ persistedKey = await serializeState(
792
+ state,
793
+ AllocSource.PERSISTENT_CHECKPOINTS_CACHE_STATE,
794
+ (stateBytes) => {
795
+ timer?.();
796
+ return this.datastore.write(cpPersist, stateBytes, payloadPresent);
797
+ },
798
+ this.bufferPool
799
+ );
800
+
801
+ persistCount++;
802
+ this.logger.verbose("Pruned checkpoint state from memory and persisted to disk", {
803
+ ...logMeta,
804
+ persistedKey: toHex(persistedKey),
805
+ });
806
+ }
807
+ // overwrite cpKey, this means the state is deleted from memory
755
808
  this.cache.set(cpKey, {type: CacheItemType.persisted, value: persistedKey});
756
- // do not update epochIndex
757
809
  } else {
758
- // delete the state from memory
759
- this.cache.delete(cpKey);
760
- this.epochIndex.get(epoch)?.delete(rootHex);
810
+ if (persistedKey) {
811
+ // persisted file will be eventually deleted by the archive task
812
+ // this also means the state is deleted from memory
813
+ this.cache.set(cpKey, {type: CacheItemType.persisted, value: persistedKey});
814
+ // do not update epochIndex
815
+ } else {
816
+ // delete the state from memory
817
+ this.cache.delete(cpKey);
818
+ this.removeFromEpochIndex(epoch, rootHex, payloadPresent);
819
+ }
820
+ this.metrics?.cpStateCache.statePruneFromMemoryCount.inc();
821
+ this.logger.verbose("Pruned checkpoint state from memory", logMeta);
761
822
  }
762
- this.metrics?.cpStateCache.statePruneFromMemoryCount.inc();
763
- this.logger.verbose("Pruned checkpoint state from memory", logMeta);
764
823
  }
765
824
  }
766
825
  }
@@ -773,26 +832,40 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
773
832
  */
774
833
  private async deleteAllEpochItems(epoch: Epoch): Promise<void> {
775
834
  let persistCount = 0;
776
- const rootHexes = this.epochIndex.get(epoch) || [];
777
- for (const rootHex of rootHexes) {
778
- const key = toCacheKey({rootHex, epoch});
779
- const cacheItem = this.cache.get(key);
780
-
781
- if (cacheItem) {
782
- const persistedKey = isPersistedCacheItem(cacheItem) ? cacheItem.value : cacheItem.persistedKey;
783
- if (persistedKey) {
784
- await this.datastore.remove(persistedKey);
785
- persistCount++;
786
- this.metrics?.cpStateCache.persistedStateRemoveCount.inc();
835
+ const rootHexMap = this.epochIndex.get(epoch) || new Map<RootHex, number>();
836
+ for (const [rootHex, bitmask] of rootHexMap) {
837
+ for (const flag of PAYLOAD_AVAILABILITY_ALL) {
838
+ if (!(bitmask & flag)) continue;
839
+ const payloadPresent = fromPayloadAvailability(flag);
840
+ const key = toCacheKey({rootHex, epoch, payloadPresent});
841
+ const cacheItem = this.cache.get(key);
842
+
843
+ if (cacheItem) {
844
+ const persistedKey = isPersistedCacheItem(cacheItem) ? cacheItem.value : cacheItem.persistedKey;
845
+ if (persistedKey) {
846
+ await this.datastore.remove(persistedKey);
847
+ persistCount++;
848
+ this.metrics?.cpStateCache.persistedStateRemoveCount.inc();
849
+ }
787
850
  }
851
+ this.cache.delete(key);
852
+ this.logger.verbose("Pruned checkpoint state", {
853
+ epoch,
854
+ rootHex,
855
+ payloadPresent,
856
+ type: cacheItem ? (isPersistedCacheItem(cacheItem) ? "persisted" : "in-memory") : "missing",
857
+ });
788
858
  }
789
- this.cache.delete(key);
790
859
  }
791
860
  this.epochIndex.delete(epoch);
792
- this.logger.verbose("Pruned checkpoint states for epoch", {
861
+ this.logger.verbose("Pruned all checkpoint states for epoch", {
793
862
  epoch,
794
863
  persistCount,
795
- rootHexes: Array.from(rootHexes).join(","),
864
+ items: Array.from(rootHexMap.entries())
865
+ .flatMap(([rootHex, bitmask]) =>
866
+ PAYLOAD_AVAILABILITY_ALL.filter((f) => bitmask & f).map((f) => `${rootHex}:${fromPayloadAvailability(f)}`)
867
+ )
868
+ .join(","),
796
869
  });
797
870
  }
798
871
 
@@ -827,15 +900,14 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
827
900
  * - Also `serializeState.test.ts` perf test shows a lot of differences allocating validators bytes once vs every time,
828
901
  * This is 2x - 3x faster than allocating memory every time.
829
902
  */
830
- private serializeStateValidators(state: CachedBeaconStateAllForks): BufferWithKey | null {
831
- const type = state.type.fields.validators;
832
- const size = type.tree_serializedSize(state.validators.node);
903
+ private serializeStateValidators(state: IBeaconStateView): BufferWithKey | null {
904
+ const size = state.serializedValidatorsSize();
833
905
  if (this.bufferPool) {
834
906
  const bufferWithKey = this.bufferPool.alloc(size, AllocSource.PERSISTENT_CHECKPOINTS_CACHE_VALIDATORS);
835
907
  if (bufferWithKey) {
836
908
  const validatorsBytes = bufferWithKey.buffer;
837
909
  const dataView = new DataView(validatorsBytes.buffer, validatorsBytes.byteOffset, validatorsBytes.byteLength);
838
- state.validators.serializeToBytes({uint8Array: validatorsBytes, dataView}, 0);
910
+ state.serializeValidatorsToBytes({uint8Array: validatorsBytes, dataView}, 0);
839
911
  return bufferWithKey;
840
912
  }
841
913
  }
@@ -844,36 +916,62 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
844
916
  }
845
917
  }
846
918
 
847
- export function toCheckpointHex(checkpoint: phase0.Checkpoint): CheckpointHex {
919
+ export function toCheckpointHexPayload(checkpoint: phase0.Checkpoint, payloadPresent: boolean): CheckpointHexPayload {
848
920
  return {
849
921
  epoch: checkpoint.epoch,
850
922
  rootHex: toRootHex(checkpoint.root),
923
+ payloadPresent,
851
924
  };
852
925
  }
853
926
 
854
- export function toCheckpointKey(cp: CheckpointHex): string {
855
- return `${cp.rootHex}:${cp.epoch}`;
856
- }
927
+ /**
928
+ * Convert fork-choice CheckpointWithPayloadStatus to beacon-node CheckpointHexPayload.
929
+ * Maps PayloadStatus enum to boolean payloadPresent.
930
+ * @throws Error if checkpoint has PENDING payload status (ambiguous which variant to use)
931
+ */
932
+ export function fcCheckpointToHexPayload(checkpoint: CheckpointWithPayloadStatus): CheckpointHexPayload {
933
+ const PayloadStatus = {PENDING: 0, EMPTY: 1, FULL: 2} as const;
857
934
 
858
- function toCacheKey(cp: CheckpointHex | phase0.Checkpoint): CacheKey {
859
- if (isCheckpointHex(cp)) {
860
- return `${cp.rootHex}_${cp.epoch}`;
935
+ if (checkpoint.payloadStatus === PayloadStatus.PENDING) {
936
+ throw Error(
937
+ `Cannot convert checkpoint with PENDING payload status at epoch ${checkpoint.epoch} root ${checkpoint.rootHex}`
938
+ );
861
939
  }
862
- return `${toRootHex(cp.root)}_${cp.epoch}`;
940
+
941
+ return {
942
+ epoch: checkpoint.epoch,
943
+ rootHex: checkpoint.rootHex,
944
+ payloadPresent: checkpoint.payloadStatus === PayloadStatus.FULL,
945
+ };
946
+ }
947
+
948
+ export function toCheckpointKey(cp: CheckpointHexPayload): string {
949
+ return `${cp.rootHex}:${cp.epoch}:${cp.payloadPresent}`;
863
950
  }
864
951
 
865
- function fromCacheKey(key: CacheKey): CheckpointHex {
866
- const [rootHex, epoch] = key.split("_");
952
+ /**
953
+ * Convert checkpoint to cache key string.
954
+ * Format: `{rootHex}_{epoch}_{payloadPresent}`
955
+ */
956
+ function toCacheKey(cp: CheckpointHexPayload): CacheKey {
957
+ return `${cp.rootHex}_${cp.epoch}_${cp.payloadPresent}`;
958
+ }
959
+
960
+ function fromCacheKey(key: CacheKey): CheckpointHexPayload {
961
+ const parts = key.split("_");
962
+ const rootHex = parts[0];
963
+ const epoch = Number(parts[1]);
964
+ // For backward compatibility with old format (rootHex_epoch), default to true
965
+ const payloadPresent = parts.length > 2 ? parts[2] === "true" : true;
867
966
  return {
868
967
  rootHex,
869
- epoch: Number(epoch),
968
+ epoch,
969
+ payloadPresent,
870
970
  };
871
971
  }
872
972
 
873
- function isCachedBeaconState(
874
- stateOrBytes: CachedBeaconStateAllForks | LoadedStateBytesData
875
- ): stateOrBytes is CachedBeaconStateAllForks {
876
- return (stateOrBytes as CachedBeaconStateAllForks).slot !== undefined;
973
+ function isBeaconStateView(stateOrBytes: IBeaconStateView | LoadedStateBytesData): stateOrBytes is IBeaconStateView {
974
+ return (stateOrBytes as IBeaconStateView).slot !== undefined;
877
975
  }
878
976
 
879
977
  function isInMemoryCacheItem(cacheItem: CacheItem): cacheItem is InMemoryCacheItem {
@@ -883,7 +981,3 @@ function isInMemoryCacheItem(cacheItem: CacheItem): cacheItem is InMemoryCacheIt
883
981
  function isPersistedCacheItem(cacheItem: CacheItem): cacheItem is PersistedCacheItem {
884
982
  return cacheItem.type === CacheItemType.persisted;
885
983
  }
886
-
887
- function isCheckpointHex(cp: CheckpointHex | phase0.Checkpoint): cp is CheckpointHex {
888
- return (cp as CheckpointHex).rootHex !== undefined;
889
- }