@lodestar/beacon-node 1.39.0-dev.882891d89c → 1.39.0-dev.b37f2bd1bd

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 (338) hide show
  1. package/lib/api/impl/beacon/blocks/utils.js +1 -1
  2. package/lib/api/impl/beacon/blocks/utils.js.map +1 -1
  3. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  4. package/lib/chain/blocks/verifyBlock.js +1 -1
  5. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  6. package/lib/chain/blocks/verifyBlocksSignatures.d.ts +1 -2
  7. package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
  8. package/lib/chain/blocks/verifyBlocksSignatures.js +2 -2
  9. package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
  10. package/lib/chain/chain.d.ts +4 -1
  11. package/lib/chain/chain.d.ts.map +1 -1
  12. package/lib/chain/chain.js +16 -8
  13. package/lib/chain/chain.js.map +1 -1
  14. package/lib/chain/genesis/genesis.d.ts +51 -0
  15. package/lib/chain/genesis/genesis.d.ts.map +1 -0
  16. package/lib/chain/genesis/genesis.js +123 -0
  17. package/lib/chain/genesis/genesis.js.map +1 -0
  18. package/lib/chain/genesis/interface.d.ts +13 -0
  19. package/lib/chain/genesis/interface.d.ts.map +1 -0
  20. package/lib/chain/genesis/interface.js +2 -0
  21. package/lib/chain/genesis/interface.js.map +1 -0
  22. package/lib/chain/initState.d.ts +14 -1
  23. package/lib/chain/initState.d.ts.map +1 -1
  24. package/lib/chain/initState.js +62 -1
  25. package/lib/chain/initState.js.map +1 -1
  26. package/lib/chain/interface.d.ts +2 -0
  27. package/lib/chain/interface.d.ts.map +1 -1
  28. package/lib/chain/interface.js.map +1 -1
  29. package/lib/chain/opPools/aggregatedAttestationPool.d.ts +4 -4
  30. package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
  31. package/lib/chain/opPools/aggregatedAttestationPool.js +4 -4
  32. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  33. package/lib/chain/opPools/opPool.d.ts +0 -3
  34. package/lib/chain/opPools/opPool.d.ts.map +1 -1
  35. package/lib/chain/opPools/opPool.js +8 -9
  36. package/lib/chain/opPools/opPool.js.map +1 -1
  37. package/lib/chain/prepareNextSlot.d.ts +4 -0
  38. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  39. package/lib/chain/prepareNextSlot.js +21 -1
  40. package/lib/chain/prepareNextSlot.js.map +1 -1
  41. package/lib/chain/produceBlock/produceBlockBody.d.ts +1 -0
  42. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  43. package/lib/chain/produceBlock/produceBlockBody.js +11 -8
  44. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  45. package/lib/chain/rewards/attestationsRewards.d.ts +1 -2
  46. package/lib/chain/rewards/attestationsRewards.d.ts.map +1 -1
  47. package/lib/chain/rewards/attestationsRewards.js +8 -8
  48. package/lib/chain/rewards/attestationsRewards.js.map +1 -1
  49. package/lib/chain/rewards/blockRewards.d.ts +1 -2
  50. package/lib/chain/rewards/blockRewards.d.ts.map +1 -1
  51. package/lib/chain/rewards/blockRewards.js +5 -5
  52. package/lib/chain/rewards/blockRewards.js.map +1 -1
  53. package/lib/chain/rewards/syncCommitteeRewards.d.ts +1 -2
  54. package/lib/chain/rewards/syncCommitteeRewards.d.ts.map +1 -1
  55. package/lib/chain/rewards/syncCommitteeRewards.js +2 -2
  56. package/lib/chain/rewards/syncCommitteeRewards.js.map +1 -1
  57. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +1 -4
  58. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  59. package/lib/chain/stateCache/persistentCheckpointsCache.js +2 -4
  60. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  61. package/lib/chain/validation/attesterSlashing.js +1 -1
  62. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  63. package/lib/chain/validation/block.js +1 -1
  64. package/lib/chain/validation/block.js.map +1 -1
  65. package/lib/chain/validation/blsToExecutionChange.js +1 -1
  66. package/lib/chain/validation/proposerSlashing.js +1 -1
  67. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  68. package/lib/chain/validation/signatureSets/aggregateAndProof.js +1 -1
  69. package/lib/chain/validation/signatureSets/aggregateAndProof.js.map +1 -1
  70. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts +1 -2
  71. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts.map +1 -1
  72. package/lib/chain/validation/signatureSets/contributionAndProof.js +2 -2
  73. package/lib/chain/validation/signatureSets/contributionAndProof.js.map +1 -1
  74. package/lib/chain/validation/signatureSets/syncCommittee.d.ts +1 -2
  75. package/lib/chain/validation/signatureSets/syncCommittee.d.ts.map +1 -1
  76. package/lib/chain/validation/signatureSets/syncCommittee.js +2 -2
  77. package/lib/chain/validation/signatureSets/syncCommittee.js.map +1 -1
  78. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts +1 -2
  79. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts.map +1 -1
  80. package/lib/chain/validation/signatureSets/syncCommitteeContribution.js +2 -2
  81. package/lib/chain/validation/signatureSets/syncCommitteeContribution.js.map +1 -1
  82. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts +1 -2
  83. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts.map +1 -1
  84. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js +2 -1
  85. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js.map +1 -1
  86. package/lib/chain/validation/syncCommittee.js +1 -1
  87. package/lib/chain/validation/syncCommittee.js.map +1 -1
  88. package/lib/chain/validation/syncCommitteeContributionAndProof.d.ts.map +1 -1
  89. package/lib/chain/validation/syncCommitteeContributionAndProof.js +3 -3
  90. package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
  91. package/lib/chain/validation/voluntaryExit.js +1 -1
  92. package/lib/chain/validation/voluntaryExit.js.map +1 -1
  93. package/lib/db/beacon.d.ts +7 -3
  94. package/lib/db/beacon.d.ts.map +1 -1
  95. package/lib/db/beacon.js +12 -33
  96. package/lib/db/beacon.js.map +1 -1
  97. package/lib/db/buckets.d.ts +6 -12
  98. package/lib/db/buckets.d.ts.map +1 -1
  99. package/lib/db/buckets.js +1 -6
  100. package/lib/db/buckets.js.map +1 -1
  101. package/lib/db/interface.d.ts +7 -2
  102. package/lib/db/interface.d.ts.map +1 -1
  103. package/lib/db/repositories/depositDataRoot.d.ts +22 -0
  104. package/lib/db/repositories/depositDataRoot.d.ts.map +1 -0
  105. package/lib/db/repositories/depositDataRoot.js +62 -0
  106. package/lib/db/repositories/depositDataRoot.js.map +1 -0
  107. package/lib/db/repositories/depositEvent.d.ts +13 -0
  108. package/lib/db/repositories/depositEvent.d.ts.map +1 -0
  109. package/lib/db/repositories/depositEvent.js +27 -0
  110. package/lib/db/repositories/depositEvent.js.map +1 -0
  111. package/lib/db/repositories/eth1Data.d.ts +13 -0
  112. package/lib/db/repositories/eth1Data.d.ts.map +1 -0
  113. package/lib/db/repositories/eth1Data.js +26 -0
  114. package/lib/db/repositories/eth1Data.js.map +1 -0
  115. package/lib/db/repositories/index.d.ts +3 -0
  116. package/lib/db/repositories/index.d.ts.map +1 -1
  117. package/lib/db/repositories/index.js +3 -0
  118. package/lib/db/repositories/index.js.map +1 -1
  119. package/lib/db/single/index.d.ts +3 -0
  120. package/lib/db/single/index.d.ts.map +1 -0
  121. package/lib/db/single/index.js +3 -0
  122. package/lib/db/single/index.js.map +1 -0
  123. package/lib/db/single/preGenesisState.d.ts +16 -0
  124. package/lib/db/single/preGenesisState.d.ts.map +1 -0
  125. package/lib/db/single/preGenesisState.js +29 -0
  126. package/lib/db/single/preGenesisState.js.map +1 -0
  127. package/lib/db/single/preGenesisStateLastProcessedBlock.d.ts +14 -0
  128. package/lib/db/single/preGenesisStateLastProcessedBlock.d.ts.map +1 -0
  129. package/lib/db/single/preGenesisStateLastProcessedBlock.js +27 -0
  130. package/lib/db/single/preGenesisStateLastProcessedBlock.js.map +1 -0
  131. package/lib/eth1/errors.d.ts +66 -0
  132. package/lib/eth1/errors.d.ts.map +1 -0
  133. package/lib/eth1/errors.js +27 -0
  134. package/lib/eth1/errors.js.map +1 -0
  135. package/lib/eth1/eth1DataCache.d.ts +19 -0
  136. package/lib/eth1/eth1DataCache.d.ts.map +1 -0
  137. package/lib/eth1/eth1DataCache.js +19 -0
  138. package/lib/eth1/eth1DataCache.js.map +1 -0
  139. package/lib/eth1/eth1DepositDataTracker.d.ts +80 -0
  140. package/lib/eth1/eth1DepositDataTracker.d.ts.map +1 -0
  141. package/lib/eth1/eth1DepositDataTracker.js +317 -0
  142. package/lib/eth1/eth1DepositDataTracker.js.map +1 -0
  143. package/lib/eth1/eth1DepositsCache.d.ts +42 -0
  144. package/lib/eth1/eth1DepositsCache.d.ts.map +1 -0
  145. package/lib/eth1/eth1DepositsCache.js +119 -0
  146. package/lib/eth1/eth1DepositsCache.js.map +1 -0
  147. package/lib/eth1/index.d.ts +31 -0
  148. package/lib/eth1/index.d.ts.map +1 -0
  149. package/lib/eth1/index.js +71 -0
  150. package/lib/eth1/index.js.map +1 -0
  151. package/lib/eth1/interface.d.ts +74 -0
  152. package/lib/eth1/interface.d.ts.map +1 -0
  153. package/lib/eth1/interface.js +8 -0
  154. package/lib/eth1/interface.js.map +1 -0
  155. package/lib/eth1/options.d.ts +22 -0
  156. package/lib/eth1/options.d.ts.map +1 -0
  157. package/lib/eth1/options.js +8 -0
  158. package/lib/eth1/options.js.map +1 -0
  159. package/lib/eth1/provider/eth1Provider.d.ts +39 -0
  160. package/lib/eth1/provider/eth1Provider.d.ts.map +1 -0
  161. package/lib/eth1/provider/eth1Provider.js +147 -0
  162. package/lib/eth1/provider/eth1Provider.js.map +1 -0
  163. package/lib/{execution/engine → eth1/provider}/jsonRpcHttpClient.d.ts +1 -1
  164. package/lib/eth1/provider/jsonRpcHttpClient.d.ts.map +1 -0
  165. package/lib/eth1/provider/jsonRpcHttpClient.js.map +1 -0
  166. package/lib/eth1/provider/jwt.d.ts.map +1 -0
  167. package/lib/eth1/provider/jwt.js.map +1 -0
  168. package/lib/eth1/provider/utils.d.ts +65 -0
  169. package/lib/eth1/provider/utils.d.ts.map +1 -0
  170. package/lib/eth1/provider/utils.js +120 -0
  171. package/lib/eth1/provider/utils.js.map +1 -0
  172. package/lib/eth1/stream.d.ts +15 -0
  173. package/lib/eth1/stream.d.ts.map +1 -0
  174. package/lib/eth1/stream.js +54 -0
  175. package/lib/eth1/stream.js.map +1 -0
  176. package/lib/eth1/utils/depositContract.d.ts +14 -0
  177. package/lib/eth1/utils/depositContract.d.ts.map +1 -0
  178. package/lib/eth1/utils/depositContract.js +33 -0
  179. package/lib/eth1/utils/depositContract.js.map +1 -0
  180. package/lib/eth1/utils/deposits.d.ts +8 -0
  181. package/lib/eth1/utils/deposits.d.ts.map +1 -0
  182. package/lib/eth1/utils/deposits.js +47 -0
  183. package/lib/eth1/utils/deposits.js.map +1 -0
  184. package/lib/eth1/utils/eth1Data.d.ts +22 -0
  185. package/lib/eth1/utils/eth1Data.d.ts.map +1 -0
  186. package/lib/eth1/utils/eth1Data.js +77 -0
  187. package/lib/eth1/utils/eth1Data.js.map +1 -0
  188. package/lib/eth1/utils/eth1DepositEvent.d.ts +7 -0
  189. package/lib/eth1/utils/eth1DepositEvent.d.ts.map +1 -0
  190. package/lib/eth1/utils/eth1DepositEvent.js +13 -0
  191. package/lib/eth1/utils/eth1DepositEvent.js.map +1 -0
  192. package/lib/eth1/utils/eth1Vote.d.ts +17 -0
  193. package/lib/eth1/utils/eth1Vote.d.ts.map +1 -0
  194. package/lib/eth1/utils/eth1Vote.js +111 -0
  195. package/lib/eth1/utils/eth1Vote.js.map +1 -0
  196. package/lib/eth1/utils/groupDepositEventsByBlock.d.ts +9 -0
  197. package/lib/eth1/utils/groupDepositEventsByBlock.d.ts.map +1 -0
  198. package/lib/eth1/utils/groupDepositEventsByBlock.js +17 -0
  199. package/lib/eth1/utils/groupDepositEventsByBlock.js.map +1 -0
  200. package/lib/eth1/utils/optimizeNextBlockDiffForGenesis.d.ts +10 -0
  201. package/lib/eth1/utils/optimizeNextBlockDiffForGenesis.d.ts.map +1 -0
  202. package/lib/eth1/utils/optimizeNextBlockDiffForGenesis.js +14 -0
  203. package/lib/eth1/utils/optimizeNextBlockDiffForGenesis.js.map +1 -0
  204. package/lib/execution/engine/http.d.ts +1 -1
  205. package/lib/execution/engine/http.d.ts.map +1 -1
  206. package/lib/execution/engine/http.js +3 -2
  207. package/lib/execution/engine/http.js.map +1 -1
  208. package/lib/execution/engine/index.d.ts.map +1 -1
  209. package/lib/execution/engine/index.js +1 -1
  210. package/lib/execution/engine/index.js.map +1 -1
  211. package/lib/execution/engine/interface.d.ts +1 -1
  212. package/lib/execution/engine/interface.d.ts.map +1 -1
  213. package/lib/execution/engine/interface.js.map +1 -1
  214. package/lib/execution/engine/mock.d.ts.map +1 -1
  215. package/lib/execution/engine/mock.js +1 -1
  216. package/lib/execution/engine/mock.js.map +1 -1
  217. package/lib/execution/engine/payloadIdCache.d.ts +1 -1
  218. package/lib/execution/engine/payloadIdCache.d.ts.map +1 -1
  219. package/lib/execution/engine/types.d.ts +1 -1
  220. package/lib/execution/engine/types.d.ts.map +1 -1
  221. package/lib/execution/engine/types.js +1 -1
  222. package/lib/execution/engine/types.js.map +1 -1
  223. package/lib/execution/engine/utils.d.ts +2 -64
  224. package/lib/execution/engine/utils.d.ts.map +1 -1
  225. package/lib/execution/engine/utils.js +2 -91
  226. package/lib/execution/engine/utils.js.map +1 -1
  227. package/lib/index.d.ts +2 -1
  228. package/lib/index.d.ts.map +1 -1
  229. package/lib/index.js +2 -1
  230. package/lib/index.js.map +1 -1
  231. package/lib/metrics/metrics/lodestar.d.ts +35 -0
  232. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  233. package/lib/metrics/metrics/lodestar.js +90 -0
  234. package/lib/metrics/metrics/lodestar.js.map +1 -1
  235. package/lib/node/nodejs.d.ts.map +1 -1
  236. package/lib/node/nodejs.js +9 -10
  237. package/lib/node/nodejs.js.map +1 -1
  238. package/lib/node/options.d.ts +2 -0
  239. package/lib/node/options.d.ts.map +1 -1
  240. package/lib/node/options.js +2 -0
  241. package/lib/node/options.js.map +1 -1
  242. package/lib/node/utils/interop/deposits.d.ts +1 -2
  243. package/lib/node/utils/interop/deposits.d.ts.map +1 -1
  244. package/lib/node/utils/interop/deposits.js.map +1 -1
  245. package/lib/node/utils/interop/state.d.ts +1 -1
  246. package/lib/node/utils/interop/state.d.ts.map +1 -1
  247. package/lib/node/utils/state.d.ts +7 -1
  248. package/lib/node/utils/state.d.ts.map +1 -1
  249. package/lib/node/utils/state.js +14 -1
  250. package/lib/node/utils/state.js.map +1 -1
  251. package/lib/sync/backfill/backfill.d.ts.map +1 -1
  252. package/lib/sync/backfill/backfill.js +4 -2
  253. package/lib/sync/backfill/backfill.js.map +1 -1
  254. package/lib/sync/backfill/verify.d.ts +1 -1
  255. package/lib/sync/backfill/verify.d.ts.map +1 -1
  256. package/lib/sync/backfill/verify.js +2 -2
  257. package/lib/sync/backfill/verify.js.map +1 -1
  258. package/package.json +20 -14
  259. package/src/api/impl/beacon/blocks/utils.ts +1 -1
  260. package/src/chain/blocks/verifyBlock.ts +0 -1
  261. package/src/chain/blocks/verifyBlocksSignatures.ts +1 -3
  262. package/src/chain/chain.ts +19 -7
  263. package/src/chain/genesis/genesis.ts +190 -0
  264. package/src/chain/genesis/interface.ts +14 -0
  265. package/src/chain/initState.ts +97 -1
  266. package/src/chain/interface.ts +2 -0
  267. package/src/chain/opPools/aggregatedAttestationPool.ts +7 -7
  268. package/src/chain/opPools/opPool.ts +8 -8
  269. package/src/chain/prepareNextSlot.ts +28 -1
  270. package/src/chain/produceBlock/produceBlockBody.ts +12 -8
  271. package/src/chain/rewards/attestationsRewards.ts +4 -13
  272. package/src/chain/rewards/blockRewards.ts +3 -6
  273. package/src/chain/rewards/syncCommitteeRewards.ts +1 -3
  274. package/src/chain/stateCache/persistentCheckpointsCache.ts +2 -15
  275. package/src/chain/validation/attesterSlashing.ts +1 -1
  276. package/src/chain/validation/block.ts +1 -1
  277. package/src/chain/validation/blsToExecutionChange.ts +1 -1
  278. package/src/chain/validation/proposerSlashing.ts +1 -1
  279. package/src/chain/validation/signatureSets/aggregateAndProof.ts +1 -1
  280. package/src/chain/validation/signatureSets/contributionAndProof.ts +1 -3
  281. package/src/chain/validation/signatureSets/syncCommittee.ts +1 -3
  282. package/src/chain/validation/signatureSets/syncCommitteeContribution.ts +1 -3
  283. package/src/chain/validation/signatureSets/syncCommitteeSelectionProof.ts +1 -2
  284. package/src/chain/validation/syncCommittee.ts +1 -1
  285. package/src/chain/validation/syncCommitteeContributionAndProof.ts +3 -8
  286. package/src/chain/validation/voluntaryExit.ts +1 -1
  287. package/src/db/beacon.ts +16 -38
  288. package/src/db/buckets.ts +7 -12
  289. package/src/db/interface.ts +13 -2
  290. package/src/db/repositories/depositDataRoot.ts +80 -0
  291. package/src/db/repositories/depositEvent.ts +32 -0
  292. package/src/db/repositories/eth1Data.ts +33 -0
  293. package/src/db/repositories/index.ts +3 -0
  294. package/src/db/single/index.ts +2 -0
  295. package/src/db/single/preGenesisState.ts +37 -0
  296. package/src/db/single/preGenesisStateLastProcessedBlock.ts +34 -0
  297. package/src/eth1/errors.ts +40 -0
  298. package/src/eth1/eth1DataCache.ts +26 -0
  299. package/src/eth1/eth1DepositDataTracker.ts +410 -0
  300. package/src/eth1/eth1DepositsCache.ts +141 -0
  301. package/src/eth1/index.ts +94 -0
  302. package/src/eth1/interface.ts +87 -0
  303. package/src/eth1/options.ts +28 -0
  304. package/src/eth1/provider/eth1Provider.ts +229 -0
  305. package/src/{execution/engine → eth1/provider}/jsonRpcHttpClient.ts +1 -1
  306. package/src/eth1/provider/utils.ts +136 -0
  307. package/src/eth1/stream.ts +75 -0
  308. package/src/eth1/utils/depositContract.ts +37 -0
  309. package/src/eth1/utils/deposits.ts +70 -0
  310. package/src/eth1/utils/eth1Data.ts +100 -0
  311. package/src/eth1/utils/eth1DepositEvent.ts +12 -0
  312. package/src/eth1/utils/eth1Vote.ts +142 -0
  313. package/src/eth1/utils/groupDepositEventsByBlock.ts +19 -0
  314. package/src/eth1/utils/optimizeNextBlockDiffForGenesis.ts +18 -0
  315. package/src/execution/engine/http.ts +9 -8
  316. package/src/execution/engine/index.ts +1 -1
  317. package/src/execution/engine/interface.ts +1 -1
  318. package/src/execution/engine/mock.ts +2 -1
  319. package/src/execution/engine/payloadIdCache.ts +1 -1
  320. package/src/execution/engine/types.ts +9 -9
  321. package/src/execution/engine/utils.ts +5 -111
  322. package/src/index.ts +2 -1
  323. package/src/metrics/metrics/lodestar.ts +92 -0
  324. package/src/node/nodejs.ts +9 -11
  325. package/src/node/options.ts +3 -0
  326. package/src/node/utils/interop/deposits.ts +1 -3
  327. package/src/node/utils/interop/state.ts +1 -1
  328. package/src/node/utils/state.ts +18 -3
  329. package/src/sync/backfill/backfill.ts +3 -8
  330. package/src/sync/backfill/verify.ts +1 -3
  331. package/lib/execution/engine/jsonRpcHttpClient.d.ts.map +0 -1
  332. package/lib/execution/engine/jsonRpcHttpClient.js.map +0 -1
  333. package/lib/execution/engine/jwt.d.ts.map +0 -1
  334. package/lib/execution/engine/jwt.js.map +0 -1
  335. /package/lib/{execution/engine → eth1/provider}/jsonRpcHttpClient.js +0 -0
  336. /package/lib/{execution/engine → eth1/provider}/jwt.d.ts +0 -0
  337. /package/lib/{execution/engine → eth1/provider}/jwt.js +0 -0
  338. /package/src/{execution/engine → eth1/provider}/jwt.ts +0 -0
