@lodestar/beacon-node 1.42.0-dev.4118b5b440 → 1.42.0-dev.47afaa6bb7

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 (463) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +25 -13
  3. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  4. package/lib/api/impl/beacon/pool/index.d.ts.map +1 -1
  5. package/lib/api/impl/beacon/pool/index.js +5 -1
  6. package/lib/api/impl/beacon/pool/index.js.map +1 -1
  7. package/lib/api/impl/beacon/state/index.d.ts.map +1 -1
  8. package/lib/api/impl/beacon/state/index.js +38 -40
  9. package/lib/api/impl/beacon/state/index.js.map +1 -1
  10. package/lib/api/impl/beacon/state/utils.d.ts +4 -4
  11. package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
  12. package/lib/api/impl/beacon/state/utils.js +7 -10
  13. package/lib/api/impl/beacon/state/utils.js.map +1 -1
  14. package/lib/api/impl/debug/index.js.map +1 -1
  15. package/lib/api/impl/lodestar/index.d.ts.map +1 -1
  16. package/lib/api/impl/lodestar/index.js +8 -6
  17. package/lib/api/impl/lodestar/index.js.map +1 -1
  18. package/lib/api/impl/proof/index.d.ts.map +1 -1
  19. package/lib/api/impl/proof/index.js +2 -6
  20. package/lib/api/impl/proof/index.js.map +1 -1
  21. package/lib/api/impl/validator/index.d.ts.map +1 -1
  22. package/lib/api/impl/validator/index.js +34 -28
  23. package/lib/api/impl/validator/index.js.map +1 -1
  24. package/lib/api/impl/validator/utils.d.ts +2 -2
  25. package/lib/api/impl/validator/utils.d.ts.map +1 -1
  26. package/lib/api/impl/validator/utils.js +3 -3
  27. package/lib/api/impl/validator/utils.js.map +1 -1
  28. package/lib/chain/ColumnReconstructionTracker.d.ts +2 -1
  29. package/lib/chain/ColumnReconstructionTracker.d.ts.map +1 -1
  30. package/lib/chain/ColumnReconstructionTracker.js +5 -5
  31. package/lib/chain/ColumnReconstructionTracker.js.map +1 -1
  32. package/lib/chain/GetBlobsTracker.d.ts +2 -1
  33. package/lib/chain/GetBlobsTracker.d.ts.map +1 -1
  34. package/lib/chain/GetBlobsTracker.js +14 -12
  35. package/lib/chain/GetBlobsTracker.js.map +1 -1
  36. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  37. package/lib/chain/archiveStore/archiveStore.js +1 -0
  38. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  39. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts +3 -7
  40. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
  41. package/lib/chain/archiveStore/historicalState/getHistoricalState.js +8 -26
  42. package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
  43. package/lib/chain/archiveStore/historicalState/historicalStateRegen.d.ts +2 -2
  44. package/lib/chain/archiveStore/historicalState/historicalStateRegen.d.ts.map +1 -1
  45. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js +1 -0
  46. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js.map +1 -1
  47. package/lib/chain/archiveStore/historicalState/types.d.ts +2 -0
  48. package/lib/chain/archiveStore/historicalState/types.d.ts.map +1 -1
  49. package/lib/chain/archiveStore/historicalState/types.js.map +1 -1
  50. package/lib/chain/archiveStore/historicalState/worker.js +1 -3
  51. package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
  52. package/lib/chain/archiveStore/interface.d.ts +1 -0
  53. package/lib/chain/archiveStore/interface.d.ts.map +1 -1
  54. package/lib/chain/balancesCache.d.ts +2 -2
  55. package/lib/chain/balancesCache.d.ts.map +1 -1
  56. package/lib/chain/balancesCache.js +4 -4
  57. package/lib/chain/balancesCache.js.map +1 -1
  58. package/lib/chain/blocks/blockInput/blockInput.d.ts +5 -5
  59. package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
  60. package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
  61. package/lib/chain/blocks/blockInput/types.d.ts +4 -4
  62. package/lib/chain/blocks/blockInput/types.d.ts.map +1 -1
  63. package/lib/chain/blocks/importBlock.d.ts +3 -3
  64. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  65. package/lib/chain/blocks/importBlock.js +37 -23
  66. package/lib/chain/blocks/importBlock.js.map +1 -1
  67. package/lib/chain/blocks/importExecutionPayload.d.ts +10 -8
  68. package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
  69. package/lib/chain/blocks/importExecutionPayload.js +87 -51
  70. package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
  71. package/lib/chain/blocks/index.d.ts.map +1 -1
  72. package/lib/chain/blocks/index.js +3 -2
  73. package/lib/chain/blocks/index.js.map +1 -1
  74. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +14 -6
  75. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
  76. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +33 -2
  77. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
  78. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +2 -1
  79. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
  80. package/lib/chain/blocks/types.d.ts +21 -15
  81. package/lib/chain/blocks/types.d.ts.map +1 -1
  82. package/lib/chain/blocks/types.js.map +1 -1
  83. package/lib/chain/blocks/utils/checkpoint.d.ts +2 -2
  84. package/lib/chain/blocks/utils/checkpoint.d.ts.map +1 -1
  85. package/lib/chain/blocks/utils/checkpoint.js.map +1 -1
  86. package/lib/chain/blocks/verifyBlock.d.ts +2 -2
  87. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  88. package/lib/chain/blocks/verifyBlock.js +4 -4
  89. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  90. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts +5 -5
  91. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
  92. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +5 -4
  93. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
  94. package/lib/chain/blocks/verifyBlocksSignatures.d.ts +2 -2
  95. package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
  96. package/lib/chain/blocks/verifyBlocksSignatures.js +4 -2
  97. package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
  98. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts +3 -3
  99. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
  100. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +3 -3
  101. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
  102. package/lib/chain/chain.d.ts +15 -14
  103. package/lib/chain/chain.d.ts.map +1 -1
  104. package/lib/chain/chain.js +114 -66
  105. package/lib/chain/chain.js.map +1 -1
  106. package/lib/chain/emitter.d.ts +31 -9
  107. package/lib/chain/emitter.d.ts.map +1 -1
  108. package/lib/chain/emitter.js +12 -3
  109. package/lib/chain/emitter.js.map +1 -1
  110. package/lib/chain/errors/blockError.d.ts +10 -5
  111. package/lib/chain/errors/blockError.d.ts.map +1 -1
  112. package/lib/chain/errors/blockError.js +2 -0
  113. package/lib/chain/errors/blockError.js.map +1 -1
  114. package/lib/chain/errors/dataColumnSidecarError.d.ts +31 -1
  115. package/lib/chain/errors/dataColumnSidecarError.d.ts.map +1 -1
  116. package/lib/chain/errors/dataColumnSidecarError.js +7 -0
  117. package/lib/chain/errors/dataColumnSidecarError.js.map +1 -1
  118. package/lib/chain/forkChoice/index.d.ts +4 -4
  119. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  120. package/lib/chain/forkChoice/index.js +30 -24
  121. package/lib/chain/forkChoice/index.js.map +1 -1
  122. package/lib/chain/initState.d.ts +2 -2
  123. package/lib/chain/initState.d.ts.map +1 -1
  124. package/lib/chain/initState.js +1 -1
  125. package/lib/chain/initState.js.map +1 -1
  126. package/lib/chain/interface.d.ts +15 -14
  127. package/lib/chain/interface.d.ts.map +1 -1
  128. package/lib/chain/lightClient/index.d.ts +2 -2
  129. package/lib/chain/lightClient/index.d.ts.map +1 -1
  130. package/lib/chain/lightClient/index.js +11 -4
  131. package/lib/chain/lightClient/index.js.map +1 -1
  132. package/lib/chain/opPools/aggregatedAttestationPool.d.ts +6 -6
  133. package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
  134. package/lib/chain/opPools/aggregatedAttestationPool.js +13 -13
  135. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  136. package/lib/chain/opPools/executionPayloadBidPool.d.ts +2 -2
  137. package/lib/chain/opPools/executionPayloadBidPool.d.ts.map +1 -1
  138. package/lib/chain/opPools/executionPayloadBidPool.js +2 -2
  139. package/lib/chain/opPools/executionPayloadBidPool.js.map +1 -1
  140. package/lib/chain/opPools/opPool.d.ts +3 -3
  141. package/lib/chain/opPools/opPool.d.ts.map +1 -1
  142. package/lib/chain/opPools/opPool.js +7 -7
  143. package/lib/chain/opPools/opPool.js.map +1 -1
  144. package/lib/chain/opPools/utils.d.ts +2 -2
  145. package/lib/chain/opPools/utils.d.ts.map +1 -1
  146. package/lib/chain/opPools/utils.js +1 -1
  147. package/lib/chain/opPools/utils.js.map +1 -1
  148. package/lib/chain/options.d.ts +1 -0
  149. package/lib/chain/options.d.ts.map +1 -1
  150. package/lib/chain/options.js +1 -0
  151. package/lib/chain/options.js.map +1 -1
  152. package/lib/chain/prepareNextSlot.d.ts +2 -2
  153. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  154. package/lib/chain/prepareNextSlot.js +10 -4
  155. package/lib/chain/prepareNextSlot.js.map +1 -1
  156. package/lib/chain/produceBlock/computeNewStateRoot.d.ts +4 -4
  157. package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
  158. package/lib/chain/produceBlock/computeNewStateRoot.js +9 -10
  159. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  160. package/lib/chain/produceBlock/produceBlockBody.d.ts +7 -7
  161. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  162. package/lib/chain/produceBlock/produceBlockBody.js +32 -17
  163. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  164. package/lib/chain/regen/interface.d.ts +13 -13
  165. package/lib/chain/regen/interface.d.ts.map +1 -1
  166. package/lib/chain/regen/queued.d.ts +14 -14
  167. package/lib/chain/regen/queued.d.ts.map +1 -1
  168. package/lib/chain/regen/queued.js.map +1 -1
  169. package/lib/chain/regen/regen.d.ts +6 -5
  170. package/lib/chain/regen/regen.d.ts.map +1 -1
  171. package/lib/chain/regen/regen.js +6 -6
  172. package/lib/chain/regen/regen.js.map +1 -1
  173. package/lib/chain/seenCache/seenGossipBlockInput.d.ts +1 -1
  174. package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
  175. package/lib/chain/seenCache/seenGossipBlockInput.js +2 -2
  176. package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
  177. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +1 -1
  178. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
  179. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +2 -2
  180. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
  181. package/lib/chain/serializeState.d.ts +2 -2
  182. package/lib/chain/serializeState.d.ts.map +1 -1
  183. package/lib/chain/serializeState.js +1 -1
  184. package/lib/chain/serializeState.js.map +1 -1
  185. package/lib/chain/shufflingCache.d.ts +2 -2
  186. package/lib/chain/shufflingCache.d.ts.map +1 -1
  187. package/lib/chain/shufflingCache.js +3 -4
  188. package/lib/chain/shufflingCache.js.map +1 -1
  189. package/lib/chain/stateCache/fifoBlockStateCache.d.ts +6 -6
  190. package/lib/chain/stateCache/fifoBlockStateCache.d.ts.map +1 -1
  191. package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
  192. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +11 -11
  193. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  194. package/lib/chain/stateCache/persistentCheckpointsCache.js +12 -16
  195. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  196. package/lib/chain/stateCache/types.d.ts +14 -14
  197. package/lib/chain/stateCache/types.d.ts.map +1 -1
  198. package/lib/chain/stateCache/types.js.map +1 -1
  199. package/lib/chain/validation/attesterSlashing.js +3 -3
  200. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  201. package/lib/chain/validation/blobSidecar.js +1 -1
  202. package/lib/chain/validation/blobSidecar.js.map +1 -1
  203. package/lib/chain/validation/block.d.ts.map +1 -1
  204. package/lib/chain/validation/block.js +15 -6
  205. package/lib/chain/validation/block.js.map +1 -1
  206. package/lib/chain/validation/blsToExecutionChange.js +2 -2
  207. package/lib/chain/validation/blsToExecutionChange.js.map +1 -1
  208. package/lib/chain/validation/dataColumnSidecar.d.ts +11 -4
  209. package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
  210. package/lib/chain/validation/dataColumnSidecar.js +185 -6
  211. package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
  212. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
  213. package/lib/chain/validation/executionPayloadBid.js +10 -7
  214. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  215. package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
  216. package/lib/chain/validation/executionPayloadEnvelope.js +7 -3
  217. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
  218. package/lib/chain/validation/payloadAttestationMessage.js +5 -3
  219. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  220. package/lib/chain/validation/proposerSlashing.js +1 -1
  221. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  222. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts +2 -2
  223. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts.map +1 -1
  224. package/lib/chain/validation/signatureSets/contributionAndProof.js +1 -1
  225. package/lib/chain/validation/signatureSets/contributionAndProof.js.map +1 -1
  226. package/lib/chain/validation/signatureSets/syncCommittee.d.ts +2 -2
  227. package/lib/chain/validation/signatureSets/syncCommittee.d.ts.map +1 -1
  228. package/lib/chain/validation/signatureSets/syncCommittee.js +1 -1
  229. package/lib/chain/validation/signatureSets/syncCommittee.js.map +1 -1
  230. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts +2 -2
  231. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts.map +1 -1
  232. package/lib/chain/validation/signatureSets/syncCommitteeContribution.js.map +1 -1
  233. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts +2 -2
  234. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts.map +1 -1
  235. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js +1 -1
  236. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js.map +1 -1
  237. package/lib/chain/validation/syncCommittee.d.ts +3 -3
  238. package/lib/chain/validation/syncCommittee.d.ts.map +1 -1
  239. package/lib/chain/validation/syncCommittee.js +5 -1
  240. package/lib/chain/validation/syncCommittee.js.map +1 -1
  241. package/lib/chain/validation/syncCommitteeContributionAndProof.d.ts.map +1 -1
  242. package/lib/chain/validation/syncCommitteeContributionAndProof.js +5 -2
  243. package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
  244. package/lib/chain/validation/voluntaryExit.d.ts.map +1 -1
  245. package/lib/chain/validation/voluntaryExit.js +3 -3
  246. package/lib/chain/validation/voluntaryExit.js.map +1 -1
  247. package/lib/chain/validatorMonitor.d.ts +3 -3
  248. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  249. package/lib/chain/validatorMonitor.js +11 -9
  250. package/lib/chain/validatorMonitor.js.map +1 -1
  251. package/lib/db/buckets.d.ts +2 -2
  252. package/lib/db/buckets.d.ts.map +1 -1
  253. package/lib/db/buckets.js +2 -2
  254. package/lib/db/buckets.js.map +1 -1
  255. package/lib/db/repositories/blockArchiveIndex.d.ts +2 -2
  256. package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
  257. package/lib/db/repositories/dataColumnSidecar.d.ts.map +1 -1
  258. package/lib/db/repositories/dataColumnSidecar.js +4 -2
  259. package/lib/db/repositories/dataColumnSidecar.js.map +1 -1
  260. package/lib/db/repositories/dataColumnSidecarArchive.d.ts.map +1 -1
  261. package/lib/db/repositories/dataColumnSidecarArchive.js +4 -2
  262. package/lib/db/repositories/dataColumnSidecarArchive.js.map +1 -1
  263. package/lib/metrics/metrics/lodestar.d.ts +20 -0
  264. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  265. package/lib/metrics/metrics/lodestar.js +33 -0
  266. package/lib/metrics/metrics/lodestar.js.map +1 -1
  267. package/lib/network/interface.d.ts +6 -3
  268. package/lib/network/interface.d.ts.map +1 -1
  269. package/lib/network/libp2p/index.d.ts.map +1 -1
  270. package/lib/network/libp2p/index.js +22 -11
  271. package/lib/network/libp2p/index.js.map +1 -1
  272. package/lib/network/network.d.ts +6 -3
  273. package/lib/network/network.d.ts.map +1 -1
  274. package/lib/network/network.js +10 -1
  275. package/lib/network/network.js.map +1 -1
  276. package/lib/network/options.d.ts.map +1 -1
  277. package/lib/network/options.js +7 -2
  278. package/lib/network/options.js.map +1 -1
  279. package/lib/network/processor/extractSlotRootFns.d.ts +1 -1
  280. package/lib/network/processor/extractSlotRootFns.d.ts.map +1 -1
  281. package/lib/network/processor/extractSlotRootFns.js +25 -5
  282. package/lib/network/processor/extractSlotRootFns.js.map +1 -1
  283. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  284. package/lib/network/processor/gossipHandlers.js +260 -73
  285. package/lib/network/processor/gossipHandlers.js.map +1 -1
  286. package/lib/network/processor/index.d.ts +11 -1
  287. package/lib/network/processor/index.d.ts.map +1 -1
  288. package/lib/network/processor/index.js +234 -22
  289. package/lib/network/processor/index.js.map +1 -1
  290. package/lib/network/reqresp/ReqRespBeaconNode.d.ts.map +1 -1
  291. package/lib/network/reqresp/ReqRespBeaconNode.js +9 -0
  292. package/lib/network/reqresp/ReqRespBeaconNode.js.map +1 -1
  293. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts +8 -0
  294. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts.map +1 -0
  295. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +69 -0
  296. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -0
  297. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.d.ts +6 -0
  298. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.d.ts.map +1 -0
  299. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js +28 -0
  300. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js.map +1 -0
  301. package/lib/network/reqresp/handlers/index.d.ts.map +1 -1
  302. package/lib/network/reqresp/handlers/index.js +11 -1
  303. package/lib/network/reqresp/handlers/index.js.map +1 -1
  304. package/lib/network/reqresp/protocols.d.ts +2 -0
  305. package/lib/network/reqresp/protocols.d.ts.map +1 -1
  306. package/lib/network/reqresp/protocols.js +10 -0
  307. package/lib/network/reqresp/protocols.js.map +1 -1
  308. package/lib/network/reqresp/rateLimit.d.ts.map +1 -1
  309. package/lib/network/reqresp/rateLimit.js +8 -0
  310. package/lib/network/reqresp/rateLimit.js.map +1 -1
  311. package/lib/network/reqresp/score.d.ts.map +1 -1
  312. package/lib/network/reqresp/score.js +2 -0
  313. package/lib/network/reqresp/score.js.map +1 -1
  314. package/lib/network/reqresp/types.d.ts +10 -4
  315. package/lib/network/reqresp/types.d.ts.map +1 -1
  316. package/lib/network/reqresp/types.js +16 -4
  317. package/lib/network/reqresp/types.js.map +1 -1
  318. package/lib/node/nodejs.d.ts +2 -2
  319. package/lib/node/nodejs.d.ts.map +1 -1
  320. package/lib/node/nodejs.js +3 -3
  321. package/lib/node/nodejs.js.map +1 -1
  322. package/lib/node/notifier.d.ts.map +1 -1
  323. package/lib/node/notifier.js +3 -3
  324. package/lib/node/notifier.js.map +1 -1
  325. package/lib/sync/backfill/backfill.d.ts +2 -2
  326. package/lib/sync/backfill/backfill.d.ts.map +1 -1
  327. package/lib/sync/backfill/backfill.js +2 -2
  328. package/lib/sync/backfill/backfill.js.map +1 -1
  329. package/lib/sync/unknownBlock.js +2 -2
  330. package/lib/sync/unknownBlock.js.map +1 -1
  331. package/lib/sync/utils/downloadByRange.d.ts +3 -3
  332. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  333. package/lib/sync/utils/downloadByRange.js +4 -2
  334. package/lib/sync/utils/downloadByRange.js.map +1 -1
  335. package/lib/sync/utils/downloadByRoot.d.ts +3 -3
  336. package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
  337. package/lib/sync/utils/downloadByRoot.js +10 -5
  338. package/lib/sync/utils/downloadByRoot.js.map +1 -1
  339. package/lib/util/blobs.d.ts +3 -3
  340. package/lib/util/blobs.d.ts.map +1 -1
  341. package/lib/util/blobs.js +21 -10
  342. package/lib/util/blobs.js.map +1 -1
  343. package/lib/util/dataColumns.d.ts +18 -11
  344. package/lib/util/dataColumns.d.ts.map +1 -1
  345. package/lib/util/dataColumns.js +51 -17
  346. package/lib/util/dataColumns.js.map +1 -1
  347. package/lib/util/execution.d.ts +6 -2
  348. package/lib/util/execution.d.ts.map +1 -1
  349. package/lib/util/execution.js +49 -25
  350. package/lib/util/execution.js.map +1 -1
  351. package/lib/util/sszBytes.d.ts +25 -1
  352. package/lib/util/sszBytes.d.ts.map +1 -1
  353. package/lib/util/sszBytes.js +189 -2
  354. package/lib/util/sszBytes.js.map +1 -1
  355. package/lib/util/types.d.ts +2 -0
  356. package/lib/util/types.d.ts.map +1 -1
  357. package/lib/util/types.js +1 -0
  358. package/lib/util/types.js.map +1 -1
  359. package/package.json +16 -16
  360. package/src/api/impl/beacon/blocks/index.ts +33 -16
  361. package/src/api/impl/beacon/pool/index.ts +5 -1
  362. package/src/api/impl/beacon/state/index.ts +43 -55
  363. package/src/api/impl/beacon/state/utils.ts +11 -25
  364. package/src/api/impl/debug/index.ts +2 -2
  365. package/src/api/impl/lodestar/index.ts +8 -8
  366. package/src/api/impl/proof/index.ts +2 -9
  367. package/src/api/impl/validator/index.ts +37 -42
  368. package/src/api/impl/validator/utils.ts +4 -7
  369. package/src/chain/ColumnReconstructionTracker.ts +6 -5
  370. package/src/chain/GetBlobsTracker.ts +14 -12
  371. package/src/chain/archiveStore/archiveStore.ts +1 -0
  372. package/src/chain/archiveStore/historicalState/getHistoricalState.ts +10 -39
  373. package/src/chain/archiveStore/historicalState/historicalStateRegen.ts +2 -1
  374. package/src/chain/archiveStore/historicalState/types.ts +2 -0
  375. package/src/chain/archiveStore/historicalState/worker.ts +1 -4
  376. package/src/chain/archiveStore/interface.ts +1 -0
  377. package/src/chain/balancesCache.ts +5 -11
  378. package/src/chain/blocks/blockInput/blockInput.ts +8 -8
  379. package/src/chain/blocks/blockInput/types.ts +4 -4
  380. package/src/chain/blocks/importBlock.ts +50 -31
  381. package/src/chain/blocks/importExecutionPayload.ts +98 -62
  382. package/src/chain/blocks/index.ts +3 -2
  383. package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +53 -12
  384. package/src/chain/blocks/payloadEnvelopeInput/types.ts +2 -1
  385. package/src/chain/blocks/types.ts +26 -15
  386. package/src/chain/blocks/utils/checkpoint.ts +2 -2
  387. package/src/chain/blocks/verifyBlock.ts +5 -10
  388. package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +10 -14
  389. package/src/chain/blocks/verifyBlocksSignatures.ts +10 -3
  390. package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +6 -8
  391. package/src/chain/chain.ts +151 -98
  392. package/src/chain/emitter.ts +27 -9
  393. package/src/chain/errors/blockError.ts +8 -5
  394. package/src/chain/errors/dataColumnSidecarError.ts +32 -1
  395. package/src/chain/forkChoice/index.ts +35 -41
  396. package/src/chain/initState.ts +7 -2
  397. package/src/chain/interface.ts +16 -15
  398. package/src/chain/lightClient/index.ts +17 -18
  399. package/src/chain/opPools/aggregatedAttestationPool.ts +20 -21
  400. package/src/chain/opPools/executionPayloadBidPool.ts +3 -3
  401. package/src/chain/opPools/opPool.ts +13 -14
  402. package/src/chain/opPools/utils.ts +3 -3
  403. package/src/chain/options.ts +2 -0
  404. package/src/chain/prepareNextSlot.ts +14 -8
  405. package/src/chain/produceBlock/computeNewStateRoot.ts +13 -16
  406. package/src/chain/produceBlock/produceBlockBody.ts +51 -48
  407. package/src/chain/regen/interface.ts +13 -17
  408. package/src/chain/regen/queued.ts +16 -20
  409. package/src/chain/regen/regen.ts +16 -17
  410. package/src/chain/seenCache/seenGossipBlockInput.ts +2 -2
  411. package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +2 -2
  412. package/src/chain/serializeState.ts +3 -3
  413. package/src/chain/shufflingCache.ts +5 -7
  414. package/src/chain/stateCache/fifoBlockStateCache.ts +7 -7
  415. package/src/chain/stateCache/persistentCheckpointsCache.ts +27 -42
  416. package/src/chain/stateCache/types.ts +14 -18
  417. package/src/chain/validation/attesterSlashing.ts +3 -3
  418. package/src/chain/validation/blobSidecar.ts +1 -1
  419. package/src/chain/validation/block.ts +16 -10
  420. package/src/chain/validation/blsToExecutionChange.ts +2 -2
  421. package/src/chain/validation/dataColumnSidecar.ts +231 -8
  422. package/src/chain/validation/executionPayloadBid.ts +10 -10
  423. package/src/chain/validation/executionPayloadEnvelope.ts +7 -4
  424. package/src/chain/validation/payloadAttestationMessage.ts +6 -4
  425. package/src/chain/validation/proposerSlashing.ts +1 -1
  426. package/src/chain/validation/signatureSets/contributionAndProof.ts +2 -7
  427. package/src/chain/validation/signatureSets/syncCommittee.ts +2 -7
  428. package/src/chain/validation/signatureSets/syncCommitteeContribution.ts +2 -2
  429. package/src/chain/validation/signatureSets/syncCommitteeSelectionProof.ts +2 -7
  430. package/src/chain/validation/syncCommittee.ts +10 -6
  431. package/src/chain/validation/syncCommitteeContributionAndProof.ts +9 -10
  432. package/src/chain/validation/voluntaryExit.ts +3 -8
  433. package/src/chain/validatorMonitor.ts +15 -13
  434. package/src/db/buckets.ts +2 -2
  435. package/src/db/repositories/dataColumnSidecar.ts +4 -2
  436. package/src/db/repositories/dataColumnSidecarArchive.ts +4 -2
  437. package/src/metrics/metrics/lodestar.ts +34 -0
  438. package/src/network/interface.ts +17 -3
  439. package/src/network/libp2p/index.ts +24 -13
  440. package/src/network/network.ts +37 -6
  441. package/src/network/options.ts +7 -2
  442. package/src/network/processor/extractSlotRootFns.ts +32 -6
  443. package/src/network/processor/gossipHandlers.ts +325 -86
  444. package/src/network/processor/index.ts +304 -22
  445. package/src/network/reqresp/ReqRespBeaconNode.ts +13 -0
  446. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +94 -0
  447. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRoot.ts +43 -0
  448. package/src/network/reqresp/handlers/index.ts +12 -0
  449. package/src/network/reqresp/protocols.ts +12 -0
  450. package/src/network/reqresp/rateLimit.ts +18 -0
  451. package/src/network/reqresp/score.ts +2 -0
  452. package/src/network/reqresp/types.ts +26 -5
  453. package/src/node/nodejs.ts +6 -5
  454. package/src/node/notifier.ts +5 -6
  455. package/src/sync/backfill/backfill.ts +3 -3
  456. package/src/sync/unknownBlock.ts +3 -3
  457. package/src/sync/utils/downloadByRange.ts +9 -7
  458. package/src/sync/utils/downloadByRoot.ts +16 -12
  459. package/src/util/blobs.ts +35 -15
  460. package/src/util/dataColumns.ts +69 -25
  461. package/src/util/execution.ts +49 -30
  462. package/src/util/sszBytes.ts +245 -3
  463. package/src/util/types.ts +6 -0
