@lodestar/beacon-node 1.50.1 → 1.51.0-dev.0586e6e617

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 (503) hide show
  1. package/lib/api/impl/api.js +1 -1
  2. package/lib/api/impl/api.js.map +1 -1
  3. package/lib/api/impl/beacon/blocks/index.d.ts +2 -1
  4. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  5. package/lib/api/impl/beacon/blocks/index.js +36 -36
  6. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  7. package/lib/api/impl/beacon/index.d.ts +2 -1
  8. package/lib/api/impl/beacon/index.d.ts.map +1 -1
  9. package/lib/api/impl/beacon/index.js +2 -2
  10. package/lib/api/impl/beacon/index.js.map +1 -1
  11. package/lib/api/impl/beacon/pool/index.d.ts.map +1 -1
  12. package/lib/api/impl/beacon/pool/index.js +5 -2
  13. package/lib/api/impl/beacon/pool/index.js.map +1 -1
  14. package/lib/api/impl/beacon/state/index.d.ts.map +1 -1
  15. package/lib/api/impl/beacon/state/index.js +8 -2
  16. package/lib/api/impl/beacon/state/index.js.map +1 -1
  17. package/lib/api/impl/beacon/state/utils.d.ts +3 -2
  18. package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
  19. package/lib/api/impl/beacon/state/utils.js +17 -9
  20. package/lib/api/impl/beacon/state/utils.js.map +1 -1
  21. package/lib/api/impl/debug/index.d.ts.map +1 -1
  22. package/lib/api/impl/debug/index.js +3 -0
  23. package/lib/api/impl/debug/index.js.map +1 -1
  24. package/lib/api/impl/validator/index.d.ts.map +1 -1
  25. package/lib/api/impl/validator/index.js +136 -27
  26. package/lib/api/impl/validator/index.js.map +1 -1
  27. package/lib/api/options.d.ts +2 -0
  28. package/lib/api/options.d.ts.map +1 -1
  29. package/lib/api/options.js +1 -0
  30. package/lib/api/options.js.map +1 -1
  31. package/lib/chain/ColumnReconstructionTracker.d.ts +11 -13
  32. package/lib/chain/ColumnReconstructionTracker.d.ts.map +1 -1
  33. package/lib/chain/ColumnReconstructionTracker.js +49 -44
  34. package/lib/chain/ColumnReconstructionTracker.js.map +1 -1
  35. package/lib/chain/GetBlobsTracker.d.ts +11 -0
  36. package/lib/chain/GetBlobsTracker.d.ts.map +1 -1
  37. package/lib/chain/GetBlobsTracker.js +85 -27
  38. package/lib/chain/GetBlobsTracker.js.map +1 -1
  39. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  40. package/lib/chain/archiveStore/archiveStore.js +1 -0
  41. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  42. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts +4 -0
  43. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
  44. package/lib/chain/archiveStore/utils/archiveBlocks.js +63 -100
  45. package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
  46. package/lib/chain/blocks/blockInput/blockInput.d.ts +1 -1
  47. package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
  48. package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
  49. package/lib/chain/blocks/blockInput/utils.js +2 -2
  50. package/lib/chain/blocks/blockInput/utils.js.map +1 -1
  51. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  52. package/lib/chain/blocks/importBlock.js +16 -11
  53. package/lib/chain/blocks/importBlock.js.map +1 -1
  54. package/lib/chain/blocks/importExecutionPayload.d.ts +6 -11
  55. package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
  56. package/lib/chain/blocks/importExecutionPayload.js +58 -17
  57. package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
  58. package/lib/chain/blocks/index.js +2 -2
  59. package/lib/chain/blocks/index.js.map +1 -1
  60. package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts +12 -9
  61. package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts.map +1 -1
  62. package/lib/chain/blocks/payloadEnvelopeProcessor.js +24 -19
  63. package/lib/chain/blocks/payloadEnvelopeProcessor.js.map +1 -1
  64. package/lib/chain/blocks/types.d.ts +4 -0
  65. package/lib/chain/blocks/types.d.ts.map +1 -1
  66. package/lib/chain/blocks/types.js +5 -0
  67. package/lib/chain/blocks/types.js.map +1 -1
  68. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  69. package/lib/chain/blocks/verifyBlock.js +1 -1
  70. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  71. package/lib/chain/blocks/verifyBlocksDataAvailability.d.ts.map +1 -1
  72. package/lib/chain/blocks/verifyBlocksDataAvailability.js +8 -1
  73. package/lib/chain/blocks/verifyBlocksDataAvailability.js.map +1 -1
  74. package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts +3 -3
  75. package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts.map +1 -1
  76. package/lib/chain/blocks/verifyPayloadsDataAvailability.js +11 -6
  77. package/lib/chain/blocks/verifyPayloadsDataAvailability.js.map +1 -1
  78. package/lib/chain/bls/multithread/index.js +5 -5
  79. package/lib/chain/bls/multithread/index.js.map +1 -1
  80. package/lib/chain/bls/multithread/types.d.ts +1 -1
  81. package/lib/chain/bls/multithread/types.d.ts.map +1 -1
  82. package/lib/chain/bls/multithread/worker.js +1 -1
  83. package/lib/chain/bls/multithread/worker.js.map +1 -1
  84. package/lib/chain/bls/singleThread.js +1 -1
  85. package/lib/chain/bls/singleThread.js.map +1 -1
  86. package/lib/chain/bls/utils.js +1 -1
  87. package/lib/chain/bls/utils.js.map +1 -1
  88. package/lib/chain/chain.d.ts +3 -2
  89. package/lib/chain/chain.d.ts.map +1 -1
  90. package/lib/chain/chain.js +12 -7
  91. package/lib/chain/chain.js.map +1 -1
  92. package/lib/chain/errors/blockError.d.ts +1 -1
  93. package/lib/chain/errors/blockError.d.ts.map +1 -1
  94. package/lib/chain/errors/blockError.js +1 -1
  95. package/lib/chain/errors/blockError.js.map +1 -1
  96. package/lib/chain/errors/executionPayloadBid.d.ts +11 -1
  97. package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -1
  98. package/lib/chain/errors/executionPayloadBid.js +2 -0
  99. package/lib/chain/errors/executionPayloadBid.js.map +1 -1
  100. package/lib/chain/errors/inclusionList.d.ts +60 -0
  101. package/lib/chain/errors/inclusionList.d.ts.map +1 -0
  102. package/lib/chain/errors/inclusionList.js +19 -0
  103. package/lib/chain/errors/inclusionList.js.map +1 -0
  104. package/lib/chain/errors/index.d.ts +1 -0
  105. package/lib/chain/errors/index.d.ts.map +1 -1
  106. package/lib/chain/errors/index.js +1 -0
  107. package/lib/chain/errors/index.js.map +1 -1
  108. package/lib/chain/interface.d.ts +5 -5
  109. package/lib/chain/interface.d.ts.map +1 -1
  110. package/lib/chain/interface.js.map +1 -1
  111. package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
  112. package/lib/chain/opPools/aggregatedAttestationPool.js +23 -10
  113. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  114. package/lib/chain/opPools/attestationPool.d.ts +1 -1
  115. package/lib/chain/opPools/attestationPool.d.ts.map +1 -1
  116. package/lib/chain/opPools/attestationPool.js +15 -4
  117. package/lib/chain/opPools/attestationPool.js.map +1 -1
  118. package/lib/chain/opPools/inclusionListStore.d.ts +63 -0
  119. package/lib/chain/opPools/inclusionListStore.d.ts.map +1 -0
  120. package/lib/chain/opPools/inclusionListStore.js +171 -0
  121. package/lib/chain/opPools/inclusionListStore.js.map +1 -0
  122. package/lib/chain/opPools/index.d.ts +1 -0
  123. package/lib/chain/opPools/index.d.ts.map +1 -1
  124. package/lib/chain/opPools/index.js +1 -0
  125. package/lib/chain/opPools/index.js.map +1 -1
  126. package/lib/chain/opPools/payloadAttestationPool.d.ts.map +1 -1
  127. package/lib/chain/opPools/payloadAttestationPool.js +17 -7
  128. package/lib/chain/opPools/payloadAttestationPool.js.map +1 -1
  129. package/lib/chain/opPools/syncCommitteeMessagePool.d.ts.map +1 -1
  130. package/lib/chain/opPools/syncCommitteeMessagePool.js +9 -3
  131. package/lib/chain/opPools/syncCommitteeMessagePool.js.map +1 -1
  132. package/lib/chain/opPools/syncContributionAndProofPool.d.ts.map +1 -1
  133. package/lib/chain/opPools/syncContributionAndProofPool.js +11 -3
  134. package/lib/chain/opPools/syncContributionAndProofPool.js.map +1 -1
  135. package/lib/chain/opPools/utils.d.ts +1 -1
  136. package/lib/chain/opPools/utils.d.ts.map +1 -1
  137. package/lib/chain/opPools/utils.js +1 -1
  138. package/lib/chain/opPools/utils.js.map +1 -1
  139. package/lib/chain/options.d.ts +0 -1
  140. package/lib/chain/options.d.ts.map +1 -1
  141. package/lib/chain/options.js +0 -1
  142. package/lib/chain/options.js.map +1 -1
  143. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  144. package/lib/chain/prepareNextSlot.js +4 -3
  145. package/lib/chain/prepareNextSlot.js.map +1 -1
  146. package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
  147. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  148. package/lib/chain/produceBlock/produceBlockBody.d.ts +3 -1
  149. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  150. package/lib/chain/produceBlock/produceBlockBody.js +37 -15
  151. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  152. package/lib/chain/regen/interface.d.ts +1 -1
  153. package/lib/chain/regen/interface.d.ts.map +1 -1
  154. package/lib/chain/regen/interface.js +1 -1
  155. package/lib/chain/regen/interface.js.map +1 -1
  156. package/lib/chain/reprocess.d.ts +2 -1
  157. package/lib/chain/reprocess.d.ts.map +1 -1
  158. package/lib/chain/reprocess.js +2 -1
  159. package/lib/chain/reprocess.js.map +1 -1
  160. package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
  161. package/lib/chain/seenCache/seenGossipBlockInput.js +1 -1
  162. package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
  163. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  164. package/lib/chain/stateCache/persistentCheckpointsCache.js +1 -1
  165. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  166. package/lib/chain/validation/executionPayloadBid.d.ts +0 -15
  167. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
  168. package/lib/chain/validation/executionPayloadBid.js +37 -158
  169. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  170. package/lib/chain/validation/inclusionList.d.ts +14 -0
  171. package/lib/chain/validation/inclusionList.d.ts.map +1 -0
  172. package/lib/chain/validation/inclusionList.js +150 -0
  173. package/lib/chain/validation/inclusionList.js.map +1 -0
  174. package/lib/chain/validation/index.d.ts +1 -0
  175. package/lib/chain/validation/index.d.ts.map +1 -1
  176. package/lib/chain/validation/index.js +1 -0
  177. package/lib/chain/validation/index.js.map +1 -1
  178. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  179. package/lib/chain/validatorMonitor.js +6 -4
  180. package/lib/chain/validatorMonitor.js.map +1 -1
  181. package/lib/constants/constants.d.ts +1 -0
  182. package/lib/constants/constants.d.ts.map +1 -1
  183. package/lib/constants/constants.js +1 -0
  184. package/lib/constants/constants.js.map +1 -1
  185. package/lib/db/beacon.d.ts +7 -0
  186. package/lib/db/beacon.d.ts.map +1 -1
  187. package/lib/db/beacon.js +34 -0
  188. package/lib/db/beacon.js.map +1 -1
  189. package/lib/db/dataColumnStore.d.ts +1 -1
  190. package/lib/db/dataColumnStore.d.ts.map +1 -1
  191. package/lib/db/dataColumnStore.js +1 -4
  192. package/lib/db/dataColumnStore.js.map +1 -1
  193. package/lib/db/flatFileStore/flatFileStore.js +5 -5
  194. package/lib/db/flatFileStore/flatFileStore.js.map +1 -1
  195. package/lib/db/flatFileStore/slotIndex.d.ts.map +1 -1
  196. package/lib/db/flatFileStore/slotIndex.js +2 -2
  197. package/lib/db/flatFileStore/slotIndex.js.map +1 -1
  198. package/lib/db/interface.d.ts +1 -0
  199. package/lib/db/interface.d.ts.map +1 -1
  200. package/lib/db/repositories/blockArchive.js +2 -2
  201. package/lib/db/repositories/blockArchive.js.map +1 -1
  202. package/lib/db/repositories/blockArchiveIndex.d.ts +1 -1
  203. package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
  204. package/lib/db/repositories/blockArchiveIndex.js +1 -2
  205. package/lib/db/repositories/blockArchiveIndex.js.map +1 -1
  206. package/lib/db/repositories/dataColumnSidecarArchive.d.ts +6 -0
  207. package/lib/db/repositories/dataColumnSidecarArchive.d.ts.map +1 -1
  208. package/lib/db/repositories/dataColumnSidecarArchive.js +19 -0
  209. package/lib/db/repositories/dataColumnSidecarArchive.js.map +1 -1
  210. package/lib/execution/builder/validateBid.d.ts.map +1 -1
  211. package/lib/execution/builder/validateBid.js +14 -1
  212. package/lib/execution/builder/validateBid.js.map +1 -1
  213. package/lib/execution/engine/blobVersionedHashes.d.ts +1 -1
  214. package/lib/execution/engine/blobVersionedHashes.d.ts.map +1 -1
  215. package/lib/execution/engine/blobVersionedHashes.js.map +1 -1
  216. package/lib/execution/engine/disabled.d.ts +1 -0
  217. package/lib/execution/engine/disabled.d.ts.map +1 -1
  218. package/lib/execution/engine/disabled.js +3 -0
  219. package/lib/execution/engine/disabled.js.map +1 -1
  220. package/lib/execution/engine/http.d.ts +8 -2
  221. package/lib/execution/engine/http.d.ts.map +1 -1
  222. package/lib/execution/engine/http.js +27 -4
  223. package/lib/execution/engine/http.js.map +1 -1
  224. package/lib/execution/engine/index.d.ts +1 -1
  225. package/lib/execution/engine/index.d.ts.map +1 -1
  226. package/lib/execution/engine/index.js +2 -2
  227. package/lib/execution/engine/index.js.map +1 -1
  228. package/lib/execution/engine/interface.d.ts +12 -3
  229. package/lib/execution/engine/interface.d.ts.map +1 -1
  230. package/lib/execution/engine/interface.js.map +1 -1
  231. package/lib/execution/engine/jsonRpcHttpClient.d.ts.map +1 -1
  232. package/lib/execution/engine/jsonRpcHttpClient.js +14 -4
  233. package/lib/execution/engine/jsonRpcHttpClient.js.map +1 -1
  234. package/lib/execution/engine/jsonRpcTransport.d.ts +3 -2
  235. package/lib/execution/engine/jsonRpcTransport.d.ts.map +1 -1
  236. package/lib/execution/engine/jsonRpcTransport.js +33 -9
  237. package/lib/execution/engine/jsonRpcTransport.js.map +1 -1
  238. package/lib/execution/engine/mock.d.ts +1 -0
  239. package/lib/execution/engine/mock.d.ts.map +1 -1
  240. package/lib/execution/engine/mock.js +31 -7
  241. package/lib/execution/engine/mock.js.map +1 -1
  242. package/lib/execution/engine/payloadIdCache.d.ts +5 -3
  243. package/lib/execution/engine/payloadIdCache.d.ts.map +1 -1
  244. package/lib/execution/engine/payloadIdCache.js +15 -4
  245. package/lib/execution/engine/payloadIdCache.js.map +1 -1
  246. package/lib/execution/engine/restTransport.d.ts +5 -2
  247. package/lib/execution/engine/restTransport.d.ts.map +1 -1
  248. package/lib/execution/engine/restTransport.js +36 -21
  249. package/lib/execution/engine/restTransport.js.map +1 -1
  250. package/lib/execution/engine/sszTypes.d.ts +38 -38
  251. package/lib/execution/engine/transport.d.ts +5 -2
  252. package/lib/execution/engine/transport.d.ts.map +1 -1
  253. package/lib/execution/engine/transportMetrics.d.ts +5 -1
  254. package/lib/execution/engine/transportMetrics.d.ts.map +1 -1
  255. package/lib/execution/engine/types.d.ts +25 -1
  256. package/lib/execution/engine/types.d.ts.map +1 -1
  257. package/lib/execution/engine/types.js +31 -17
  258. package/lib/execution/engine/types.js.map +1 -1
  259. package/lib/index.d.ts +1 -0
  260. package/lib/index.d.ts.map +1 -1
  261. package/lib/index.js +2 -0
  262. package/lib/index.js.map +1 -1
  263. package/lib/metrics/metrics/beacon.d.ts +16 -0
  264. package/lib/metrics/metrics/beacon.d.ts.map +1 -1
  265. package/lib/metrics/metrics/beacon.js +35 -0
  266. package/lib/metrics/metrics/beacon.js.map +1 -1
  267. package/lib/metrics/metrics/lodestar.d.ts +26 -0
  268. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  269. package/lib/metrics/metrics/lodestar.js +61 -1
  270. package/lib/metrics/metrics/lodestar.js.map +1 -1
  271. package/lib/monitoring/service.js +1 -1
  272. package/lib/monitoring/service.js.map +1 -1
  273. package/lib/network/core/networkCore.d.ts +2 -0
  274. package/lib/network/core/networkCore.d.ts.map +1 -1
  275. package/lib/network/core/networkCore.js +3 -0
  276. package/lib/network/core/networkCore.js.map +1 -1
  277. package/lib/network/core/networkCoreWorker.js +1 -0
  278. package/lib/network/core/networkCoreWorker.js.map +1 -1
  279. package/lib/network/core/networkCoreWorkerHandler.d.ts +2 -0
  280. package/lib/network/core/networkCoreWorkerHandler.d.ts.map +1 -1
  281. package/lib/network/core/networkCoreWorkerHandler.js +3 -0
  282. package/lib/network/core/networkCoreWorkerHandler.js.map +1 -1
  283. package/lib/network/core/types.d.ts +2 -0
  284. package/lib/network/core/types.d.ts.map +1 -1
  285. package/lib/network/gossip/gossipsub.d.ts.map +1 -1
  286. package/lib/network/gossip/gossipsub.js +3 -1
  287. package/lib/network/gossip/gossipsub.js.map +1 -1
  288. package/lib/network/gossip/interface.d.ts +8 -2
  289. package/lib/network/gossip/interface.d.ts.map +1 -1
  290. package/lib/network/gossip/interface.js +1 -0
  291. package/lib/network/gossip/interface.js.map +1 -1
  292. package/lib/network/gossip/topic.d.ts +13 -19
  293. package/lib/network/gossip/topic.d.ts.map +1 -1
  294. package/lib/network/gossip/topic.js +13 -1
  295. package/lib/network/gossip/topic.js.map +1 -1
  296. package/lib/network/interface.d.ts +4 -1
  297. package/lib/network/interface.d.ts.map +1 -1
  298. package/lib/network/network.d.ts +4 -1
  299. package/lib/network/network.d.ts.map +1 -1
  300. package/lib/network/network.js +11 -1
  301. package/lib/network/network.js.map +1 -1
  302. package/lib/network/peers/peerManager.d.ts +2 -1
  303. package/lib/network/peers/peerManager.d.ts.map +1 -1
  304. package/lib/network/peers/peerManager.js.map +1 -1
  305. package/lib/network/peers/utils/assertPeerRelevance.d.ts +9 -1
  306. package/lib/network/peers/utils/assertPeerRelevance.d.ts.map +1 -1
  307. package/lib/network/peers/utils/assertPeerRelevance.js +32 -21
  308. package/lib/network/peers/utils/assertPeerRelevance.js.map +1 -1
  309. package/lib/network/peers/utils/enrSubnetsDeserialize.d.ts.map +1 -1
  310. package/lib/network/peers/utils/enrSubnetsDeserialize.js +5 -2
  311. package/lib/network/peers/utils/enrSubnetsDeserialize.js.map +1 -1
  312. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  313. package/lib/network/processor/gossipHandlers.js +76 -27
  314. package/lib/network/processor/gossipHandlers.js.map +1 -1
  315. package/lib/network/processor/gossipQueues/index.d.ts.map +1 -1
  316. package/lib/network/processor/gossipQueues/index.js +6 -0
  317. package/lib/network/processor/gossipQueues/index.js.map +1 -1
  318. package/lib/network/processor/gossipValidatorFn.d.ts.map +1 -1
  319. package/lib/network/processor/gossipValidatorFn.js +5 -1
  320. package/lib/network/processor/gossipValidatorFn.js.map +1 -1
  321. package/lib/network/processor/index.d.ts +5 -0
  322. package/lib/network/processor/index.d.ts.map +1 -1
  323. package/lib/network/processor/index.js +40 -29
  324. package/lib/network/processor/index.js.map +1 -1
  325. package/lib/network/reqresp/ReqRespBeaconNode.d.ts.map +1 -1
  326. package/lib/network/reqresp/ReqRespBeaconNode.js +6 -0
  327. package/lib/network/reqresp/ReqRespBeaconNode.js.map +1 -1
  328. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
  329. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +4 -4
  330. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
  331. package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js +3 -3
  332. package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js.map +1 -1
  333. package/lib/network/reqresp/handlers/inclusionListsByIndices.d.ts +10 -0
  334. package/lib/network/reqresp/handlers/inclusionListsByIndices.d.ts.map +1 -0
  335. package/lib/network/reqresp/handlers/inclusionListsByIndices.js +30 -0
  336. package/lib/network/reqresp/handlers/inclusionListsByIndices.js.map +1 -0
  337. package/lib/network/reqresp/handlers/index.d.ts.map +1 -1
  338. package/lib/network/reqresp/handlers/index.js +5 -0
  339. package/lib/network/reqresp/handlers/index.js.map +1 -1
  340. package/lib/network/reqresp/protocols.d.ts +1 -0
  341. package/lib/network/reqresp/protocols.d.ts.map +1 -1
  342. package/lib/network/reqresp/protocols.js +5 -0
  343. package/lib/network/reqresp/protocols.js.map +1 -1
  344. package/lib/network/reqresp/rateLimit.d.ts.map +1 -1
  345. package/lib/network/reqresp/rateLimit.js +6 -2
  346. package/lib/network/reqresp/rateLimit.js.map +1 -1
  347. package/lib/network/reqresp/types.d.ts +5 -2
  348. package/lib/network/reqresp/types.d.ts.map +1 -1
  349. package/lib/network/reqresp/types.js +3 -0
  350. package/lib/network/reqresp/types.js.map +1 -1
  351. package/lib/network/subnets/attnetsService.d.ts.map +1 -1
  352. package/lib/network/subnets/attnetsService.js +3 -1
  353. package/lib/network/subnets/attnetsService.js.map +1 -1
  354. package/lib/node/nodejs.d.ts +1 -1
  355. package/lib/node/nodejs.d.ts.map +1 -1
  356. package/lib/node/nodejs.js +10 -2
  357. package/lib/node/nodejs.js.map +1 -1
  358. package/lib/node/notifier.d.ts.map +1 -1
  359. package/lib/node/notifier.js +12 -13
  360. package/lib/node/notifier.js.map +1 -1
  361. package/lib/node/options.d.ts +1 -1
  362. package/lib/node/options.d.ts.map +1 -1
  363. package/lib/node/options.js +1 -1
  364. package/lib/node/options.js.map +1 -1
  365. package/lib/sync/interface.d.ts.map +1 -1
  366. package/lib/sync/interface.js.map +1 -1
  367. package/lib/sync/sync.d.ts +7 -0
  368. package/lib/sync/sync.d.ts.map +1 -1
  369. package/lib/sync/sync.js +61 -3
  370. package/lib/sync/sync.js.map +1 -1
  371. package/lib/sync/unknownBlock.d.ts.map +1 -1
  372. package/lib/sync/unknownBlock.js +45 -20
  373. package/lib/sync/unknownBlock.js.map +1 -1
  374. package/lib/util/clock.d.ts.map +1 -1
  375. package/lib/util/clock.js +3 -4
  376. package/lib/util/clock.js.map +1 -1
  377. package/lib/util/file.d.ts.map +1 -1
  378. package/lib/util/file.js +8 -9
  379. package/lib/util/file.js.map +1 -1
  380. package/lib/util/queue/itemQueue.js +1 -1
  381. package/lib/util/queue/itemQueue.js.map +1 -1
  382. package/lib/util/sszBytes.d.ts +2 -2
  383. package/lib/util/sszBytes.d.ts.map +1 -1
  384. package/lib/util/sszBytes.js +24 -16
  385. package/lib/util/sszBytes.js.map +1 -1
  386. package/package.json +31 -32
  387. package/src/api/impl/api.ts +1 -1
  388. package/src/api/impl/beacon/blocks/index.ts +67 -65
  389. package/src/api/impl/beacon/index.ts +3 -1
  390. package/src/api/impl/beacon/pool/index.ts +5 -1
  391. package/src/api/impl/beacon/state/index.ts +10 -1
  392. package/src/api/impl/beacon/state/utils.ts +20 -10
  393. package/src/api/impl/debug/index.ts +4 -0
  394. package/src/api/impl/validator/index.ts +176 -29
  395. package/src/api/options.ts +3 -0
  396. package/src/chain/ColumnReconstructionTracker.ts +63 -46
  397. package/src/chain/GetBlobsTracker.ts +97 -38
  398. package/src/chain/archiveStore/archiveStore.ts +1 -0
  399. package/src/chain/archiveStore/utils/archiveBlocks.ts +78 -133
  400. package/src/chain/blocks/blockInput/blockInput.ts +1 -1
  401. package/src/chain/blocks/blockInput/utils.ts +2 -2
  402. package/src/chain/blocks/importBlock.ts +19 -18
  403. package/src/chain/blocks/importExecutionPayload.ts +81 -23
  404. package/src/chain/blocks/index.ts +6 -2
  405. package/src/chain/blocks/payloadEnvelopeProcessor.ts +35 -24
  406. package/src/chain/blocks/types.ts +5 -0
  407. package/src/chain/blocks/verifyBlock.ts +1 -0
  408. package/src/chain/blocks/verifyBlocksDataAvailability.ts +10 -1
  409. package/src/chain/blocks/verifyPayloadsDataAvailability.ts +14 -6
  410. package/src/chain/bls/multithread/index.ts +5 -5
  411. package/src/chain/bls/multithread/types.ts +1 -1
  412. package/src/chain/bls/multithread/worker.ts +1 -5
  413. package/src/chain/bls/singleThread.ts +1 -1
  414. package/src/chain/bls/utils.ts +1 -1
  415. package/src/chain/chain.ts +13 -7
  416. package/src/chain/errors/blockError.ts +1 -1
  417. package/src/chain/errors/executionPayloadBid.ts +12 -0
  418. package/src/chain/errors/inclusionList.ts +38 -0
  419. package/src/chain/errors/index.ts +1 -0
  420. package/src/chain/interface.ts +6 -4
  421. package/src/chain/opPools/aggregatedAttestationPool.ts +25 -9
  422. package/src/chain/opPools/attestationPool.ts +16 -4
  423. package/src/chain/opPools/inclusionListStore.ts +208 -0
  424. package/src/chain/opPools/index.ts +1 -0
  425. package/src/chain/opPools/payloadAttestationPool.ts +18 -7
  426. package/src/chain/opPools/syncCommitteeMessagePool.ts +10 -3
  427. package/src/chain/opPools/syncContributionAndProofPool.ts +13 -3
  428. package/src/chain/opPools/utils.ts +1 -1
  429. package/src/chain/options.ts +0 -2
  430. package/src/chain/prepareNextSlot.ts +7 -3
  431. package/src/chain/produceBlock/computeNewStateRoot.ts +9 -2
  432. package/src/chain/produceBlock/produceBlockBody.ts +70 -24
  433. package/src/chain/regen/interface.ts +1 -1
  434. package/src/chain/reprocess.ts +2 -1
  435. package/src/chain/seenCache/seenGossipBlockInput.ts +2 -1
  436. package/src/chain/stateCache/persistentCheckpointsCache.ts +4 -1
  437. package/src/chain/validation/executionPayloadBid.ts +54 -183
  438. package/src/chain/validation/inclusionList.ts +192 -0
  439. package/src/chain/validation/index.ts +1 -0
  440. package/src/chain/validatorMonitor.ts +7 -4
  441. package/src/constants/constants.ts +1 -0
  442. package/src/db/beacon.ts +44 -0
  443. package/src/db/dataColumnStore.ts +2 -4
  444. package/src/db/flatFileStore/flatFileStore.ts +7 -7
  445. package/src/db/flatFileStore/slotIndex.ts +4 -3
  446. package/src/db/interface.ts +2 -0
  447. package/src/db/repositories/blockArchive.ts +2 -2
  448. package/src/db/repositories/blockArchiveIndex.ts +2 -3
  449. package/src/db/repositories/dataColumnSidecarArchive.ts +20 -0
  450. package/src/execution/builder/validateBid.ts +23 -2
  451. package/src/execution/engine/blobVersionedHashes.ts +1 -1
  452. package/src/execution/engine/disabled.ts +4 -0
  453. package/src/execution/engine/http.ts +40 -5
  454. package/src/execution/engine/index.ts +3 -2
  455. package/src/execution/engine/interface.ts +28 -4
  456. package/src/execution/engine/jsonRpcHttpClient.ts +12 -5
  457. package/src/execution/engine/jsonRpcTransport.ts +46 -9
  458. package/src/execution/engine/mock.ts +32 -7
  459. package/src/execution/engine/payloadIdCache.ts +24 -6
  460. package/src/execution/engine/restTransport.ts +68 -23
  461. package/src/execution/engine/transport.ts +7 -2
  462. package/src/execution/engine/transportMetrics.ts +2 -1
  463. package/src/execution/engine/types.ts +56 -17
  464. package/src/index.ts +2 -0
  465. package/src/metrics/metrics/beacon.ts +37 -0
  466. package/src/metrics/metrics/lodestar.ts +63 -1
  467. package/src/monitoring/service.ts +1 -1
  468. package/src/network/core/networkCore.ts +5 -0
  469. package/src/network/core/networkCoreWorker.ts +1 -0
  470. package/src/network/core/networkCoreWorkerHandler.ts +4 -0
  471. package/src/network/core/types.ts +2 -0
  472. package/src/network/gossip/gossipsub.ts +3 -1
  473. package/src/network/gossip/interface.ts +5 -0
  474. package/src/network/gossip/topic.ts +14 -0
  475. package/src/network/interface.ts +4 -0
  476. package/src/network/network.ts +19 -1
  477. package/src/network/peers/peerManager.ts +1 -1
  478. package/src/network/peers/utils/assertPeerRelevance.ts +39 -23
  479. package/src/network/peers/utils/enrSubnetsDeserialize.ts +5 -2
  480. package/src/network/processor/gossipHandlers.ts +96 -29
  481. package/src/network/processor/gossipQueues/index.ts +6 -0
  482. package/src/network/processor/gossipValidatorFn.ts +5 -0
  483. package/src/network/processor/index.ts +36 -27
  484. package/src/network/processor/types.ts +1 -1
  485. package/src/network/reqresp/ReqRespBeaconNode.ts +7 -0
  486. package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +4 -10
  487. package/src/network/reqresp/handlers/dataColumnSidecarsByRoot.ts +3 -3
  488. package/src/network/reqresp/handlers/inclusionListsByIndices.ts +44 -0
  489. package/src/network/reqresp/handlers/index.ts +5 -0
  490. package/src/network/reqresp/protocols.ts +6 -0
  491. package/src/network/reqresp/rateLimit.ts +6 -2
  492. package/src/network/reqresp/types.ts +6 -0
  493. package/src/network/subnets/attnetsService.ts +8 -3
  494. package/src/node/nodejs.ts +24 -7
  495. package/src/node/notifier.ts +14 -13
  496. package/src/node/options.ts +4 -5
  497. package/src/sync/interface.ts +1 -0
  498. package/src/sync/sync.ts +65 -4
  499. package/src/sync/unknownBlock.ts +50 -30
  500. package/src/util/clock.ts +3 -4
  501. package/src/util/file.ts +8 -9
  502. package/src/util/queue/itemQueue.ts +1 -1
  503. package/src/util/sszBytes.ts +27 -14
