@lodestar/beacon-node 1.50.0-dev.8ba9d1dd30 → 1.50.0-dev.9203d3d7da

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 (382) 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 +80 -18
  16. package/lib/api/impl/validator/index.js.map +1 -1
  17. package/lib/chain/ColumnReconstructionTracker.d.ts +0 -2
  18. package/lib/chain/ColumnReconstructionTracker.d.ts.map +1 -1
  19. package/lib/chain/ColumnReconstructionTracker.js +4 -5
  20. package/lib/chain/ColumnReconstructionTracker.js.map +1 -1
  21. package/lib/chain/archiveStore/archiveStore.d.ts +5 -0
  22. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  23. package/lib/chain/archiveStore/archiveStore.js +14 -24
  24. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  25. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts +2 -2
  26. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
  27. package/lib/chain/archiveStore/historicalState/getHistoricalState.js +5 -7
  28. package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
  29. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js +1 -1
  30. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js.map +1 -1
  31. package/lib/chain/archiveStore/historicalState/types.d.ts +2 -2
  32. package/lib/chain/archiveStore/historicalState/types.d.ts.map +1 -1
  33. package/lib/chain/archiveStore/historicalState/worker.js +1 -1
  34. package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
  35. package/lib/chain/archiveStore/interface.d.ts +1 -1
  36. package/lib/chain/archiveStore/interface.d.ts.map +1 -1
  37. package/lib/chain/archiveStore/utils/pruneHistory.d.ts +1 -1
  38. package/lib/chain/archiveStore/utils/pruneHistory.d.ts.map +1 -1
  39. package/lib/chain/archiveStore/utils/pruneHistory.js +2 -1
  40. package/lib/chain/archiveStore/utils/pruneHistory.js.map +1 -1
  41. package/lib/chain/beaconProposerCache.d.ts +6 -0
  42. package/lib/chain/beaconProposerCache.d.ts.map +1 -1
  43. package/lib/chain/beaconProposerCache.js +16 -0
  44. package/lib/chain/beaconProposerCache.js.map +1 -1
  45. package/lib/chain/blocks/blockInput/blockInput.d.ts +1 -1
  46. package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
  47. package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
  48. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  49. package/lib/chain/blocks/importBlock.js +20 -11
  50. package/lib/chain/blocks/importBlock.js.map +1 -1
  51. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +2 -1
  52. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
  53. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  54. package/lib/chain/blocks/verifyBlock.js +7 -7
  55. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  56. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts +2 -1
  57. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
  58. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +5 -4
  59. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
  60. package/lib/chain/chain.d.ts +10 -5
  61. package/lib/chain/chain.d.ts.map +1 -1
  62. package/lib/chain/chain.js +105 -35
  63. package/lib/chain/chain.js.map +1 -1
  64. package/lib/chain/emitter.d.ts +7 -1
  65. package/lib/chain/emitter.d.ts.map +1 -1
  66. package/lib/chain/emitter.js +5 -0
  67. package/lib/chain/emitter.js.map +1 -1
  68. package/lib/chain/errors/envelopeReconstructionError.d.ts +5 -0
  69. package/lib/chain/errors/envelopeReconstructionError.d.ts.map +1 -1
  70. package/lib/chain/errors/envelopeReconstructionError.js +2 -0
  71. package/lib/chain/errors/envelopeReconstructionError.js.map +1 -1
  72. package/lib/chain/errors/gossipValidation.d.ts +1 -0
  73. package/lib/chain/errors/gossipValidation.d.ts.map +1 -1
  74. package/lib/chain/errors/gossipValidation.js +1 -0
  75. package/lib/chain/errors/gossipValidation.js.map +1 -1
  76. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  77. package/lib/chain/forkChoice/index.js +2 -0
  78. package/lib/chain/forkChoice/index.js.map +1 -1
  79. package/lib/chain/interface.d.ts +6 -3
  80. package/lib/chain/interface.d.ts.map +1 -1
  81. package/lib/chain/opPools/aggregatedAttestationPool.d.ts +4 -2
  82. package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
  83. package/lib/chain/opPools/aggregatedAttestationPool.js +30 -8
  84. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  85. package/lib/chain/opPools/opPool.d.ts.map +1 -1
  86. package/lib/chain/opPools/opPool.js +1 -23
  87. package/lib/chain/opPools/opPool.js.map +1 -1
  88. package/lib/chain/opPools/proposerPreferencesPool.d.ts +8 -4
  89. package/lib/chain/opPools/proposerPreferencesPool.d.ts.map +1 -1
  90. package/lib/chain/opPools/proposerPreferencesPool.js +27 -12
  91. package/lib/chain/opPools/proposerPreferencesPool.js.map +1 -1
  92. package/lib/chain/opPools/utils.d.ts +11 -0
  93. package/lib/chain/opPools/utils.d.ts.map +1 -1
  94. package/lib/chain/opPools/utils.js +22 -0
  95. package/lib/chain/opPools/utils.js.map +1 -1
  96. package/lib/chain/options.d.ts +2 -1
  97. package/lib/chain/options.d.ts.map +1 -1
  98. package/lib/chain/options.js +1 -1
  99. package/lib/chain/options.js.map +1 -1
  100. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  101. package/lib/chain/prepareNextSlot.js +15 -6
  102. package/lib/chain/prepareNextSlot.js.map +1 -1
  103. package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
  104. package/lib/chain/produceBlock/computeNewStateRoot.js +1 -1
  105. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  106. package/lib/chain/produceBlock/produceBlockBody.d.ts +8 -0
  107. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  108. package/lib/chain/produceBlock/produceBlockBody.js +48 -34
  109. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  110. package/lib/chain/regen/regen.d.ts +2 -0
  111. package/lib/chain/regen/regen.d.ts.map +1 -1
  112. package/lib/chain/regen/regen.js +10 -4
  113. package/lib/chain/regen/regen.js.map +1 -1
  114. package/lib/chain/reprocess.d.ts +2 -1
  115. package/lib/chain/reprocess.d.ts.map +1 -1
  116. package/lib/chain/reprocess.js +2 -1
  117. package/lib/chain/reprocess.js.map +1 -1
  118. package/lib/chain/seenCache/seenGossipBlockInput.d.ts +7 -0
  119. package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
  120. package/lib/chain/seenCache/seenGossipBlockInput.js +22 -1
  121. package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
  122. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +9 -2
  123. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
  124. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +23 -13
  125. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
  126. package/lib/chain/shufflingCache.d.ts +18 -8
  127. package/lib/chain/shufflingCache.d.ts.map +1 -1
  128. package/lib/chain/shufflingCache.js +72 -18
  129. package/lib/chain/shufflingCache.js.map +1 -1
  130. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  131. package/lib/chain/stateCache/persistentCheckpointsCache.js +1 -1
  132. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  133. package/lib/chain/validatorMonitor.d.ts +5 -1
  134. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  135. package/lib/chain/validatorMonitor.js +70 -58
  136. package/lib/chain/validatorMonitor.js.map +1 -1
  137. package/lib/constants/constants.d.ts +1 -0
  138. package/lib/constants/constants.d.ts.map +1 -1
  139. package/lib/constants/constants.js +1 -0
  140. package/lib/constants/constants.js.map +1 -1
  141. package/lib/db/beacon.d.ts +4 -1
  142. package/lib/db/beacon.d.ts.map +1 -1
  143. package/lib/db/beacon.js +6 -1
  144. package/lib/db/beacon.js.map +1 -1
  145. package/lib/db/buckets.d.ts +3 -1
  146. package/lib/db/buckets.d.ts.map +1 -1
  147. package/lib/db/buckets.js +2 -0
  148. package/lib/db/buckets.js.map +1 -1
  149. package/lib/db/interface.d.ts +4 -1
  150. package/lib/db/interface.d.ts.map +1 -1
  151. package/lib/db/repositories/blockArchive.js +2 -2
  152. package/lib/db/repositories/blockArchive.js.map +1 -1
  153. package/lib/db/repositories/blockArchiveIndex.d.ts +3 -3
  154. package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
  155. package/lib/db/repositories/blockArchiveIndex.js +1 -2
  156. package/lib/db/repositories/blockArchiveIndex.js.map +1 -1
  157. package/lib/db/repositories/earliestAvailableSlot.d.ts +11 -0
  158. package/lib/db/repositories/earliestAvailableSlot.d.ts.map +1 -0
  159. package/lib/db/repositories/earliestAvailableSlot.js +19 -0
  160. package/lib/db/repositories/earliestAvailableSlot.js.map +1 -0
  161. package/lib/db/repositories/index.d.ts +1 -0
  162. package/lib/db/repositories/index.d.ts.map +1 -1
  163. package/lib/db/repositories/index.js +1 -0
  164. package/lib/db/repositories/index.js.map +1 -1
  165. package/lib/db/repositories/proposerPreferences.d.ts +14 -0
  166. package/lib/db/repositories/proposerPreferences.d.ts.map +1 -0
  167. package/lib/db/repositories/proposerPreferences.js +21 -0
  168. package/lib/db/repositories/proposerPreferences.js.map +1 -0
  169. package/lib/execution/engine/blobVersionedHashes.d.ts +9 -0
  170. package/lib/execution/engine/blobVersionedHashes.d.ts.map +1 -0
  171. package/lib/execution/engine/blobVersionedHashes.js +74 -0
  172. package/lib/execution/engine/blobVersionedHashes.js.map +1 -0
  173. package/lib/execution/engine/disabled.d.ts +0 -2
  174. package/lib/execution/engine/disabled.d.ts.map +1 -1
  175. package/lib/execution/engine/disabled.js +0 -6
  176. package/lib/execution/engine/disabled.js.map +1 -1
  177. package/lib/execution/engine/http.d.ts +46 -16
  178. package/lib/execution/engine/http.d.ts.map +1 -1
  179. package/lib/execution/engine/http.js +236 -213
  180. package/lib/execution/engine/http.js.map +1 -1
  181. package/lib/execution/engine/index.d.ts +3 -2
  182. package/lib/execution/engine/index.d.ts.map +1 -1
  183. package/lib/execution/engine/index.js +33 -8
  184. package/lib/execution/engine/index.js.map +1 -1
  185. package/lib/execution/engine/interface.d.ts +2 -4
  186. package/lib/execution/engine/interface.d.ts.map +1 -1
  187. package/lib/execution/engine/jsonRpcTransport.d.ts +25 -0
  188. package/lib/execution/engine/jsonRpcTransport.d.ts.map +1 -0
  189. package/lib/execution/engine/jsonRpcTransport.js +158 -0
  190. package/lib/execution/engine/jsonRpcTransport.js.map +1 -0
  191. package/lib/execution/engine/mock.d.ts +0 -2
  192. package/lib/execution/engine/mock.d.ts.map +1 -1
  193. package/lib/execution/engine/mock.js +0 -8
  194. package/lib/execution/engine/mock.js.map +1 -1
  195. package/lib/execution/engine/restHttpClient.d.ts +71 -0
  196. package/lib/execution/engine/restHttpClient.d.ts.map +1 -0
  197. package/lib/execution/engine/restHttpClient.js +201 -0
  198. package/lib/execution/engine/restHttpClient.js.map +1 -0
  199. package/lib/execution/engine/restTransport.d.ts +46 -0
  200. package/lib/execution/engine/restTransport.d.ts.map +1 -0
  201. package/lib/execution/engine/restTransport.js +399 -0
  202. package/lib/execution/engine/restTransport.js.map +1 -0
  203. package/lib/execution/engine/sszTypes.d.ts +1261 -0
  204. package/lib/execution/engine/sszTypes.d.ts.map +1 -0
  205. package/lib/execution/engine/sszTypes.js +216 -0
  206. package/lib/execution/engine/sszTypes.js.map +1 -0
  207. package/lib/execution/engine/transport.d.ts +39 -0
  208. package/lib/execution/engine/transport.d.ts.map +1 -0
  209. package/lib/execution/engine/transport.js +2 -0
  210. package/lib/execution/engine/transport.js.map +1 -0
  211. package/lib/execution/engine/types.d.ts +2 -8
  212. package/lib/execution/engine/types.d.ts.map +1 -1
  213. package/lib/execution/engine/types.js +24 -57
  214. package/lib/execution/engine/types.js.map +1 -1
  215. package/lib/execution/engine/utils.d.ts.map +1 -1
  216. package/lib/execution/engine/utils.js +9 -2
  217. package/lib/execution/engine/utils.js.map +1 -1
  218. package/lib/metrics/metrics/lodestar.d.ts +10 -0
  219. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  220. package/lib/metrics/metrics/lodestar.js +22 -0
  221. package/lib/metrics/metrics/lodestar.js.map +1 -1
  222. package/lib/metrics/metrics.d.ts +7 -3
  223. package/lib/metrics/metrics.d.ts.map +1 -1
  224. package/lib/metrics/metrics.js +4 -4
  225. package/lib/metrics/metrics.js.map +1 -1
  226. package/lib/network/core/events.d.ts +5 -1
  227. package/lib/network/core/events.d.ts.map +1 -1
  228. package/lib/network/core/events.js +8 -0
  229. package/lib/network/core/events.js.map +1 -1
  230. package/lib/network/gossip/topic.d.ts +0 -14
  231. package/lib/network/gossip/topic.d.ts.map +1 -1
  232. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  233. package/lib/network/processor/gossipHandlers.js +63 -64
  234. package/lib/network/processor/gossipHandlers.js.map +1 -1
  235. package/lib/network/processor/gossipValidatorFn.d.ts +4 -2
  236. package/lib/network/processor/gossipValidatorFn.d.ts.map +1 -1
  237. package/lib/network/processor/gossipValidatorFn.js +6 -2
  238. package/lib/network/processor/gossipValidatorFn.js.map +1 -1
  239. package/lib/network/processor/index.d.ts +8 -0
  240. package/lib/network/processor/index.d.ts.map +1 -1
  241. package/lib/network/processor/index.js +52 -5
  242. package/lib/network/processor/index.js.map +1 -1
  243. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js +1 -1
  244. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js.map +1 -1
  245. package/lib/network/reqresp/rateLimit.js +2 -2
  246. package/lib/network/reqresp/rateLimit.js.map +1 -1
  247. package/lib/network/subnets/attnetsService.d.ts.map +1 -1
  248. package/lib/network/subnets/attnetsService.js +3 -1
  249. package/lib/network/subnets/attnetsService.js.map +1 -1
  250. package/lib/node/nodejs.d.ts +3 -1
  251. package/lib/node/nodejs.d.ts.map +1 -1
  252. package/lib/node/nodejs.js +27 -4
  253. package/lib/node/nodejs.js.map +1 -1
  254. package/lib/node/notifier.d.ts.map +1 -1
  255. package/lib/node/notifier.js +12 -13
  256. package/lib/node/notifier.js.map +1 -1
  257. package/lib/node/options.d.ts +3 -2
  258. package/lib/node/options.d.ts.map +1 -1
  259. package/lib/node/options.js +2 -2
  260. package/lib/node/options.js.map +1 -1
  261. package/lib/sync/range/batch.d.ts +11 -5
  262. package/lib/sync/range/batch.d.ts.map +1 -1
  263. package/lib/sync/range/batch.js +21 -17
  264. package/lib/sync/range/batch.js.map +1 -1
  265. package/lib/sync/range/chain.d.ts +4 -4
  266. package/lib/sync/range/chain.d.ts.map +1 -1
  267. package/lib/sync/range/chain.js +12 -6
  268. package/lib/sync/range/chain.js.map +1 -1
  269. package/lib/sync/range/range.d.ts.map +1 -1
  270. package/lib/sync/range/range.js +75 -29
  271. package/lib/sync/range/range.js.map +1 -1
  272. package/lib/sync/unknownBlock.d.ts +5 -2
  273. package/lib/sync/unknownBlock.d.ts.map +1 -1
  274. package/lib/sync/unknownBlock.js +52 -26
  275. package/lib/sync/unknownBlock.js.map +1 -1
  276. package/lib/sync/utils/downloadByRange.d.ts +38 -14
  277. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  278. package/lib/sync/utils/downloadByRange.js +84 -39
  279. package/lib/sync/utils/downloadByRange.js.map +1 -1
  280. package/lib/util/asyncIterableToEvents.d.ts +10 -2
  281. package/lib/util/asyncIterableToEvents.d.ts.map +1 -1
  282. package/lib/util/asyncIterableToEvents.js +29 -3
  283. package/lib/util/asyncIterableToEvents.js.map +1 -1
  284. package/lib/util/clock.d.ts.map +1 -1
  285. package/lib/util/clock.js +3 -4
  286. package/lib/util/clock.js.map +1 -1
  287. package/lib/util/execution.d.ts +9 -11
  288. package/lib/util/execution.d.ts.map +1 -1
  289. package/lib/util/execution.js +5 -1
  290. package/lib/util/execution.js.map +1 -1
  291. package/lib/util/metadata.d.ts.map +1 -1
  292. package/lib/util/metadata.js +2 -1
  293. package/lib/util/metadata.js.map +1 -1
  294. package/lib/util/sszBytes.d.ts +2 -2
  295. package/lib/util/sszBytes.d.ts.map +1 -1
  296. package/lib/util/sszBytes.js +22 -14
  297. package/lib/util/sszBytes.js.map +1 -1
  298. package/package.json +18 -17
  299. package/src/api/impl/beacon/blocks/index.ts +17 -7
  300. package/src/api/impl/beacon/index.ts +15 -0
  301. package/src/api/impl/beacon/state/index.ts +43 -6
  302. package/src/api/impl/debug/index.ts +28 -19
  303. package/src/api/impl/validator/index.ts +102 -21
  304. package/src/chain/ColumnReconstructionTracker.ts +4 -6
  305. package/src/chain/archiveStore/archiveStore.ts +19 -25
  306. package/src/chain/archiveStore/historicalState/getHistoricalState.ts +5 -7
  307. package/src/chain/archiveStore/historicalState/historicalStateRegen.ts +1 -1
  308. package/src/chain/archiveStore/historicalState/types.ts +2 -2
  309. package/src/chain/archiveStore/historicalState/worker.ts +1 -2
  310. package/src/chain/archiveStore/interface.ts +1 -1
  311. package/src/chain/archiveStore/utils/pruneHistory.ts +4 -1
  312. package/src/chain/beaconProposerCache.ts +19 -1
  313. package/src/chain/blocks/blockInput/blockInput.ts +1 -1
  314. package/src/chain/blocks/importBlock.ts +24 -10
  315. package/src/chain/blocks/payloadEnvelopeInput/types.ts +2 -1
  316. package/src/chain/blocks/verifyBlock.ts +8 -6
  317. package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +6 -3
  318. package/src/chain/chain.ts +135 -37
  319. package/src/chain/emitter.ts +7 -1
  320. package/src/chain/errors/envelopeReconstructionError.ts +3 -0
  321. package/src/chain/errors/gossipValidation.ts +1 -0
  322. package/src/chain/forkChoice/index.ts +2 -0
  323. package/src/chain/interface.ts +7 -3
  324. package/src/chain/opPools/aggregatedAttestationPool.ts +34 -10
  325. package/src/chain/opPools/opPool.ts +1 -31
  326. package/src/chain/opPools/proposerPreferencesPool.ts +34 -11
  327. package/src/chain/opPools/utils.ts +31 -0
  328. package/src/chain/options.ts +3 -3
  329. package/src/chain/prepareNextSlot.ts +22 -6
  330. package/src/chain/produceBlock/computeNewStateRoot.ts +10 -3
  331. package/src/chain/produceBlock/produceBlockBody.ts +78 -39
  332. package/src/chain/regen/regen.ts +12 -4
  333. package/src/chain/reprocess.ts +2 -1
  334. package/src/chain/seenCache/seenGossipBlockInput.ts +25 -1
  335. package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +31 -13
  336. package/src/chain/shufflingCache.ts +84 -22
  337. package/src/chain/stateCache/persistentCheckpointsCache.ts +4 -1
  338. package/src/chain/validatorMonitor.ts +82 -61
  339. package/src/constants/constants.ts +1 -0
  340. package/src/db/beacon.ts +6 -0
  341. package/src/db/buckets.ts +2 -0
  342. package/src/db/interface.ts +4 -0
  343. package/src/db/repositories/blockArchive.ts +2 -2
  344. package/src/db/repositories/blockArchiveIndex.ts +2 -3
  345. package/src/db/repositories/earliestAvailableSlot.ts +19 -0
  346. package/src/db/repositories/index.ts +1 -0
  347. package/src/db/repositories/proposerPreferences.ts +23 -0
  348. package/src/execution/engine/blobVersionedHashes.ts +72 -0
  349. package/src/execution/engine/disabled.ts +0 -8
  350. package/src/execution/engine/http.ts +304 -300
  351. package/src/execution/engine/index.ts +41 -7
  352. package/src/execution/engine/interface.ts +2 -6
  353. package/src/execution/engine/jsonRpcTransport.ts +247 -0
  354. package/src/execution/engine/mock.ts +1 -19
  355. package/src/execution/engine/restHttpClient.ts +269 -0
  356. package/src/execution/engine/restTransport.ts +544 -0
  357. package/src/execution/engine/sszTypes.ts +354 -0
  358. package/src/execution/engine/transport.ts +61 -0
  359. package/src/execution/engine/types.ts +34 -84
  360. package/src/execution/engine/utils.ts +12 -2
  361. package/src/metrics/metrics/lodestar.ts +23 -0
  362. package/src/metrics/metrics.ts +21 -6
  363. package/src/network/core/events.ts +16 -1
  364. package/src/network/processor/gossipHandlers.ts +94 -77
  365. package/src/network/processor/gossipValidatorFn.ts +12 -2
  366. package/src/network/processor/index.ts +58 -5
  367. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRoot.ts +1 -1
  368. package/src/network/reqresp/rateLimit.ts +2 -2
  369. package/src/network/subnets/attnetsService.ts +8 -3
  370. package/src/node/nodejs.ts +35 -3
  371. package/src/node/notifier.ts +14 -13
  372. package/src/node/options.ts +10 -1
  373. package/src/sync/range/batch.ts +25 -19
  374. package/src/sync/range/chain.ts +15 -8
  375. package/src/sync/range/range.ts +76 -30
  376. package/src/sync/unknownBlock.ts +65 -27
  377. package/src/sync/utils/downloadByRange.ts +123 -58
  378. package/src/util/asyncIterableToEvents.ts +44 -5
  379. package/src/util/clock.ts +3 -4
  380. package/src/util/execution.ts +16 -8
  381. package/src/util/metadata.ts +2 -1
  382. package/src/util/sszBytes.ts +25 -12