@@ -12,6 +12,16 @@ import {Metrics} from "../../metrics/metrics.js";
12
12
  import {ClockEvent} from "../../util/clock.js";
13
13
  import {callInNextEventLoop} from "../../util/eventLoop.js";
14
14
  import {PeerIdStr} from "../../util/peerId.js";
15
+ import {
16
+ getBeaconBlockRootFromExecutionPayloadEnvelopeSerialized,
17
+ getDataIndexFromSignedAggregateAndProofSerialized,
18
+ getDataIndexFromSingleAttestationSerialized,
19
+ getParentBlockHashFromGloasSignedBeaconBlockSerialized,
20
+ getParentBlockHashFromSignedExecutionPayloadBidSerialized,
21
+ getParentBlockRootFromSignedExecutionPayloadBidSerialized,
22
+ getParentRootFromSignedBeaconBlockSerialized,
23
+ getPayloadPresentFromPayloadAttestationMessageSerialized,
24
+ } from "../../util/sszBytes.js";
15
25
  import {NetworkEvent, NetworkEventBus} from "../events.js";
16
26
  import {
17
27
  GossipHandlers,
@@ -89,6 +99,8 @@ const MAX_JOBS_SUBMITTED_PER_TICK = 128;
89
99
 
90
100
  // How many gossip messages we keep before new ones get dropped.
91
101
  const MAX_QUEUED_UNKNOWN_BLOCK_GOSSIP_OBJECTS = 16_384;
102
+ // TODO gloas: arbitrary constant, check metrics.
103
+ const MAX_QUEUED_UNKNOWN_PAYLOAD_GOSSIP_OBJECTS = 1024;
92
104
 
93
105
  // We don't want to process too many gossip messages in a single tick
94
106
  // As seen on mainnet, gossip messages concurrency metric ranges from 1000 to 2000
@@ -126,6 +138,20 @@ export enum CannotAcceptWorkReason {
126
138
  regen = "regen_busy",
127
139
  }
128
140
 
141
+ /**
142
+ * No metrics needed here; using a number to keep it lightweight
143
+ */
144
+ enum PreprocessAction {
145
+ AwaitBlock,
146
+ AwaitEnvelope,
147
+ PushToQueue,
148
+ }
149
+
150
+ type PreprocessResult =
151
+ | {action: PreprocessAction.PushToQueue}
152
+ | {action: PreprocessAction.AwaitBlock; root: RootHex}
153
+ | {action: PreprocessAction.AwaitEnvelope; root: RootHex};
154
+
129
155
  /**
130
156
  * Network processor handles the gossip queues and throtles processing to not overload the main thread
131
157
  * - Decides when to process work and what to process
@@ -159,7 +185,11 @@ export class NetworkProcessor {
159
185
  // we may not receive the block for messages like Attestation and SignedAggregateAndProof messages, in that case PendingGossipsubMessage needs
160
186
  // to be stored in this Map and reprocessed once the block comes
161
187
  private readonly awaitingMessagesByBlockRoot: MapDef<RootHex, Set<PendingGossipsubMessage>>;
188
+ // we may not receive the payload for messages that require the FULL payload variant to be processed,
189
+ // in that case PendingGossipsubMessage needs to be stored in this Map and reprocessed once the payload comes
190
+ private readonly awaitingMessagesByPayloadBlockRoot: MapDef<RootHex, Set<PendingGossipsubMessage>>;
162
191
  private unknownBlocksBySlot = new MapDef<Slot, Set<RootHex>>(() => new Set());
192
+ private unknownEnvelopesBySlot = new MapDef<Slot, Set<RootHex>>(() => new Set());
163
193
 
164
194
  constructor(
165
195
  modules: NetworkProcessorModules,
@@ -179,11 +209,13 @@ export class NetworkProcessor {
179
209
  modules
180
210
  );
181
211
 
182
- events.on(NetworkEvent.pendingGossipsubMessage, this.onPendingGossipsubMessage.bind(this));
183
- this.chain.emitter.on(routes.events.EventType.block, this.onBlockProcessed.bind(this));
184
- this.chain.clock.on(ClockEvent.slot, this.onClockSlot.bind(this));
212
+ events.on(NetworkEvent.pendingGossipsubMessage, this.onPendingGossipsubMessage);
213
+ this.chain.emitter.on(routes.events.EventType.block, this.onBlockProcessed);
214
+ this.chain.emitter.on(routes.events.EventType.executionPayload, this.onPayloadEnvelopeProcessed);
215
+ this.chain.clock.on(ClockEvent.slot, this.onClockSlot);
185
216
 
186
217
  this.awaitingMessagesByBlockRoot = new MapDef<RootHex, Set<PendingGossipsubMessage>>(() => new Set());
218
+ this.awaitingMessagesByPayloadBlockRoot = new MapDef<RootHex, Set<PendingGossipsubMessage>>(() => new Set());
187
219
 
188
220
  // TODO: Implement queues and priorization for ReqResp incoming requests
189
221
  // Listens to NetworkEvent.reqRespIncomingRequest event
@@ -196,6 +228,7 @@ export class NetworkProcessor {
196
228
  metrics.gossipValidationQueue.concurrency.set({topic}, this.gossipTopicConcurrency[topic]);
197
229
  }
198
230
  metrics.awaitingBlockGossipMessages.countPerSlot.set(this.unknownBlockGossipsubMessagesCount);
231
+ metrics.awaitingPayloadGossipMessages.countPerSlot.set(this.unknownPayloadGossipsubMessagesCount);
199
232
  // specific metric for beacon_attestation topic
200
233
  metrics.gossipValidationQueue.keyAge.reset();
201
234
  for (const ageMs of this.gossipQueues.beacon_attestation.getDataAgeMs()) {
@@ -212,6 +245,7 @@ export class NetworkProcessor {
212
245
  async stop(): Promise<void> {
213
246
  this.events.off(NetworkEvent.pendingGossipsubMessage, this.onPendingGossipsubMessage);
214
247
  this.chain.emitter.off(routes.events.EventType.block, this.onBlockProcessed);
248
+ this.chain.emitter.off(routes.events.EventType.executionPayload, this.onPayloadEnvelopeProcessed);
215
249
  this.chain.emitter.off(ClockEvent.slot, this.onClockSlot);
216
250
  }
217
251
 
@@ -232,7 +266,7 @@ export class NetworkProcessor {
232
266
 
233
267
  /**
234
268
  * Search block via `ChainEvent.unknownBlockRoot` event
235
- * Note that slot is not necessarily the same to the block's slot but it can be used for a good prune strategy.
269
+ * Slot is the message slot, which is not necessarily the same as the block's slot, but it can be used for a good prune strategy.
236
270
  * In the rare case, if 2 messages on 2 slots search for the same root (for example beacon_attestation) we may emit the same root twice but BlockInputSync should handle it well.
237
271
  */
238
272
  searchUnknownBlock({slot, root}: SlotRootHex, source: BlockInputSource, peer?: PeerIdStr): void {
@@ -248,9 +282,29 @@ export class NetworkProcessor {
248
282
  this.chain.emitter.emit(ChainEvent.unknownBlockRoot, {rootHex: root, peer, source});
249
283
  }
250
284
 
251
- private onPendingGossipsubMessage(message: PendingGossipsubMessage): void {
285
+ /**
286
+ * Search envelope via `ChainEvent.unknownEnvelopeBlockRoot` event
287
+ * Slot is the message slot, which is not necessarily the same as the envelope's slot, but it can be used for a good prune strategy.
288
+ * In the rare case, if 2 messages on 2 slots search for the same root (for example beacon_attestation) we may emit the same root twice but BlockInputSync should handle it well.
289
+ */
290
+ searchUnknownEnvelope({slot, root}: SlotRootHex, source: BlockInputSource, peer?: PeerIdStr): void {
291
+ if (
292
+ this.chain.seenPayloadEnvelope(root) ||
293
+ this.awaitingMessagesByPayloadBlockRoot.has(root) ||
294
+ this.unknownEnvelopesBySlot.getOrDefault(slot).has(root)
295
+ ) {
296
+ return;
297
+ }
298
+ this.unknownEnvelopesBySlot.getOrDefault(slot).add(root);
299
+ this.chain.emitter.emit(ChainEvent.unknownEnvelopeBlockRoot, {rootHex: root, peer, source});
300
+ }
301
+
302
+ private onPendingGossipsubMessage = (message: PendingGossipsubMessage): void => {
252
303
  const topicType = message.topic.type;
253
304
  const extractBlockSlotRootFn = this.extractBlockSlotRootFns[topicType];
305
+
306
+ // 1st extract round: make sure slot is in range and if block root is not available
307
+ // proactively search for it + queue the message
254
308
  const slotRoot = extractBlockSlotRootFn
255
309
  ? extractBlockSlotRootFn(message.msg.data, message.topic.boundary.fork)
256
310
  : null;
@@ -282,27 +336,198 @@ export class NetworkProcessor {
282
336
 
283
337
  message.msgSlot = slot;
284
338
 
339
+ // this determines whether this message needs to wait for a Block or Envelope
340
+ // a message should only wait for what it voted for, hence we don't want to put it on both queues
341
+ let preprocessResult: PreprocessResult = {action: PreprocessAction.PushToQueue};
285
342
  // no need to check if root is a descendant of the current finalized block, it will be checked once we validate the message if needed
286
343
  if (root && !this.chain.forkChoice.hasBlockHexUnsafe(root)) {
344
+ // starting from GLOAS, unknown root from data_column_sidecar also falls into this case
287
345
  this.searchUnknownBlock({slot, root}, BlockInputSource.network_processor, message.propagationSource.toString());
346
+ // for beacon_attestation and beacon_aggregate_and_proof messages, this is only temporary.
347
+ // if "index = 1" we need to await for the Envelope instead
348
+ preprocessResult = {action: PreprocessAction.AwaitBlock, root};
349
+ }
288
350
 
289
- if (this.unknownBlockGossipsubMessagesCount > MAX_QUEUED_UNKNOWN_BLOCK_GOSSIP_OBJECTS) {
290
- // No need to report the dropped job to gossip. It will be eventually pruned from the mcache
291
- this.metrics?.awaitingBlockGossipMessages.reject.inc({
292
- reason: ReprocessRejectReason.reached_limit,
293
- topic: topicType,
294
- });
295
- return;
351
+ // 2nd extract round for some specific topics
352
+ // we separate the search action from the await action
353
+
354
+ // beacon_block: proactively search for parent block/envelope across all forks, but never queue.
355
+ // BlockInputSync handles cascading recovery if the gossip handler throws.
356
+ if (topicType === GossipType.beacon_block) {
357
+ const parentRoot = getParentRootFromSignedBeaconBlockSerialized(message.msg.data);
358
+ if (parentRoot) {
359
+ if (ForkSeq[fork] >= ForkSeq.gloas) {
360
+ // GLOAS: also check parent envelope, same logic as execution_payload_bid
361
+ const parentBlockHash = getParentBlockHashFromGloasSignedBeaconBlockSerialized(message.msg.data);
362
+ if (parentBlockHash && !this.chain.forkChoice.getBlockHexAndBlockHash(parentRoot, parentBlockHash)) {
363
+ const protoBlock = this.chain.forkChoice.getBlockHexDefaultStatus(parentRoot);
364
+ if (protoBlock === null) {
365
+ this.searchUnknownBlock(
366
+ {slot, root: parentRoot},
367
+ BlockInputSource.network_processor,
368
+ message.propagationSource.toString()
369
+ );
370
+ } else if (
371
+ protoBlock.executionPayloadBlockHash &&
372
+ protoBlock.executionPayloadBlockHash !== parentBlockHash
373
+ ) {
374
+ // only search for the envelope by block root if we're sure there is one. Otherwise UnknownBlockSync will penalize the peer.
375
+ this.searchUnknownEnvelope(
376
+ {slot, root: parentRoot},
377
+ BlockInputSource.network_processor,
378
+ message.propagationSource.toString()
379
+ );
380
+ }
381
+ }
382
+ } else if (!this.chain.forkChoice.hasBlockHexUnsafe(parentRoot)) {
383
+ this.searchUnknownBlock(
384
+ {slot, root: parentRoot},
385
+ BlockInputSource.network_processor,
386
+ message.propagationSource.toString()
387
+ );
388
+ }
296
389
  }
390
+ preprocessResult = {action: PreprocessAction.PushToQueue};
391
+ }
297
392
 
298
- this.metrics?.awaitingBlockGossipMessages.queue.inc({topic: topicType});
299
- const awaitingGossipsubMessages = this.awaitingMessagesByBlockRoot.getOrDefault(root);
300
- awaitingGossipsubMessages.add(message);
301
- return;
393
+ if (ForkSeq[fork] >= ForkSeq.gloas) {
394
+ // specific check for each topic
395
+ // note that it's supposed to NOT queue beacon_block (handled above) and execution_payload because it's not a one-off;
396
+ // for those topics, gossip handlers will throw and BlockInputSync will handle a tree of them instead
397
+ switch (topicType) {
398
+ case GossipType.beacon_attestation:
399
+ case GossipType.beacon_aggregate_and_proof: {
400
+ if (root == null) break;
401
+ const attIndex =
402
+ topicType === GossipType.beacon_attestation
403
+ ? getDataIndexFromSingleAttestationSerialized(fork, message.msg.data)
404
+ : getDataIndexFromSignedAggregateAndProofSerialized(message.msg.data);
405
+ if (attIndex === 1 && !this.chain.forkChoice.hasPayloadHexUnsafe(root)) {
406
+ // attestation votes that the payload is available but it is not yet known
407
+ this.searchUnknownEnvelope(
408
+ {slot, root},
409
+ BlockInputSource.network_processor,
410
+ message.propagationSource.toString()
411
+ );
412
+ preprocessResult = {action: PreprocessAction.AwaitEnvelope, root};
413
+ }
414
+ break;
415
+ }
416
+ case GossipType.payload_attestation_message: {
417
+ if (root == null) break;
418
+ const payloadPresent = getPayloadPresentFromPayloadAttestationMessageSerialized(message.msg.data);
419
+ if (payloadPresent && !this.chain.forkChoice.hasPayloadHexUnsafe(root)) {
420
+ // payload attestation votes that the payload is available but it is not yet known
421
+ this.searchUnknownEnvelope(
422
+ {slot, root},
423
+ BlockInputSource.network_processor,
424
+ message.propagationSource.toString()
425
+ );
426
+ // do not await the envelope, payload attestation processing only requires that the block is known
427
+ // also do not reset preprocessResult, we may already await for the block
428
+ }
429
+ break;
430
+ }
431
+ case GossipType.data_column_sidecar: {
432
+ if (root == null) break;
433
+ if (!this.chain.forkChoice.hasPayloadHexUnsafe(root)) {
434
+ this.searchUnknownEnvelope(
435
+ {slot, root},
436
+ BlockInputSource.network_processor,
437
+ message.propagationSource.toString()
438
+ );
439
+ // do not await the envelope, we can do gossip validation
440
+ // also do not reset preprocessResult, we may already await for the block
441
+ }
442
+ break;
443
+ }
444
+ case GossipType.execution_payload: {
445
+ // extractBlockSlotRootFn does not return a root for this topic.
446
+ // Extract beacon_block_root directly and proactively trigger block sync if missing.
447
+ // Do NOT await the block — the handler runs immediately; BlockInputSync handles recovery.
448
+ const blockRoot = getBeaconBlockRootFromExecutionPayloadEnvelopeSerialized(message.msg.data);
449
+ if (blockRoot && !this.chain.forkChoice.hasBlockHexUnsafe(blockRoot)) {
450
+ this.searchUnknownBlock(
451
+ {slot, root: blockRoot},
452
+ BlockInputSource.network_processor,
453
+ message.propagationSource.toString()
454
+ );
455
+ }
456
+ // do not await the block, we want UnknownBlockSync to handle it.
457
+ preprocessResult = {action: PreprocessAction.PushToQueue};
458
+ break;
459
+ }
460
+ case GossipType.execution_payload_bid: {
461
+ // instead of searching for the message root, this searches for the parent root
462
+ const parentBlockRoot = getParentBlockRootFromSignedExecutionPayloadBidSerialized(message.msg.data);
463
+ const parentBlockHash = getParentBlockHashFromSignedExecutionPayloadBidSerialized(message.msg.data);
464
+ if (
465
+ parentBlockRoot &&
466
+ parentBlockHash &&
467
+ !this.chain.forkChoice.getBlockHexAndBlockHash(parentBlockRoot, parentBlockHash)
468
+ ) {
469
+ const protoBlock = this.chain.forkChoice.getBlockHexDefaultStatus(parentBlockRoot);
470
+ if (protoBlock === null) {
471
+ this.searchUnknownBlock(
472
+ {slot, root: parentBlockRoot},
473
+ BlockInputSource.network_processor,
474
+ message.propagationSource.toString()
475
+ );
476
+ preprocessResult = {action: PreprocessAction.AwaitBlock, root: parentBlockRoot};
477
+ } else if (
478
+ protoBlock.executionPayloadBlockHash &&
479
+ protoBlock.executionPayloadBlockHash !== parentBlockHash
480
+ ) {
481
+ this.searchUnknownEnvelope(
482
+ {slot, root: parentBlockRoot},
483
+ BlockInputSource.network_processor,
484
+ message.propagationSource.toString()
485
+ );
486
+ preprocessResult = {action: PreprocessAction.AwaitEnvelope, root: parentBlockRoot};
487
+ }
488
+ }
489
+ break;
490
+ }
491
+ }
302
492
  }
303
493
 
304
- this.pushPendingGossipsubMessageToQueue(message);
305
- }
494
+ switch (preprocessResult.action) {
495
+ case PreprocessAction.PushToQueue:
496
+ this.pushPendingGossipsubMessageToQueue(message);
497
+ break;
498
+ case PreprocessAction.AwaitBlock: {
499
+ if (this.unknownBlockGossipsubMessagesCount > MAX_QUEUED_UNKNOWN_BLOCK_GOSSIP_OBJECTS) {
500
+ // No need to report the dropped job to gossip. It will be eventually pruned from the mcache
501
+ this.metrics?.awaitingBlockGossipMessages.reject.inc({
502
+ reason: ReprocessRejectReason.reached_limit,
503
+ topic: topicType,
504
+ });
505
+ return;
506
+ }
507
+
508
+ this.metrics?.awaitingBlockGossipMessages.queue.inc({topic: topicType});
509
+ const awaitingGossipsubMessages = this.awaitingMessagesByBlockRoot.getOrDefault(preprocessResult.root);
510
+ awaitingGossipsubMessages.add(message);
511
+ break;
512
+ }
513
+ case PreprocessAction.AwaitEnvelope: {
514
+ if (this.unknownPayloadGossipsubMessagesCount > MAX_QUEUED_UNKNOWN_PAYLOAD_GOSSIP_OBJECTS) {
515
+ this.metrics?.awaitingPayloadGossipMessages.reject.inc({
516
+ reason: ReprocessRejectReason.reached_limit,
517
+ topic: topicType,
518
+ });
519
+ return;
520
+ }
521
+
522
+ this.metrics?.awaitingPayloadGossipMessages.queue.inc({topic: topicType});
523
+ const awaitingPayloadGossipsubMessages = this.awaitingMessagesByPayloadBlockRoot.getOrDefault(
524
+ preprocessResult.root
525
+ );
526
+ awaitingPayloadGossipsubMessages.add(message);
527
+ break;
528
+ }
529
+ }
530
+ };
306
531
 
307
532
  private pushPendingGossipsubMessageToQueue(message: PendingGossipsubMessage): void {
308
533
  const topicType = message.topic.type;
@@ -316,7 +541,7 @@ export class NetworkProcessor {
316
541
  this.executeWork();
317
542
  }
318
543
 
319
- private async onBlockProcessed({block: rootHex}: {block: string; executionOptimistic: boolean}): Promise<void> {
544
+ private onBlockProcessed = async ({block: rootHex}: {block: string; executionOptimistic: boolean}): Promise<void> => {
320
545
  const waitingGossipsubMessages = this.awaitingMessagesByBlockRoot.get(rootHex);
321
546
  if (!waitingGossipsubMessages || waitingGossipsubMessages.size === 0) {
322
547
  return;
@@ -343,9 +568,35 @@ export class NetworkProcessor {
343
568
  }
344
569
 
345
570
  this.awaitingMessagesByBlockRoot.delete(rootHex);
346
- }
571
+ };
572
+
573
+ private onPayloadEnvelopeProcessed = async ({blockRoot: rootHex}: {blockRoot: RootHex}): Promise<void> => {
574
+ const waitingGossipsubMessages = this.awaitingMessagesByPayloadBlockRoot.get(rootHex);
575
+ if (!waitingGossipsubMessages || waitingGossipsubMessages.size === 0) {
576
+ return;
577
+ }
578
+
579
+ const nowSec = Date.now() / 1000;
580
+ let count = 0;
581
+ for (const message of waitingGossipsubMessages) {
582
+ const topicType = message.topic.type;
583
+ this.metrics?.awaitingPayloadGossipMessages.waitSecBeforeResolve.set(
584
+ {topic: topicType},
585
+ nowSec - message.seenTimestampSec
586
+ );
587
+ this.metrics?.awaitingPayloadGossipMessages.resolve.inc({topic: topicType});
588
+ this.pushPendingGossipsubMessageToQueue(message);
589
+ count++;
590
+ if (count === MAX_AWAITING_GOSSIP_OBJECTS_PER_TICK) {
591
+ count = 0;
592
+ await sleep(AWAITING_GOSSIP_OBJECTS_YIELD_EVERY_MS);
593
+ }
594
+ }
347
595
 
348
- private onClockSlot(clockSlot: Slot): void {
596
+ this.awaitingMessagesByPayloadBlockRoot.delete(rootHex);
597
+ };
598
+
599
+ private onClockSlot = (clockSlot: Slot): void => {
349
600
  const nowSec = Date.now() / 1000;
350
601
  const minSlot = clockSlot - MAX_UNKNOWN_ROOTS_SLOT_CACHE_SIZE;
351
602
 
@@ -371,7 +622,30 @@ export class NetworkProcessor {
371
622
  }
372
623
  this.unknownBlocksBySlot.delete(slot);
373
624
  }
374
- }
625
+
626
+ for (const [slot, roots] of this.unknownEnvelopesBySlot) {
627
+ if (slot > minSlot) continue;
628
+ for (const rootHex of roots) {
629
+ const gossipMessages = this.awaitingMessagesByPayloadBlockRoot.get(rootHex);
630
+ if (gossipMessages !== undefined) {
631
+ for (const message of gossipMessages) {
632
+ const topicType = message.topic.type;
633
+ this.metrics?.awaitingPayloadGossipMessages.reject.inc({
634
+ topic: topicType,
635
+ reason: ReprocessRejectReason.expired,
636
+ });
637
+ this.metrics?.awaitingPayloadGossipMessages.waitSecBeforeReject.set(
638
+ {topic: topicType, reason: ReprocessRejectReason.expired},
639
+ nowSec - message.seenTimestampSec
640
+ );
641
+ // No need to report the dropped job to gossip. It will be eventually pruned from the mcache
642
+ }
643
+ this.awaitingMessagesByPayloadBlockRoot.delete(rootHex);
644
+ }
645
+ }
646
+ this.unknownEnvelopesBySlot.delete(slot);
647
+ }
648
+ };
375
649
 
376
650
  private executeWork(): void {
377
651
  // TODO: Maybe de-bounce by timing the last time executeWork was run
@@ -517,4 +791,12 @@ export class NetworkProcessor {
517
791
  }
518
792
  return count;
519
793
  }
794
+
795
+ private get unknownPayloadGossipsubMessagesCount(): number {
796
+ let count = 0;
797
+ for (const messages of this.awaitingMessagesByPayloadBlockRoot.values()) {
798
+ count += messages.size;
799
+ }
800
+ return count;
801
+ }
520
802
  }
@@ -297,6 +297,19 @@ export class ReqRespBeaconNode extends ReqResp {
297
297
  );
298
298
  }
299
299
 
300
+ if (ForkSeq[fork] >= ForkSeq.gloas) {
301
+ protocolsAtFork.push(
302
+ [
303
+ protocols.ExecutionPayloadEnvelopesByRoot(fork, this.config),
304
+ this.getHandler(ReqRespMethod.ExecutionPayloadEnvelopesByRoot),
305
+ ],
306
+ [
307
+ protocols.ExecutionPayloadEnvelopesByRange(fork, this.config),
308
+ this.getHandler(ReqRespMethod.ExecutionPayloadEnvelopesByRange),
309
+ ]
310
+ );
311
+ }
312
+
300
313
  return protocolsAtFork;
301
314
  }
302
315
 
@@ -0,0 +1,94 @@
1
+ import {ChainConfig} from "@lodestar/config";
2
+ import {PayloadStatus} from "@lodestar/fork-choice";
3
+ import {GENESIS_SLOT} from "@lodestar/params";
4
+ import {RespStatus, ResponseError, ResponseOutgoing} from "@lodestar/reqresp";
5
+ import {computeEpochAtSlot} from "@lodestar/state-transition";
6
+ import {gloas} from "@lodestar/types";
7
+ import {IBeaconChain} from "../../../chain/index.js";
8
+ import {IBeaconDb} from "../../../db/index.js";
9
+
10
+ export async function* onExecutionPayloadEnvelopesByRange(
11
+ request: gloas.ExecutionPayloadEnvelopesByRangeRequest,
12
+ chain: IBeaconChain,
13
+ db: IBeaconDb
14
+ ): AsyncIterable<ResponseOutgoing> {
15
+ const {startSlot, count} = validateExecutionPayloadEnvelopesByRangeRequest(chain.config, request);
16
+ const endSlot = startSlot + count;
17
+
18
+ if (startSlot < chain.earliestAvailableSlot) {
19
+ return;
20
+ }
21
+
22
+ const finalized = db.executionPayloadEnvelopeArchive;
23
+ const finalizedSlot = chain.forkChoice.getFinalizedCheckpointSlot();
24
+
25
+ // Finalized range of envelopes
26
+ if (startSlot <= finalizedSlot) {
27
+ for await (const {key, value: envelopeBytes} of finalized.binaryEntriesStream({
28
+ gte: startSlot,
29
+ lt: endSlot,
30
+ })) {
31
+ const slot = finalized.decodeKey(key);
32
+ yield {
33
+ data: envelopeBytes,
34
+ boundary: chain.config.getForkBoundaryAtEpoch(computeEpochAtSlot(slot)),
35
+ };
36
+ }
37
+ }
38
+
39
+ // Non-finalized range of envelopes
40
+ if (endSlot > finalizedSlot) {
41
+ const headBlock = chain.forkChoice.getHead();
42
+ const headRoot = headBlock.blockRoot;
43
+ const headChain = chain.forkChoice.getAllAncestorBlocks(headRoot, headBlock.payloadStatus);
44
+
45
+ // Iterate head chain with ascending block numbers
46
+ for (let i = headChain.length - 1; i >= 0; i--) {
47
+ const block = headChain[i];
48
+
49
+ if (block.slot >= startSlot && block.slot < endSlot) {
50
+ // Skip EMPTY blocks
51
+ if (block.payloadStatus !== PayloadStatus.FULL) {
52
+ continue;
53
+ }
54
+
55
+ const envelopeBytes = await chain.getSerializedExecutionPayloadEnvelope(block.slot, block.blockRoot);
56
+ if (!envelopeBytes) {
57
+ throw new ResponseError(
58
+ RespStatus.SERVER_ERROR,
59
+ `No envelope for root ${block.blockRoot} slot ${block.slot}, startSlot=${startSlot} endSlot=${endSlot} finalizedSlot=${finalizedSlot}`
60
+ );
61
+ }
62
+
63
+ yield {
64
+ data: envelopeBytes,
65
+ boundary: chain.config.getForkBoundaryAtEpoch(computeEpochAtSlot(block.slot)),
66
+ };
67
+ } else if (block.slot >= endSlot) {
68
+ break;
69
+ }
70
+ }
71
+ }
72
+ }
73
+
74
+ export function validateExecutionPayloadEnvelopesByRangeRequest(
75
+ config: ChainConfig,
76
+ request: gloas.ExecutionPayloadEnvelopesByRangeRequest
77
+ ): gloas.ExecutionPayloadEnvelopesByRangeRequest {
78
+ const {startSlot} = request;
79
+ let {count} = request;
80
+
81
+ if (count < 1) {
82
+ throw new ResponseError(RespStatus.INVALID_REQUEST, "count < 1");
83
+ }
84
+ // TODO: validate against MIN_EPOCHS_FOR_BLOCK_REQUESTS
85
+ if (startSlot < GENESIS_SLOT) {
86
+ throw new ResponseError(RespStatus.INVALID_REQUEST, "startSlot < genesis");
87
+ }
88
+
89
+ if (count > config.MAX_REQUEST_BLOCKS_DENEB) {
90
+ count = config.MAX_REQUEST_BLOCKS_DENEB;
91
+ }
92
+
93
+ return {startSlot, count};
94
+ }
@@ -0,0 +1,43 @@
1
+ import {ResponseOutgoing} from "@lodestar/reqresp";
2
+ import {computeEpochAtSlot} from "@lodestar/state-transition";
3
+ import {toRootHex} from "@lodestar/utils";
4
+ import {IBeaconChain} from "../../../chain/index.js";
5
+ import {IBeaconDb} from "../../../db/index.js";
6
+ import {ExecutionPayloadEnvelopesByRootRequest} from "../../../util/types.js";
7
+
8
+ export async function* onExecutionPayloadEnvelopesByRoot(
9
+ requestBody: ExecutionPayloadEnvelopesByRootRequest,
10
+ chain: IBeaconChain,
11
+ db: IBeaconDb
12
+ ): AsyncIterable<ResponseOutgoing> {
13
+ // Spec: [max(GLOAS_FORK_EPOCH, current_epoch - MIN_EPOCHS_FOR_BLOCK_REQUESTS), current_epoch]
14
+ const currentEpoch = chain.clock.currentEpoch;
15
+ const minimumRequestEpoch = Math.max(
16
+ currentEpoch - chain.config.MIN_EPOCHS_FOR_BLOCK_REQUESTS,
17
+ chain.config.GLOAS_FORK_EPOCH
18
+ );
19
+
20
+ for (const root of requestBody) {
21
+ const rootHex = toRootHex(root);
22
+ const block = chain.forkChoice.getBlockHexDefaultStatus(rootHex);
23
+ // If the block is not in fork choice, it may be finalized. Attempt to find its slot in block archive
24
+ const slot = block ? block.slot : await db.blockArchive.getSlotByRoot(root);
25
+
26
+ if (slot === null) {
27
+ continue;
28
+ }
29
+
30
+ const requestedEpoch = computeEpochAtSlot(slot);
31
+ if (requestedEpoch < minimumRequestEpoch) {
32
+ continue;
33
+ }
34
+
35
+ const envelopeBytes = await chain.getSerializedExecutionPayloadEnvelope(slot, rootHex);
36
+ if (envelopeBytes) {
37
+ yield {
38
+ data: envelopeBytes,
39
+ boundary: chain.config.getForkBoundaryAtEpoch(requestedEpoch),
40
+ };
41
+ }
42
+ }
43
+ }
@@ -6,6 +6,7 @@ import {
6
6
  BeaconBlocksByRootRequestType,
7
7
  BlobSidecarsByRootRequestType,
8
8
  DataColumnSidecarsByRootRequestType,
9
+ ExecutionPayloadEnvelopesByRootRequestType,
9
10
  } from "../../../util/types.js";
10
11
  import {GetReqRespHandlerFn, ReqRespMethod} from "../types.js";
11
12
  import {onBeaconBlocksByRange} from "./beaconBlocksByRange.js";
@@ -14,6 +15,8 @@ import {onBlobSidecarsByRange} from "./blobSidecarsByRange.js";
14
15
  import {onBlobSidecarsByRoot} from "./blobSidecarsByRoot.js";
15
16
  import {onDataColumnSidecarsByRange} from "./dataColumnSidecarsByRange.js";
16
17
  import {onDataColumnSidecarsByRoot} from "./dataColumnSidecarsByRoot.js";
18
+ import {onExecutionPayloadEnvelopesByRange} from "./executionPayloadEnvelopesByRange.js";
19
+ import {onExecutionPayloadEnvelopesByRoot} from "./executionPayloadEnvelopesByRoot.js";
17
20
  import {onLightClientBootstrap} from "./lightClientBootstrap.js";
18
21
  import {onLightClientFinalityUpdate} from "./lightClientFinalityUpdate.js";
19
22
  import {onLightClientOptimisticUpdate} from "./lightClientOptimisticUpdate.js";
@@ -62,6 +65,15 @@ export function getReqRespHandlers({db, chain}: {db: IBeaconDb; chain: IBeaconCh
62
65
  return onDataColumnSidecarsByRoot(body, chain, db, peerId, peerClient);
63
66
  },
64
67
 
68
+ [ReqRespMethod.ExecutionPayloadEnvelopesByRoot]: (req) => {
69
+ const body = ExecutionPayloadEnvelopesByRootRequestType(chain.config).deserialize(req.data);
70
+ return onExecutionPayloadEnvelopesByRoot(body, chain, db);
71
+ },
72
+ [ReqRespMethod.ExecutionPayloadEnvelopesByRange]: (req) => {
73
+ const body = ssz.gloas.ExecutionPayloadEnvelopesByRangeRequest.deserialize(req.data);
74
+ return onExecutionPayloadEnvelopesByRange(body, chain, db);
75
+ },
76
+
65
77
  [ReqRespMethod.LightClientBootstrap]: (req) => {
66
78
  const body = ssz.Root.deserialize(req.data);
67
79
  return onLightClientBootstrap(body, chain);
@@ -94,6 +94,18 @@ export const DataColumnSidecarsByRoot = toProtocol({
94
94
  contextBytesType: ContextBytesType.ForkDigest,
95
95
  });
96
96
 
97
+ export const ExecutionPayloadEnvelopesByRoot = toProtocol({
98
+ method: ReqRespMethod.ExecutionPayloadEnvelopesByRoot,
99
+ version: Version.V1,
100
+ contextBytesType: ContextBytesType.ForkDigest,
101
+ });
102
+
103
+ export const ExecutionPayloadEnvelopesByRange = toProtocol({
104
+ method: ReqRespMethod.ExecutionPayloadEnvelopesByRange,
105
+ version: Version.V1,
106
+ contextBytesType: ContextBytesType.ForkDigest,
107
+ });
108
+
97
109
  export const LightClientBootstrap = toProtocol({
98
110
  method: ReqRespMethod.LightClientBootstrap,
99
111
  version: Version.V1,
@@ -73,6 +73,24 @@ export const rateLimitQuotas: (fork: ForkName, config: BeaconConfig) => Record<R
73
73
  req.reduce((total, item) => total + item.columns.length, 0)
74
74
  ),
75
75
  },
76
+ [ReqRespMethod.ExecutionPayloadEnvelopesByRoot]: {
77
+ byPeer: {quota: config.MAX_REQUEST_PAYLOADS, quotaTimeMs: 10_000},
78
+ getRequestCount: getRequestCountFn(
79
+ fork,
80
+ config,
81
+ ReqRespMethod.ExecutionPayloadEnvelopesByRoot,
82
+ (req) => req.length
83
+ ),
84
+ },
85
+ [ReqRespMethod.ExecutionPayloadEnvelopesByRange]: {
86
+ byPeer: {quota: config.MAX_REQUEST_BLOCKS_DENEB, quotaTimeMs: 10_000},
87
+ getRequestCount: getRequestCountFn(
88
+ fork,
89
+ config,
90
+ ReqRespMethod.ExecutionPayloadEnvelopesByRange,
91
+ (req) => req.count
92
+ ),
93
+ },
76
94
  [ReqRespMethod.LightClientBootstrap]: {
77
95
  // As similar in the nature of `Status` protocol so we use the same rate limits.
78
96
  byPeer: {quota: 5, quotaTimeMs: 15_000},
@@ -46,6 +46,8 @@ export function onOutgoingReqRespError(e: RequestError, method: ReqRespMethod):
46
46
  return PeerAction.LowToleranceError;
47
47
  case ReqRespMethod.BeaconBlocksByRange:
48
48
  case ReqRespMethod.BeaconBlocksByRoot:
49
+ case ReqRespMethod.ExecutionPayloadEnvelopesByRoot:
50
+ case ReqRespMethod.ExecutionPayloadEnvelopesByRange:
49
51
  return PeerAction.MidToleranceError;
50
52
  default:
51
53
  return null;