@@ -0,0 +1,44 @@
1
+ import {PeerId} from "@libp2p/interface";
2
+ import {ResponseOutgoing} from "@lodestar/reqresp";
3
+ import {computeEpochAtSlot, computeStartSlotAtEpoch} from "@lodestar/state-transition";
4
+ import {heze, ssz} from "@lodestar/types";
5
+ import {toRootHex} from "@lodestar/utils";
6
+ import {IBeaconChain} from "../../../chain/index.js";
7
+ import {prettyPrintPeerId} from "../../util.js";
8
+
9
+ /**
10
+ * Only lists that passed gossip validation are stored and the store skips equivocators, so the spec's
11
+ * "SHOULD NOT respond with lists that fail gossip validation or are from equivocators" holds by construction.
12
+ */
13
+ export async function* onInclusionListsByIndices(
14
+ requestBody: heze.InclusionListsByIndicesRequest,
15
+ chain: IBeaconChain,
16
+ peerId: PeerId,
17
+ peerClient: string
18
+ ): AsyncIterable<ResponseOutgoing> {
19
+ const {slot, dependentRoot, indices} = requestBody;
20
+
21
+ const minimumRequestSlot = Math.max(
22
+ chain.clock.currentSlot - chain.config.MIN_SLOTS_FOR_INCLUSION_LISTS_REQUESTS,
23
+ computeStartSlotAtEpoch(chain.config.HEZE_FORK_EPOCH)
24
+ );
25
+ if (slot < minimumRequestSlot) {
26
+ chain.logger.debug("Cannot serve InclusionListsByIndices: slot below minimum request slot", {
27
+ slot,
28
+ minimumRequestSlot,
29
+ peer: prettyPrintPeerId(peerId),
30
+ client: peerClient,
31
+ });
32
+ return;
33
+ }
34
+
35
+ const signedInclusionLists = chain.inclusionListStore.getByIndices(slot, toRootHex(dependentRoot), indices);
36
+
37
+ const boundary = chain.config.getForkBoundaryAtEpoch(computeEpochAtSlot(slot));
38
+ for (const signedInclusionList of signedInclusionLists.slice(0, chain.config.MAX_REQUEST_INCLUSION_LIST)) {
39
+ yield {
40
+ data: ssz.heze.SignedInclusionList.serialize(signedInclusionList),
41
+ boundary,
42
+ };
43
+ }
44
+ }
@@ -19,6 +19,7 @@ import {onDataColumnSidecarsByRange} from "./dataColumnSidecarsByRange.js";
19
19
  import {onDataColumnSidecarsByRoot} from "./dataColumnSidecarsByRoot.js";