@@ -1,5 +1,4 @@
1
1
  import {BeaconConfig} from "@lodestar/config";
2
- import {DbBatch, Id, Repository} from "@lodestar/db";
3
2
  import {
4
3
  BLS_WITHDRAWAL_PREFIX,
5
4
  ForkName,
@@ -42,6 +41,7 @@ import {
42
41
  getAttesterSlashingSignatureDomains,
43
42
  getProposerSlashingSignatureDomain,
44
43
  isValidBlsToExecutionChangeForBlockInclusion,
44
+ persistDiff,
45
45
  } from "./utils.js";
46
46
 
47
47
  type HexRoot = string;
@@ -500,33 +500,3 @@ function isVoluntaryExitSignatureIncludable(stateFork: ForkSeq, voluntaryExitFor
500
500
  function isSlashableAtEpoch(validator: phase0.Validator, epoch: Epoch): boolean {
501
501
  return !validator.slashed && validator.activationEpoch <= epoch && epoch < validator.withdrawableEpoch;
502
502
  }
503
-
504
- /**
505
- * Persist target items `items` in `dbRepo` doing minimum put and delete writes.
506
- * Reads all keys in repository to compute the diff between current persisted data and target data.
507
- */
508
- async function persistDiff<K extends Id, V>(
509
- dbRepo: Repository<K, V>,
510
- items: {key: K; value: V}[],
511
- serializeKey: (key: K) => number | string,
512
- opts: {updateExisting?: boolean} = {}
513
- ): Promise<void> {
514
- const persistedKeys = await dbRepo.keys();
515
- const batch: DbBatch<K, V> = [];
516
-
517
- const persistedKeysSerialized = new Set(persistedKeys.map(serializeKey));
518
- for (const item of items) {
519
- if (opts.updateExisting || !persistedKeysSerialized.has(serializeKey(item.key))) {
520
- batch.push({type: "put", key: item.key, value: item.value});
521
- }
522
- }
523
-
524
- const targetKeysSerialized = new Set(items.map((item) => serializeKey(item.key)));
525
- for (const persistedKey of persistedKeys) {
526
- if (!targetKeysSerialized.has(serializeKey(persistedKey))) {
527
- batch.push({type: "del", key: persistedKey});
528
- }
529
- }
530
-
531
- if (batch.length > 0) await dbRepo.batch(batch);
532
- }
@@ -1,13 +1,15 @@
1
1
  import {RootHex, Slot, ValidatorIndex, gloas} from "@lodestar/types";
2
- import {toRootHex} from "@lodestar/utils";
2
+ import {toHex, toRootHex} from "@lodestar/utils";
3
+ import {IBeaconDb} from "../../db/index.js";
4
+ import {persistDiff} from "./utils.js";
3
5
 
4
6
  /**
5
7
  * Pool of validated `SignedProposerPreferences` indexed by `(slot, dependent_root)`.
6
8
  *
7
9
  * The primary consumer is `validateExecutionPayloadBid`, which looks up the matching
8
10
  * preferences via `get(bid.slot, dependent_root)` to enforce the IGNORE-existence and
9
- * REJECT-equality rules from the gloas spec. The beacon API `/pool/proposer_preferences`
10
- * GET endpoint reads from the same pool via `getAll`.
11
+ * REJECT-equality rules from the gloas spec. The beacon API `getProposerPreferences`
12
+ * endpoint reads from the same pool via `getAll`.
11
13
  *
12
14
  * `validator_index` is intentionally not part of the key: gossip validation enforces
13
15
  * `proposers[proposalSlot % SLOTS_PER_EPOCH] === validatorIndex` against the shuffling
@@ -37,15 +39,19 @@ export class ProposerPreferencesPool {
37
39
  byRoot.set(rootHex, signed);
38
40
  }
39
41
 
40
- /** API read-out: flatten across branches, optionally filtered by slot. */
41
- getAll(slot?: Slot): gloas.SignedProposerPreferences[] {
42
- if (slot !== undefined) {
43
- const byRoot = this.bySlot.get(slot);
44
- return byRoot ? Array.from(byRoot.values()) : [];
45
- }
42
+ /** API read-out: flatten across branches, optionally filtered by slot and dependent root. */
43
+ getAll(slot?: Slot, dependentRootHex?: RootHex): gloas.SignedProposerPreferences[] {
46
44
  const out: gloas.SignedProposerPreferences[] = [];
47
- for (const byRoot of this.bySlot.values()) {
48
- for (const v of byRoot.values()) out.push(v);
45
+ for (const [s, byRoot] of this.bySlot) {
46
+ if (slot !== undefined && s !== slot) {
47
+ continue;
48
+ }
49
+ for (const [root, signed] of byRoot) {
50
+ if (dependentRootHex !== undefined && root !== dependentRootHex) {
51
+ continue;
52
+ }
53
+ out.push(signed);
54
+ }
49
55
  }
50
56
  return out;
51
57
  }
@@ -60,4 +66,21 @@ export class ProposerPreferencesPool {
60
66
  if (slot < currentSlot) this.bySlot.delete(slot);
61
67
  }
62
68
  }
69
+
70
+ /** Restore the preferences of upcoming slots, they were validated before they were persisted */
71
+ async fromPersisted(db: IBeaconDb, currentSlot: Slot): Promise<void> {
72
+ for (const signed of await db.proposerPreferences.values()) {
73
+ if (signed.message.proposalSlot >= currentSlot) {
74
+ this.add(signed);
75
+ }
76
+ }
77
+ }
78
+
79
+ async toPersisted(db: IBeaconDb): Promise<void> {
80
+ await persistDiff(
81
+ db.proposerPreferences,
82
+ this.getAll().map((signed) => ({key: db.proposerPreferences.getId(signed), value: signed})),
83
+ toHex
84
+ );
85
+ }
63
86
  }
@@ -1,5 +1,6 @@
1
1
  import {Signature} from "@chainsafe/lodestar-z/blst";
2
2
  import {BeaconConfig} from "@lodestar/config";
3
+ import {DbBatch, Id, Repository} from "@lodestar/db";
3
4
  import {BLS_WITHDRAWAL_PREFIX, DOMAIN_BEACON_ATTESTER, DOMAIN_BEACON_PROPOSER} from "@lodestar/params";
4
5
  import {IBeaconStateView, computeStartSlotAtEpoch} from "@lodestar/state-transition";
5
6
  import {AttesterSlashing, Domain, Slot, capella, phase0} from "@lodestar/types";
@@ -91,3 +92,33 @@ export function isValidBlsToExecutionChangeForBlockInclusion(
91
92
  export function isElectraAggregate(aggregate: AggregateFast): aggregate is AggregateFastElectra {
92
93
  return (aggregate as AggregateFastElectra).committeeBits !== undefined;
93
94
  }
95
+
96
+ /**
97
+ * Persist target items `items` in `dbRepo` doing minimum put and delete writes.
98
+ * Reads all keys in repository to compute the diff between current persisted data and target data.
99
+ */
100
+ export async function persistDiff<K extends Id, V>(
101
+ dbRepo: Repository<K, V>,
102
+ items: {key: K; value: V}[],
103
+ serializeKey: (key: K) => number | string,
104
+ opts: {updateExisting?: boolean} = {}
105
+ ): Promise<void> {
106
+ const persistedKeys = await dbRepo.keys();
107
+ const batch: DbBatch<K, V> = [];
108
+
109
+ const persistedKeysSerialized = new Set(persistedKeys.map(serializeKey));
110
+ for (const item of items) {
111
+ if (opts.updateExisting || !persistedKeysSerialized.has(serializeKey(item.key))) {
112
+ batch.push({type: "put", key: item.key, value: item.value});
113
+ }
114
+ }
115
+
116
+ const targetKeysSerialized = new Set(items.map((item) => serializeKey(item.key)));
117
+ for (const persistedKey of persistedKeys) {
118
+ if (!targetKeysSerialized.has(serializeKey(persistedKey))) {
119
+ batch.push({type: "del", key: persistedKey});
120
+ }
121
+ }
122
+
123
+ if (batch.length > 0) await dbRepo.batch(batch);
124
+ }
@@ -27,8 +27,8 @@ export type IChainOptions = BlockProcessOpts &
27
27
  blsVerifyAllMainThread?: boolean;
28
28
  blsVerifyAllMultiThread?: boolean;
29
29
  blacklistedBlocks?: string[];
30
- // TODO GLOAS: add similar option for execution payload envelopes?
31
30
  persistProducedBlocks?: boolean;
31
+ persistProducedPayloadEnvelopes?: boolean;
32
32
  /** Archive finalized Gloas payload envelopes as headers (bodies reconstructed from the EL on read) */
33
33
  dedupePayloads?: boolean;
34
34
  persistInvalidSszObjects?: boolean;
@@ -52,7 +52,7 @@ export type IChainOptions = BlockProcessOpts &
52
52
  minSameMessageSignatureSetsToBatch: number;
53
53
  archiveDateEpochs?: number;
54
54
  nHistoricalStatesFileDataStore?: boolean;
55
- nativeStateView?: boolean;
55
+ nativeStateTransition?: boolean;
56
56
  /** Builder circuit breaker fault inspection window in slots */
57
57
  faultInspectionWindow?: number;
58
58
  /** Canonical EMPTY blocks allowed per `faultInspectionWindow` observed blocks */
@@ -131,7 +131,7 @@ export const defaultChainOptions: IChainOptions = {
131
131
  // - users can prune the persisted checkpoint state files manually to save disc space
132
132
  // - it helps debug easier when network is unfinalized
133
133
  nHistoricalStatesFileDataStore: true,
134
- nativeStateView: false,
134
+ nativeStateTransition: false,
135
135
  maxBlockStates: DEFAULT_MAX_BLOCK_STATES,
136
136
  maxCPStateEpochsInMemory: DEFAULT_MAX_CP_STATE_EPOCHS_IN_MEMORY,
137
137
  maxCPStateEpochsOnDisk: DEFAULT_MAX_CP_STATE_ON_DISK,
@@ -22,7 +22,7 @@ import {
22
22
  isStatePostGloas,
23
23
  } from "@lodestar/state-transition";
24
24
  import {Bytes32, Slot, ValidatorIndex} from "@lodestar/types";
25
- import {Logger, fromHex, isErrorAborted, sleep} from "@lodestar/utils";
25
+ import {Logger, fromHex, isErrorAborted, sleep, toHex} from "@lodestar/utils";
26
26
  import {GENESIS_SLOT} from "../constants/constants.js";
27
27
  import {BuilderStatus} from "../execution/builder/http.js";
28
28
  import {PayloadAttributes} from "../execution/index.js";
@@ -31,7 +31,11 @@ import {ClockEvent} from "../util/clock.js";
31
31
  import {isQueueErrorAborted} from "../util/queue/index.js";
32
32
  import {ForkchoiceCaller} from "./forkChoice/index.js";
33
33
  import {IBeaconChain} from "./interface.js";
34
- import {getPayloadAttributesForSSE, prepareExecutionPayload} from "./produceBlock/produceBlockBody.js";
34
+ import {
35
+ getPayloadAttributesForSSE,
36
+ getPooledProposerPreferences,
37
+ prepareExecutionPayload,
38
+ } from "./produceBlock/produceBlockBody.js";
35
39
  import {RegenCaller} from "./regen/index.js";
36
40
 
37
41
  // TODO GLOAS: re-evaluate this timing
@@ -92,6 +96,7 @@ export class PrepareNextSlotScheduler {
92
96
  const nextEpoch = computeEpochAtSlot(clockSlot) + 1;
93
97
  const isEpochTransition = prepareEpoch === nextEpoch;
94
98
  const fork = this.config.getForkName(prepareSlot);
99
+ const currentFork = this.config.getForkName(clockSlot);
95
100
 
96
101
  // Early return if we are pre-genesis
97
102
  // or we are pre-bellatrix and this is not an epoch transition
@@ -102,7 +107,7 @@ export class PrepareNextSlotScheduler {
102
107
  try {
103
108
  // At PREPARE_NEXT_SLOT_BPS (~67%) of the current slot we prepare payload for the next slot
104
109
  // or precompute epoch transition
105
- await sleep(this.config.getSlotComponentDurationMs(PREPARE_NEXT_SLOT_BPS), this.signal);
110
+ await sleep(this.config.getSlotComponentDurationMs(currentFork, PREPARE_NEXT_SLOT_BPS), this.signal);
106
111
 
107
112
  // calling updateHead() here before we produce a block to reduce reorg possibility
108
113
  const headBlock = this.chain.recomputeForkChoiceHead(ForkchoiceCaller.prepareNextSlot);
@@ -158,7 +163,15 @@ export class PrepareNextSlotScheduler {
158
163
  };
159
164
 
160
165
  const proposerIndex = await getProposerIndex();
161
- feeRecipient = this.chain.beaconProposerCache.get(proposerIndex);
166
+ if (this.chain.beaconProposerCache.has(proposerIndex)) {
167
+ const pooledPreferences = isForkPostGloas(fork)
168
+ ? getPooledProposerPreferences(this.chain, prepareSlot, headRoot)
169
+ : null;
170
+ feeRecipient =
171
+ pooledPreferences !== null
172
+ ? toHex(pooledPreferences.feeRecipient)
173
+ : this.chain.beaconProposerCache.getOrDefault(proposerIndex);
174
+ }
162
175
 
163
176
  // Predict the proposer head of the next slot when either:
164
177
  // - we are proposing the next slot (single-slot proposer-boost-reorg), or
@@ -357,7 +370,7 @@ export class PrepareNextSlotScheduler {
357
370
  // skip when we're the next-slot proposer — don't compete with block-production prep.
358
371
  feeRecipient === undefined
359
372
  ) {
360
- const maxDurationMs = this.config.getSlotComponentDurationMs(BUILDER_PREVERIFY_LIMIT_BPS);
373
+ const maxDurationMs = this.config.getSlotComponentDurationMs(currentFork, BUILDER_PREVERIFY_LIMIT_BPS);
361
374
  const preVerifyTimer = this.metrics?.builderDepositPreVerify.duration.startTimer();
362
375
  const result = headState.preVerifyBuilderDepositsPreGloas(MAX_BUILDER_DEPOSITS_PER_SLOT, maxDurationMs);
363
376
  preVerifyTimer?.();
@@ -411,7 +424,10 @@ export class PrepareNextSlotScheduler {
411
424
  * later in the slot, connecting at PREPARE_NEXT_SLOT_BPS would go cold before bids are requested.
412
425
  */
413
426
  private checkBuilderStatusBeforeSlot(prepareSlot: Slot): void {
414
- const msBeforeSlot = this.config.getSlotComponentDurationMs(BUILDER_STATUS_CHECK_BEFORE_SLOT_BPS);
427
+ const msBeforeSlot = this.config.getSlotComponentDurationMs(
428
+ this.config.getForkName(prepareSlot - 1),
429
+ BUILDER_STATUS_CHECK_BEFORE_SLOT_BPS
430
+ );
415
431
  const msUntilCheck = -this.chain.clock.msFromSlot(prepareSlot) - msBeforeSlot;
416
432
  sleep(Math.max(0, msUntilCheck), this.signal)
417
433
  .then(() => this.chain.builderApiClient.checkStatus())
@@ -1,5 +1,12 @@
1
1
  import {EMPTY_SIGNATURE, IBeaconStateView, StateHashTreeRootSource} from "@lodestar/state-transition";
2
- import {BeaconBlock, BlindedBeaconBlock, Gwei, Root} from "@lodestar/types";
2
+ import {
3
+ BeaconBlock,
4
+ BlindedBeaconBlock,
5
+ Gwei,
6
+ Root,
7
+ SignedBeaconBlock,
8
+ SignedBlindedBeaconBlock,
9
+ } from "@lodestar/types";
3
10
  import {Metrics} from "../../metrics/index.js";
4
11
 
5
12
  /**
@@ -13,10 +20,10 @@ export function computeNewStateRoot(
13
20
  block: BeaconBlock | BlindedBeaconBlock
14
21
  ): {newStateRoot: Root; proposerReward: Gwei; postState: IBeaconStateView} {
15
22
  // Set signature to zero to re-use stateTransition() function which requires the SignedBeaconBlock type
16
- const signedBlock = {message: block, signature: EMPTY_SIGNATURE};
23
+ const signedBlock = {message: block, signature: EMPTY_SIGNATURE} as SignedBeaconBlock | SignedBlindedBeaconBlock;
17
24
  const {newStateRoot, proposerReward, postState, hashTreeRootTime} = state.computeNewStateRoot(
18
25
  {block: signedBlock},
19
- {metrics}
26
+ {metrics: metrics?.stateTransition}
20
27
  );
21
28
 
22
29
  metrics?.stateHashTreeRootTime.observe({source: StateHashTreeRootSource.computeNewStateRoot}, hashTreeRootTime);
@@ -20,6 +20,7 @@ import {
20
20
  isForkPostAltair,
21
21
  isForkPostBellatrix,
22
22
  isForkPostGloas,
23
+ isForkPostHeze,
23
24
  } from "@lodestar/params";
24
25
  import {
25
26
  G2_POINT_AT_INFINITY,
@@ -77,6 +78,7 @@ import {IExecutionBuilder, IExecutionEngine, PayloadAttributes, PayloadId} from
77
78
  import {getShufflingDependentRoot} from "../../util/dependentRoot.js";
78
79
  import {fromGraffitiBytes} from "../../util/graffiti.js";
79
80
  import {kzg} from "../../util/kzg.js";
81
+ import {BeaconProposerCache} from "../beaconProposerCache.js";
80
82
  import type {BeaconChain} from "../chain.js";
81
83
  import {CommonBlockBody} from "../interface.js";
82
84
  import {ProposerPreferencesPool} from "../opPools/index.js";
@@ -286,10 +288,13 @@ export async function produceBlockBody<T extends BlockType>(
286
288
  // this into a completely separate function and have pre/post gloas more separated
287
289
  const safeBlockHash = getSafeExecutionBlockHash(this.forkChoice, this.logger);
288
290
  const finalizedBlockHash = getFinalizedExecutionBlockHash(this.forkChoice);
289
- // TODO GLOAS: post-Gloas, proposer feeRecipient is also carried (signed) in
290
- // ProposerPreferencesPool. Consider using this unified cache instead
291
- // see https://github.com/ChainSafe/lodestar/issues/9379
292
- const feeRecipient = requestedFeeRecipient ?? this.beaconProposerCache.getOrDefault(proposerIndex);
291
+ const {feeRecipient, feeRecipientType} = getProposerFeeRecipient(
292
+ requestedFeeRecipient,
293
+ getPooledProposerPreferences(this, blockSlot, parentBlock.blockRoot),
294
+ this.beaconProposerCache,
295
+ proposerIndex
296
+ );
297
+ Object.assign(logMeta, {feeRecipientType, feeRecipient});
293
298
 
294
299
  const endExecutionPayload = this.metrics?.executionBlockProductionTimeSteps.startTimer();
295
300
 
@@ -442,13 +447,12 @@ export async function produceBlockBody<T extends BlockType>(
442
447
 
443
448
  const safeBlockHash = getSafeExecutionBlockHash(this.forkChoice, this.logger);
444
449
  const finalizedBlockHash = getFinalizedExecutionBlockHash(this.forkChoice);
445
- const feeRecipient = requestedFeeRecipient ?? this.beaconProposerCache.getOrDefault(proposerIndex);
446
- const feeRecipientType = requestedFeeRecipient
447
- ? "requested"
448
- : this.beaconProposerCache.get(proposerIndex)
449
- ? "cached"
450
- : "default";
451
-
450
+ const {feeRecipient, feeRecipientType} = getProposerFeeRecipient(
451
+ requestedFeeRecipient,
452
+ null,
453
+ this.beaconProposerCache,
454
+ proposerIndex
455
+ );
452
456
  Object.assign(logMeta, {feeRecipientType, feeRecipient});
453
457
 
454
458
  if (blockType === BlockType.Blinded) {
@@ -681,12 +685,11 @@ export async function produceBlockBody<T extends BlockType>(
681
685
  executionPayloadValue = BigInt(0);
682
686
  }
683
687
 
684
- const {graffiti, attestations, deposits, voluntaryExits, attesterSlashings, proposerSlashings} = blockBody;
688
+ const {graffiti, attestations, voluntaryExits, attesterSlashings, proposerSlashings} = blockBody;
685
689
 
686
690
  Object.assign(logMeta, {
687
691
  graffiti: fromGraffitiBytes(graffiti),
688
692
  attestations: attestations.length,
689
- deposits: deposits.length,
690
693
  voluntaryExits: voluntaryExits.length,
691
694
  attesterSlashings: attesterSlashings.length,
692
695
  proposerSlashings: proposerSlashings.length,
@@ -974,9 +977,8 @@ function preparePayloadAttributes(
974
977
  * Resolve the proposer's preferred (target) gas limit for the Gloas `PayloadAttributesV4`
975
978
  * `targetGasLimit` field (consensus-specs#5235, execution-apis#796).
976
979
  *
977
- * Sourced from the `SignedProposerPreferences` the proposer's VC submitted to the pool
978
- * (same `(slot, dependent_root)` lookup as gossip bid validation). When no matching
979
- * preferences are pooled, target the parent payload's gas limit so the gas limit stays
980
+ * Sourced from the `SignedProposerPreferences` the proposer's VC submitted to the pool. When no
981
+ * matching preferences are pooled, target the parent payload's gas limit so the gas limit stays
980
982
  * unchanged (`is_gas_limit_target_compatible` then requires `gas_limit == parent_gas_limit`).
981
983
  *
982
984
  * The parent payload's gas_limit is read from fork choice — the variant matching
@@ -991,26 +993,9 @@ function getProposerTargetGasLimit(
991
993
  parentBlockHash: Bytes32
992
994
  ): bigint {
993
995
  const parentBlockRootHex = toRootHex(parentBlockRoot);
994
- const parentBlock = chain.forkChoice.getBlockHexDefaultStatus(parentBlockRootHex);
995
- const dependentRootHex = (() => {
996
- if (parentBlock === null) {
997
- return null;
998
- }
999
- try {
1000
- return getShufflingDependentRoot(
1001
- chain.forkChoice,
1002
- computeEpochAtSlot(prepareSlot),
1003
- computeEpochAtSlot(parentBlock.slot),
1004
- parentBlock
1005
- );
1006
- } catch {
1007
- return null;
1008
- }
1009
- })();
1010
-
1011
- const pref = dependentRootHex !== null ? chain.proposerPreferencesPool.get(prepareSlot, dependentRootHex) : null;
1012
- if (pref !== null) {
1013
- return pref.message.targetGasLimit;
996
+ const preferences = getPooledProposerPreferences(chain, prepareSlot, parentBlockRootHex);
997
+ if (preferences !== null) {
998
+ return preferences.targetGasLimit;
1014
999
  }
1015
1000
 
1016
1001
  const parentPayloadVariant = chain.forkChoice.getBlockHexAndBlockHash(parentBlockRootHex, toRootHex(parentBlockHash));
@@ -1022,6 +1007,55 @@ function getProposerTargetGasLimit(
1022
1007
  return BigInt(parentPayloadVariant.executionPayloadGasLimit);
1023
1008
  }
1024
1009
 
1010
+ /** The proposer's request wins over its signed preferences, which win over its registered proposer data */
1011
+ function getProposerFeeRecipient(
1012
+ requestedFeeRecipient: string | undefined,
1013
+ pooledPreferences: gloas.ProposerPreferences | null,
1014
+ beaconProposerCache: BeaconProposerCache,
1015
+ proposerIndex: ValidatorIndex
1016
+ ): {feeRecipient: string; feeRecipientType: "requested" | "preferences" | "cached" | "default"} {
1017
+ if (requestedFeeRecipient !== undefined) {
1018
+ return {feeRecipient: requestedFeeRecipient, feeRecipientType: "requested"};
1019
+ }
1020
+ if (pooledPreferences !== null) {
1021
+ return {feeRecipient: toHex(pooledPreferences.feeRecipient), feeRecipientType: "preferences"};
1022
+ }
1023
+ const cachedFeeRecipient = beaconProposerCache.get(proposerIndex);
1024
+ if (cachedFeeRecipient !== undefined) {
1025
+ return {feeRecipient: cachedFeeRecipient, feeRecipientType: "cached"};
1026
+ }
1027
+ return {feeRecipient: beaconProposerCache.getOrDefault(proposerIndex), feeRecipientType: "default"};
1028
+ }
1029
+
1030
+ /**
1031
+ * The preferences the proposer of `slot` signed for the branch of `parentBlockRoot`, the same
1032
+ * `(slot, dependent_root)` lookup as gossip bid validation. Null if none are pooled.
1033
+ */
1034
+ export function getPooledProposerPreferences(
1035
+ chain: {forkChoice: IForkChoice; proposerPreferencesPool: ProposerPreferencesPool},
1036
+ slot: Slot,
1037
+ parentBlockRootHex: RootHex
1038
+ ): gloas.ProposerPreferences | null {
1039
+ const parentBlock = chain.forkChoice.getBlockHexDefaultStatus(parentBlockRootHex);
1040
+ if (parentBlock === null) {
1041
+ return null;
1042
+ }
1043
+
1044
+ let dependentRootHex: RootHex;
1045
+ try {
1046
+ dependentRootHex = getShufflingDependentRoot(
1047
+ chain.forkChoice,
1048
+ computeEpochAtSlot(slot),
1049
+ computeEpochAtSlot(parentBlock.slot),
1050
+ parentBlock
1051
+ );
1052
+ } catch {
1053
+ return null;
1054
+ }
1055
+
1056
+ return chain.proposerPreferencesPool.get(slot, dependentRootHex)?.message ?? null;
1057
+ }
1058
+
1025
1059
  export async function produceCommonBlockBody<T extends BlockType>(
1026
1060
  this: BeaconChain,
1027
1061
  blockType: T,
@@ -1072,16 +1106,21 @@ export async function produceCommonBlockBody<T extends BlockType>(
1072
1106
  });
1073
1107
 
1074
1108
  // Live proposal production is supported from Fulu onward.
1075
- return {
1109
+ const commonBlockBody: CommonBlockBody = {
1076
1110
  randaoReveal,
1077
1111
  graffiti,
1078
- eth1Data: currentState.eth1Data,
1079
1112
  proposerSlashings: this.opts.disableProposerSlashings === true ? [] : proposerSlashings,
1080
1113
  attesterSlashings,
1081
1114
  attestations,
1082
- deposits: [],
1083
1115
  voluntaryExits,
1084
1116
  blsToExecutionChanges,
1085
1117
  syncAggregate,
1086
1118
  };
1119
+
1120
+ if (!isForkPostHeze(fork)) {
1121
+ commonBlockBody.eth1Data = currentState.eth1Data;
1122
+ commonBlockBody.deposits = [];
1123
+ }
1124
+
1125
+ return commonBlockBody;
1087
1126
  }
@@ -14,6 +14,7 @@ import {Logger, fromHex, toRootHex} from "@lodestar/utils";
14
14
  import {IBeaconDb} from "../../db/index.js";
15
15
  import {Metrics} from "../../metrics/index.js";
16
16
  import {nextEventLoop} from "../../util/eventLoop.js";
17
+ import {SerializedCache} from "../../util/serializedCache.js";
17
18
  import {getCheckpointFromState} from "../blocks/utils/checkpoint.js";
18
19
  import {ChainEvent, ChainEventEmitter} from "../emitter.js";
19
20
  import {SeenBlockInput} from "../seenCache/seenGossipBlockInput.js";
@@ -28,6 +29,7 @@ export type RegenModules = {
28
29
  blockStateCache: BlockStateCache;
29
30
  checkpointStateCache: CheckpointStateCache;
30
31
  seenBlockInputCache: SeenBlockInput;
32
+ serializedCache: SerializedCache;
31
33
  config: ChainForkConfig;
32
34
  emitter: ChainEventEmitter;
33
35
  logger: Logger;
@@ -235,7 +237,7 @@ export class StateRegenerator implements IStateRegeneratorInternal {
235
237
  // We are only running the state transition to get a specific state's data.
236
238
  // stateTransition() does the clone() inside, transfer cache to make the regen faster
237
239
  state = state.stateTransition(
238
- block,
240
+ {block, ssz: this.modules.serializedCache.get(block)},
239
241
  {
240
242
  // Replay previously imported blocks, assume valid and available
241
243
  executionPayloadStatus: ExecutionPayloadStatus.valid,
@@ -245,7 +247,7 @@ export class StateRegenerator implements IStateRegeneratorInternal {
245
247
  verifySignatures: false,
246
248
  dontTransferCache: false,
247
249
  },
248
- this.modules
250
+ {metrics: this.modules.metrics?.stateTransition, validatorMonitor: this.modules.validatorMonitor}
249
251
  );
250
252
 
251
253
  const hashTreeRootTimer = this.modules.metrics?.stateHashTreeRootTime.startTimer({
@@ -316,7 +318,10 @@ async function processSlotsByCheckpoint(
316
318
  ): Promise<IBeaconStateView> {
317
319
  let postState = await processSlotsToNearestCheckpoint(modules, preState, slot, regenCaller, opts);
318
320
  if (postState.slot < slot) {
319
- postState = postState.processSlots(slot, opts, modules);
321
+ postState = postState.processSlots(slot, opts, {
322
+ metrics: modules.metrics?.stateTransition,
323
+ validatorMonitor: modules.validatorMonitor,
324
+ });
320
325
  }
321
326
  return postState;
322
327
  }
@@ -361,7 +366,10 @@ export async function processSlotsToNearestCheckpoint(
361
366
  caller: regenCaller,
362
367
  });
363
368
  // processSlots calls .clone() before mutating
364
- postState = postState.processSlots(nextEpochSlot, opts, modules);
369
+ postState = postState.processSlots(nextEpochSlot, opts, {
370
+ metrics: metrics?.stateTransition,
371
+ validatorMonitor: modules.validatorMonitor,
372
+ });
365
373
  metrics?.epochTransitionByCaller.inc({caller: regenCaller});
366
374
 
367
375
  // this is usually added when we prepare for next slot or validate gossip block
@@ -5,8 +5,9 @@ import {Metrics} from "../metrics/index.js";
5
5
  /**
6
6
  * To prevent our node from having to reprocess while struggling to sync,
7
7
  * we only want to reprocess attestations if block reaches our node before this time.
8
+ * Expressed in basis points of slot duration (1667 BPS = 2s for 12s slots).
8
9
  */
9
- export const REPROCESS_MIN_TIME_TO_NEXT_SLOT_SEC = 2;
10
+ export const REPROCESS_MIN_TIME_TO_NEXT_SLOT_BPS = 1667;
10
11
 
11
12
  /**
12
13
  * Reprocess status for metrics
@@ -4,6 +4,7 @@ import {
4
4
  ForkName,
5
5
  ForkPostFulu,
6
6
  ForkPostGloas,
7
+ ForkPreDeneb,
7
8
  ForkPreGloas,
8
9
  SLOTS_PER_EPOCH,
9
10
  isForkPostDeneb,
@@ -111,6 +112,9 @@ export class SeenBlockInput {
111
112
  // there should only 1 block root per slot but we need to always compare against rootHex
112
113
  // and the signature to ensure we only skip verification if both match
113
114
  private verifiedProposerSignatures = new Map<Slot, Map<RootHex, BLSSignature>>();
115
+ // Roots of gossip blocks under validation, counted because blocks with the same root but different signatures
116
+ // can be validated concurrently
117
+ private validatingBlockRoots = new Map<RootHex, number>();
114
118
 
115
119
  constructor({
116
120
  config,
@@ -153,6 +157,26 @@ export class SeenBlockInput {
153
157
  return this.blockInputs.get(rootHex)?.hasBlock() ?? false;
154
158
  }
155
159
 
160
+ /**
161
+ * Mark a gossip block root as under validation, every call MUST be paired with `unmarkValidatingBlock()`
162
+ */
163
+ markValidatingBlock(rootHex: RootHex): void {
164
+ this.validatingBlockRoots.set(rootHex, (this.validatingBlockRoots.get(rootHex) ?? 0) + 1);
165
+ }
166
+
167
+ unmarkValidatingBlock(rootHex: RootHex): void {
168
+ const count = this.validatingBlockRoots.get(rootHex) ?? 0;
169
+ if (count <= 1) {
170
+ this.validatingBlockRoots.delete(rootHex);
171
+ } else {
172
+ this.validatingBlockRoots.set(rootHex, count - 1);
173
+ }
174
+ }
175
+
176
+ isValidatingBlock(rootHex: RootHex): boolean {
177
+ return this.validatingBlockRoots.has(rootHex);
178
+ }
179
+
156
180
  get(rootHex: RootHex): IBlockInput | undefined {
157
181
  return this.blockInputs.get(rootHex);
158
182
  }
@@ -217,7 +241,7 @@ export class SeenBlockInput {
217
241
  } else if (!isForkPostDeneb(forkName)) {
218
242
  // Pre-deneb
219
243
  blockInput = BlockInputPreData.createFromBlock({
220
- block,
244
+ block: block as SignedBeaconBlock<ForkPreDeneb>,
221
245
  blockRootHex,
222
246
  daOutOfRange,
223
247
  forkName,
@@ -47,8 +47,9 @@ export type SeenPayloadEnvelopeInputModules = {
47
47
  * Created whenever we have a block because it needs block bid.
48
48
  * Steady state (linear chain, healthy progression): the cache holds ~2 entries — the head
49
49
  * (parent for next-slot production) and its parent (proposer-boost-reorg fallback). It can
50
- * transiently hold more during forks, range-sync bursts, or when `prepareNextSlot` skips
51
- * ticks; subsequent ticks settle it back.
50
+ * hold more during forks and range sync, or while an entry's payload is not FULL on the head's
51
+ * branch or its columns are still being gathered. Such entries are evicted on a later block
52
+ * import, on finalization or by the size cap.
52
53
  */
53
54
  export class SeenPayloadEnvelopeInput {
54
55
  private readonly config: ChainForkConfig;
@@ -264,18 +265,35 @@ export class SeenPayloadEnvelopeInput {
264
265
  }
265
266
  }
266
267
 
268
+ /**
269
+ * Removes a PayloadEnvelopeInput whose envelope failed import with a definitive invalid verdict. The envelope
270
+ * cannot be replaced in place, sync recreates the entry via `getOrReload()` or `add()` to fetch another one.
271
+ * No-op if the cached entry is a different object, it may already be the recreated one.
272
+ */
273
+ removeInvalid(payloadInput: PayloadEnvelopeInput): void {
274
+ if (this.payloadInputs.get(payloadInput.blockRootHex) === payloadInput) {
275
+ this.evictPayloadInput(payloadInput, "invalid");
276
+ }
277
+ }
278
+
267
279
  pruneBelowParent(parentBlock: ProtoBlock): void {
268
- for (const block of this.forkChoice.getAllAncestorBlocks(parentBlock.blockRoot, parentBlock.payloadStatus)) {
269
- // Only evict once the payload is FULL (revealed/imported) — on an EMPTY/PENDING branch we may
270
- // still need to download the FULL envelope (see #9475), and evicting would make payload-by-root
271
- // sync throw "Missing PayloadEnvelopeInput for known block".
272
- if (block.slot < parentBlock.slot && block.payloadStatus === PayloadStatus.FULL) {
273
- const input = this.payloadInputs.get(block.blockRoot);
274
- // ...and don't evict while columns are still being gathered: writeDataColumnsToDb awaits the
275
- // same hasComputedAllData() before persisting. Such entries are pruned by a later call.
276
- if (input?.hasComputedAllData()) {
277
- this.evictPayloadInput(input, "belowParent");
278
- }
280
+ for (const input of this.payloadInputs.values()) {
281
+ if (
282
+ input.slot < parentBlock.slot &&
283
+ // Don't evict while columns are still being gathered: writeDataColumnsToDb awaits the same
284
+ // hasComputedAllData() before persisting. Such entries are pruned by a later call.
285
+ input.hasComputedAllData() &&
286
+ // Only evict once the payload is FULL (revealed/imported) on the parent's branch. On an EMPTY/PENDING
287
+ // branch we may still need to download the FULL envelope (see #9475), and without the entry gossip
288
+ // for the block is ignored until by-root sync reloads it.
289
+ this.forkChoice.isDescendant(
290
+ input.blockRootHex,
291
+ PayloadStatus.FULL,
292
+ parentBlock.blockRoot,
293
+ parentBlock.payloadStatus
294
+ )
295
+ ) {
296
+ this.evictPayloadInput(input, "belowParent");
279
297
  }
280
298
  }
281
299
  }