@lodestar/beacon-node 1.41.0-dev.d41697c085 → 1.41.0-dev.dce096d70c

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 (367) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +123 -4
  3. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  4. package/lib/api/impl/beacon/state/index.js +8 -8
  5. package/lib/api/impl/beacon/state/index.js.map +1 -1
  6. package/lib/api/impl/beacon/state/utils.d.ts +3 -4
  7. package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
  8. package/lib/api/impl/beacon/state/utils.js +5 -24
  9. package/lib/api/impl/beacon/state/utils.js.map +1 -1
  10. package/lib/api/impl/debug/index.d.ts.map +1 -1
  11. package/lib/api/impl/debug/index.js +6 -2
  12. package/lib/api/impl/debug/index.js.map +1 -1
  13. package/lib/api/impl/node/utils.d.ts +1 -1
  14. package/lib/api/impl/node/utils.d.ts.map +1 -1
  15. package/lib/api/impl/node/utils.js.map +1 -1
  16. package/lib/api/impl/validator/index.d.ts.map +1 -1
  17. package/lib/api/impl/validator/index.js +130 -16
  18. package/lib/api/impl/validator/index.js.map +1 -1
  19. package/lib/chain/archiveStore/archiveStore.d.ts +1 -0
  20. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  21. package/lib/chain/archiveStore/archiveStore.js +9 -0
  22. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  23. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts +5 -6
  24. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
  25. package/lib/chain/archiveStore/historicalState/getHistoricalState.js +9 -10
  26. package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
  27. package/lib/chain/archiveStore/historicalState/worker.js +3 -3
  28. package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
  29. package/lib/chain/archiveStore/utils/archivePayloads.d.ts +7 -0
  30. package/lib/chain/archiveStore/utils/archivePayloads.d.ts.map +1 -0
  31. package/lib/chain/archiveStore/utils/archivePayloads.js +10 -0
  32. package/lib/chain/archiveStore/utils/archivePayloads.js.map +1 -0
  33. package/lib/chain/archiveStore/utils/updateBackfillRange.js +1 -1
  34. package/lib/chain/archiveStore/utils/updateBackfillRange.js.map +1 -1
  35. package/lib/chain/blocks/blockInput/blockInput.d.ts +20 -2
  36. package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
  37. package/lib/chain/blocks/blockInput/blockInput.js +47 -0
  38. package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
  39. package/lib/chain/blocks/blockInput/types.d.ts +13 -1
  40. package/lib/chain/blocks/blockInput/types.d.ts.map +1 -1
  41. package/lib/chain/blocks/blockInput/types.js +1 -0
  42. package/lib/chain/blocks/blockInput/types.js.map +1 -1
  43. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  44. package/lib/chain/blocks/importBlock.js +27 -4
  45. package/lib/chain/blocks/importBlock.js.map +1 -1
  46. package/lib/chain/blocks/index.d.ts.map +1 -1
  47. package/lib/chain/blocks/index.js +2 -1
  48. package/lib/chain/blocks/index.js.map +1 -1
  49. package/lib/chain/blocks/verifyBlocksDataAvailability.d.ts.map +1 -1
  50. package/lib/chain/blocks/verifyBlocksDataAvailability.js +3 -0
  51. package/lib/chain/blocks/verifyBlocksDataAvailability.js.map +1 -1
  52. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts +4 -0
  53. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
  54. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +5 -1
  55. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
  56. package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts.map +1 -1
  57. package/lib/chain/blocks/verifyBlocksSanityChecks.js +4 -1
  58. package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
  59. package/lib/chain/blocks/writeBlockInputToDb.d.ts +12 -3
  60. package/lib/chain/blocks/writeBlockInputToDb.d.ts.map +1 -1
  61. package/lib/chain/blocks/writeBlockInputToDb.js +101 -96
  62. package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
  63. package/lib/chain/bls/multithread/index.d.ts +3 -3
  64. package/lib/chain/bls/multithread/index.d.ts.map +1 -1
  65. package/lib/chain/bls/multithread/index.js +5 -5
  66. package/lib/chain/bls/multithread/index.js.map +1 -1
  67. package/lib/chain/bls/multithread/jobItem.d.ts +2 -2
  68. package/lib/chain/bls/multithread/jobItem.d.ts.map +1 -1
  69. package/lib/chain/bls/multithread/jobItem.js +2 -2
  70. package/lib/chain/bls/multithread/jobItem.js.map +1 -1
  71. package/lib/chain/bls/singleThread.d.ts +4 -4
  72. package/lib/chain/bls/singleThread.d.ts.map +1 -1
  73. package/lib/chain/bls/singleThread.js +4 -4
  74. package/lib/chain/bls/singleThread.js.map +1 -1
  75. package/lib/chain/bls/utils.d.ts +2 -2
  76. package/lib/chain/bls/utils.d.ts.map +1 -1
  77. package/lib/chain/bls/utils.js +7 -4
  78. package/lib/chain/bls/utils.js.map +1 -1
  79. package/lib/chain/chain.d.ts +7 -10
  80. package/lib/chain/chain.d.ts.map +1 -1
  81. package/lib/chain/chain.js +40 -24
  82. package/lib/chain/chain.js.map +1 -1
  83. package/lib/chain/emitter.d.ts +5 -5
  84. package/lib/chain/emitter.d.ts.map +1 -1
  85. package/lib/chain/errors/executionPayloadEnvelope.d.ts +2 -2
  86. package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
  87. package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
  88. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  89. package/lib/chain/forkChoice/index.js +30 -24
  90. package/lib/chain/forkChoice/index.js.map +1 -1
  91. package/lib/chain/interface.d.ts +4 -6
  92. package/lib/chain/interface.d.ts.map +1 -1
  93. package/lib/chain/interface.js.map +1 -1
  94. package/lib/chain/opPools/aggregatedAttestationPool.js +1 -1
  95. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  96. package/lib/chain/options.d.ts.map +1 -1
  97. package/lib/chain/options.js.map +1 -1
  98. package/lib/chain/prepareNextSlot.js +3 -3
  99. package/lib/chain/prepareNextSlot.js.map +1 -1
  100. package/lib/chain/produceBlock/computeNewStateRoot.d.ts +10 -2
  101. package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
  102. package/lib/chain/produceBlock/computeNewStateRoot.js +24 -2
  103. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  104. package/lib/chain/produceBlock/produceBlockBody.d.ts +22 -7
  105. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  106. package/lib/chain/produceBlock/produceBlockBody.js +109 -10
  107. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  108. package/lib/chain/regen/queued.d.ts.map +1 -1
  109. package/lib/chain/regen/queued.js +4 -1
  110. package/lib/chain/regen/queued.js.map +1 -1
  111. package/lib/chain/regen/regen.d.ts.map +1 -1
  112. package/lib/chain/regen/regen.js +5 -1
  113. package/lib/chain/regen/regen.js.map +1 -1
  114. package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
  115. package/lib/chain/seenCache/seenGossipBlockInput.js +15 -7
  116. package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
  117. package/lib/chain/validation/aggregateAndProof.js +1 -1
  118. package/lib/chain/validation/aggregateAndProof.js.map +1 -1
  119. package/lib/chain/validation/attestation.d.ts.map +1 -1
  120. package/lib/chain/validation/attestation.js +7 -4
  121. package/lib/chain/validation/attestation.js.map +1 -1
  122. package/lib/chain/validation/attesterSlashing.d.ts.map +1 -1
  123. package/lib/chain/validation/attesterSlashing.js +9 -2
  124. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  125. package/lib/chain/validation/blobSidecar.js +2 -2
  126. package/lib/chain/validation/blobSidecar.js.map +1 -1
  127. package/lib/chain/validation/block.d.ts.map +1 -1
  128. package/lib/chain/validation/block.js +6 -3
  129. package/lib/chain/validation/block.js.map +1 -1
  130. package/lib/chain/validation/dataColumnSidecar.d.ts +2 -2
  131. package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
  132. package/lib/chain/validation/dataColumnSidecar.js +1 -1
  133. package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
  134. package/lib/chain/validation/executionPayloadBid.js +1 -2
  135. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  136. package/lib/chain/validation/executionPayloadEnvelope.js +4 -4
  137. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
  138. package/lib/chain/validation/payloadAttestationMessage.js +9 -3
  139. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  140. package/lib/chain/validation/proposerSlashing.js +1 -1
  141. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  142. package/lib/chain/validation/syncCommitteeContributionAndProof.js +1 -1
  143. package/lib/db/beacon.d.ts +3 -1
  144. package/lib/db/beacon.d.ts.map +1 -1
  145. package/lib/db/beacon.js +5 -1
  146. package/lib/db/beacon.js.map +1 -1
  147. package/lib/db/buckets.d.ts +3 -1
  148. package/lib/db/buckets.d.ts.map +1 -1
  149. package/lib/db/buckets.js +2 -0
  150. package/lib/db/buckets.js.map +1 -1
  151. package/lib/db/interface.d.ts +3 -1
  152. package/lib/db/interface.d.ts.map +1 -1
  153. package/lib/db/repositories/blockArchive.d.ts.map +1 -1
  154. package/lib/db/repositories/blockArchive.js +1 -2
  155. package/lib/db/repositories/blockArchive.js.map +1 -1
  156. package/lib/db/repositories/blockArchiveIndex.d.ts +2 -2
  157. package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
  158. package/lib/db/repositories/dataColumnSidecar.d.ts +5 -3
  159. package/lib/db/repositories/dataColumnSidecar.d.ts.map +1 -1
  160. package/lib/db/repositories/dataColumnSidecar.js +14 -1
  161. package/lib/db/repositories/dataColumnSidecar.js.map +1 -1
  162. package/lib/db/repositories/dataColumnSidecarArchive.d.ts +5 -3
  163. package/lib/db/repositories/dataColumnSidecarArchive.d.ts.map +1 -1
  164. package/lib/db/repositories/dataColumnSidecarArchive.js +14 -1
  165. package/lib/db/repositories/dataColumnSidecarArchive.js.map +1 -1
  166. package/lib/db/repositories/executionPayloadEnvelope.d.ts +19 -0
  167. package/lib/db/repositories/executionPayloadEnvelope.d.ts.map +1 -0
  168. package/lib/db/repositories/executionPayloadEnvelope.js +22 -0
  169. package/lib/db/repositories/executionPayloadEnvelope.js.map +1 -0
  170. package/lib/db/repositories/executionPayloadEnvelopeArchive.d.ts +18 -0
  171. package/lib/db/repositories/executionPayloadEnvelopeArchive.d.ts.map +1 -0
  172. package/lib/db/repositories/executionPayloadEnvelopeArchive.js +28 -0
  173. package/lib/db/repositories/executionPayloadEnvelopeArchive.js.map +1 -0
  174. package/lib/db/repositories/index.d.ts +2 -0
  175. package/lib/db/repositories/index.d.ts.map +1 -1
  176. package/lib/db/repositories/index.js +2 -0
  177. package/lib/db/repositories/index.js.map +1 -1
  178. package/lib/execution/engine/http.d.ts +1 -0
  179. package/lib/execution/engine/http.d.ts.map +1 -1
  180. package/lib/execution/engine/http.js +3 -0
  181. package/lib/execution/engine/http.js.map +1 -1
  182. package/lib/metrics/metrics/beacon.d.ts +1 -0
  183. package/lib/metrics/metrics/beacon.d.ts.map +1 -1
  184. package/lib/metrics/metrics/beacon.js +5 -0
  185. package/lib/metrics/metrics/beacon.js.map +1 -1
  186. package/lib/metrics/metrics/lodestar.d.ts +8 -0
  187. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  188. package/lib/metrics/metrics/lodestar.js +14 -0
  189. package/lib/metrics/metrics/lodestar.js.map +1 -1
  190. package/lib/monitoring/service.d.ts +2 -2
  191. package/lib/monitoring/service.d.ts.map +1 -1
  192. package/lib/monitoring/service.js +3 -2
  193. package/lib/monitoring/service.js.map +1 -1
  194. package/lib/network/core/networkCore.d.ts +3 -3
  195. package/lib/network/core/networkCore.d.ts.map +1 -1
  196. package/lib/network/core/networkCore.js.map +1 -1
  197. package/lib/network/core/networkCoreWorkerHandler.d.ts +3 -3
  198. package/lib/network/core/networkCoreWorkerHandler.d.ts.map +1 -1
  199. package/lib/network/core/types.d.ts +2 -2
  200. package/lib/network/core/types.d.ts.map +1 -1
  201. package/lib/network/events.d.ts +2 -1
  202. package/lib/network/events.d.ts.map +1 -1
  203. package/lib/network/events.js.map +1 -1
  204. package/lib/network/gossip/encoding.d.ts +3 -3
  205. package/lib/network/gossip/encoding.d.ts.map +1 -1
  206. package/lib/network/gossip/encoding.js.map +1 -1
  207. package/lib/network/gossip/gossipsub.d.ts +13 -4
  208. package/lib/network/gossip/gossipsub.d.ts.map +1 -1
  209. package/lib/network/gossip/gossipsub.js +47 -20
  210. package/lib/network/gossip/gossipsub.js.map +1 -1
  211. package/lib/network/gossip/interface.d.ts +6 -6
  212. package/lib/network/gossip/interface.d.ts.map +1 -1
  213. package/lib/network/gossip/scoringParameters.d.ts +1 -1
  214. package/lib/network/gossip/scoringParameters.d.ts.map +1 -1
  215. package/lib/network/gossip/scoringParameters.js +1 -1
  216. package/lib/network/gossip/scoringParameters.js.map +1 -1
  217. package/lib/network/gossip/topic.d.ts +113 -63
  218. package/lib/network/gossip/topic.d.ts.map +1 -1
  219. package/lib/network/gossip/topic.js +2 -2
  220. package/lib/network/gossip/topic.js.map +1 -1
  221. package/lib/network/interface.d.ts +6 -5
  222. package/lib/network/interface.d.ts.map +1 -1
  223. package/lib/network/libp2p/index.d.ts +1 -1
  224. package/lib/network/libp2p/index.d.ts.map +1 -1
  225. package/lib/network/libp2p/index.js +7 -2
  226. package/lib/network/libp2p/index.js.map +1 -1
  227. package/lib/network/network.d.ts +5 -4
  228. package/lib/network/network.d.ts.map +1 -1
  229. package/lib/network/network.js +10 -1
  230. package/lib/network/network.js.map +1 -1
  231. package/lib/network/options.d.ts.map +1 -1
  232. package/lib/network/options.js +3 -0
  233. package/lib/network/options.js.map +1 -1
  234. package/lib/network/peers/datastore.d.ts +7 -5
  235. package/lib/network/peers/datastore.d.ts.map +1 -1
  236. package/lib/network/peers/datastore.js +10 -10
  237. package/lib/network/peers/datastore.js.map +1 -1
  238. package/lib/network/peers/peerManager.d.ts +3 -0
  239. package/lib/network/peers/peerManager.d.ts.map +1 -1
  240. package/lib/network/peers/peerManager.js +103 -53
  241. package/lib/network/peers/peerManager.js.map +1 -1
  242. package/lib/network/peers/utils/prioritizePeers.d.ts +3 -3
  243. package/lib/network/peers/utils/prioritizePeers.d.ts.map +1 -1
  244. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  245. package/lib/network/processor/gossipHandlers.js +9 -2
  246. package/lib/network/processor/gossipHandlers.js.map +1 -1
  247. package/lib/network/processor/gossipValidatorFn.js +1 -1
  248. package/lib/network/processor/types.d.ts +1 -1
  249. package/lib/network/processor/types.d.ts.map +1 -1
  250. package/lib/network/reqresp/handlers/blobSidecarsByRoot.js +1 -1
  251. package/lib/network/reqresp/handlers/blobSidecarsByRoot.js.map +1 -1
  252. package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js +1 -1
  253. package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js.map +1 -1
  254. package/lib/network/reqresp/score.d.ts.map +1 -1
  255. package/lib/network/reqresp/score.js +0 -1
  256. package/lib/network/reqresp/score.js.map +1 -1
  257. package/lib/network/util.js +2 -2
  258. package/lib/network/util.js.map +1 -1
  259. package/lib/node/nodejs.d.ts +3 -5
  260. package/lib/node/nodejs.d.ts.map +1 -1
  261. package/lib/node/nodejs.js +6 -4
  262. package/lib/node/nodejs.js.map +1 -1
  263. package/lib/util/blobs.d.ts +2 -2
  264. package/lib/util/blobs.d.ts.map +1 -1
  265. package/lib/util/blobs.js.map +1 -1
  266. package/lib/util/clock.d.ts +6 -0
  267. package/lib/util/clock.d.ts.map +1 -1
  268. package/lib/util/clock.js +9 -3
  269. package/lib/util/clock.js.map +1 -1
  270. package/lib/util/dataColumns.d.ts +11 -3
  271. package/lib/util/dataColumns.d.ts.map +1 -1
  272. package/lib/util/dataColumns.js +27 -0
  273. package/lib/util/dataColumns.js.map +1 -1
  274. package/lib/util/multifork.d.ts +8 -0
  275. package/lib/util/multifork.d.ts.map +1 -1
  276. package/lib/util/multifork.js +37 -0
  277. package/lib/util/multifork.js.map +1 -1
  278. package/package.json +39 -42
  279. package/src/api/impl/beacon/blocks/index.ts +147 -3
  280. package/src/api/impl/beacon/state/index.ts +8 -8
  281. package/src/api/impl/beacon/state/utils.ts +15 -29
  282. package/src/api/impl/debug/index.ts +9 -5
  283. package/src/api/impl/node/utils.ts +3 -3
  284. package/src/api/impl/validator/index.ts +153 -17
  285. package/src/chain/archiveStore/archiveStore.ts +10 -0
  286. package/src/chain/archiveStore/historicalState/getHistoricalState.ts +10 -11
  287. package/src/chain/archiveStore/historicalState/worker.ts +3 -3
  288. package/src/chain/archiveStore/utils/archivePayloads.ts +15 -0
  289. package/src/chain/archiveStore/utils/updateBackfillRange.ts +1 -1
  290. package/src/chain/blocks/blockInput/blockInput.ts +68 -3
  291. package/src/chain/blocks/blockInput/types.ts +13 -0
  292. package/src/chain/blocks/importBlock.ts +35 -4
  293. package/src/chain/blocks/index.ts +2 -1
  294. package/src/chain/blocks/verifyBlocksDataAvailability.ts +3 -0
  295. package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +9 -2
  296. package/src/chain/blocks/verifyBlocksSanityChecks.ts +7 -2
  297. package/src/chain/blocks/writeBlockInputToDb.ts +119 -101
  298. package/src/chain/bls/multithread/index.ts +7 -7
  299. package/src/chain/bls/multithread/jobItem.ts +3 -3
  300. package/src/chain/bls/singleThread.ts +5 -5
  301. package/src/chain/bls/utils.ts +8 -5
  302. package/src/chain/chain.ts +60 -35
  303. package/src/chain/emitter.ts +5 -5
  304. package/src/chain/errors/executionPayloadEnvelope.ts +6 -2
  305. package/src/chain/forkChoice/index.ts +39 -21
  306. package/src/chain/interface.ts +4 -11
  307. package/src/chain/opPools/aggregatedAttestationPool.ts +1 -1
  308. package/src/chain/options.ts +1 -0
  309. package/src/chain/prepareNextSlot.ts +5 -5
  310. package/src/chain/produceBlock/computeNewStateRoot.ts +35 -3
  311. package/src/chain/produceBlock/produceBlockBody.ts +162 -13
  312. package/src/chain/regen/queued.ts +7 -2
  313. package/src/chain/regen/regen.ts +8 -2
  314. package/src/chain/seenCache/seenGossipBlockInput.ts +16 -7
  315. package/src/chain/validation/aggregateAndProof.ts +1 -1
  316. package/src/chain/validation/attestation.ts +7 -4
  317. package/src/chain/validation/attesterSlashing.ts +10 -1
  318. package/src/chain/validation/blobSidecar.ts +2 -2
  319. package/src/chain/validation/block.ts +9 -4
  320. package/src/chain/validation/dataColumnSidecar.ts +3 -6
  321. package/src/chain/validation/executionPayloadBid.ts +1 -2
  322. package/src/chain/validation/executionPayloadEnvelope.ts +4 -4
  323. package/src/chain/validation/payloadAttestationMessage.ts +10 -3
  324. package/src/chain/validation/proposerSlashing.ts +1 -1
  325. package/src/chain/validation/syncCommitteeContributionAndProof.ts +1 -1
  326. package/src/db/beacon.ts +8 -0
  327. package/src/db/buckets.ts +3 -0
  328. package/src/db/interface.ts +5 -0
  329. package/src/db/repositories/blockArchive.ts +1 -2
  330. package/src/db/repositories/dataColumnSidecar.ts +18 -3
  331. package/src/db/repositories/dataColumnSidecarArchive.ts +18 -3
  332. package/src/db/repositories/executionPayloadEnvelope.ts +26 -0
  333. package/src/db/repositories/executionPayloadEnvelopeArchive.ts +32 -0
  334. package/src/db/repositories/index.ts +2 -0
  335. package/src/execution/engine/http.ts +3 -0
  336. package/src/metrics/metrics/beacon.ts +5 -0
  337. package/src/metrics/metrics/lodestar.ts +14 -0
  338. package/src/monitoring/service.ts +3 -2
  339. package/src/network/core/networkCore.ts +3 -3
  340. package/src/network/core/networkCoreWorkerHandler.ts +3 -3
  341. package/src/network/core/types.ts +2 -2
  342. package/src/network/events.ts +2 -1
  343. package/src/network/gossip/encoding.ts +3 -3
  344. package/src/network/gossip/gossipsub.ts +86 -25
  345. package/src/network/gossip/interface.ts +6 -6
  346. package/src/network/gossip/scoringParameters.ts +4 -4
  347. package/src/network/gossip/topic.ts +2 -1
  348. package/src/network/interface.ts +7 -4
  349. package/src/network/libp2p/index.ts +8 -3
  350. package/src/network/network.ts +24 -6
  351. package/src/network/options.ts +3 -0
  352. package/src/network/peers/datastore.ts +13 -10
  353. package/src/network/peers/peerManager.ts +118 -54
  354. package/src/network/peers/utils/prioritizePeers.ts +3 -3
  355. package/src/network/processor/gossipHandlers.ts +19 -4
  356. package/src/network/processor/gossipValidatorFn.ts +1 -1
  357. package/src/network/processor/types.ts +1 -1
  358. package/src/network/reqresp/handlers/blobSidecarsByRoot.ts +1 -1
  359. package/src/network/reqresp/handlers/dataColumnSidecarsByRoot.ts +1 -1
  360. package/src/network/reqresp/score.ts +0 -1
  361. package/src/network/util.ts +2 -2
  362. package/src/node/nodejs.ts +8 -9
  363. package/src/util/blobs.ts +3 -3
  364. package/src/util/clock.ts +9 -4
  365. package/src/util/dataColumns.ts +37 -1
  366. package/src/util/multifork.ts +45 -0
  367. package/src/util/workerEvents.ts +1 -1