20
20
  import {onExecutionPayloadEnvelopesByRange} from "./executionPayloadEnvelopesByRange.js";
21
21
  import {onExecutionPayloadEnvelopesByRoot} from "./executionPayloadEnvelopesByRoot.js";
22
+ import {onInclusionListsByIndices} from "./inclusionListsByIndices.js";
22
23
  import {onLightClientBootstrap} from "./lightClientBootstrap.js";
23
24
  import {onLightClientFinalityUpdate} from "./lightClientFinalityUpdate.js";
24
25
  import {onLightClientOptimisticUpdate} from "./lightClientOptimisticUpdate.js";
@@ -142,6 +143,10 @@ export function getReqRespHandlers({db, chain}: {db: IBeaconDb; chain: IBeaconCh
142
143
  },
143
144
  [ReqRespMethod.LightClientFinalityUpdate]: () => onLightClientFinalityUpdate(chain),
144
145
  [ReqRespMethod.LightClientOptimisticUpdate]: () => onLightClientOptimisticUpdate(chain),
146
+ [ReqRespMethod.InclusionListsByIndices]: (req, peerId, peerClient) => {
147
+ const body = deserializeRequestBody(ssz.heze.InclusionListsByIndicesRequest, req.data);
148
+ return onInclusionListsByIndices(body, chain, peerId, peerClient);
149
+ },
145
150
  };