@@ -43,6 +43,7 @@ import {Logger, fromHex, gweiToWei, isErrorAborted, pruneSetToMax, sleep, toRoot
43
43
  import {ProcessShutdownCallback} from "@lodestar/validator";
44
44
  import {GENESIS_EPOCH, ZERO_HASH} from "../constants/index.js";
45
45
  import {IBeaconDb} from "../db/index.js";
46
+ import {IEth1ForBlockProduction} from "../eth1/index.js";
46
47
  import {BuilderStatus} from "../execution/builder/http.js";
47
48
  import {IExecutionBuilder, IExecutionEngine} from "../execution/index.js";
48
49
  import {Metrics} from "../metrics/index.js";
@@ -116,6 +117,7 @@ const DEFAULT_MAX_CACHED_PRODUCED_RESULTS = 4;
116
117
  export class BeaconChain implements IBeaconChain {
117
118
  readonly genesisTime: UintNum64;
118
119
  readonly genesisValidatorsRoot: Root;
120
+ readonly eth1: IEth1ForBlockProduction;
119
121
  readonly executionEngine: IExecutionEngine;
120
122
  readonly executionBuilder?: IExecutionBuilder;
121
123
  // Expose config for convenience in modularized functions
@@ -142,7 +144,7 @@ export class BeaconChain implements IBeaconChain {
142
144
  readonly aggregatedAttestationPool: AggregatedAttestationPool;
143
145
  readonly syncCommitteeMessagePool: SyncCommitteeMessagePool;
144
146
  readonly syncContributionAndProofPool;
145
- readonly opPool: OpPool;
147
+ readonly opPool = new OpPool();
146
148
 
147
149
  // Gossip seen cache
148
150
  readonly seenAttesters = new SeenAttesters();
@@ -214,6 +216,7 @@ export class BeaconChain implements IBeaconChain {
214
216
  validatorMonitor,
215
217
  anchorState,
216
218
  isAnchorStateFinalized,
219
+ eth1,
217
220
  executionEngine,
218
221
  executionBuilder,
219
222
  }: {
@@ -230,6 +233,7 @@ export class BeaconChain implements IBeaconChain {
230
233
  validatorMonitor: ValidatorMonitor | null;
231
234
  anchorState: BeaconStateAllForks;
232
235
  isAnchorStateFinalized: boolean;
236
+ eth1: IEth1ForBlockProduction;
233
237
  executionEngine: IExecutionEngine;
234
238
  executionBuilder?: IExecutionBuilder;
235
239
  }
@@ -244,6 +248,7 @@ export class BeaconChain implements IBeaconChain {
244
248
  this.genesisTime = anchorState.genesisTime;
245
249
  this.anchorStateLatestBlockSlot = anchorState.latestBlockHeader.slot;
246
250
  this.genesisValidatorsRoot = anchorState.genesisValidatorsRoot;
251
+ this.eth1 = eth1;
247
252
  this.executionEngine = executionEngine;
248
253
  this.executionBuilder = executionBuilder;
249
254
  const signal = this.abortController.signal;
@@ -260,7 +265,6 @@ export class BeaconChain implements IBeaconChain {
260
265
  this.aggregatedAttestationPool = new AggregatedAttestationPool(this.config, metrics);
261
266
  this.syncCommitteeMessagePool = new SyncCommitteeMessagePool(config, clock, this.opts?.preaggregateSlotDistance);
262
267
  this.syncContributionAndProofPool = new SyncContributionAndProofPool(config, clock, metrics, logger);
263
- this.opPool = new OpPool(config);
264
268
 
265
269
  this.seenAggregatedAttestations = new SeenAggregatedAttestations(metrics);
266
270
  this.seenContributionAndProof = new SeenContributionAndProof(metrics);
@@ -290,7 +294,7 @@ export class BeaconChain implements IBeaconChain {
290
294
  // Restore state caches
291
295
  // anchorState may already by a CachedBeaconState. If so, don't create the cache again, since deserializing all
292
296
  // pubkeys takes ~30 seconds for 350k keys (mainnet 2022Q2).
293
- // When the BeaconStateCache is created in initializeBeaconStateFromEth1 it may be incorrect. Until we can ensure that
297
+ // When the BeaconStateCache is created in eth1 genesis builder it may be incorrect. Until we can ensure that
294
298
  // it's safe to re-use _ANY_ BeaconStateCache, this option is disabled by default and only used in tests.
295
299
  const cachedState =
296
300
  isCachedBeaconState(anchorState) && opts.skipCreateStateCacheIfAvailable
@@ -335,7 +339,6 @@ export class BeaconChain implements IBeaconChain {
335
339
  this.cpStateDatastore = fileDataStore ? new FileCPStateDatastore(dataDir) : new DbCPStateDatastore(this.db);
336
340
  checkpointStateCache = new PersistentCheckpointStateCache(
337
341
  {
338
- config,
339
342
  metrics,
340
343
  logger,
341
344
  clock,
@@ -414,6 +417,15 @@ export class BeaconChain implements IBeaconChain {
414
417
  signal
415
418
  );
416
419
 
420
+ // Stop polling eth1 data if anchor state is in Electra AND deposit_requests_start_index is reached
421
+ const anchorStateFork = this.config.getForkName(anchorState.slot);
422
+ if (isForkPostElectra(anchorStateFork)) {
423
+ const {eth1DepositIndex, depositRequestsStartIndex} = anchorState as BeaconStateElectra;
424
+ if (eth1DepositIndex === Number(depositRequestsStartIndex)) {
425
+ this.eth1.stopPollingEth1Data();
426
+ }
427
+ }
428
+
417
429
  // always run PrepareNextSlotScheduler except for fork_choice spec tests
418
430
  if (!opts?.disablePrepareNextSlot) {
419
431
  new PrepareNextSlotScheduler(this, this.config, metrics, this.logger, signal);
@@ -1308,7 +1320,7 @@ export class BeaconChain implements IBeaconChain {
1308
1320
 
1309
1321
  const postState = this.regen.getStateSync(toRootHex(block.stateRoot)) ?? undefined;
1310
1322
 
1311
- return computeBlockRewards(this.config, block, preState.clone(), postState?.clone());
1323
+ return computeBlockRewards(block, preState.clone(), postState?.clone());
1312
1324
  }
1313
1325
 
1314
1326
  async getAttestationsRewards(
@@ -1332,7 +1344,7 @@ export class BeaconChain implements IBeaconChain {
1332
1344
  throw Error(`State is not in cache for slot ${slot}`);
1333
1345
  }
1334
1346
 
1335
- const rewards = await computeAttestationsRewards(this.config, this.pubkey2index, cachedState, validatorIds);
1347
+ const rewards = await computeAttestationsRewards(this.pubkey2index, cachedState, validatorIds);
1336
1348
 
1337
1349
  return {rewards, executionOptimistic, finalized};
1338
1350
  }
@@ -1349,6 +1361,6 @@ export class BeaconChain implements IBeaconChain {
1349
1361
 
1350
1362
  preState = processSlots(preState, block.slot); // Dial preState's slot to block.slot
1351
1363
 
1352
- return computeSyncCommitteeRewards(this.config, this.index2pubkey, block, preState.clone(), validatorIds);
1364
+ return computeSyncCommitteeRewards(this.index2pubkey, block, preState.clone(), validatorIds);
1353
1365
  }
1354
1366
  }
@@ -0,0 +1,190 @@
1
+ import {Tree, toGindex} from "@chainsafe/persistent-merkle-tree";
2
+ import {BeaconConfig, ChainForkConfig} from "@lodestar/config";
3
+ import {GENESIS_EPOCH, GENESIS_SLOT} from "@lodestar/params";
4
+ import {
5
+ BeaconStateAllForks,
6
+ CachedBeaconStateAllForks,
7
+ applyDeposits,
8
+ applyEth1BlockHash,
9
+ applyTimestamp,
10
+ createCachedBeaconState,
11
+ createEmptyEpochCacheImmutableData,
12
+ getActiveValidatorIndices,
13
+ getGenesisBeaconState,
14
+ getTemporaryBlockHeader,
15
+ } from "@lodestar/state-transition";
16
+ import {phase0, ssz} from "@lodestar/types";
17
+ import {Logger} from "@lodestar/utils";
18
+ import {DepositTree} from "../../db/repositories/depositDataRoot.js";
19
+ import {IEth1Provider} from "../../eth1/index.js";
20
+ import {IEth1StreamParams} from "../../eth1/interface.js";
21
+ import {getDepositsAndBlockStreamForGenesis, getDepositsStream} from "../../eth1/stream.js";
22
+ import {GenesisResult, IGenesisBuilder} from "./interface.js";
23
+
24
+ export type GenesisBuilderKwargs = {
25
+ config: ChainForkConfig;
26
+ eth1Provider: IEth1Provider;
27
+ logger: Logger;
28
+
29
+ /** Use to restore pending progress */
30
+ pendingStatus?: {
31
+ state: BeaconStateAllForks;
32
+ depositTree: DepositTree;
33
+ lastProcessedBlockNumber: number;
34
+ };
35
+
36
+ signal?: AbortSignal;
37
+ maxBlocksPerPoll?: number;
38
+ };
39
+
40
+ export class GenesisBuilder implements IGenesisBuilder {
41
+ // Expose state to persist on error
42
+ readonly state: CachedBeaconStateAllForks;
43
+ readonly depositTree: DepositTree;
44
+ /** Is null if no block has been processed yet */
45
+ lastProcessedBlockNumber: number | null = null;
46
+
47
+ private readonly config: BeaconConfig;
48
+ private readonly eth1Provider: IEth1Provider;
49
+ private readonly logger: Logger;
50
+ private readonly signal?: AbortSignal;
51
+ private readonly eth1Params: IEth1StreamParams;
52
+ private readonly depositCache = new Set<number>();
53
+ private readonly fromBlock: number;
54
+ private readonly logEvery = 30 * 1000;
55
+ private lastLog = 0;
56
+ /** Current count of active validators in the state */
57
+ private activatedValidatorCount: number;
58
+
59
+ constructor({config, eth1Provider, logger, signal, pendingStatus, maxBlocksPerPoll}: GenesisBuilderKwargs) {
60
+ // at genesis builder, there is no genesis validator so we don't have a real BeaconConfig
61
+ // but we need BeaconConfig to temporarily create CachedBeaconState, the cast here is safe since we don't use any getDomain here
62
+ // the use of state as CachedBeaconState is just for convenient, GenesisResult returns TreeView anyway
63
+ this.eth1Provider = eth1Provider;
64
+ this.logger = logger;
65
+ this.signal = signal;
66
+ this.eth1Params = {
67
+ ...config,
68
+ maxBlocksPerPoll: maxBlocksPerPoll ?? 10000,
69
+ };
70
+
71
+ let stateView: BeaconStateAllForks;
72
+
73
+ if (pendingStatus) {
74
+ this.logger.info("Restoring pending genesis state", {block: pendingStatus.lastProcessedBlockNumber});
75
+ stateView = pendingStatus.state;
76
+ this.depositTree = pendingStatus.depositTree;
77
+ this.fromBlock = Math.max(pendingStatus.lastProcessedBlockNumber + 1, this.eth1Provider.deployBlock);
78
+ } else {
79
+ stateView = getGenesisBeaconState(
80
+ config,
81
+ ssz.phase0.Eth1Data.defaultValue(),
82
+ getTemporaryBlockHeader(config, config.getForkTypes(GENESIS_SLOT).BeaconBlock.defaultValue())
83
+ );
84
+ this.depositTree = ssz.phase0.DepositDataRootList.defaultViewDU();
85
+ this.fromBlock = this.eth1Provider.deployBlock;
86
+ }
87
+
88
+ // TODO - PENDING: Ensure EpochCacheImmutableData is created only once
89
+ this.state = createCachedBeaconState(stateView, createEmptyEpochCacheImmutableData(config, stateView));
90
+ this.config = this.state.config;
91
+ this.activatedValidatorCount = getActiveValidatorIndices(stateView, GENESIS_EPOCH).length;
92
+ }
93
+
94
+ /**
95
+ * Get eth1 deposit events and blocks and apply to this.state until we found genesis.
96
+ */
97
+ async waitForGenesis(): Promise<GenesisResult> {
98
+ await this.eth1Provider.validateContract();
99
+
100
+ // Load data from data from this.db.depositData, this.db.depositDataRoot
101
+ // And start from a more recent fromBlock
102
+ const blockNumberValidatorGenesis = await this.waitForGenesisValidators();
103
+
104
+ const depositsAndBlocksStream = getDepositsAndBlockStreamForGenesis(
105
+ blockNumberValidatorGenesis,
106
+ this.eth1Provider,
107
+ this.eth1Params,
108
+ this.signal
109
+ );
110
+
111
+ for await (const [depositEvents, block] of depositsAndBlocksStream) {
112
+ this.applyDeposits(depositEvents);
113
+ applyTimestamp(this.config, this.state, block.timestamp);
114
+ applyEth1BlockHash(this.state, block.blockHash);
115
+ this.lastProcessedBlockNumber = block.blockNumber;
116
+
117
+ if (
118
+ this.state.genesisTime >= this.config.MIN_GENESIS_TIME &&
119
+ this.activatedValidatorCount >= this.config.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT
120
+ ) {
121
+ this.logger.info("Found genesis state", {blockNumber: block.blockNumber});
122
+ return {
123
+ state: this.state,
124
+ depositTree: this.depositTree,
125
+ block,
126
+ };
127
+ }
128
+
129
+ this.throttledLog(`Waiting for min genesis time ${block.timestamp} / ${this.config.MIN_GENESIS_TIME}`);
130
+ }
131
+
132
+ throw Error("depositsStream stopped without a valid genesis state");
133
+ }
134
+
135
+ /**
136
+ * First phase of waiting for genesis.
137
+ * Stream deposits events in batches as big as possible without querying block data
138
+ * @returns Block number at which there are enough active validators is state for genesis
139
+ */
140
+ private async waitForGenesisValidators(): Promise<number> {
141
+ const depositsStream = getDepositsStream(this.fromBlock, this.eth1Provider, this.eth1Params, this.signal);
142
+
143
+ for await (const {depositEvents, blockNumber} of depositsStream) {
144
+ this.applyDeposits(depositEvents);
145
+ this.lastProcessedBlockNumber = blockNumber;
146
+
147
+ if (this.activatedValidatorCount >= this.config.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT) {
148
+ this.logger.info("Found enough genesis validators", {blockNumber});
149
+ return blockNumber;
150
+ }
151
+
152
+ this.throttledLog(
153
+ `Found ${this.state.validators.length} / ${this.config.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT} validators to genesis`
154
+ );
155
+ }
156
+
157
+ throw Error("depositsStream stopped without a valid genesis state");
158
+ }
159
+
160
+ private applyDeposits(depositEvents: phase0.DepositEvent[]): void {
161
+ const newDeposits = depositEvents
162
+ .filter((depositEvent) => !this.depositCache.has(depositEvent.index))
163
+ .map((depositEvent) => {
164
+ this.depositCache.add(depositEvent.index);
165
+ this.depositTree.push(ssz.phase0.DepositData.hashTreeRoot(depositEvent.depositData));
166
+ const gindex = toGindex(this.depositTree.type.depth, BigInt(depositEvent.index));
167
+
168
+ // Apply changes from the push above
169
+ this.depositTree.commit();
170
+ const depositTreeNode = this.depositTree.node;
171
+ return {
172
+ proof: new Tree(depositTreeNode).getSingleProof(gindex),
173
+ data: depositEvent.depositData,
174
+ };
175
+ });
176
+
177
+ const {activatedValidatorCount} = applyDeposits(this.config, this.state, newDeposits, this.depositTree);
178
+ this.activatedValidatorCount += activatedValidatorCount;
179
+
180
+ // TODO: If necessary persist deposits here to this.db.depositData, this.db.depositDataRoot
181
+ }
182
+
183
+ /** Throttle genesis generation status log to prevent spamming */
184
+ private throttledLog(message: string): void {
185
+ if (Date.now() - this.lastLog > this.logEvery) {
186
+ this.lastLog = Date.now();
187
+ this.logger.info(message);
188
+ }
189
+ }
190
+ }
@@ -0,0 +1,14 @@
1
+ import {CompositeViewDU, VectorCompositeType} from "@chainsafe/ssz";
2
+ import {CachedBeaconStateAllForks} from "@lodestar/state-transition";
3
+ import {ssz} from "@lodestar/types";
4
+ import {Eth1Block} from "../../eth1/interface.js";
5
+
6
+ export type GenesisResult = {
7
+ state: CachedBeaconStateAllForks;
8
+ depositTree: CompositeViewDU<VectorCompositeType<typeof ssz.Root>>;
9
+ block: Eth1Block;
10
+ };
11
+
12
+ export interface IGenesisBuilder {
13
+ waitForGenesis: () => Promise<GenesisResult>;
14
+ }
@@ -1,11 +1,37 @@
1
1
  import {ChainForkConfig} from "@lodestar/config";
2
2
  import {ZERO_HASH} from "@lodestar/params";
3
- import {BeaconStateAllForks, computeEpochAtSlot, computeStartSlotAtEpoch} from "@lodestar/state-transition";
3
+ import {
4
+ BeaconStateAllForks,
5
+ CachedBeaconStateAllForks,
6
+ computeEpochAtSlot,
7
+ computeStartSlotAtEpoch,
8
+ } from "@lodestar/state-transition";
4
9
  import {SignedBeaconBlock, ssz} from "@lodestar/types";
5
10
  import {Logger, toHex, toRootHex} from "@lodestar/utils";
6
11
  import {GENESIS_SLOT} from "../constants/index.js";
7
12
  import {IBeaconDb} from "../db/index.js";
13
+ import {Eth1Provider} from "../eth1/index.js";
14
+ import {Eth1Options} from "../eth1/options.js";
8
15
  import {Metrics} from "../metrics/index.js";
16
+ import {GenesisBuilder} from "./genesis/genesis.js";
17
+ import {GenesisResult} from "./genesis/interface.js";
18
+
19
+ export async function persistGenesisResult(
20
+ db: IBeaconDb,
21
+ genesisResult: GenesisResult,
22
+ genesisBlock: SignedBeaconBlock
23
+ ): Promise<void> {
24
+ await Promise.all([
25
+ db.stateArchive.add(genesisResult.state),
26
+ db.blockArchive.add(genesisBlock),
27
+ db.depositDataRoot.putList(genesisResult.depositTree.getAllReadonlyValues()),
28
+ db.eth1Data.put(genesisResult.block.timestamp, {
29
+ ...genesisResult.block,
30
+ depositCount: genesisResult.depositTree.length,
31
+ depositRoot: genesisResult.depositTree.hashTreeRoot(),
32
+ }),
33
+ ]);
34
+ }
9
35
 
10
36
  export async function persistAnchorState(
11
37
  config: ChainForkConfig,
@@ -49,6 +75,76 @@ export function createGenesisBlock(config: ChainForkConfig, genesisState: Beacon
49
75
  return genesisBlock;
50
76
  }
51
77
 
78
+ /**
79
+ * Initialize and persist a genesis state and related data
80
+ */
81
+ export async function initStateFromEth1({
82
+ config,
83
+ db,
84
+ logger,
85
+ opts,
86
+ signal,
87
+ }: {
88
+ config: ChainForkConfig;
89
+ db: IBeaconDb;
90
+ logger: Logger;
91
+ opts: Eth1Options;
92
+ signal: AbortSignal;
93
+ }): Promise<CachedBeaconStateAllForks> {
94
+ logger.info("Listening to eth1 for genesis state");
95
+
96
+ const statePreGenesis = await db.preGenesisState.get();
97
+ const depositTree = await db.depositDataRoot.getDepositRootTree();
98
+ const lastProcessedBlockNumber = await db.preGenesisStateLastProcessedBlock.get();
99
+
100
+ const builder = new GenesisBuilder({
101
+ config,
102
+ eth1Provider: new Eth1Provider(config, {...opts, logger}, signal),
103
+ logger,
104
+ signal,
105
+ pendingStatus:
106
+ statePreGenesis && depositTree !== undefined && lastProcessedBlockNumber != null
107
+ ? {state: statePreGenesis, depositTree, lastProcessedBlockNumber}
108
+ : undefined,
109
+ });
110
+
111
+ try {
112
+ const genesisResult = await builder.waitForGenesis();
113
+
114
+ // Note: .hashTreeRoot() automatically commits()
115
+ const genesisBlock = createGenesisBlock(config, genesisResult.state);
116
+ const types = config.getForkTypes(GENESIS_SLOT);
117
+ const stateRoot = genesisResult.state.hashTreeRoot();
118
+ const blockRoot = types.BeaconBlock.hashTreeRoot(genesisBlock.message);
119
+
120
+ logger.info("Initializing genesis state", {
121
+ stateRoot: toRootHex(stateRoot),
122
+ blockRoot: toRootHex(blockRoot),
123
+ validatorCount: genesisResult.state.validators.length,
124
+ });
125
+
126
+ await persistGenesisResult(db, genesisResult, genesisBlock);
127
+
128
+ logger.verbose("Clearing pending genesis state if any");
129
+ await db.preGenesisState.delete();
130
+ await db.preGenesisStateLastProcessedBlock.delete();
131
+
132
+ return genesisResult.state;
133
+ } catch (e) {
134
+ if (builder.lastProcessedBlockNumber != null) {
135
+ logger.info("Persisting genesis state", {block: builder.lastProcessedBlockNumber});
136
+
137
+ // Commit changed before serializing
138
+ builder.state.commit();
139
+
140
+ await db.preGenesisState.put(builder.state);
141
+ await db.depositDataRoot.putList(builder.depositTree.getAllReadonlyValues());
142
+ await db.preGenesisStateLastProcessedBlock.put(builder.lastProcessedBlockNumber);
143
+ }
144
+ throw e;
145
+ }
146
+ }
147
+
52
148
  /**
53
149
  * Restore the latest beacon state from db
54
150
  */
@@ -25,6 +25,7 @@ import {
25
25
  phase0,
26
26
  } from "@lodestar/types";
27
27
  import {Logger} from "@lodestar/utils";
28
+ import {IEth1ForBlockProduction} from "../eth1/index.js";
28
29
  import {IExecutionBuilder, IExecutionEngine} from "../execution/index.js";
29
30
  import {Metrics} from "../metrics/metrics.js";
30
31
  import {BufferPool} from "../util/bufferPool.js";
@@ -87,6 +88,7 @@ export interface IBeaconChain {
87
88
  readonly genesisTime: UintNum64;
88
89
  readonly genesisValidatorsRoot: Root;
89
90
  readonly earliestAvailableSlot: Slot;
91
+ readonly eth1: IEth1ForBlockProduction;
90
92
  readonly executionEngine: IExecutionEngine;
91
93
  readonly executionBuilder?: IExecutionBuilder;
92
94
  // Expose config for convenience in modularized functions
@@ -1,6 +1,6 @@
1
1
  import {Signature, aggregateSignatures} from "@chainsafe/blst";
2
2
  import {BitArray} from "@chainsafe/ssz";
3
- import {BeaconConfig} from "@lodestar/config";
3
+ import {ChainForkConfig} from "@lodestar/config";
4
4
  import {IForkChoice} from "@lodestar/fork-choice";
5
5
  import {
6
6
  ForkName,
@@ -162,7 +162,7 @@ export class AggregatedAttestationPool {
162
162
  private lowestPermissibleSlot = 0;
163
163
 
164
164
  constructor(
165
- private readonly config: BeaconConfig,
165
+ private readonly config: ChainForkConfig,
166
166
  private readonly metrics: Metrics | null = null
167
167
  ) {
168
168
  metrics?.opPool.aggregatedAttestationPool.attDataPerSlot.addCollect(() => this.onScrapeMetrics(metrics));
@@ -249,7 +249,7 @@ export class AggregatedAttestationPool {
249
249
  const stateEpoch = state.epochCtx.epoch;
250
250
  const statePrevEpoch = stateEpoch - 1;
251
251
 
252
- const notSeenValidatorsFn = getNotSeenValidatorsFn(this.config, state);
252
+ const notSeenValidatorsFn = getNotSeenValidatorsFn(state);
253
253
  const validateAttestationDataFn = getValidateAttestationDataFn(forkChoice, state);
254
254
 
255
255
  const attestationsByScore: AttestationWithScore[] = [];
@@ -362,7 +362,7 @@ export class AggregatedAttestationPool {
362
362
  const statePrevEpoch = stateEpoch - 1;
363
363
  const rootCache = new RootCache(state);
364
364
 
365
- const notSeenValidatorsFn = getNotSeenValidatorsFn(this.config, state);
365
+ const notSeenValidatorsFn = getNotSeenValidatorsFn(state);
366
366
  const validateAttestationDataFn = getValidateAttestationDataFn(forkChoice, state);
367
367
 
368
368
  const slots = Array.from(this.attestationGroupByIndexByDataHexBySlot.keys()).sort((a, b) => b - a);
@@ -656,7 +656,7 @@ export class MatchingDataAttestationGroup {
656
656
  private readonly attestations: AttestationWithIndex[] = [];
657
657
 
658
658
  constructor(
659
- private readonly config: BeaconConfig,
659
+ private readonly config: ChainForkConfig,
660
660
  readonly committee: Uint32Array,
661
661
  readonly data: phase0.AttestationData
662
662
  ) {}
@@ -864,9 +864,9 @@ export function aggregateConsolidation({byCommittee, attData}: AttestationsConso
864
864
  * Pre-compute participation from a CachedBeaconStateAllForks, for use to check if an attestation's committee
865
865
  * has already attested or not.
866
866
  */
867
- export function getNotSeenValidatorsFn(config: BeaconConfig, state: CachedBeaconStateAllForks): GetNotSeenValidatorsFn {
867
+ export function getNotSeenValidatorsFn(state: CachedBeaconStateAllForks): GetNotSeenValidatorsFn {
868
868
  const stateSlot = state.slot;
869
- if (config.getForkName(stateSlot) === ForkName.phase0) {
869
+ if (state.config.getForkName(stateSlot) === ForkName.phase0) {
870
870
  // Get attestations to be included in a phase0 block.
871
871
  // As we are close to altair, this is not really important, it's mainly for e2e.
872
872
  // The performance is not great due to the different BeaconState data structure to altair.
@@ -1,4 +1,3 @@
1
- import {BeaconConfig} from "@lodestar/config";
2
1
  import {Id, Repository} from "@lodestar/db";
3
2
  import {
4
3
  BLS_WITHDRAWAL_PREFIX,
@@ -52,8 +51,6 @@ export class OpPool {
52
51
  /** Map of validator index -> SignedBLSToExecutionChange */
53
52
  private readonly blsToExecutionChanges = new Map<ValidatorIndex, SignedBLSToExecutionChangeVersioned>();
54
53
 
55
- constructor(private readonly config: BeaconConfig) {}
56
-
57
54
  // Getters for metrics
58
55
 
59
56
  get attesterSlashingsSize(): number {
@@ -194,8 +191,9 @@ export class OpPool {
194
191
  phase0.SignedVoluntaryExit[],
195
192
  capella.SignedBLSToExecutionChange[],
196
193
  ] {
194
+ const {config} = state;
197
195
  const stateEpoch = computeEpochAtSlot(state.slot);
198
- const stateFork = this.config.getForkSeq(state.slot);
196
+ const stateFork = config.getForkSeq(state.slot);
199
197
  const toBeSlashedIndices = new Set<ValidatorIndex>();
200
198
  const proposerSlashings: phase0.ProposerSlashing[] = [];
201
199
 
@@ -267,7 +265,7 @@ export class OpPool {
267
265
  // a future fork.
268
266
  isVoluntaryExitSignatureIncludable(
269
267
  stateFork,
270
- this.config.getForkSeq(computeStartSlotAtEpoch(voluntaryExit.message.epoch))
268
+ config.getForkSeq(computeStartSlotAtEpoch(voluntaryExit.message.epoch))
271
269
  )
272
270
  ) {
273
271
  voluntaryExits.push(voluntaryExit);
@@ -370,13 +368,14 @@ export class OpPool {
370
368
  * Prune if validator has already exited at or before the finalized checkpoint of the head.
371
369
  */
372
370
  private pruneVoluntaryExits(headState: CachedBeaconStateAllForks): void {
373
- const headStateFork = this.config.getForkSeq(headState.slot);
371
+ const {config} = headState;
372
+ const headStateFork = config.getForkSeq(headState.slot);
374
373
  const finalizedEpoch = headState.finalizedCheckpoint.epoch;
375
374
 
376
375
  for (const [key, voluntaryExit] of this.voluntaryExits.entries()) {
377
376
  // VoluntaryExit messages signed in the previous fork become invalid and can never be included in any future
378
377
  // block, so just drop as the head state advances into the next fork.
379
- if (this.config.getForkSeq(computeStartSlotAtEpoch(voluntaryExit.message.epoch)) < headStateFork) {
378
+ if (config.getForkSeq(computeStartSlotAtEpoch(voluntaryExit.message.epoch)) < headStateFork) {
380
379
  this.voluntaryExits.delete(key);
381
380
  }
382
381
 
@@ -393,8 +392,9 @@ export class OpPool {
393
392
  * to opPool once gossipsub seen cache TTL passes.
394
393
  */
395
394
  private pruneBlsToExecutionChanges(headBlock: SignedBeaconBlock, headState: CachedBeaconStateAllForks): void {
395
+ const {config} = headState;
396
396
  const recentBlsToExecutionChanges =
397
- this.config.getForkSeq(headBlock.message.slot) >= ForkSeq.capella
397
+ config.getForkSeq(headBlock.message.slot) >= ForkSeq.capella
398
398
  ? (headBlock as capella.SignedBeaconBlock).message.body.blsToExecutionChanges
399
399
  : [];
400
400
 
@@ -1,8 +1,9 @@
1
1
  import {routes} from "@lodestar/api";
2
2
  import {ChainForkConfig} from "@lodestar/config";
3
3
  import {getSafeExecutionBlockHash} from "@lodestar/fork-choice";
4
- import {ForkPostBellatrix, ForkSeq, SLOTS_PER_EPOCH} from "@lodestar/params";
4
+ import {ForkPostBellatrix, ForkSeq, SLOTS_PER_EPOCH, isForkPostElectra} from "@lodestar/params";
5
5
  import {
6
+ BeaconStateElectra,
6
7
  CachedBeaconStateAllForks,
7
8
  CachedBeaconStateExecutions,
8
9
  StateHashTreeRootSource,
@@ -221,6 +222,9 @@ export class PrepareNextSlotScheduler {
221
222
  }
222
223
  this.metrics?.precomputeNextEpochTransition.hits.set(previousHits ?? 0);
223
224
 
225
+ // Check if we can stop polling eth1 data
226
+ this.stopEth1Polling();
227
+
224
228
  this.logger.verbose("Completed PrepareNextSlotScheduler epoch transition", {
225
229
  nextEpoch,
226
230
  headSlot,
@@ -248,4 +252,27 @@ export class PrepareNextSlotScheduler {
248
252
  state.hashTreeRoot();
249
253
  hashTreeRootTimer?.();
250
254
  }
255
+
256
+ /**
257
+ * Stop eth1 data polling after eth1_deposit_index has reached deposit_requests_start_index in Electra as described in EIP-6110
258
+ */
259
+ stopEth1Polling(): void {
260
+ // Only continue if eth1 is still polling and finalized checkpoint is in Electra. State regen is expensive
261
+ if (this.chain.eth1.isPollingEth1Data()) {
262
+ const finalizedCheckpoint = this.chain.forkChoice.getFinalizedCheckpoint();
263
+ const checkpointFork = this.config.getForkInfoAtEpoch(finalizedCheckpoint.epoch).name;
264
+
265
+ if (isForkPostElectra(checkpointFork)) {
266
+ const finalizedState = this.chain.getStateByCheckpoint(finalizedCheckpoint)?.state;
267
+
268
+ if (
269
+ finalizedState !== undefined &&
270
+ finalizedState.eth1DepositIndex === Number((finalizedState as BeaconStateElectra).depositRequestsStartIndex)
271
+ ) {
272
+ // Signal eth1 to stop polling eth1Data
273
+ this.chain.eth1.stopPollingEth1Data();
274
+ }
275
+ }
276
+ }
277
+ }
251
278
  }
@@ -45,7 +45,7 @@ import {
45
45
  } from "@lodestar/types";
46
46
  import {Logger, sleep, toHex, toPubkeyHex, toRootHex} from "@lodestar/utils";
47
47
  import {ZERO_HASH_HEX} from "../../constants/index.js";
48
- import {numToQuantity} from "../../execution/engine/utils.js";
48
+ import {numToQuantity} from "../../eth1/provider/utils.js";
49
49
  import {
50
50
  IExecutionBuilder,
51
51
  IExecutionEngine,
@@ -78,6 +78,7 @@ export enum BlockProductionStep {
78
78
  voluntaryExits = "voluntaryExits",
79
79
  blsToExecutionChanges = "blsToExecutionChanges",
80
80
  attestations = "attestations",
81
+ eth1DataAndDeposits = "eth1DataAndDeposits",
81
82
  syncAggregate = "syncAggregate",
82
83
  executionPayload = "executionPayload",
83
84
  }
@@ -165,7 +166,7 @@ export async function produceBlockBody<T extends BlockType>(
165
166
  // even though shouldOverrideBuilder is relevant for the engine response, for simplicity of typing
166
167
  // we just return it undefined for the builder which anyway doesn't get consumed downstream
167
168
  let shouldOverrideBuilder: boolean | undefined;
168
- const fork = this.config.getForkName(blockSlot);
169
+ const fork = currentState.config.getForkName(blockSlot);
169
170
  const produceResult = {
170
171
  type: blockType,
171
172
  fork,
@@ -644,7 +645,7 @@ export async function produceCommonBlockBody<T extends BlockType>(
644
645
  ? this.metrics?.executionBlockProductionTimeSteps
645
646
  : this.metrics?.builderBlockProductionTimeSteps;
646
647
 
647
- const fork = this.config.getForkName(slot);
648
+ const fork = currentState.config.getForkName(slot);
648
649
 
649
650
  // TODO:
650
651
  // Iterate through the naive aggregation pool and ensure all the attestations from there
@@ -666,17 +667,20 @@ export async function produceCommonBlockBody<T extends BlockType>(
666
667
  step: BlockProductionStep.attestations,
667
668
  });
668
669
 
670
+ const endEth1DataAndDeposits = stepsMetrics?.startTimer();
671
+ const {eth1Data, deposits} = await this.eth1.getEth1DataAndDeposits(currentState);
672
+ endEth1DataAndDeposits?.({
673
+ step: BlockProductionStep.eth1DataAndDeposits,
674
+ });
675
+
669
676
  const blockBody: Omit<CommonBlockBody, "blsToExecutionChanges" | "syncAggregate"> = {
670
677
  randaoReveal,
671
678
  graffiti,
672
- // Eth1 data voting is no longer required since electra
673
- eth1Data: currentState.eth1Data,
679
+ eth1Data,
674
680
  proposerSlashings,
675
681
  attesterSlashings,
676
682
  attestations,
677
- // Since electra, deposits are processed by the execution layer,
678
- // we no longer support handling deposits from earlier forks.
679
- deposits: [],
683
+ deposits,
680
684
  voluntaryExits,
681
685
  };
682
686