@@ -1,8 +1,8 @@
1
- import {PubkeyIndexMap} from "@chainsafe/pubkey-index-map";
2
1
  import {routes} from "@lodestar/api";
3
2
  import {ApplicationMethods} from "@lodestar/api/server";
4
- import {ExecutionStatus, ProtoBlock} from "@lodestar/fork-choice";
3
+ import {ExecutionStatus, PayloadStatus, ProtoBlock} from "@lodestar/fork-choice";
5
4
  import {
5
+ BUILDER_INDEX_SELF_BUILD,
6
6
  ForkName,
7
7
  ForkPostBellatrix,
8
8
  ForkPreGloas,
@@ -14,6 +14,7 @@ import {
14
14
  isForkPostBellatrix,
15
15
  isForkPostDeneb,
16
16
  isForkPostElectra,
17
+ isForkPostGloas,
17
18
  } from "@lodestar/params";
18
19
  import {
19
20
  CachedBeaconStateAllForks,
@@ -25,6 +26,7 @@ import {
25
26
  computeStartSlotAtEpoch,
26
27
  computeTimeAtSlot,
27
28
  createCachedBeaconState,
29
+ createPubkeyCache,
28
30
  getBlockRootAtSlot,
29
31
  getCurrentSlot,
30
32
  loadState,
@@ -45,6 +47,7 @@ import {
45
47
  Wei,
46
48
  bellatrix,
47
49
  getValidatorStatus,
50
+ gloas,
48
51
  phase0,
49
52
  ssz,
50
53
  } from "@lodestar/types";
@@ -69,7 +72,7 @@ import {
69
72
  } from "../../../chain/errors/index.js";
70
73
  import {ChainEvent, CommonBlockBody} from "../../../chain/index.js";
71
74
  import {PREPARE_NEXT_SLOT_BPS} from "../../../chain/prepareNextSlot.js";
72
- import {BlockType, ProduceFullDeneb} from "../../../chain/produceBlock/index.js";
75
+ import {BlockType, ProduceFullDeneb, ProduceFullGloas} from "../../../chain/produceBlock/index.js";
73
76
  import {RegenCaller} from "../../../chain/regen/index.js";
74
77
  import {CheckpointHex} from "../../../chain/stateCache/types.js";
75
78
  import {validateApiAggregateAndProof} from "../../../chain/validation/index.js";
@@ -386,7 +389,7 @@ export function getValidatorApi(
386
389
  */
387
390
 
388
391
  function notOnOptimisticBlockRoot(beaconBlockRoot: Root): void {
389
- const protoBeaconBlock = chain.forkChoice.getBlock(beaconBlockRoot);
392
+ const protoBeaconBlock = chain.forkChoice.getBlockDefaultStatus(beaconBlockRoot);
390
393
  if (!protoBeaconBlock) {
391
394
  throw new ApiError(404, `Block not in forkChoice, beaconBlockRoot=${toRootHex(beaconBlockRoot)}`);
392
395
  }
@@ -398,7 +401,7 @@ export function getValidatorApi(
398
401
  }
399
402
 
400
403
  function notOnOutOfRangeData(beaconBlockRoot: Root): void {
401
- const protoBeaconBlock = chain.forkChoice.getBlock(beaconBlockRoot);
404
+ const protoBeaconBlock = chain.forkChoice.getBlockDefaultStatus(beaconBlockRoot);
402
405
  if (!protoBeaconBlock) {
403
406
  throw new ApiError(404, `Block not in forkChoice, beaconBlockRoot=${toRootHex(beaconBlockRoot)}`);
404
407
  }
@@ -901,6 +904,77 @@ export function getValidatorApi(
901
904
  return {data, meta};
902
905
  },
903
906
 
907
+ async produceBlockV4({slot, randaoReveal, graffiti, feeRecipient}) {
908
+ const fork = config.getForkName(slot);
909
+
910
+ if (!isForkPostGloas(fork)) {
911
+ throw new ApiError(400, `produceBlockV4 not supported for pre-gloas fork=${fork}`);
912
+ }
913
+
914
+ notWhileSyncing();
915
+ await waitForSlot(slot);
916
+
917
+ // TODO GLOAS: support producing blocks from builder bids
918
+ const source = ProducedBlockSource.engine;
919
+
920
+ // TODO GLOAS: needs to be updated after fork choice changes are merged
921
+ const parentBlock = chain.getProposerHead(slot);
922
+ const {blockRoot: parentBlockRootHex, slot: parentSlot} = parentBlock;
923
+ const parentBlockRoot = fromHex(parentBlockRootHex);
924
+ notOnOutOfRangeData(parentBlockRoot);
925
+ metrics?.blockProductionSlotDelta.set(slot - parentSlot);
926
+ metrics?.blockProductionRequests.inc({source});
927
+
928
+ const graffitiBytes = toGraffitiBytes(
929
+ graffiti ?? getDefaultGraffiti(getLodestarClientVersion(), chain.executionEngine.clientVersion, {})
930
+ );
931
+ const commonBlockBodyPromise = chain.produceCommonBlockBody({
932
+ slot,
933
+ parentBlock,
934
+ randaoReveal,
935
+ graffiti: graffitiBytes,
936
+ });
937
+
938
+ let timer: undefined | ((opts: {source: ProducedBlockSource}) => number);
939
+ try {
940
+ timer = metrics?.blockProductionTime.startTimer();
941
+ const {block, executionPayloadValue, consensusBlockValue} = await chain.produceBlock({
942
+ slot,
943
+ parentBlock,
944
+ randaoReveal,
945
+ graffiti: graffitiBytes,
946
+ feeRecipient,
947
+ commonBlockBodyPromise,
948
+ });
949
+
950
+ metrics?.blockProductionSuccess.inc({source});
951
+ metrics?.blockProductionNumAggregated.observe({source}, block.body.attestations.length);
952
+ metrics?.blockProductionConsensusBlockValue.observe({source}, Number(formatWeiToEth(consensusBlockValue)));
953
+ metrics?.blockProductionExecutionPayloadValue.observe({source}, Number(formatWeiToEth(executionPayloadValue)));
954
+
955
+ const blockRoot = toRootHex(config.getForkTypes(slot).BeaconBlock.hashTreeRoot(block));
956
+ logger.verbose("Produced block", {
957
+ slot,
958
+ executionPayloadValue,
959
+ consensusBlockValue,
960
+ root: blockRoot,
961
+ });
962
+ if (chain.opts.persistProducedBlocks) {
963
+ void chain.persistBlock(block, "produced_engine_block");
964
+ }
965
+
966
+ return {
967
+ data: block as gloas.BeaconBlock,
968
+ meta: {
969
+ version: fork,
970
+ consensusBlockValue,
971
+ },
972
+ };
973
+ } finally {
974
+ timer?.({source});
975
+ }
976
+ },
977
+
904
978
  async produceAttestationData({committeeIndex, slot}) {
905
979
  notWhileSyncing();
906
980
 
@@ -915,8 +989,30 @@ export function getValidatorApi(
915
989
  const headBlockRoot = fromHex(headBlockRootHex);
916
990
  const fork = config.getForkName(slot);
917
991
 
992
+ const beaconBlockRoot =
993
+ slot >= headSlot
994
+ ? // When attesting to the head slot or later, always use the head of the chain.
995
+ headBlockRoot
996
+ : // Permit attesting to slots *prior* to the current head. This is desirable when
997
+ // the VC and BN are out-of-sync due to time issues or overloading.
998
+ getBlockRootAtSlot(headState, slot);
999
+
918
1000
  let index: CommitteeIndex;
919
- if (isForkPostElectra(fork)) {
1001
+ if (isForkPostGloas(fork)) {
1002
+ const canonicalBlock = chain.forkChoice.getCanonicalBlockByRoot(beaconBlockRoot);
1003
+ if (!canonicalBlock) {
1004
+ // This should never happen
1005
+ throw Error(`Block not found in fork choice for slot=${slot}, root=${toRootHex(beaconBlockRoot)}`);
1006
+ }
1007
+ // After Gloas, attestation.data.index signals payload status in fork-choice:
1008
+ // - 0 = EMPTY / not present, 1 = FULL / present
1009
+ // - same-slot attestations must always use index = 0
1010
+ if (canonicalBlock.slot !== slot) {
1011
+ index = canonicalBlock.payloadStatus === PayloadStatus.FULL ? 1 : 0;
1012
+ } else {
1013
+ index = 0;
1014
+ }
1015
+ } else if (isForkPostElectra(fork)) {
920
1016
  index = 0;
921
1017
  } else {
922
1018
  if (committeeIndex === undefined) {
@@ -925,14 +1021,6 @@ export function getValidatorApi(
925
1021
  index = committeeIndex;
926
1022
  }
927
1023
 
928
- const beaconBlockRoot =
929
- slot >= headSlot
930
- ? // When attesting to the head slot or later, always use the head of the chain.
931
- headBlockRoot
932
- : // Permit attesting to slots *prior* to the current head. This is desirable when
933
- // the VC and BN are out-of-sync due to time issues or overloading.
934
- getBlockRootAtSlot(headState, slot);
935
-
936
1024
  const targetSlot = computeStartSlotAtEpoch(attEpoch);
937
1025
  const targetRoot =
938
1026
  targetSlot >= headSlot
@@ -1049,8 +1137,7 @@ export function getValidatorApi(
1049
1137
  {
1050
1138
  config: chain.config,
1051
1139
  // Not required to compute proposers
1052
- pubkey2index: new PubkeyIndexMap(),
1053
- index2pubkey: [],
1140
+ pubkeyCache: createPubkeyCache(),
1054
1141
  },
1055
1142
  {skipSyncPubkeys: true, skipSyncCommitteeCache: true}
1056
1143
  );
@@ -1511,7 +1598,7 @@ export function getValidatorApi(
1511
1598
 
1512
1599
  const filteredRegistrations = registrations.filter((registration) => {
1513
1600
  const {pubkey} = registration.message;
1514
- const validatorIndex = chain.pubkey2index.get(pubkey);
1601
+ const validatorIndex = chain.pubkeyCache.getIndex(pubkey);
1515
1602
  if (validatorIndex === null) return false;
1516
1603
 
1517
1604
  const validator = headState.validators.getReadonly(validatorIndex);
@@ -1532,5 +1619,54 @@ export function getValidatorApi(
1532
1619
  count: filteredRegistrations.length,
1533
1620
  });
1534
1621
  },
1622
+
1623
+ async getExecutionPayloadEnvelope({slot, beaconBlockRoot}) {
1624
+ const fork = config.getForkName(slot);
1625
+
1626
+ if (!isForkPostGloas(fork)) {
1627
+ throw new ApiError(400, `getExecutionPayloadEnvelope not supported for pre-gloas fork=${fork}`);
1628
+ }
1629
+
1630
+ notWhileSyncing();
1631
+ await waitForSlot(slot);
1632
+
1633
+ const blockRootHex = toRootHex(beaconBlockRoot);
1634
+ const produceResult = chain.blockProductionCache.get(blockRootHex);
1635
+
1636
+ if (produceResult === undefined) {
1637
+ throw new ApiError(404, `No cached block production result found for block root ${blockRootHex}`);
1638
+ }
1639
+ if (!isForkPostGloas(produceResult.fork)) {
1640
+ throw Error(`Cached block production result is for pre-gloas fork=${produceResult.fork}`);
1641
+ }
1642
+ if (produceResult.type !== BlockType.Full) {
1643
+ throw Error("Cached block production result is not full block");
1644
+ }
1645
+
1646
+ const {executionPayload, executionRequests, envelopeStateRoot} = produceResult as ProduceFullGloas;
1647
+
1648
+ const envelope: gloas.ExecutionPayloadEnvelope = {
1649
+ payload: executionPayload,
1650
+ executionRequests: executionRequests,
1651
+ builderIndex: BUILDER_INDEX_SELF_BUILD,
1652
+ beaconBlockRoot,
1653
+ slot,
1654
+ stateRoot: envelopeStateRoot,
1655
+ };
1656
+
1657
+ logger.info("Produced execution payload envelope", {
1658
+ slot,
1659
+ blockRoot: blockRootHex,
1660
+ transactions: executionPayload.transactions.length,
1661
+ blockHash: toRootHex(executionPayload.blockHash),
1662
+ });
1663
+
1664
+ return {
1665
+ data: envelope,
1666
+ meta: {
1667
+ version: fork,
1668
+ },
1669
+ };
1670
+ },
1535
1671
  };
1536
1672
  }
@@ -1,5 +1,6 @@
1
1
  import {CheckpointWithHex} from "@lodestar/fork-choice";
2
2
  import {LoggerNode} from "@lodestar/logger/node";
3
+ import {ForkSeq} from "@lodestar/params";
3
4
  import {Checkpoint} from "@lodestar/types/phase0";
4
5
  import {callFnWhenAwait} from "@lodestar/utils";
5
6
  import {IBeaconDb} from "../../db/index.js";
@@ -13,6 +14,7 @@ import {HistoricalStateRegen} from "./historicalState/historicalStateRegen.js";
13
14
  import {ArchiveMode, ArchiveStoreOpts, StateArchiveStrategy} from "./interface.js";
14
15
  import {FrequencyStateArchiveStrategy} from "./strategies/frequencyStateArchiveStrategy.js";
15
16
  import {archiveBlocks} from "./utils/archiveBlocks.js";
17
+ import {archiveExecutionPayloadEnvelopes} from "./utils/archivePayloads.js";
16
18
  import {pruneHistory} from "./utils/pruneHistory.js";
17
19
  import {updateBackfillRange} from "./utils/updateBackfillRange.js";
18
20
 
@@ -27,6 +29,7 @@ type ArchiveStoreInitOpts = ArchiveStoreOpts & {dbName: string; anchorState: {fi
27
29
 
28
30
  export enum ArchiveStoreTask {
29
31
  ArchiveBlocks = "archive_blocks",
32
+ ArchivePayloads = "archive_payloads",
30
33
  PruneHistory = "prune_history",
31
34
  OnFinalizedCheckpoint = "on_finalized_checkpoint",
32
35
  MaybeArchiveState = "maybe_archive_state",
@@ -189,6 +192,7 @@ export class ArchiveStore {
189
192
  private processFinalizedCheckpoint = async (finalized: CheckpointWithHex): Promise<void> => {
190
193
  try {
191
194
  const finalizedEpoch = finalized.epoch;
195
+ const finalizedFork = this.chain.config.getForkSeqAtEpoch(finalizedEpoch);
192
196
  this.logger.verbose("Start processing finalized checkpoint", {epoch: finalizedEpoch, rootHex: finalized.rootHex});
193
197
 
194
198
  let timer = this.metrics?.processFinalizedCheckpoint.durationByTask.startTimer();
@@ -206,6 +210,12 @@ export class ArchiveStore {
206
210
  );
207
211
  timer?.({source: ArchiveStoreTask.ArchiveBlocks});
208
212
 
213
+ if (finalizedFork >= ForkSeq.gloas) {
214
+ timer = this.metrics?.processFinalizedCheckpoint.durationByTask.startTimer();
215
+ await archiveExecutionPayloadEnvelopes(this.chain, finalized);
216
+ timer?.({source: ArchiveStoreTask.ArchivePayloads});
217
+ }
218
+
209
219
  if (this.opts.pruneHistory) {
210
220
  timer = this.metrics?.processFinalizedCheckpoint.durationByTask.startTimer();
211
221
  await pruneHistory(
@@ -1,10 +1,10 @@
1
- import {PubkeyIndexMap} from "@chainsafe/pubkey-index-map";
2
1
  import {BeaconConfig} from "@lodestar/config";
3
2
  import {
4
3
  BeaconStateAllForks,
5
4
  CachedBeaconStateAllForks,
6
5
  DataAvailabilityStatus,
7
6
  ExecutionPayloadStatus,
7
+ PubkeyCache,
8
8
  createCachedBeaconState,
9
9
  stateTransition,
10
10
  } from "@lodestar/state-transition";
@@ -15,16 +15,16 @@ import {HistoricalStateRegenMetrics} from "./metrics.js";
15
15
  import {RegenErrorType} from "./types.js";
16
16
 
17
17
  /**
18
- * Populate a PubkeyIndexMap with any new entries based on a BeaconState
18
+ * Populate a PubkeyCache with any new entries based on a BeaconState
19
19
  */
20
- export function syncPubkeyCache(state: BeaconStateAllForks, pubkey2index: PubkeyIndexMap): void {
20
+ export function syncPubkeyCache(state: BeaconStateAllForks, pubkeyCache: PubkeyCache): void {
21
21
  // Get the validators sub tree once for all the loop
22
22
  const validators = state.validators;
23
23
 
24
24
  const newCount = state.validators.length;
25
- for (let i = pubkey2index.size; i < newCount; i++) {
25
+ for (let i = pubkeyCache.size; i < newCount; i++) {
26
26
  const pubkey = validators.getReadonly(i).pubkey;
27
- pubkey2index.set(pubkey, i);
27
+ pubkeyCache.set(i, pubkey);
28
28
  }
29
29
  }
30
30
 
@@ -35,7 +35,7 @@ export async function getNearestState(
35
35
  slot: number,
36
36
  config: BeaconConfig,
37
37
  db: IBeaconDb,
38
- pubkey2index: PubkeyIndexMap
38
+ pubkeyCache: PubkeyCache
39
39
  ): Promise<CachedBeaconStateAllForks> {
40
40
  const stateBytesArr = await db.stateArchive.binaries({limit: 1, lte: slot, reverse: true});
41
41
  if (!stateBytesArr.length) {
@@ -44,14 +44,13 @@ export async function getNearestState(
44
44
 
45
45
  const stateBytes = stateBytesArr[0];
46
46
  const state = getStateTypeFromBytes(config, stateBytes).deserializeToViewDU(stateBytes);
47
- syncPubkeyCache(state, pubkey2index);
47
+ syncPubkeyCache(state, pubkeyCache);
48
48
 
49
49
  return createCachedBeaconState(
50
50
  state,
51
51
  {
52
52
  config,
53
- pubkey2index,
54
- index2pubkey: [],
53
+ pubkeyCache,
55
54
  },
56
55
  {
57
56
  skipSyncPubkeys: true,
@@ -66,13 +65,13 @@ export async function getHistoricalState(
66
65
  slot: number,
67
66
  config: BeaconConfig,
68
67
  db: IBeaconDb,
69
- pubkey2index: PubkeyIndexMap,
68
+ pubkeyCache: PubkeyCache,
70
69
  metrics?: HistoricalStateRegenMetrics
71
70
  ): Promise<Uint8Array> {
72
71
  const regenTimer = metrics?.regenTime.startTimer();
73
72
 
74
73
  const loadStateTimer = metrics?.loadStateTime.startTimer();
75
- let state = await getNearestState(slot, config, db, pubkey2index).catch((e) => {
74
+ let state = await getNearestState(slot, config, db, pubkeyCache).catch((e) => {
76
75
  metrics?.regenErrorCount.inc({reason: RegenErrorType.loadState});
77
76
  throw e;
78
77
  });
@@ -1,9 +1,9 @@
1
1
  import worker from "node:worker_threads";
2
- import {PubkeyIndexMap} from "@chainsafe/pubkey-index-map";
3
2
  import {Transfer, expose} from "@chainsafe/threads/worker";
4
3
  import {chainConfigFromJson, createBeaconConfig} from "@lodestar/config";
5
4
  import {LevelDbController} from "@lodestar/db/controller/level";
6
5
  import {getNodeLogger} from "@lodestar/logger/node";
6
+ import {createPubkeyCache} from "@lodestar/state-transition";
7
7
  import {BeaconDb} from "../../../db/index.js";
8
8
  import {RegistryMetricCreator, collectNodeJSMetrics} from "../../../metrics/index.js";
9
9
  import {JobFnQueue} from "../../../util/queue/fnQueue.js";
@@ -52,7 +52,7 @@ const queue = new JobFnQueue(
52
52
  queueMetrics
53
53
  );
54
54
 
55
- const pubkey2index = new PubkeyIndexMap();
55
+ const pubkeyCache = createPubkeyCache();
56
56
 
57
57
  const api: HistoricalStateWorkerApi = {
58
58
  async close() {
@@ -65,7 +65,7 @@ const api: HistoricalStateWorkerApi = {
65
65
  historicalStateRegenMetrics?.regenRequestCount.inc();
66
66
 
67
67
  const stateBytes = await queue.push<Uint8Array>(() =>
68
- getHistoricalState(slot, config, db, pubkey2index, historicalStateRegenMetrics)
68
+ getHistoricalState(slot, config, db, pubkeyCache, historicalStateRegenMetrics)
69
69
  );
70
70
  const result = Transfer(stateBytes, [stateBytes.buffer]) as unknown as Uint8Array;
71
71
 
@@ -0,0 +1,15 @@
1
+ import {CheckpointWithHex} from "@lodestar/fork-choice";
2
+ import {IBeaconChain} from "../../interface.js";
3
+
4
+ /**
5
+ * Archives execution payload envelopes from hot DB to archive DB after finalization.
6
+ */
7
+ export async function archiveExecutionPayloadEnvelopes(
8
+ chain: IBeaconChain,
9
+ _finalized: CheckpointWithHex
10
+ ): Promise<void> {
11
+ const finalizedBlock = chain.forkChoice.getFinalizedBlock();
12
+ if (!finalizedBlock) return;
13
+
14
+ // TODO GLOAS: Implement payload envelope archival after epbs fork choice changes are merged
15
+ }
@@ -20,7 +20,7 @@ export async function updateBackfillRange(
20
20
  try {
21
21
  // Mark the sequence in backfill db from finalized block's slot till anchor slot as
22
22
  // filled.
23
- const finalizedBlockFC = chain.forkChoice.getBlockHex(finalized.rootHex);
23
+ const finalizedBlockFC = chain.forkChoice.getBlockHexDefaultStatus(finalized.rootHex);
24
24
  if (finalizedBlockFC && finalizedBlockFC.slot > chain.anchorStateLatestBlockSlot) {
25
25
  await db.backfilledRanges.put(finalizedBlockFC.slot, chain.anchorStateLatestBlockSlot);
26
26
 
@@ -1,5 +1,5 @@
1
- import {ForkName, ForkPostFulu, ForkPreDeneb, ForkPreGloas, NUMBER_OF_COLUMNS} from "@lodestar/params";
2
- import {BeaconBlockBody, BlobIndex, ColumnIndex, SignedBeaconBlock, Slot, deneb, fulu} from "@lodestar/types";
1
+ import {ForkName, ForkPostFulu, ForkPostGloas, ForkPreDeneb, ForkPreGloas, NUMBER_OF_COLUMNS} from "@lodestar/params";
2
+ import {BeaconBlockBody, BlobIndex, ColumnIndex, SignedBeaconBlock, Slot, deneb, fulu, gloas} from "@lodestar/types";
3
3
  import {byteArrayEquals, fromHex, prettyBytes, toRootHex, withTimeout} from "@lodestar/utils";
4
4
  import {VersionedHashes} from "../../../execution/index.js";
5
5
  import {kzgCommitmentToVersionedHash} from "../../../util/blobs.js";
@@ -24,7 +24,7 @@ import {
24
24
  SourceMeta,
25
25
  } from "./types.js";
26
26
 
27
- export type BlockInput = BlockInputPreData | BlockInputBlobs | BlockInputColumns;
27
+ export type BlockInput = BlockInputPreData | BlockInputBlobs | BlockInputColumns | BlockInputNoData;
28
28
 
29
29
  export function isBlockInputPreDeneb(blockInput: IBlockInput): blockInput is BlockInputPreData {
30
30
  return blockInput.type === DAType.PreData;
@@ -37,6 +37,10 @@ export function isBlockInputColumns(blockInput: IBlockInput): blockInput is Bloc
37
37
  return blockInput.type === DAType.Columns;
38
38
  }
39
39
 
40
+ export function isBlockInputNoData(blockInput: IBlockInput): blockInput is BlockInputNoData {
41
+ return blockInput.type === DAType.NoData;
42
+ }
43
+
40
44
  function createPromise<T>(): PromiseParts<T> {
41
45
  let resolve!: (value: T) => void;
42
46
  let reject!: (e: Error) => void;
@@ -903,3 +907,64 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
903
907
  return Promise.resolve(this.getSampledColumns());
904
908
  }
905
909
  }
910
+
911
+ type BlockInputNoDataState = {
912
+ hasBlock: true;
913
+ hasAllData: true;
914
+ block: SignedBeaconBlock<ForkPostGloas>;
915
+ source: SourceMeta;
916
+ timeCompleteSec: number;
917
+ };
918
+
919
+ export class BlockInputNoData extends AbstractBlockInput<ForkPostGloas, null> {
920
+ type = DAType.NoData as const;
921
+
922
+ state: BlockInputNoDataState;
923
+
924
+ private constructor(init: BlockInputInit, state: BlockInputNoDataState) {
925
+ super(init);
926
+ this.state = state;
927
+ this.dataPromise.resolve(null);
928
+ this.blockPromise.resolve(state.block);
929
+ }
930
+
931
+ static createFromBlock(props: AddBlock<ForkPostGloas> & CreateBlockInputMeta): BlockInputNoData {
932
+ const init: BlockInputInit = {
933
+ daOutOfRange: props.daOutOfRange,
934
+ timeCreated: props.seenTimestampSec,
935
+ forkName: props.forkName,
936
+ slot: props.block.message.slot,
937
+ blockRootHex: props.blockRootHex,
938
+ parentRootHex: toRootHex(props.block.message.parentRoot),
939
+ };
940
+ const state: BlockInputNoDataState = {
941
+ hasBlock: true,
942
+ hasAllData: true,
943
+ block: props.block,
944
+ source: {
945
+ source: props.source,
946
+ seenTimestampSec: props.seenTimestampSec,
947
+ peerIdStr: props.peerIdStr,
948
+ },
949
+ timeCompleteSec: props.seenTimestampSec,
950
+ };
951
+ return new BlockInputNoData(init, state);
952
+ }
953
+
954
+ addBlock(_: AddBlock<ForkPostGloas>, opts = {throwOnDuplicateAdd: true}): void {
955
+ if (opts.throwOnDuplicateAdd) {
956
+ throw new BlockInputError(
957
+ {
958
+ code: BlockInputErrorCode.INVALID_CONSTRUCTION,
959
+ blockRoot: this.blockRootHex,
960
+ },
961
+ "Cannot addBlock to BlockInputNoData - block already exists"
962
+ );
963
+ }
964
+ }
965
+
966
+ getBlobKzgCommitments(): deneb.BlobKzgCommitments {
967
+ return (this.state.block.message.body as gloas.BeaconBlockBody).signedExecutionPayloadBid.message
968
+ .blobKzgCommitments;
969
+ }
970
+ }
@@ -6,6 +6,7 @@ export enum DAType {
6
6
  PreData = "pre-data",
7
7
  Blobs = "blobs",
8
8
  Columns = "columns",
9
+ NoData = "no-data",
9
10
  }
10
11
 
11
12
  export type DAData = null | deneb.BlobSidecars | fulu.DataColumnSidecars;
@@ -99,6 +100,18 @@ export type MissingColumnMeta = {
99
100
  versionedHashes: VersionedHashes;
100
101
  };
101
102
 
103
+ /**
104
+ * Minimal interface required to write data columns to the DB.
105
+ * Used by `writeDataColumnsToDb` and designed to be reusable across forks (e.g. Fulu, Gloas).
106
+ */
107
+ export interface IDataColumnsInput {
108
+ readonly slot: Slot;
109
+ readonly blockRootHex: string;
110
+ getCustodyColumns(): fulu.DataColumnSidecars;
111
+ hasComputedAllData(): boolean;
112
+ waitForComputedAllData(timeout: number, signal?: AbortSignal): Promise<fulu.DataColumnSidecars>;
113
+ }
114
+
102
115
  /**
103
116
  * This is used to validate that BlockInput implementations follow some minimal subset of operations
104
117
  * and that adding a new implementation won't break consumers that rely on this subset.
@@ -20,7 +20,7 @@ import {
20
20
  isStartSlotOfEpoch,
21
21
  isStateValidatorsNodesPopulated,
22
22
  } from "@lodestar/state-transition";
23
- import {Attestation, BeaconBlock, altair, capella, electra, phase0, ssz} from "@lodestar/types";
23
+ import {Attestation, BeaconBlock, altair, capella, electra, isGloasBeaconBlock, phase0, ssz} from "@lodestar/types";
24
24
  import {isErrorAborted, toRootHex} from "@lodestar/utils";
25
25
  import {ZERO_HASH_HEX} from "../../constants/index.js";
26
26
  import {callInNextEventLoop} from "../../util/eventLoop.js";
@@ -95,7 +95,7 @@ export async function importBlock(
95
95
  // Without this, a supernode syncing from behind can accumulate many blocks worth of column
96
96
  // data in memory (up to 128 columns per block) causing OOM before persistence catches up.
97
97
  await this.unfinalizedBlockWrites.waitForSpace();
98
- this.unfinalizedBlockWrites.push([blockInput]).catch((e) => {
98
+ this.unfinalizedBlockWrites.push(blockInput).catch((e) => {
99
99
  if (!isQueueErrorAborted(e)) {
100
100
  this.logger.error("Error pushing block to unfinalized write queue", {slot: blockSlot}, e as Error);
101
101
  }
@@ -230,6 +230,32 @@ export async function importBlock(
230
230
  }
231
231
  }
232
232
 
233
+ // 4.5. Import payload attestations to fork choice (Gloas)
234
+ //
235
+ if (isGloasBeaconBlock(block.message)) {
236
+ for (const payloadAttestation of block.message.body.payloadAttestations) {
237
+ try {
238
+ // Extract PTC indices from aggregation bits
239
+ const ptcIndices: number[] = [];
240
+ for (let i = 0; i < payloadAttestation.aggregationBits.bitLen; i++) {
241
+ if (payloadAttestation.aggregationBits.get(i)) {
242
+ ptcIndices.push(i);
243
+ }
244
+ }
245
+
246
+ if (ptcIndices.length > 0) {
247
+ this.forkChoice.notifyPtcMessages(
248
+ toRootHex(payloadAttestation.data.beaconBlockRoot),
249
+ ptcIndices,
250
+ payloadAttestation.data.payloadPresent
251
+ );
252
+ }
253
+ } catch (e) {
254
+ this.logger.warn("Error processing PayloadAttestation from block", {slot: blockSlot}, e as Error);
255
+ }
256
+ }
257
+ }
258
+
233
259
  // 5. Compute head. If new head, immediately stateCache.setHeadState()
234
260
 
235
261
  const oldHead = this.forkChoice.getHead();
@@ -345,7 +371,7 @@ export async function importBlock(
345
371
  // 3) Proposer boost reorg related flag is turned on (this is checked inside the function)
346
372
  // 4) Block meets the criteria of being re-orged out (this is also checked inside the function)
347
373
  const result = this.forkChoice.shouldOverrideForkChoiceUpdate(
348
- blockSummary.blockRoot,
374
+ blockSummary,
349
375
  this.clock.secFromSlot(currentSlot),
350
376
  currentSlot
351
377
  );
@@ -441,7 +467,12 @@ export async function importBlock(
441
467
  this.metrics?.currentActiveValidators.set(activeValidatorsCount);
442
468
  this.metrics?.currentValidators.set({status: "active"}, activeValidatorsCount);
443
469
 
444
- const parentBlockSummary = this.forkChoice.getBlock(checkpointState.latestBlockHeader.parentRoot);
470
+ const parentBlockSummary = isGloasBeaconBlock(block.message)
471
+ ? this.forkChoice.getBlockHexAndBlockHash(
472
+ toRootHex(checkpointState.latestBlockHeader.parentRoot),
473
+ toRootHex(block.message.body.signedExecutionPayloadBid.message.parentBlockHash)
474
+ )
475
+ : this.forkChoice.getBlockDefaultStatus(checkpointState.latestBlockHeader.parentRoot);
445
476
 
446
477
  if (parentBlockSummary) {
447
478
  const justifiedCheckpoint = checkpointState.currentJustifiedCheckpoint;
@@ -1,6 +1,7 @@
1
1
  import {SignedBeaconBlock} from "@lodestar/types";
2
2
  import {isErrorAborted, toRootHex} from "@lodestar/utils";
3
3
  import {Metrics} from "../../metrics/metrics.js";
4
+ import {nextEventLoop} from "../../util/eventLoop.js";
4
5
  import {JobItemQueue, isQueueErrorAborted} from "../../util/queue/index.js";
5
6
  import type {BeaconChain} from "../chain.js";
6
7
  import {BlockError, BlockErrorCode, isBlockErrorAborted} from "../errors/index.js";
@@ -100,9 +101,9 @@ export async function processBlocks(
100
101
  );
101
102
 
102
103
  for (const fullyVerifiedBlock of fullyVerifiedBlocks) {
103
- // No need to sleep(0) here since `importBlock` includes a disk write
104
104
  // TODO: Consider batching importBlock too if it takes significant time
105
105
  await importBlock.call(this, fullyVerifiedBlock, opts);
106
+ await nextEventLoop();
106
107
  }
107
108
  } catch (e) {
108
109
  if (isErrorAborted(e) || isQueueErrorAborted(e) || isBlockErrorAborted(e)) {
@@ -29,6 +29,9 @@ export async function verifyBlocksDataAvailability(
29
29
 
30
30
  const availableTime = Math.max(0, Math.max(...blocks.map((blockInput) => blockInput.getTimeComplete())));
31
31
  const dataAvailabilityStatuses: DataAvailabilityStatus[] = blocks.map((blockInput) => {
32
+ if (blockInput.type === DAType.NoData) {
33
+ return DataAvailabilityStatus.NotRequired;
34
+ }
32
35
  if (blockInput.type === DAType.PreData) {
33
36
  return DataAvailabilityStatus.PreData;
34
37
  }