146
151
 
147
152
  return (method) => handlers[method];
@@ -113,6 +113,12 @@ export const ExecutionPayloadEnvelopesByRange = toProtocol({
113
113
  contextBytesType: ContextBytesType.ForkDigest,
114
114
  });
115
115
 
116
+ export const InclusionListsByIndices = toProtocol({
117
+ method: ReqRespMethod.InclusionListsByIndices,
118
+ version: Version.V1,
119
+ contextBytesType: ContextBytesType.ForkDigest,
120
+ });
121
+
116
122
  export const LightClientBootstrap = toProtocol({
117
123
  method: ReqRespMethod.LightClientBootstrap,
118
124
  version: Version.V1,
@@ -107,12 +107,16 @@ export const rateLimitQuotas: (fork: ForkName, config: BeaconConfig) => Record<R
107
107
  [ReqRespMethod.LightClientFinalityUpdate]: {
108
108
  // Finality updates should not be requested more than once per epoch.
109
109
  // Allow 2 per slot and a very safe bound until there's more testing of real usage.
110
- byPeer: {quota: 2, quotaTimeMs: 12_000},
110
+ byPeer: {quota: 2, quotaTimeMs: config.getSlotDurationMs(fork)},
111
+ },
112
+ [ReqRespMethod.InclusionListsByIndices]: {
113
+ // Peers only backfill what gossip missed, so a small per-slot allowance is enough
114
+ byPeer: {quota: 5, quotaTimeMs: config.getSlotDurationMs(fork)},
111
115
  },
112
116
  [ReqRespMethod.LightClientOptimisticUpdate]: {
113
117
  // Optimistic updates should not be requested more than once per slot.
114
118
  // Allow 2 per slot and a very safe bound until there's more testing of real usage.
115
- byPeer: {quota: 2, quotaTimeMs: 12_000},
119
+ byPeer: {quota: 2, quotaTimeMs: config.getSlotDurationMs(fork)},
116
120
  },
117
121
  });
