@lodestar/beacon-node 1.50.0-dev.fd4f342a40 → 1.50.0-dev.fe4e7408b4

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 (333) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +13 -3
  3. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  4. package/lib/api/impl/beacon/index.d.ts.map +1 -1
  5. package/lib/api/impl/beacon/index.js +13 -0
  6. package/lib/api/impl/beacon/index.js.map +1 -1
  7. package/lib/api/impl/beacon/state/index.d.ts.map +1 -1
  8. package/lib/api/impl/beacon/state/index.js +28 -6
  9. package/lib/api/impl/beacon/state/index.js.map +1 -1
  10. package/lib/api/impl/debug/index.d.ts.map +1 -1
  11. package/lib/api/impl/debug/index.js +26 -18
  12. package/lib/api/impl/debug/index.js.map +1 -1
  13. package/lib/api/impl/validator/index.d.ts +1 -0
  14. package/lib/api/impl/validator/index.d.ts.map +1 -1
  15. package/lib/api/impl/validator/index.js +65 -4
  16. package/lib/api/impl/validator/index.js.map +1 -1
  17. package/lib/chain/archiveStore/archiveStore.d.ts +5 -0
  18. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  19. package/lib/chain/archiveStore/archiveStore.js +14 -24
  20. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  21. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts +2 -2
  22. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
  23. package/lib/chain/archiveStore/historicalState/getHistoricalState.js +5 -7
  24. package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
  25. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js +1 -1
  26. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js.map +1 -1
  27. package/lib/chain/archiveStore/historicalState/types.d.ts +2 -2
  28. package/lib/chain/archiveStore/historicalState/types.d.ts.map +1 -1
  29. package/lib/chain/archiveStore/historicalState/worker.js +1 -1
  30. package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
  31. package/lib/chain/archiveStore/interface.d.ts +1 -1
  32. package/lib/chain/archiveStore/interface.d.ts.map +1 -1
  33. package/lib/chain/archiveStore/utils/pruneHistory.d.ts +1 -1
  34. package/lib/chain/archiveStore/utils/pruneHistory.d.ts.map +1 -1
  35. package/lib/chain/archiveStore/utils/pruneHistory.js +2 -1
  36. package/lib/chain/archiveStore/utils/pruneHistory.js.map +1 -1
  37. package/lib/chain/beaconProposerCache.d.ts +6 -0
  38. package/lib/chain/beaconProposerCache.d.ts.map +1 -1
  39. package/lib/chain/beaconProposerCache.js +16 -0
  40. package/lib/chain/beaconProposerCache.js.map +1 -1
  41. package/lib/chain/blocks/blockInput/blockInput.d.ts +1 -1
  42. package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
  43. package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
  44. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  45. package/lib/chain/blocks/importBlock.js +14 -8
  46. package/lib/chain/blocks/importBlock.js.map +1 -1
  47. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  48. package/lib/chain/blocks/verifyBlock.js +7 -7
  49. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  50. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts +2 -1
  51. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
  52. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +5 -4
  53. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
  54. package/lib/chain/chain.d.ts +10 -5
  55. package/lib/chain/chain.d.ts.map +1 -1
  56. package/lib/chain/chain.js +102 -33
  57. package/lib/chain/chain.js.map +1 -1
  58. package/lib/chain/emitter.d.ts +7 -1
  59. package/lib/chain/emitter.d.ts.map +1 -1
  60. package/lib/chain/emitter.js +5 -0
  61. package/lib/chain/emitter.js.map +1 -1
  62. package/lib/chain/errors/envelopeReconstructionError.d.ts +5 -0
  63. package/lib/chain/errors/envelopeReconstructionError.d.ts.map +1 -1
  64. package/lib/chain/errors/envelopeReconstructionError.js +2 -0
  65. package/lib/chain/errors/envelopeReconstructionError.js.map +1 -1
  66. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  67. package/lib/chain/forkChoice/index.js +2 -0
  68. package/lib/chain/forkChoice/index.js.map +1 -1
  69. package/lib/chain/interface.d.ts +6 -3
  70. package/lib/chain/interface.d.ts.map +1 -1
  71. package/lib/chain/opPools/aggregatedAttestationPool.d.ts +4 -2
  72. package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
  73. package/lib/chain/opPools/aggregatedAttestationPool.js +30 -8
  74. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  75. package/lib/chain/opPools/opPool.d.ts.map +1 -1
  76. package/lib/chain/opPools/opPool.js +1 -23
  77. package/lib/chain/opPools/opPool.js.map +1 -1
  78. package/lib/chain/opPools/proposerPreferencesPool.d.ts +8 -4
  79. package/lib/chain/opPools/proposerPreferencesPool.d.ts.map +1 -1
  80. package/lib/chain/opPools/proposerPreferencesPool.js +27 -12
  81. package/lib/chain/opPools/proposerPreferencesPool.js.map +1 -1
  82. package/lib/chain/opPools/utils.d.ts +11 -0
  83. package/lib/chain/opPools/utils.d.ts.map +1 -1
  84. package/lib/chain/opPools/utils.js +22 -0
  85. package/lib/chain/opPools/utils.js.map +1 -1
  86. package/lib/chain/options.d.ts +2 -1
  87. package/lib/chain/options.d.ts.map +1 -1
  88. package/lib/chain/options.js +1 -1
  89. package/lib/chain/options.js.map +1 -1
  90. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  91. package/lib/chain/prepareNextSlot.js +11 -3
  92. package/lib/chain/prepareNextSlot.js.map +1 -1
  93. package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
  94. package/lib/chain/produceBlock/computeNewStateRoot.js +1 -1
  95. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  96. package/lib/chain/produceBlock/produceBlockBody.d.ts +8 -0
  97. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  98. package/lib/chain/produceBlock/produceBlockBody.js +48 -34
  99. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  100. package/lib/chain/regen/regen.d.ts +2 -0
  101. package/lib/chain/regen/regen.d.ts.map +1 -1
  102. package/lib/chain/regen/regen.js +10 -4
  103. package/lib/chain/regen/regen.js.map +1 -1
  104. package/lib/chain/seenCache/seenGossipBlockInput.d.ts +7 -0
  105. package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
  106. package/lib/chain/seenCache/seenGossipBlockInput.js +22 -1
  107. package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
  108. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +3 -2
  109. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
  110. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +13 -13
  111. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
  112. package/lib/chain/shufflingCache.d.ts +18 -8
  113. package/lib/chain/shufflingCache.d.ts.map +1 -1
  114. package/lib/chain/shufflingCache.js +72 -18
  115. package/lib/chain/shufflingCache.js.map +1 -1
  116. package/lib/chain/validatorMonitor.d.ts +5 -1
  117. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  118. package/lib/chain/validatorMonitor.js +64 -54
  119. package/lib/chain/validatorMonitor.js.map +1 -1
  120. package/lib/db/beacon.d.ts +4 -1
  121. package/lib/db/beacon.d.ts.map +1 -1
  122. package/lib/db/beacon.js +6 -1
  123. package/lib/db/beacon.js.map +1 -1
  124. package/lib/db/buckets.d.ts +3 -1
  125. package/lib/db/buckets.d.ts.map +1 -1
  126. package/lib/db/buckets.js +2 -0
  127. package/lib/db/buckets.js.map +1 -1
  128. package/lib/db/interface.d.ts +4 -1
  129. package/lib/db/interface.d.ts.map +1 -1
  130. package/lib/db/repositories/blockArchive.js +2 -2
  131. package/lib/db/repositories/blockArchive.js.map +1 -1
  132. package/lib/db/repositories/blockArchiveIndex.d.ts +3 -3
  133. package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
  134. package/lib/db/repositories/blockArchiveIndex.js +1 -2
  135. package/lib/db/repositories/blockArchiveIndex.js.map +1 -1
  136. package/lib/db/repositories/earliestAvailableSlot.d.ts +11 -0
  137. package/lib/db/repositories/earliestAvailableSlot.d.ts.map +1 -0
  138. package/lib/db/repositories/earliestAvailableSlot.js +19 -0
  139. package/lib/db/repositories/earliestAvailableSlot.js.map +1 -0
  140. package/lib/db/repositories/index.d.ts +1 -0
  141. package/lib/db/repositories/index.d.ts.map +1 -1
  142. package/lib/db/repositories/index.js +1 -0
  143. package/lib/db/repositories/index.js.map +1 -1
  144. package/lib/db/repositories/proposerPreferences.d.ts +14 -0
  145. package/lib/db/repositories/proposerPreferences.d.ts.map +1 -0
  146. package/lib/db/repositories/proposerPreferences.js +21 -0
  147. package/lib/db/repositories/proposerPreferences.js.map +1 -0
  148. package/lib/execution/engine/blobVersionedHashes.d.ts +9 -0
  149. package/lib/execution/engine/blobVersionedHashes.d.ts.map +1 -0
  150. package/lib/execution/engine/blobVersionedHashes.js +74 -0
  151. package/lib/execution/engine/blobVersionedHashes.js.map +1 -0
  152. package/lib/execution/engine/disabled.d.ts +0 -2
  153. package/lib/execution/engine/disabled.d.ts.map +1 -1
  154. package/lib/execution/engine/disabled.js +0 -6
  155. package/lib/execution/engine/disabled.js.map +1 -1
  156. package/lib/execution/engine/http.d.ts +46 -16
  157. package/lib/execution/engine/http.d.ts.map +1 -1
  158. package/lib/execution/engine/http.js +236 -213
  159. package/lib/execution/engine/http.js.map +1 -1
  160. package/lib/execution/engine/index.d.ts +3 -2
  161. package/lib/execution/engine/index.d.ts.map +1 -1
  162. package/lib/execution/engine/index.js +33 -8
  163. package/lib/execution/engine/index.js.map +1 -1
  164. package/lib/execution/engine/interface.d.ts +2 -4
  165. package/lib/execution/engine/interface.d.ts.map +1 -1
  166. package/lib/execution/engine/jsonRpcTransport.d.ts +25 -0
  167. package/lib/execution/engine/jsonRpcTransport.d.ts.map +1 -0
  168. package/lib/execution/engine/jsonRpcTransport.js +158 -0
  169. package/lib/execution/engine/jsonRpcTransport.js.map +1 -0
  170. package/lib/execution/engine/mock.d.ts +0 -2
  171. package/lib/execution/engine/mock.d.ts.map +1 -1
  172. package/lib/execution/engine/mock.js +0 -8
  173. package/lib/execution/engine/mock.js.map +1 -1
  174. package/lib/execution/engine/restHttpClient.d.ts +71 -0
  175. package/lib/execution/engine/restHttpClient.d.ts.map +1 -0
  176. package/lib/execution/engine/restHttpClient.js +201 -0
  177. package/lib/execution/engine/restHttpClient.js.map +1 -0
  178. package/lib/execution/engine/restTransport.d.ts +46 -0
  179. package/lib/execution/engine/restTransport.d.ts.map +1 -0
  180. package/lib/execution/engine/restTransport.js +399 -0
  181. package/lib/execution/engine/restTransport.js.map +1 -0
  182. package/lib/execution/engine/sszTypes.d.ts +1261 -0
  183. package/lib/execution/engine/sszTypes.d.ts.map +1 -0
  184. package/lib/execution/engine/sszTypes.js +216 -0
  185. package/lib/execution/engine/sszTypes.js.map +1 -0
  186. package/lib/execution/engine/transport.d.ts +39 -0
  187. package/lib/execution/engine/transport.d.ts.map +1 -0
  188. package/lib/execution/engine/transport.js +2 -0
  189. package/lib/execution/engine/transport.js.map +1 -0
  190. package/lib/execution/engine/types.d.ts +2 -8
  191. package/lib/execution/engine/types.d.ts.map +1 -1
  192. package/lib/execution/engine/types.js +24 -57
  193. package/lib/execution/engine/types.js.map +1 -1
  194. package/lib/execution/engine/utils.d.ts.map +1 -1
  195. package/lib/execution/engine/utils.js +9 -2
  196. package/lib/execution/engine/utils.js.map +1 -1
  197. package/lib/metrics/metrics/lodestar.d.ts +10 -0
  198. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  199. package/lib/metrics/metrics/lodestar.js +22 -0
  200. package/lib/metrics/metrics/lodestar.js.map +1 -1
  201. package/lib/metrics/metrics.d.ts +7 -3
  202. package/lib/metrics/metrics.d.ts.map +1 -1
  203. package/lib/metrics/metrics.js +4 -4
  204. package/lib/metrics/metrics.js.map +1 -1
  205. package/lib/network/core/events.d.ts +5 -1
  206. package/lib/network/core/events.d.ts.map +1 -1
  207. package/lib/network/core/events.js +8 -0
  208. package/lib/network/core/events.js.map +1 -1
  209. package/lib/network/gossip/topic.d.ts +0 -14
  210. package/lib/network/gossip/topic.d.ts.map +1 -1
  211. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  212. package/lib/network/processor/gossipHandlers.js +60 -64
  213. package/lib/network/processor/gossipHandlers.js.map +1 -1
  214. package/lib/network/processor/index.js +3 -3
  215. package/lib/network/processor/index.js.map +1 -1
  216. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js +1 -1
  217. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js.map +1 -1
  218. package/lib/node/nodejs.d.ts +3 -1
  219. package/lib/node/nodejs.d.ts.map +1 -1
  220. package/lib/node/nodejs.js +27 -4
  221. package/lib/node/nodejs.js.map +1 -1
  222. package/lib/node/options.d.ts +3 -2
  223. package/lib/node/options.d.ts.map +1 -1
  224. package/lib/node/options.js +2 -2
  225. package/lib/node/options.js.map +1 -1
  226. package/lib/sync/range/batch.d.ts +11 -5
  227. package/lib/sync/range/batch.d.ts.map +1 -1
  228. package/lib/sync/range/batch.js +21 -17
  229. package/lib/sync/range/batch.js.map +1 -1
  230. package/lib/sync/range/chain.d.ts +4 -4
  231. package/lib/sync/range/chain.d.ts.map +1 -1
  232. package/lib/sync/range/chain.js +12 -6
  233. package/lib/sync/range/chain.js.map +1 -1
  234. package/lib/sync/range/range.d.ts.map +1 -1
  235. package/lib/sync/range/range.js +25 -11
  236. package/lib/sync/range/range.js.map +1 -1
  237. package/lib/sync/unknownBlock.d.ts +5 -2
  238. package/lib/sync/unknownBlock.d.ts.map +1 -1
  239. package/lib/sync/unknownBlock.js +44 -20
  240. package/lib/sync/unknownBlock.js.map +1 -1
  241. package/lib/sync/utils/downloadByRange.d.ts +38 -14
  242. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  243. package/lib/sync/utils/downloadByRange.js +84 -39
  244. package/lib/sync/utils/downloadByRange.js.map +1 -1
  245. package/lib/util/asyncIterableToEvents.d.ts +10 -2
  246. package/lib/util/asyncIterableToEvents.d.ts.map +1 -1
  247. package/lib/util/asyncIterableToEvents.js +29 -3
  248. package/lib/util/asyncIterableToEvents.js.map +1 -1
  249. package/lib/util/execution.d.ts +9 -11
  250. package/lib/util/execution.d.ts.map +1 -1
  251. package/lib/util/execution.js +5 -1
  252. package/lib/util/execution.js.map +1 -1
  253. package/lib/util/metadata.d.ts.map +1 -1
  254. package/lib/util/metadata.js +2 -1
  255. package/lib/util/metadata.js.map +1 -1
  256. package/lib/util/sszBytes.d.ts +2 -2
  257. package/lib/util/sszBytes.d.ts.map +1 -1
  258. package/lib/util/sszBytes.js +21 -14
  259. package/lib/util/sszBytes.js.map +1 -1
  260. package/package.json +18 -17
  261. package/src/api/impl/beacon/blocks/index.ts +17 -7
  262. package/src/api/impl/beacon/index.ts +15 -0
  263. package/src/api/impl/beacon/state/index.ts +43 -6
  264. package/src/api/impl/debug/index.ts +28 -19
  265. package/src/api/impl/validator/index.ts +81 -7
  266. package/src/chain/archiveStore/archiveStore.ts +19 -25
  267. package/src/chain/archiveStore/historicalState/getHistoricalState.ts +5 -7
  268. package/src/chain/archiveStore/historicalState/historicalStateRegen.ts +1 -1
  269. package/src/chain/archiveStore/historicalState/types.ts +2 -2
  270. package/src/chain/archiveStore/historicalState/worker.ts +1 -2
  271. package/src/chain/archiveStore/interface.ts +1 -1
  272. package/src/chain/archiveStore/utils/pruneHistory.ts +4 -1
  273. package/src/chain/beaconProposerCache.ts +19 -1
  274. package/src/chain/blocks/blockInput/blockInput.ts +1 -1
  275. package/src/chain/blocks/importBlock.ts +17 -7
  276. package/src/chain/blocks/verifyBlock.ts +8 -6
  277. package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +6 -3
  278. package/src/chain/chain.ts +132 -35
  279. package/src/chain/emitter.ts +7 -1
  280. package/src/chain/errors/envelopeReconstructionError.ts +3 -0
  281. package/src/chain/forkChoice/index.ts +2 -0
  282. package/src/chain/interface.ts +7 -3
  283. package/src/chain/opPools/aggregatedAttestationPool.ts +34 -10
  284. package/src/chain/opPools/opPool.ts +1 -31
  285. package/src/chain/opPools/proposerPreferencesPool.ts +34 -11
  286. package/src/chain/opPools/utils.ts +31 -0
  287. package/src/chain/options.ts +3 -3
  288. package/src/chain/prepareNextSlot.ts +15 -3
  289. package/src/chain/produceBlock/computeNewStateRoot.ts +10 -3
  290. package/src/chain/produceBlock/produceBlockBody.ts +78 -39
  291. package/src/chain/regen/regen.ts +12 -4
  292. package/src/chain/seenCache/seenGossipBlockInput.ts +25 -1
  293. package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +20 -13
  294. package/src/chain/shufflingCache.ts +84 -22
  295. package/src/chain/validatorMonitor.ts +75 -57
  296. package/src/db/beacon.ts +6 -0
  297. package/src/db/buckets.ts +2 -0
  298. package/src/db/interface.ts +4 -0
  299. package/src/db/repositories/blockArchive.ts +2 -2
  300. package/src/db/repositories/blockArchiveIndex.ts +2 -3
  301. package/src/db/repositories/earliestAvailableSlot.ts +19 -0
  302. package/src/db/repositories/index.ts +1 -0
  303. package/src/db/repositories/proposerPreferences.ts +23 -0
  304. package/src/execution/engine/blobVersionedHashes.ts +72 -0
  305. package/src/execution/engine/disabled.ts +0 -8
  306. package/src/execution/engine/http.ts +304 -300
  307. package/src/execution/engine/index.ts +41 -7
  308. package/src/execution/engine/interface.ts +2 -6
  309. package/src/execution/engine/jsonRpcTransport.ts +247 -0
  310. package/src/execution/engine/mock.ts +1 -19
  311. package/src/execution/engine/restHttpClient.ts +269 -0
  312. package/src/execution/engine/restTransport.ts +544 -0
  313. package/src/execution/engine/sszTypes.ts +354 -0
  314. package/src/execution/engine/transport.ts +61 -0
  315. package/src/execution/engine/types.ts +34 -84
  316. package/src/execution/engine/utils.ts +12 -2
  317. package/src/metrics/metrics/lodestar.ts +23 -0
  318. package/src/metrics/metrics.ts +21 -6
  319. package/src/network/core/events.ts +16 -1
  320. package/src/network/processor/gossipHandlers.ts +91 -77
  321. package/src/network/processor/index.ts +3 -3
  322. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRoot.ts +1 -1
  323. package/src/node/nodejs.ts +35 -3
  324. package/src/node/options.ts +10 -1
  325. package/src/sync/range/batch.ts +25 -19
  326. package/src/sync/range/chain.ts +15 -8
  327. package/src/sync/range/range.ts +26 -12
  328. package/src/sync/unknownBlock.ts +57 -21
  329. package/src/sync/utils/downloadByRange.ts +123 -58
  330. package/src/util/asyncIterableToEvents.ts +44 -5
  331. package/src/util/execution.ts +16 -8
  332. package/src/util/metadata.ts +2 -1
  333. package/src/util/sszBytes.ts +25 -12