118
122
 
@@ -16,6 +16,7 @@ import {
16
16
  deneb,
17
17
  fulu,
18
18
  gloas,
19
+ heze,
19
20
  phase0,
20
21
  ssz,
21
22
  sszTypesFor,
@@ -53,6 +54,7 @@ export enum ReqRespMethod {
53
54
  LightClientUpdatesByRange = "light_client_updates_by_range",
54
55
  LightClientFinalityUpdate = "light_client_finality_update",
55
56
  LightClientOptimisticUpdate = "light_client_optimistic_update",
57
+ InclusionListsByIndices = "inclusion_lists_by_indices",
56
58
  }
57
59
 
58
60
  // To typesafe events to network
@@ -74,6 +76,7 @@ export type RequestBodyByMethod = {
74
76
  [ReqRespMethod.LightClientUpdatesByRange]: altair.LightClientUpdatesByRange;
75
77
  [ReqRespMethod.LightClientFinalityUpdate]: null;
76
78
  [ReqRespMethod.LightClientOptimisticUpdate]: null;
79
+ [ReqRespMethod.InclusionListsByIndices]: heze.InclusionListsByIndicesRequest;
77
80
  };
78
81
 
79
82
  type ResponseBodyByMethod = {
@@ -96,6 +99,7 @@ type ResponseBodyByMethod = {
96
99
  [ReqRespMethod.LightClientUpdatesByRange]: LightClientUpdate;
97
100
  [ReqRespMethod.LightClientFinalityUpdate]: LightClientFinalityUpdate;
98
101
  [ReqRespMethod.LightClientOptimisticUpdate]: LightClientOptimisticUpdate;
102
+ [ReqRespMethod.InclusionListsByIndices]: heze.SignedInclusionList;
99
103
  };
100
104
 
101
105
  /** Request SSZ type for each method and ForkName */
@@ -126,6 +130,7 @@ export const requestSszTypeByMethod: (
126
130
  [ReqRespMethod.LightClientUpdatesByRange]: ssz.altair.LightClientUpdatesByRange,
127
131
  [ReqRespMethod.LightClientFinalityUpdate]: null,
128
132
  [ReqRespMethod.LightClientOptimisticUpdate]: null,
133
+ [ReqRespMethod.InclusionListsByIndices]: ssz.heze.InclusionListsByIndicesRequest,
129
134
  });
130
135
 
131
136
  export type ResponseTypeGetter<T> = (fork: ForkName, version: number) => Type<T>;
@@ -158,6 +163,7 @@ export const responseSszTypeByMethod: {[K in ReqRespMethod]: ResponseTypeGetter<
158
163
  [ReqRespMethod.ExecutionPayloadEnvelopesByRange]: () => ssz.gloas.SignedExecutionPayloadEnvelope,
159
164
  [ReqRespMethod.LightClientOptimisticUpdate]: (fork) =>
160
165
  sszTypesFor(onlyPostAltairFork(fork)).LightClientOptimisticUpdate,
166
+ [ReqRespMethod.InclusionListsByIndices]: () => ssz.heze.SignedInclusionList,
161
167
  };
162
168
 
163
169
  function onlyPostAltairFork(fork: ForkName): ForkPostAltair {
@@ -3,6 +3,7 @@ import {ATTESTATION_SUBNET_COUNT, SLOTS_PER_EPOCH} from "@lodestar/params";
3
3
  import {computeEpochAtSlot} from "@lodestar/state-transition";
4
4
  import {Epoch, Slot, SubnetID, ssz} from "@lodestar/types";
5
5
  import {Logger, MapDef} from "@lodestar/utils";
6
+ import {HALF_SLOT_BPS} from "../../constants/index.js";
6
7
  import {ClockEvent, IClock} from "../../util/clock.js";
7
8
  import {NetworkCoreMetrics} from "../core/metrics.js";
8
9
  import {getActiveForkBoundaries} from "../forks.js";
@@ -163,9 +164,13 @@ export class AttnetsService implements IAttnetsService {
163
164
  */
164
165
  private onSlot = (clockSlot: Slot): void => {
165
166
  try {
166
- setTimeout(() => {
167
- this.onHalfSlot(clockSlot);
168
- }, this.config.SLOT_DURATION_MS * 0.5);
167
+ const fork = this.config.getForkName(clockSlot);
168
+ setTimeout(
169
+ () => {
170
+ this.onHalfSlot(clockSlot);
171
+ },
172
+ this.config.getSlotComponentDurationMs(fork, HALF_SLOT_BPS)
173
+ );
169
174
 
170
175
  for (const [dutiedSlot, dutiedInfo] of this.aggregatorSlotSubnet.entries()) {
171
176
  if (dutiedSlot === clockSlot + this.opts.slotsToSubscribeBeforeAggregatorDuty) {
@@ -1,23 +1,29 @@
1
1
  import {setMaxListeners} from "node:events";
2
2
  import {PrivateKey} from "@libp2p/interface";
3
3
  import {Registry} from "prom-client";
4
+ import {hasher} from "@chainsafe/persistent-merkle-tree";
5
+ import {BeaconApiMethods} from "@lodestar/api/beacon/server";
6
+ import {BeaconConfig} from "@lodestar/config";
7
+ import type {LoggerNode} from "@lodestar/logger/node";
4
8
  import {
5
9
  init as initNativeMetrics,
6
10
  registerLocalValidator as registerNativeLocalValidator,
7
11
  scrapeMetrics as scrapeNativeMetrics,
8
12
  unregisterLocalValidator as unregisterNativeLocalValidator,
9
- } from "@chainsafe/lodestar-z/metrics";
10
- import {type PubkeyCache} from "@chainsafe/lodestar-z/pubkeys";
11
- import {hasher} from "@chainsafe/persistent-merkle-tree";
12
- import {BeaconApiMethods} from "@lodestar/api/beacon/server";
13
- import {BeaconConfig} from "@lodestar/config";
14
- import type {LoggerNode} from "@lodestar/logger/node";
13
+ } from "@lodestar/native/metrics";
14
+ import {type PubkeyCache} from "@lodestar/native/pubkeys";
15
15
  import {ZERO_HASH_HEX} from "@lodestar/params";
16
- import {IBeaconStateView, isStatePostBellatrix, isStatePostGloas} from "@lodestar/state-transition";
16
+ import {
17
+ IBeaconStateView,
18
+ computeStartSlotAtEpoch,
19
+ isStatePostBellatrix,
20
+ isStatePostGloas,
21
+ } from "@lodestar/state-transition";
17
22
  import {Slot} from "@lodestar/types";
18
23
  import {sleep, toRootHex} from "@lodestar/utils";
19
24
  import {ProcessShutdownCallback} from "@lodestar/validator";
20
25
  import {BeaconRestApiServer, getApi} from "../api/index.js";
26
+ import {getDataColumnSidecarsMinEpoch} from "../chain/archiveStore/utils/archiveBlocks.js";
21
27
  import {BeaconChain, IBeaconChain, initBeaconMetrics} from "../chain/index.js";
22
28
  import {ValidatorMonitor, createValidatorMonitor} from "../chain/validatorMonitor.js";
23
29
  import {IBeaconDb} from "../db/index.js";
@@ -212,6 +218,17 @@ export class BeaconNode {
212
218
 
213
219
  const clock = new Clock({config, genesisTime: anchorState.genesisTime, signal});
214
220
 
221
+ // Before any lookup into the legacy column buckets, which can be slow until compacted
222
+ const columnsMinEpoch =
223
+ opts.chain.archiveDataEpochs === Infinity
224
+ ? null
225
+ : getDataColumnSidecarsMinEpoch(config, clock.currentEpoch, opts.chain.archiveDataEpochs);
226
+ await db.compactLegacyDataColumns(
227
+ columnsMinEpoch !== null && columnsMinEpoch >= config.FULU_FORK_EPOCH
228
+ ? computeStartSlotAtEpoch(columnsMinEpoch)
229
+ : 0
230
+ );
231
+
215
232
  await db.init();
216
233
 
217
234
  // Prune hot db repos
@@ -5,6 +5,7 @@ import {
5
5
  IBeaconStateView,
6
6
  computeEpochAtSlot,
7
7
  computeStartSlotAtEpoch,
8
+ computeTimeAtSlot,
8
9
  isStatePostBellatrix,
9
10
  } from "@lodestar/state-transition";
10
11
  import {Epoch} from "@lodestar/types";
@@ -140,21 +141,21 @@ export async function runNodeNotifier(modules: NodeNotifierModules): Promise<voi
140
141
  }
141
142
 
142
143
  function timeToNextHalfSlot(config: BeaconConfig, chain: IBeaconChain, isFirstTime: boolean): number {
143
- const msPerSlot = config.SLOT_DURATION_MS;
144
- const msPerHalfSlot = msPerSlot / 2;
145
- const msFromGenesis = Date.now() - chain.genesisTime * 1000;
146
- const msToNextSlot =
147
- msFromGenesis < 0
148
- ? // For future genesis time, calculate time left in the slot
149
- -msFromGenesis % msPerSlot
150
- : // For past genesis time, calculate time until the next slot
151
- msPerSlot - (msFromGenesis % msPerSlot);
144
+ const currentSlot = chain.clock.currentSlot;
145
+ const nextSlotTimeSec = computeTimeAtSlot(config, currentSlot + 1, chain.genesisTime);
146
+ const nowMs = Date.now();
147
+
152
148
  if (isFirstTime) {
153
- // at the 1st time we may miss middle of the current clock slot
154
- return msToNextSlot > msPerHalfSlot ? msToNextSlot - msPerHalfSlot : msToNextSlot + msPerHalfSlot;
149
+ const currentSlotTimeSec = computeTimeAtSlot(config, currentSlot, chain.genesisTime);
150
+ const currentMidpointMs = ((currentSlotTimeSec + nextSlotTimeSec) / 2) * 1000;
151
+ if (currentMidpointMs > nowMs) {
152
+ return currentMidpointMs - nowMs;
153
+ }
155
154
  }
156
- // after the 1st time always wait until middle of next clock slot
157
- return msToNextSlot + msPerHalfSlot;
155
+
156
+ const nextSlotEndTimeSec = computeTimeAtSlot(config, currentSlot + 2, chain.genesisTime);
157
+ const nextMidpointMs = ((nextSlotTimeSec + nextSlotEndTimeSec) / 2) * 1000;
158
+ return Math.max(0, nextMidpointMs - nowMs);
158
159
  }
159
160
 
160
161
  function getHeadExecutionInfo(
@@ -19,16 +19,15 @@ import {SyncOptions, defaultSyncOptions} from "../sync/options.js";
19
19
 
20
20
  // Re-export so the CLI doesn't need to depend on lodestar-api
21
21
  export {allNamespaces} from "../api/rest/index.js";
22
-
22
+ export type {EngineApiMode};
23
23
  // Re-export to use as default values in CLI args
24
24
  export {
25
- defaultExecutionEngineHttpOpts,
26
- defaultExecutionBuilderHttpOpts,
27
- engineApiModes,
28
25
  ArchiveMode,
29
26
  DEFAULT_ARCHIVE_MODE,
27
+ defaultExecutionBuilderHttpOpts,
28
+ defaultExecutionEngineHttpOpts,
29
+ engineApiModes,
30
30
  };
31
- export type {EngineApiMode};
32
31
 
33
32
  export interface IBeaconNodeOptions {
34
33
  api: ApiOptions;
@@ -7,6 +7,7 @@ import {IBeaconDb} from "../db/index.js";
7
7
  import {Metrics} from "../metrics/index.js";
8
8
  import {INetwork} from "../network/index.js";
9
9
  import {SyncChainDebugState} from "./range/chain.js";
10
+
10
11
  export type {SyncChainDebugState};
11
12
 
12
13
  export type SyncingStatus = routes.node.SyncingStatus;
package/src/sync/sync.ts CHANGED
@@ -1,13 +1,17 @@
1
1
  import {SLOTS_PER_EPOCH} from "@lodestar/params";
2
- import {Slot} from "@lodestar/types";
2
+ import {computeStartSlotAtEpoch} from "@lodestar/state-transition";
3
+ import {Slot, Status} from "@lodestar/types";
3
4
  import {Logger, toRootHex} from "@lodestar/utils";
4
5
  import {IBeaconChain} from "../chain/index.js";
5
- import {GENESIS_SLOT} from "../constants/constants.js";
6
+ import {GENESIS_EPOCH, GENESIS_SLOT} from "../constants/constants.js";
7
+ import {GoodByeReasonCode} from "../constants/index.js";
8
+ import {IBeaconDb} from "../db/index.js";
6
9
  import {ExecutionEngineState} from "../execution/index.js";
7
10
  import {Metrics} from "../metrics/index.js";
8
- import {INetwork, NetworkEvent, NetworkEventData} from "../network/index.js";
11
+ import {INetwork, NetworkEvent, NetworkEventData, PeerAction} from "../network/index.js";
9
12
  import {ClockEvent} from "../util/clock.js";
10
13
  import {isOptimisticBlock} from "../util/forkChoice.js";
14
+ import {PeerIdStr} from "../util/peerId.js";
11
15
  import {MIN_EPOCH_TO_START_GOSSIP} from "./constants.js";
12
16
  import {IBeaconSync, SyncChainDebugState, SyncModules, SyncState, SyncingStatus, syncStateMetric} from "./interface.js";
13
17
  import {SyncOptions} from "./options.js";
@@ -19,6 +23,7 @@ export class BeaconSync implements IBeaconSync {
19
23
  private readonly logger: Logger;
20
24
  private readonly network: INetwork;
21
25
  private readonly chain: IBeaconChain;
26
+ private readonly db: IBeaconDb;
22
27
  private readonly metrics: Metrics | null;
23
28
  private readonly opts: SyncOptions;
24
29
 
@@ -30,10 +35,11 @@ export class BeaconSync implements IBeaconSync {
30
35
  private readonly slotImportTolerance: Slot;
31
36
 
32
37
  constructor(opts: SyncOptions, modules: SyncModules) {
33
- const {config, chain, metrics, network, logger} = modules;
38
+ const {config, chain, db, metrics, network, logger} = modules;
34
39
  this.opts = opts;
35
40
  this.network = network;
36
41
  this.chain = chain;
42
+ this.db = db;
37
43
  this.metrics = metrics;
38
44
  this.logger = logger;
39
45
  this.rangeSync = new RangeSync(modules, opts);
@@ -192,6 +198,11 @@ export class BeaconSync implements IBeaconSync {
192
198
  */
193
199
  private addPeer = (data: NetworkEventData[NetworkEvent.peerConnected]): void => {
194
200
  const localStatus = this.chain.getStatus();
201
+ // Genesis and equal finalized epochs are already checked by assertPeerRelevance in the network worker
202
+ if (data.status.finalizedEpoch > GENESIS_EPOCH && data.status.finalizedEpoch < localStatus.finalizedEpoch) {
203
+ void this.verifyPastFinalizedCheckpoint(data.peer, data.status);
204
+ }
205
+
195
206
  const syncType = getPeerSyncType(localStatus, data.status, this.chain.forkChoice, this.slotImportTolerance);
196
207
  this.logger.verbose("Peer sync type classified", {
197
208
  peer: data.peer,
@@ -216,6 +227,56 @@ export class BeaconSync implements IBeaconSync {
216
227
  this.updateSyncState();
217
228
  };
218
229
 
230
+ /**
231
+ * A behind peer's finalized checkpoint must be the canonical block in effect at the start slot of its epoch
232
+ */
233
+ async verifyPastFinalizedCheckpoint(peer: PeerIdStr, remote: Status): Promise<void> {
234
+ const startSlot = computeStartSlotAtEpoch(remote.finalizedEpoch);
235
+ const root = toRootHex(remote.finalizedRoot);
236
+ try {
237
+ let reason: string | null = null;
238
+ // After a finality jump, finalized blocks stay in fork choice until the archiver migrates them.
239
+ // Fork choice is pruned only after archiving, so a miss here means the db already has this range.
240
+ const canonicalBlock = this.chain.forkChoice.getCanonicalBlockClosestLteSlot(startSlot);
241
+ if (canonicalBlock !== null) {
242
+ if (canonicalBlock.blockRoot === root) return;
243
+ reason = "finalized_root_not_canonical";
244
+ } else {
245
+ const slot = await this.db.blockArchive.getSlotByRoot(remote.finalizedRoot);
246
+ if (slot !== null && slot > startSlot) {
247
+ reason = "finalized_root_after_epoch_start";
248
+ } else if (slot !== startSlot) {
249
+ const childSlot = await this.db.blockArchive.getSlotByParentRoot(remote.finalizedRoot);
250
+ if (childSlot !== null) {
251
+ if (childSlot <= startSlot) reason = "finalized_root_not_in_effect_at_epoch_start";
252
+ } else if (slot === null && startSlot > this.chain.earliestAvailableSlot) {
253
+ // childSlot == null too, neither the root nor a child is canonical
254
+ // or they are canonical and both pruned but peer's finalized epoch starts after earliestAvailableSlot
255
+ reason = "unknown_finalized_root";
256
+ }
257
+ }
258
+ }
259
+
260
+ if (reason !== null) {
261
+ this.logger.debug("Peer finalized checkpoint not in our chain", {
262
+ peer,
263
+ finalizedEpoch: remote.finalizedEpoch,
264
+ root,
265
+ reason,
266
+ });
267
+ this.metrics?.syncPeerFinalizedCheckpointMismatch.inc({reason});
268
+ this.network.reportPeer(peer, PeerAction.Fatal, "PeerFinalizedCheckpointMismatch");
269
+ await this.network.goodbyeAndDisconnect(peer, GoodByeReasonCode.IRRELEVANT_NETWORK);
270
+ }
271
+ } catch (e) {
272
+ this.logger.debug(
273
+ "Error verifying peer finalized checkpoint",
274
+ {peer, finalizedEpoch: remote.finalizedEpoch, root},
275
+ e as Error
276
+ );
277
+ }
278
+ }
279
+
219
280
  /**
220
281
  * Must be called by libp2p when a peer is removed from the peer manager
221
282
  */
@@ -300,10 +300,19 @@ export class BlockInputSync {
300
300
 
301
301
  private onIncompletePayloadEnvelope = (data: ChainEventData[ChainEvent.incompletePayloadEnvelope]): void => {
302
302
  try {
303
- this.addByPayloadInput(data.payloadInput, data.peer);
304
- this.triggerUnknownBlockSearch();
305
- this.metrics?.blockInputSync.requests.inc({type: PendingBlockType.INCOMPLETE_PAYLOAD_ENVELOPE});
306
- this.metrics?.blockInputSync.payloadSource.inc({source: data.source});
303
+ const isNewRoot = this.addByPayloadInput(data.payloadInput, data.peer);
304
+ const pendingPayload = this.pendingPayloads.get(data.payloadInput.blockRootHex);
305
+ if (
306
+ pendingPayload &&
307
+ pendingPayload.status !== PendingPayloadInputStatus.fetching &&
308
+ pendingPayload.status !== PendingPayloadInputStatus.processing
309
+ ) {
310
+ this.triggerUnknownBlockSearch();
311
+ }
312
+ if (isNewRoot) {
313
+ this.metrics?.blockInputSync.requests.inc({type: PendingBlockType.INCOMPLETE_PAYLOAD_ENVELOPE});
314
+ this.metrics?.blockInputSync.payloadSource.inc({source: data.source});
315
+ }
307
316
  } catch (e) {
308
317
  this.logger.debug("Error handling incompletePayloadEnvelope event", {}, e as Error);
309
318
  }
@@ -599,43 +608,44 @@ export class BlockInputSync {
599
608
  return this.chain.seenPayloadEnvelopeInputCache.get(rootHex)?.slot;
600
609
  }
601
610
 
602
- private addByPayloadInput = (
603
- payloadInput: PayloadEnvelopeInput,
604
- peerIdStr?: PeerIdStr,
605
- envelope?: gloas.SignedExecutionPayloadEnvelope
606
- ): void => {
611
+ private addByPayloadInput = (payloadInput: PayloadEnvelopeInput, peerIdStr?: PeerIdStr): boolean => {
607
612
  if (this.knownBadBlocks.has(payloadInput.blockRootHex)) {
608
613
  this.logger.debug("Ignoring payload input for known bad block root", {
609
614
  slot: payloadInput.slot,
610
615
  root: payloadInput.blockRootHex,
611
616
  peerIdStr,
612
617
  });
613
- return;
618
+ return false;
614
619
  }
615
620
 
616
- const pendingPayload = this.toPendingPayloadInput(
617
- payloadInput,
618
- this.pendingPayloads.get(payloadInput.blockRootHex),
619
- envelope
620
- );
621
+ let pendingPayload = this.pendingPayloads.get(payloadInput.blockRootHex);
622
+ const isNewRoot = pendingPayload === undefined;
623
+ // Envelope-only entries must go through reconciliation to validate their speculative envelope.
624
+ if (
625
+ !pendingPayload ||
626
+ pendingPayload.status === PendingPayloadInputStatus.pending ||
627
+ pendingPayload.status === PendingPayloadInputStatus.downloaded
628
+ ) {
629
+ pendingPayload = this.toPendingPayloadInput(payloadInput, pendingPayload);
630
+ this.pendingPayloads.set(payloadInput.blockRootHex, pendingPayload);
631
+
632
+ this.logger.verbose("Added payloadInput to BlockInputSync.pendingPayloads", {
633
+ slot: payloadInput.slot,
634
+ root: payloadInput.blockRootHex,
635
+ delaySec: this.chain.clock.secFromSlot(payloadInput.slot),
636
+ });
637
+ }
621
638
 
622
639
  if (peerIdStr && pendingPayload.peerIdStrings.size < MAX_PEERS_PER_ROOT) {
623
640
  pendingPayload.peerIdStrings.add(peerIdStr);
624
641
  }
625
642
 
626
- this.pendingPayloads.set(payloadInput.blockRootHex, pendingPayload);
627
-
628
- this.logger.verbose("Added payloadInput to BlockInputSync.pendingPayloads", {
629
- slot: payloadInput.slot,
630
- root: payloadInput.blockRootHex,
631
- delaySec: this.chain.clock.secFromSlot(payloadInput.slot),
632
- });
633
-
634
643
  const prunedItemCount = pruneSetToMax(this.pendingPayloads, this.maxPendingBlocks);
635
644
  if (prunedItemCount > 0) {
636
645
  this.metrics?.blockInputSync.removedPayloads.inc({reason: DroppedItemReason.capacity}, prunedItemCount);
637
646
  this.logger.verbose(`Pruned ${prunedItemCount} items from BlockInputSync.pendingPayloads`);
638
647
  }
648
+ return isNewRoot;
639
649
  };
640
650
 
641
651
  private onPeerConnected = (data: NetworkEventData[NetworkEvent.peerConnected]): void => {
@@ -918,16 +928,17 @@ export class BlockInputSync {
918
928
  * Poll unknown payloads of the current slot.
919
929
  */
920
930
  private async pollPayloadsAtSlot(slot: Slot, signal: AbortSignal): Promise<void> {
931
+ const fork = this.config.getForkName(slot);
921
932
  // fixed tick count so the loop cannot outlive its slot: for mainnet, it's 6 ticks
922
933
  const tickCount = Math.floor(
923
- (this.config.SLOT_DURATION_MS - this.config.getPayloadDueMs()) / PAYLOAD_POLL_INTERVAL_MS
934
+ (this.config.getSlotDurationMs(fork) - this.config.getPayloadDueMs(fork)) / PAYLOAD_POLL_INTERVAL_MS
924
935
  );
925
936
  // a root still missing on several ticks is searched on each of them, recorded once
926
937
  const searchedRoots = new Set<RootHex>();
927
938
  let polls = 0;
928
939
 
929
940
  try {
930
- await sleep(Math.max(0, this.config.getPayloadDueMs() - this.chain.clock.msFromSlot(slot)), signal);
941
+ await sleep(Math.max(0, this.config.getPayloadDueMs(fork) - this.chain.clock.msFromSlot(slot)), signal);
931
942
 
932
943
  for (polls = 0; polls < tickCount; polls++) {
933
944
  let importedCount = 0;
@@ -1266,6 +1277,9 @@ export class BlockInputSync {
1266
1277
  }
1267
1278
 
1268
1279
  const payloadInput = await this.chain.seenPayloadEnvelopeInputCache.getOrReload(rootHex);
1280
+ if (this.pendingPayloads.get(rootHex) !== pendingPayload) {
1281
+ return;
1282
+ }
1269
1283
  if (!payloadInput) {
1270
1284
  this.logger.debug("PayloadEnvelopeInput not yet reloadable for imported block, will retry", {
1271
1285
  root: rootHex,
@@ -1277,6 +1291,9 @@ export class BlockInputSync {
1277
1291
  const validationResult = await wrapError(
1278
1292
  validateGossipExecutionPayloadEnvelope(this.chain, pendingPayload.envelope)
1279
1293
  );
1294
+ if (this.pendingPayloads.get(rootHex) !== pendingPayload) {
1295
+ return;
1296
+ }
1280
1297
  if (validationResult.err) {
1281
1298
  this.logger.debug(
1282
1299
  "Pending payload envelope failed validation after block import, refetching by root",
@@ -1344,14 +1361,13 @@ export class BlockInputSync {
1344
1361
  payload.status = PendingPayloadInputStatus.fetching;
1345
1362
 
1346
1363
  const res = await wrapError(this.fetchPayloadInput(payload));
1364
+ if (this.pendingPayloads.get(rootHex) !== payload) {
1365
+ this.logger.verbose("Dropping downloaded payload, entry changed during fetch", logCtx);
1366
+ return;
1367
+ }
1347
1368
  if (!res.err) {
1348
1369
  const pendingPayload = res.result;
1349
1370
  const resultRootHex = getPayloadSyncCacheItemRootHex(pendingPayload);
1350
- // finalization may have deleted this entry while we were awaiting the network, do not resurrect it via the set below
1351
- if (!this.pendingPayloads.has(resultRootHex)) {
1352
- this.logger.verbose("Dropping downloaded payload, entry pruned during fetch", logCtx);
1353
- return;
1354
- }
1355
1371
  this.pendingPayloads.set(resultRootHex, pendingPayload);
1356
1372
  const result = isPendingPayloadEnvelope(pendingPayload)
1357
1373
  ? DownloadResult.WaitingForBlock
@@ -1422,12 +1438,16 @@ export class BlockInputSync {
1422
1438
  this.logger.debug("Processing downloaded payload", logCtx);
1423
1439
 
1424
1440
  const res = await wrapError(this.chain.processExecutionPayload(pendingPayload.payloadInput));
1441
+ // The executionPayload event emitted during import usually removes the entry before this point
1425
1442
  if (!res.err) {
1426
1443
  this.logger.debug("Processed payload from unknown sync", logCtx);
1427
1444
  this.pendingPayloads.delete(rootHex);
1428
1445
  this.triggerUnknownBlockSearch();
1429
1446
  return;
1430
1447
  }
1448
+ if (this.pendingPayloads.get(rootHex) !== pendingPayload) {
1449
+ return;
1450
+ }
1431
1451
 
1432
1452
  if (res.err instanceof PayloadError) {
1433
1453
  switch (res.err.type.code) {
package/src/util/clock.ts CHANGED
@@ -78,9 +78,9 @@ export class Clock extends EventEmitter implements IClock {
78
78
 
79
79
  this.config = config;
80
80
  this.genesisTime = genesisTime;
81
- this.timeoutId = setTimeout(this.onNextSlot, this.msUntilNextSlot());
82
81
  this.signal = signal;
83
82
  this._currentSlot = getCurrentSlot(this.config, this.genesisTime);
83
+ this.timeoutId = setTimeout(this.onNextSlot, this.msUntilNextSlot());
84
84
  this.signal.addEventListener("abort", () => clearTimeout(this.timeoutId), {once: true});
85
85
  }
86
86
 
@@ -204,8 +204,7 @@ export class Clock extends EventEmitter implements IClock {
204
204
  };
205
205
 
206
206
  private msUntilNextSlot(): number {
207
- const milliSecondsPerSlot = this.config.SLOT_DURATION_MS;
208
- const diffInMilliSeconds = Date.now() - this.genesisTime * 1000;
209
- return milliSecondsPerSlot - (diffInMilliSeconds % milliSecondsPerSlot);
207
+ const nextSlotTimeSec = computeTimeAtSlot(this.config, this._currentSlot + 1, this.genesisTime);
208
+ return Math.max(0, nextSlotTimeSec * 1000 - Date.now());
210
209
  }
211
210
  }
package/src/util/file.ts CHANGED
@@ -1,25 +1,24 @@
1
- import fs from "node:fs";
2
- import {promisify} from "node:util";
1
+ import {readFile as fsReadFile, mkdir, readdir, stat, unlink, writeFile} from "node:fs/promises";
3
2
 
4
3
  /** Ensure a directory exists */
5
4
  export async function ensureDir(path: string): Promise<void> {
6
5
  try {
7
- await promisify(fs.stat)(path);
6
+ await stat(path);
8
7
  } catch (_) {
9
8
  // not exists
10
- await promisify(fs.mkdir)(path, {recursive: true});
9
+ await mkdir(path, {recursive: true});
11
10
  }
12
11
  }
13
12
 
14
13
  /** Write data to a file if it does not exist */
15
14
  export async function writeIfNotExist(filepath: string, bytes: Uint8Array): Promise<boolean> {
16
15
  try {
17
- await promisify(fs.stat)(filepath);
16
+ await stat(filepath);
18
17
  return false;
19
18
  // file exists, do nothing
20
19
  } catch (_) {
21
20
  // not exists
22
- await promisify(fs.writeFile)(filepath, bytes);
21
+ await writeFile(filepath, bytes);
23
22
  return true;
24
23
  }
25
24
  }
@@ -27,7 +26,7 @@ export async function writeIfNotExist(filepath: string, bytes: Uint8Array): Prom
27
26
  /** Remove a file if it exists */
28
27
  export async function removeFile(path: string): Promise<boolean> {
29
28
  try {
30
- await promisify(fs.unlink)(path);
29
+ await unlink(path);
31
30
  return true;
32
31
  } catch (_) {
33
32
  // may not exists
@@ -37,7 +36,7 @@ export async function removeFile(path: string): Promise<boolean> {
37
36
 
38
37
  export async function readFile(path: string): Promise<Uint8Array | null> {
39
38
  try {
40
- return await fs.promises.readFile(path);
39
+ return await fsReadFile(path);
41
40
  } catch (_) {
42
41
  return null;
43
42
  }
@@ -45,7 +44,7 @@ export async function readFile(path: string): Promise<Uint8Array | null> {
45
44
 
46
45
  export async function readFileNames(folderPath: string): Promise<string[]> {
47
46
  try {
48
- return await fs.promises.readdir(folderPath);
47
+ return await readdir(folderPath);
49
48
  } catch (_) {
50
49
  return [];
51
50
  }
@@ -69,7 +69,7 @@ export class JobItemQueue<Args extends any[], R> {
69
69
  if (this.jobs.length === 1 && this.opts.noYieldIfOneItem) {
70
70
  void this.runJob();
71
71
  } else if (this.runningJobs < this.opts.maxConcurrency) {
72
- callInNextEventLoop(this.runJob);
72
+ callInNextEventLoop(() => void this.runJob());
73
73
  }
74
74
  });
75
75
  }