@@ -5,6 +5,8 @@ import {
5
5
  BUILDER_INDEX_SELF_BUILD,
6
6
  ForkName,
7
7
  ForkPostBellatrix,
8
+ ForkPostDeneb,
9
+ ForkPreDeneb,
8
10
  ForkPreGloas,
9
11
  ForkSeq,
10
12
  GENESIS_SLOT,
@@ -167,8 +169,8 @@ function compareBidCandidates(a: BidCandidate, b: BidCandidate): number {
167
169
  }
168
170
 
169
171
  type ProduceBlockContentsRes = {executionPayloadValue: Wei; consensusBlockValue: Wei} & {
170
- data: BlockContents;
171
- version: ForkName;
172
+ data: BlockContents<ForkPreGloas>;
173
+ version: ForkPreGloas;
172
174
  };
173
175
  type ProduceBlindedBlockRes = {executionPayloadValue: Wei; consensusBlockValue: Wei} & {
174
176
  data: BlindedBeaconBlock;
@@ -189,6 +191,7 @@ export enum EngineBlockSelectionReason {
189
191
  BuilderTimeout = "builder_timeout",
190
192
  BuilderPending = "builder_pending",
191
193
  BuilderNoBid = "builder_no_bid",
194
+ BuilderCircuitBreaker = "builder_circuit_breaker",
192
195
  BuilderCensorship = "builder_censorship",
193
196
  BlockValue = "block_value",
194
197
  EnginePreferred = "engine_preferred",
@@ -510,6 +513,10 @@ export function getValidatorApi(
510
513
  parentBlock: ProtoBlock;
511
514
  }
512
515
  ): Promise<ProduceBlockContentsRes & {shouldOverrideBuilder?: boolean}> {
516
+ const version = config.getForkName(slot);
517
+ if (isForkPostGloas(version)) {
518
+ throw Error(`produceEngineBlockContents called for post-gloas fork=${version}`);
519
+ }
513
520
  const source = ProducedBlockSource.engine;
514
521
  metrics?.blockProductionRequests.inc({source});
515
522
 
@@ -524,7 +531,6 @@ export function getValidatorApi(
524
531
  feeRecipient,
525
532
  commonBlockBodyPromise,
526
533
  });
527
- const version = config.getForkName(block.slot);
528
534
  if (strictFeeRecipientCheck && feeRecipient && isForkPostBellatrix(version)) {
529
535
  const blockFeeRecipient = toHex((block as bellatrix.BeaconBlock).body.executionPayload.feeRecipient);
530
536
  if (blockFeeRecipient !== feeRecipient) {
@@ -562,7 +568,7 @@ export function getValidatorApi(
562
568
 
563
569
  return {
564
570
  data: {
565
- block,
571
+ block: block as BeaconBlock<ForkPostDeneb & ForkPreGloas>,
566
572
  blobs: blobsBundle.blobs,
567
573
  kzgProofs: blobsBundle.proofs,
568
574
  },
@@ -573,7 +579,13 @@ export function getValidatorApi(
573
579
  };
574
580
  }
575
581
 
576
- return {data: {block}, version, executionPayloadValue, consensusBlockValue, shouldOverrideBuilder};
582
+ return {
583
+ data: {block: block as BeaconBlock<ForkPreDeneb>},
584
+ version,
585
+ executionPayloadValue,
586
+ consensusBlockValue,
587
+ shouldOverrideBuilder,
588
+ };
577
589
  } finally {
578
590
  if (timer) timer({source});
579
591
  }
@@ -877,6 +889,10 @@ export function getValidatorApi(
877
889
 
878
890
  return {
879
891
  async produceBlockV3({slot, randaoReveal, graffiti, skipRandaoVerification, builderBoostFactor, ...opts}) {
892
+ const forkName = config.getForkName(slot);
893
+ if (isForkPostGloas(forkName)) {
894
+ throw new ApiError(400, `produceBlockV3 not supported for post-gloas fork=${forkName}, use produceBlockV4`);
895
+ }
880
896
  const {data, ...meta} = await produceEngineOrBuilderBlock(
881
897
  slot,
882
898
  randaoReveal,
@@ -1160,8 +1176,21 @@ export function getValidatorApi(
1160
1176
  : {}),
1161
1177
  };
1162
1178
 
1163
- // handle shouldOverrideBuilder separately
1164
- if (
1179
+ if (circuitBreakerActive && engineResult.status === "fulfilled") {
1180
+ source = ProducedBlockSource.engine;
1181
+ bestResult = engineResult;
1182
+ metrics?.blockProductionSelectionResults.inc({
1183
+ source: ProducedBlockSource.engine,
1184
+ reason: EngineBlockSelectionReason.BuilderCircuitBreaker,
1185
+ });
1186
+ logger.info("Selected local block: builder circuit breaker is active", {
1187
+ reason: EngineBlockSelectionReason.BuilderCircuitBreaker,
1188
+ ...logCtx,
1189
+ durationMs: engineResult.durationMs,
1190
+ ...getBlockValueLogInfo(engineResult.value),
1191
+ });
1192
+ } else if (
1193
+ // handle shouldOverrideBuilder separately
1165
1194
  engineResult.status === "fulfilled" &&
1166
1195
  engineResult.value.shouldOverrideBuilder &&
1167
1196
  (builderBidExpected || bidBlockResult.status === "fulfilled")
@@ -1286,6 +1315,10 @@ export function getValidatorApi(
1286
1315
  blobs: blobsBundle.blobs,
1287
1316
  };
1288
1317
 
1318
+ if (chain.opts.persistProducedPayloadEnvelopes) {
1319
+ chain.persistExecutionPayloadEnvelope(blockContents.executionPayloadEnvelope);
1320
+ }
1321
+
1289
1322
  return {
1290
1323
  data: blockContents,
1291
1324
  meta: {version: fork, consensusBlockValue, executionPayloadValue, executionPayloadIncluded: true},
@@ -1914,6 +1947,17 @@ export function getValidatorApi(
1914
1947
  },
1915
1948
 
1916
1949
  async prepareBeaconCommitteeSubnet({subscriptions}) {
1950
+ // The subscribing validators use this node for duties regardless of its sync state and
1951
+ // the subscription must not fail on the tracking, e.g. if the finalized state is unavailable
1952
+ try {
1953
+ await chain.updateAttachedValidators(
1954
+ chain.clock.currentEpoch,
1955
+ Array.from(new Set(subscriptions.map(({validatorIndex}) => validatorIndex)))
1956
+ );
1957
+ } catch (e) {
1958
+ logger.warn("Error tracking attached validators", {count: subscriptions.length}, e as Error);
1959
+ }
1960
+
1917
1961
  notWhileSyncing(chain, sync.state);
1918
1962
 
1919
1963
  await network.prepareBeaconCommitteeSubnets(
@@ -1977,6 +2021,13 @@ export function getValidatorApi(
1977
2021
  },
1978
2022
 
1979
2023
  async prepareBeaconProposer({proposers}) {
2024
+ if (isForkPostGloas(config.getForkName(chain.clock.currentSlot))) {
2025
+ throw new ApiError(
2026
+ 410,
2027
+ "prepareBeaconProposer is no longer supported from gloas, submit signed proposer preferences via POST /eth/v1/validator/proposer_preferences instead"
2028
+ );
2029
+ }
2030
+
1980
2031
  await chain.updateBeaconProposerData(chain.clock.currentEpoch, proposers);
1981
2032
  },
1982
2033
 
@@ -2011,6 +2062,13 @@ export function getValidatorApi(
2011
2062
  },
2012
2063
 
2013
2064
  async registerValidator({registrations}) {
2065
+ if (isForkPostGloas(config.getForkName(chain.clock.currentSlot))) {
2066
+ throw new ApiError(
2067
+ 410,
2068
+ "registerValidator is no longer supported from gloas, submit builder preferences via POST /eth/v1/validator/builder_preferences instead"
2069
+ );
2070
+ }
2071
+
2014
2072
  if (!chain.executionBuilder) {
2015
2073
  throw Error("External builder not configured");
2016
2074
  }
@@ -2046,11 +2104,14 @@ export function getValidatorApi(
2046
2104
 
2047
2105
  async submitProposerPreferences({signedProposerPreferences}) {
2048
2106
  const failures: FailureList = [];
2107
+ // Preferences submitted here are signed by validators using this node, gossiped ones are not
2108
+ const attachedValidatorIndices: ValidatorIndex[] = [];
2049
2109
 
2050
2110
  await Promise.all(
2051
2111
  signedProposerPreferences.map(async (signed, i) => {
2052
2112
  try {
2053
2113
  await validateGossipProposerPreferences(chain, signed);
2114
+ attachedValidatorIndices.push(signed.message.validatorIndex);
2054
2115
 
2055
2116
  chain.proposerPreferencesPool.add(signed);
2056
2117
  await network.publishProposerPreferences(signed);
@@ -2066,6 +2127,7 @@ export function getValidatorApi(
2066
2127
  };
2067
2128
 
2068
2129
  if (e instanceof ProposerPreferencesError && e.type.code === ProposerPreferencesErrorCode.ALREADY_KNOWN) {
2130
+ attachedValidatorIndices.push(signed.message.validatorIndex);
2069
2131
  logger.debug("Ignoring known signed proposer preferences", logCtx);
2070
2132
  return;
2071
2133
  }
@@ -2079,6 +2141,14 @@ export function getValidatorApi(
2079
2141
  })
2080
2142
  );
2081
2143
 
2144
+ if (attachedValidatorIndices.length > 0) {
2145
+ try {
2146
+ await chain.updateAttachedValidators(chain.clock.currentEpoch, attachedValidatorIndices);
2147
+ } catch (e) {
2148
+ logger.warn("Error tracking attached validators", {count: attachedValidatorIndices.length}, e as Error);
2149
+ }
2150
+ }
2151
+
2082
2152
  if (failures.length > 0) {
2083
2153
  throw new IndexedError("Error processing signed proposer preferences", failures);
2084
2154
  }
@@ -2173,6 +2243,10 @@ export function getValidatorApi(
2173
2243
  blockHash: toRootHex(executionPayload.blockHash),
2174
2244
  });
2175
2245
 
2246
+ if (chain.opts.persistProducedPayloadEnvelopes) {
2247
+ chain.persistExecutionPayloadEnvelope(envelope);
2248
+ }
2249
+
2176
2250
  return {
2177
2251
  data: envelope,
2178
2252
  meta: {
@@ -113,7 +113,9 @@ export class ArchiveStore {
113
113
  this.logger,
114
114
  this.metrics,
115
115
  this.opts.anchorState.finalizedCheckpoint.epoch,
116
- this.chain.clock.currentEpoch
116
+ this.chain.clock.currentEpoch,
117
+ this.statePruneFromSlot,
118
+ this.advanceEarliestAvailableSlot
117
119
  ),
118
120
  () => this.logger.info("Still pruning historical data, please wait..."),
119
121
  30_000,
@@ -122,33 +124,13 @@ export class ArchiveStore {
122
124
  this.statePruneFromSlot = stateCutoffSlot;
123
125
  }
124
126
 
125
- // Initialize earliestAvailableSlot from the earliest block actually retained (after any pruning
126
- // above), rather than the anchor state slot set in the constructor. On an in-place restart the DB
127
- // still holds finalized history below the anchor; leaving the value at the anchor makes the node
128
- // reject by_range requests (beacon_blocks, execution_payload_envelopes and data_column_sidecars
129
- // all gate on this slot) for data it still retains. An empty archive (e.g. a fresh checkpoint
130
- // sync with nothing below the anchor) leaves the constructor's anchor slot in place.
131
- const earliestArchivedBlockSlot = await this.db.blockArchive.firstKey();
132
- if (earliestArchivedBlockSlot != null) {
133
- const oldEarliestAvailableSlot = this.chain.earliestAvailableSlot;
134
- this.chain.earliestAvailableSlot = earliestArchivedBlockSlot;
135
- this.logger.verbose("Initialized earliestAvailableSlot from retained block archive", {
136
- oldEarliestAvailableSlot,
137
- newEarliestAvailableSlot: earliestArchivedBlockSlot,
138
- });
139
- } else {
140
- this.logger.verbose("Empty block archive on init, keeping anchor earliestAvailableSlot", {
141
- earliestAvailableSlot: this.chain.earliestAvailableSlot,
142
- });
143
- }
144
-
145
127
  if (this.opts.serveHistoricalState) {
146
128
  this.historicalStateRegen = await HistoricalStateRegen.init({
147
129
  opts: {
148
130
  genesisTime: this.chain.clock.genesisTime,
149
131
  dbLocation: this.opts.dbName,
150
132
  dataColumnDir: this.opts.dataColumnDir,
151
- nativeStateView: this.opts.nativeStateView ?? false,
133
+ nativeStateTransition: this.opts.nativeStateTransition ?? false,
152
134
  },
153
135
  config: this.chain.config,
154
136
  metrics: this.metrics,
@@ -158,6 +140,18 @@ export class ArchiveStore {
158
140
  }
159
141
  }
160
142
 
143
+ /**
144
+ * The CLI owns the initial value; this only advances it during pruneHistory.
145
+ * Persisted before any deletion so a crash mid-prune never leaves the floor below deleted data.
146
+ */
147
+ private advanceEarliestAvailableSlot = async (blockCutoffSlot: Slot): Promise<void> => {
148
+ const earliestAvailableSlot = Math.max(this.chain.earliestAvailableSlot, blockCutoffSlot);
149
+ if (earliestAvailableSlot !== this.chain.earliestAvailableSlot) {
150
+ await this.db.earliestAvailableSlot.set(earliestAvailableSlot);
151
+ this.chain.earliestAvailableSlot = earliestAvailableSlot;
152
+ }
153
+ };
154
+
161
155
  async close(): Promise<void> {
162
156
  await this.historicalStateRegen?.close();
163
157
  }
@@ -259,17 +253,17 @@ export class ArchiveStore {
259
253
 
260
254
  if (this.opts.pruneHistory) {
261
255
  timer = this.metrics?.processFinalizedCheckpoint.durationByTask.startTimer();
262
- const {blockCutoffSlot, stateCutoffSlot} = await pruneHistory(
256
+ const {stateCutoffSlot} = await pruneHistory(
263
257
  this.chain.config,
264
258
  this.db,
265
259
  this.logger,
266
260
  this.metrics,
267
261
  finalizedEpoch,
268
262
  this.chain.clock.currentEpoch,
269
- this.statePruneFromSlot
263
+ this.statePruneFromSlot,
264
+ this.advanceEarliestAvailableSlot
270
265
  );
271
266
  this.statePruneFromSlot = stateCutoffSlot;
272
- this.chain.earliestAvailableSlot = Math.max(this.chain.earliestAvailableSlot, blockCutoffSlot);
273
267
  timer?.({source: ArchiveStoreTask.PruneHistory});
274
268
  }
275
269
 
@@ -17,7 +17,7 @@ export async function getNearestState(
17
17
  slot: number,
18
18
  config: BeaconConfig,
19
19
  db: IBeaconDb,
20
- nativeStateView: boolean
20
+ nativeStateTransition: boolean
21
21
  ): Promise<IBeaconStateView> {
22
22
  const stateBytesArr = await db.stateArchive.binaries({limit: 1, lte: slot, reverse: true});
23
23
  if (!stateBytesArr.length) {
@@ -25,9 +25,7 @@ export async function getNearestState(
25
25
  }
26
26
 
27
27
  const stateBytes = stateBytesArr[0];
28
- return nativeStateView
29
- ? createBeaconStateViewForHistoricalRegen({useNative: true, stateBytes})
30
- : createBeaconStateViewForHistoricalRegen({useNative: false, config, stateBytes});
28
+ return createBeaconStateViewForHistoricalRegen({nativeStateTransition: nativeStateTransition, config, stateBytes});
31
29
  }
32
30
 
33
31
  /**
@@ -37,13 +35,13 @@ export async function getHistoricalState(
37
35
  slot: number,
38
36
  config: BeaconConfig,
39
37
  db: IBeaconDb,
40
- nativeStateView: boolean,
38
+ nativeStateTransition: boolean,
41
39
  metrics?: HistoricalStateRegenMetrics
42
40
  ): Promise<Uint8Array> {
43
41
  const regenTimer = metrics?.regenTime.startTimer();
44
42
 
45
43
  const loadStateTimer = metrics?.loadStateTime.startTimer();
46
- let state = await getNearestState(slot, config, db, nativeStateView).catch((e) => {
44
+ let state = await getNearestState(slot, config, db, nativeStateTransition).catch((e) => {
47
45
  metrics?.regenErrorCount.inc({reason: RegenErrorType.loadState});
48
46
  throw e;
49
47
  });
@@ -54,7 +52,7 @@ export async function getHistoricalState(
54
52
  for await (const block of db.blockArchive.valuesStream({gt: state.slot, lte: slot})) {
55
53
  try {
56
54
  state = state.stateTransition(
57
- block,
55
+ {block},
58
56
  {
59
57
  verifyProposer: false,
60
58
  verifySignatures: false,
@@ -36,7 +36,7 @@ export class HistoricalStateRegen implements HistoricalStateWorkerApi {
36
36
  dataColumnDir: modules.opts.dataColumnDir,
37
37
  metricsEnabled: Boolean(modules.metrics),
38
38
  loggerOpts: modules.logger.toOpts(),
39
- nativeStateView: modules.opts.nativeStateView,
39
+ nativeStateTransition: modules.opts.nativeStateTransition,
40
40
  };
41
41
 
42
42
  const worker = new Worker(path.join(WORKER_DIR, "worker.js"), {
@@ -8,7 +8,7 @@ export type HistoricalStateRegenInitModules = {
8
8
  genesisTime: number;
9
9
  dbLocation: string;
10
10
  dataColumnDir: string;
11
- nativeStateView: boolean;
11
+ nativeStateTransition: boolean;
12
12
  };
13
13
  config: BeaconConfig;
14
14
  logger: LoggerNode;
@@ -29,7 +29,7 @@ export type HistoricalStateWorkerData = {
29
29
  dataColumnDir: string;
30
30
  metricsEnabled: boolean;
31
31
  loggerOpts: LoggerNodeOpts;
32
- nativeStateView: boolean;
32
+ nativeStateTransition: boolean;
33
33
  };
34
34
 
35
35
  export type HistoricalStateWorkerApi = {
@@ -36,7 +36,6 @@ const abortController = new AbortController();
36
36
  const metricsRegister = workerData.metricsEnabled ? new RegistryMetricCreator() : null;
37
37
  let historicalStateRegenMetrics: HistoricalStateRegenMetrics | undefined;
38
38
  let queueMetrics: QueueMetrics | undefined;
39
-
40
39
  if (metricsRegister) {
41
40
  const closeMetrics = collectNodeJSMetrics(metricsRegister, "lodestar_historical_state_worker_");
42
41
  abortController.signal.addEventListener("abort", closeMetrics, {once: true});
@@ -65,7 +64,7 @@ const api: HistoricalStateWorkerApi = {
65
64
  historicalStateRegenMetrics?.regenRequestCount.inc();
66
65
 
67
66
  const stateBytes = await queue.push<Uint8Array>(() =>
68
- getHistoricalState(slot, config, db, workerData.nativeStateView, historicalStateRegenMetrics)
67
+ getHistoricalState(slot, config, db, workerData.nativeStateTransition, historicalStateRegenMetrics)
69
68
  );
70
69
  const result = Transfer(stateBytes, [stateBytes.buffer]) as unknown as Uint8Array;
71
70
 
@@ -25,7 +25,7 @@ export type ArchiveStoreOpts = StatesArchiveOpts & {
25
25
  archiveDataEpochs?: number;
26
26
  pruneHistory?: boolean;
27
27
  serveHistoricalState?: boolean;
28
- nativeStateView?: boolean;
28
+ nativeStateTransition?: boolean;
29
29
  };
30
30
 
31
31
  export type ProposalStats = {
@@ -12,7 +12,8 @@ export async function pruneHistory(
12
12
  metrics: Metrics | null | undefined,
13
13
  finalizedEpoch: Epoch,
14
14
  currentEpoch: Epoch,
15
- statePruneFromSlot: Slot = 0
15
+ statePruneFromSlot: Slot,
16
+ beforePrune: (blockCutoffSlot: Slot) => Promise<void>
16
17
  ): Promise<{blockCutoffSlot: Slot; stateCutoffSlot: Slot}> {
17
18
  const blockCutoffEpoch = Math.min(
18
19
  // set by config, with underflow protection
@@ -51,6 +52,8 @@ export async function pruneHistory(
51
52
  stateSlots: prettyPrintIndices(states),
52
53
  });
53
54
 
55
+ await beforePrune(blockCutoffSlot);
56
+
54
57
  const step1 = metrics?.pruneHistory.pruneKeys.startTimer();
55
58
  await Promise.all([
56
59
  // ->
@@ -6,7 +6,7 @@ const PROPOSER_PRESERVE_EPOCHS = 2;
6
6
  export type ProposerPreparationData = routes.validator.ProposerPreparationData;
7
7
 
8
8
  export class BeaconProposerCache {
9
- private readonly feeRecipientByValidatorIndex: Map<number, {epoch: Epoch; feeRecipient: string}>;
9
+ private readonly feeRecipientByValidatorIndex: Map<number, {epoch: Epoch; feeRecipient?: string}>;
10
10
  constructor(readonly opts: {suggestedFeeRecipient: string}) {
11
11
  this.feeRecipientByValidatorIndex = new Map();
12
12
  }
@@ -15,6 +15,24 @@ export class BeaconProposerCache {
15
15
  this.feeRecipientByValidatorIndex.set(validatorIndex, {epoch, feeRecipient});
16
16
  }
17
17
 
18
+ /**
19
+ * Track a validator that uses this node for duties, keeping the fee recipient it may have
20
+ * registered. Returns true if the validator was not tracked before.
21
+ */
22
+ track(epoch: Epoch, validatorIndex: number): boolean {
23
+ const entry = this.feeRecipientByValidatorIndex.get(validatorIndex);
24
+ if (entry !== undefined) {
25
+ entry.epoch = epoch;
26
+ return false;
27
+ }
28
+ this.feeRecipientByValidatorIndex.set(validatorIndex, {epoch});
29
+ return true;
30
+ }
31
+
32
+ has(validatorIndex: number): boolean {
33
+ return this.feeRecipientByValidatorIndex.has(validatorIndex);
34
+ }
35
+
18
36
  prune(epoch: Epoch): void {
19
37
  // This is not so optimized function, but could maintain a 2d array may be?
20
38
  for (const [validatorIndex, feeRecipientEntry] of this.feeRecipientByValidatorIndex.entries()) {
@@ -210,7 +210,7 @@ export class BlockInputPreData extends AbstractBlockInput<ForkPreDeneb, null> {
210
210
  this.blockPromise.resolve(state.block);
211
211
  }
212
212
 
213
- static createFromBlock(props: AddBlock & CreateBlockInputMeta): BlockInputPreData {
213
+ static createFromBlock(props: AddBlock<ForkPreDeneb> & CreateBlockInputMeta): BlockInputPreData {
214
214
  const init: BlockInputInit = {
215
215
  daOutOfRange: props.daOutOfRange,
216
216
  timeCreated: props.seenTimestampSec,
@@ -22,6 +22,7 @@ import {
22
22
  RootCache,
23
23
  computeEpochAtSlot,
24
24
  computeTimeAtSlot,
25
+ getBeaconCommittees,
25
26
  isStatePostAltair,
26
27
  isStatePostBellatrix,
27
28
  } from "@lodestar/state-transition";
@@ -129,11 +130,17 @@ export async function importBlock(
129
130
 
130
131
  // Should compute checkpoint balances before forkchoice.onBlock
131
132
  this.checkpointBalancesCache.processState(blockRootHex, postState);
132
- if (fork >= ForkSeq.gloas) {
133
+ if (isGloasBeaconBlock(block.message)) {
134
+ // A gloas block has no payload of its own, it inherits the status of the payload it builds on,
135
+ // i.e. the parent variant matching the bid's parent block hash. The parent's default (PENDING)
136
+ // variant does not reflect a SYNCING parent payload, and onBlock would then mark that payload VALID.
133
137
  const parentRootHex = toRootHex(block.message.parentRoot);
134
- const parentBlock = this.forkChoice.getBlockHexDefaultStatus(parentRootHex);
138
+ const parentBlockHashHex = toRootHex(block.message.body.signedExecutionPayloadBid.message.parentBlockHash);
139
+ const parentBlock = this.forkChoice.getBlockHexAndBlockHash(parentRootHex, parentBlockHashHex);
135
140
  if (parentBlock === null) {
136
- throw Error(`Parent block not found in forkChoice, parentRoot=${parentRootHex}`);
141
+ throw Error(
142
+ `Parent block not found in forkChoice, parentRoot=${parentRootHex} parentBlockHash=${parentBlockHashHex}`
143
+ );
137
144
  }
138
145
  if (parentBlock.executionStatus === ExecutionStatus.Invalid) {
139
146
  throw Error(`Parent block has invalid execution status, parentRoot=${parentRootHex}`);
@@ -400,9 +407,8 @@ export async function importBlock(
400
407
  const proposalSlot = blockSlot + 1;
401
408
  try {
402
409
  const proposerIndex = postState.getBeaconProposer(proposalSlot);
403
- const feeRecipient = this.beaconProposerCache.get(proposerIndex);
404
410
 
405
- if (feeRecipient) {
411
+ if (this.beaconProposerCache.has(proposerIndex)) {
406
412
  // We would set this to true if
407
413
  // 1) This is a gossip block
408
414
  // 2) We are proposer of next slot
@@ -657,8 +663,12 @@ export function addAttestationPostElectra(
657
663
  } else {
658
664
  const attSlot = attestation.data.slot;
659
665
  const attEpoch = computeEpochAtSlot(attSlot);
660
- const decisionRoot = state.getShufflingDecisionRoot(attEpoch);
661
- const committees = this.shufflingCache.getBeaconCommittees(attEpoch, decisionRoot, attSlot, committeeIndices);
666
+ // calling getShufflingAtEpoch may take some time for NativeBeaconStateView
667
+ // we should have the shuffling inside ShufflingCache most of the time
668
+ const shuffling =
669
+ this.shufflingCache.getSync(attEpoch, state.getShufflingDecisionRoot(attEpoch)) ??
670
+ state.getShufflingAtEpoch(attEpoch);
671
+ const committees = getBeaconCommittees(shuffling, attSlot, committeeIndices);
662
672
  const aggregationBools = attestation.aggregationBits.toBoolArray();
663
673
  let offset = 0;
664
674
  for (let i = 0; i < committees.length; i++) {
@@ -4,6 +4,7 @@ import {
4
4
  DataAvailabilityStatus,
5
5
  IBeaconStateView,
6
6
  computeEpochAtSlot,
7
+ getIndexedAttestation,
7
8
  signedBlockToSignedHeader,
8
9
  } from "@lodestar/state-transition";
9
10
  import {IndexedAttestation, Slot, deneb} from "@lodestar/types";
@@ -81,10 +82,6 @@ export async function verifyBlocksInEpoch(
81
82
  throw new BlockError(block0, {code: BlockErrorCode.PRESTATE_MISSING, error: e as Error});
82
83
  });
83
84
 
84
- // in forky condition, make sure to populate ShufflingCache with regened state
85
- // otherwise it may fail to get indexed attestations from shuffling cache later
86
- this.shufflingCache.processState(preState0);
87
-
88
85
  if (!preState0.isStateValidatorsNodesPopulated()) {
89
86
  this.logger.verbose("verifyBlocksInEpoch preState0 SSZ cache stats", {
90
87
  slot: preState0.slot,
@@ -117,8 +114,12 @@ export async function verifyBlocksInEpoch(
117
114
  for (const [i, block] of blocks.entries()) {
118
115
  indexedAttestationsByBlock[i] = block.message.body.attestations.map((attestation) => {
119
116
  const attEpoch = computeEpochAtSlot(attestation.data.slot);
120
- const decisionRoot = preState0.getShufflingDecisionRoot(attEpoch);
121
- return this.shufflingCache.getIndexedAttestation(attEpoch, decisionRoot, fork, attestation);
117
+ // calling getShufflingAtEpoch may take some time for NativeBeaconStateView
118
+ // we should have the shuffling inside ShufflingCache most of the time
119
+ const shuffling =
120
+ this.shufflingCache.getSync(attEpoch, preState0.getShufflingDecisionRoot(attEpoch)) ??
121
+ preState0.getShufflingAtEpoch(attEpoch);
122
+ return getIndexedAttestation(shuffling, fork, attestation);
122
123
  });
123
124
  }
124
125
 
@@ -188,6 +189,7 @@ export async function verifyBlocksInEpoch(
188
189
  blockInputs,
189
190
  // hack availability for state transition eval as availability is separately determined
190
191
  blocks.map(() => DataAvailabilityStatus.Available),
192
+ this.serializedCache,
191
193
  this.logger,
192
194
  this.metrics,
193
195
  this.validatorMonitor,
@@ -7,6 +7,7 @@ import {
7
7
  import {ErrorAborted, Logger, byteArrayEquals} from "@lodestar/utils";
8
8
  import {Metrics} from "../../metrics/index.js";
9
9
  import {nextEventLoop} from "../../util/eventLoop.js";
10
+ import {SerializedCache} from "../../util/serializedCache.js";
10
11
  import {BlockError, BlockErrorCode} from "../errors/index.js";
11
12
  import {BlockProcessOpts} from "../options.js";
12
13
  import {ValidatorMonitor} from "../validatorMonitor.js";
@@ -25,6 +26,7 @@ export async function verifyBlocksStateTransitionOnly(
25
26
  preState0: IBeaconStateView,
26
27
  blocks: IBlockInput[],
27
28
  dataAvailabilityStatuses: DataAvailabilityStatus[],
29
+ serializedCache: SerializedCache,
28
30
  logger: Logger,
29
31
  metrics: Metrics | null,
30
32
  validatorMonitor: ValidatorMonitor | null,
@@ -37,7 +39,8 @@ export async function verifyBlocksStateTransitionOnly(
37
39
 
38
40
  for (let i = 0; i < blocks.length; i++) {
39
41
  const {validProposerSignature, validSignatures} = opts;
40
- const block = blocks[i].getBlock();
42
+ const blockInput = blocks[i];
43
+ const block = blockInput.getBlock();
41
44
  const preState = i === 0 ? preState0 : postStates[i - 1];
42
45
  const dataAvailabilityStatus = dataAvailabilityStatuses[i];
43
46
 
@@ -47,7 +50,7 @@ export async function verifyBlocksStateTransitionOnly(
47
50
  let postState: IBeaconStateView;
48
51
  try {
49
52
  postState = preState.stateTransition(
50
- block,
53
+ {block, ssz: serializedCache.get(block)},
51
54
  {
52
55
  // NOTE: Assume valid for now while sending payload to execution engine in parallel
53
56
  // Latter verifyBlocksInEpoch() will make sure that payload is indeed valid
@@ -60,7 +63,7 @@ export async function verifyBlocksStateTransitionOnly(
60
63
  verifySignatures: !useBlsBatchVerify && !validSignatures,
61
64
  dontTransferCache: false,
62
65
  },
63
- {metrics, validatorMonitor}
66
+ {metrics: metrics?.stateTransition, validatorMonitor}
64
67
  );
65
68
  } catch (e) {
66
69
  throw new BlockError(block, {