@lodestar/beacon-node 1.34.1 → 1.35.0-dev.092cc3954a

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 (512) hide show
  1. package/lib/api/impl/beacon/blocks/index.js +71 -53
  2. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  3. package/lib/api/impl/beacon/pool/index.js +3 -3
  4. package/lib/api/impl/beacon/pool/index.js.map +1 -1
  5. package/lib/api/impl/debug/index.js +20 -9
  6. package/lib/api/impl/debug/index.js.map +1 -1
  7. package/lib/api/impl/errors.js +2 -0
  8. package/lib/api/impl/errors.js.map +1 -1
  9. package/lib/api/impl/index.d.ts +3 -3
  10. package/lib/api/impl/index.js +3 -3
  11. package/lib/api/impl/index.js.map +1 -1
  12. package/lib/api/impl/lodestar/index.js +1 -1
  13. package/lib/api/impl/lodestar/index.js.map +1 -1
  14. package/lib/api/impl/validator/index.js +2 -1
  15. package/lib/api/impl/validator/index.js.map +1 -1
  16. package/lib/api/rest/activeSockets.js +3 -2
  17. package/lib/api/rest/activeSockets.js.map +1 -1
  18. package/lib/api/rest/base.d.ts +1 -1
  19. package/lib/api/rest/base.js +6 -2
  20. package/lib/api/rest/base.js.map +1 -1
  21. package/lib/api/rest/index.js +2 -0
  22. package/lib/api/rest/index.js.map +1 -1
  23. package/lib/api/rest/swaggerUI.js +4 -2
  24. package/lib/api/rest/swaggerUI.js.map +1 -1
  25. package/lib/bun-wrappers/prometheus-gc-stats.d.ts +2 -0
  26. package/lib/bun-wrappers/prometheus-gc-stats.js +8 -0
  27. package/lib/bun-wrappers/prometheus-gc-stats.js.map +1 -0
  28. package/lib/chain/ColumnReconstructionTracker.d.ts +32 -0
  29. package/lib/chain/ColumnReconstructionTracker.js +71 -0
  30. package/lib/chain/ColumnReconstructionTracker.js.map +1 -0
  31. package/lib/chain/GetBlobsTracker.d.ts +31 -0
  32. package/lib/chain/GetBlobsTracker.js +82 -0
  33. package/lib/chain/GetBlobsTracker.js.map +1 -0
  34. package/lib/chain/archiveStore/archiveStore.js +49 -38
  35. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  36. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js +2 -0
  37. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js.map +1 -1
  38. package/lib/chain/archiveStore/index.d.ts +1 -1
  39. package/lib/chain/archiveStore/index.js +1 -1
  40. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js +5 -0
  41. package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js.map +1 -1
  42. package/lib/chain/archiveStore/utils/archiveBlocks.js +14 -7
  43. package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
  44. package/lib/chain/balancesCache.js +1 -3
  45. package/lib/chain/balancesCache.js.map +1 -1
  46. package/lib/chain/beaconProposerCache.js +1 -0
  47. package/lib/chain/beaconProposerCache.js.map +1 -1
  48. package/lib/chain/blocks/blockInput/blockInput.d.ts +19 -7
  49. package/lib/chain/blocks/blockInput/blockInput.js +132 -88
  50. package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
  51. package/lib/chain/blocks/blockInput/index.d.ts +1 -1
  52. package/lib/chain/blocks/blockInput/index.js +1 -1
  53. package/lib/chain/blocks/blockInput/types.d.ts +19 -10
  54. package/lib/chain/blocks/blockInput/types.js +1 -0
  55. package/lib/chain/blocks/blockInput/types.js.map +1 -1
  56. package/lib/chain/blocks/blockInput/utils.d.ts +0 -4
  57. package/lib/chain/blocks/blockInput/utils.js +6 -29
  58. package/lib/chain/blocks/blockInput/utils.js.map +1 -1
  59. package/lib/chain/blocks/importBlock.js +36 -32
  60. package/lib/chain/blocks/importBlock.js.map +1 -1
  61. package/lib/chain/blocks/index.d.ts +6 -5
  62. package/lib/chain/blocks/index.js +5 -4
  63. package/lib/chain/blocks/index.js.map +1 -1
  64. package/lib/chain/blocks/types.d.ts +3 -108
  65. package/lib/chain/blocks/types.js +0 -119
  66. package/lib/chain/blocks/types.js.map +1 -1
  67. package/lib/chain/blocks/utils/chainSegment.d.ts +2 -2
  68. package/lib/chain/blocks/utils/chainSegment.js +2 -2
  69. package/lib/chain/blocks/utils/chainSegment.js.map +1 -1
  70. package/lib/chain/blocks/verifyBlock.d.ts +3 -3
  71. package/lib/chain/blocks/verifyBlock.js +15 -14
  72. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  73. package/lib/chain/blocks/verifyBlocksDataAvailability.d.ts +7 -22
  74. package/lib/chain/blocks/verifyBlocksDataAvailability.js +18 -110
  75. package/lib/chain/blocks/verifyBlocksDataAvailability.js.map +1 -1
  76. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts +4 -3
  77. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +24 -22
  78. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
  79. package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts +4 -3
  80. package/lib/chain/blocks/verifyBlocksSanityChecks.js +2 -2
  81. package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
  82. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts +3 -2
  83. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +2 -2
  84. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
  85. package/lib/chain/blocks/writeBlockInputToDb.d.ts +3 -3
  86. package/lib/chain/blocks/writeBlockInputToDb.js +61 -63
  87. package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
  88. package/lib/chain/bls/multithread/index.js +167 -163
  89. package/lib/chain/bls/multithread/index.js.map +1 -1
  90. package/lib/chain/bls/singleThread.js +1 -0
  91. package/lib/chain/bls/singleThread.js.map +1 -1
  92. package/lib/chain/chain.d.ts +13 -11
  93. package/lib/chain/chain.js +79 -20
  94. package/lib/chain/chain.js.map +1 -1
  95. package/lib/chain/emitter.d.ts +43 -2
  96. package/lib/chain/emitter.js +18 -0
  97. package/lib/chain/emitter.js.map +1 -1
  98. package/lib/chain/errors/blobSidecarError.d.ts +24 -0
  99. package/lib/chain/errors/blobSidecarError.js +10 -0
  100. package/lib/chain/errors/blobSidecarError.js.map +1 -1
  101. package/lib/chain/errors/blockError.js +1 -0
  102. package/lib/chain/errors/blockError.js.map +1 -1
  103. package/lib/chain/errors/dataColumnSidecarError.d.ts +42 -0
  104. package/lib/chain/errors/dataColumnSidecarError.js +14 -0
  105. package/lib/chain/errors/dataColumnSidecarError.js.map +1 -1
  106. package/lib/chain/errors/gossipValidation.js +1 -0
  107. package/lib/chain/errors/gossipValidation.js.map +1 -1
  108. package/lib/chain/errors/index.d.ts +2 -2
  109. package/lib/chain/errors/index.js +2 -2
  110. package/lib/chain/errors/index.js.map +1 -1
  111. package/lib/chain/forkChoice/index.js.map +1 -1
  112. package/lib/chain/genesis/genesis.js +16 -5
  113. package/lib/chain/genesis/genesis.js.map +1 -1
  114. package/lib/chain/index.d.ts +2 -2
  115. package/lib/chain/index.js +2 -2
  116. package/lib/chain/index.js.map +1 -1
  117. package/lib/chain/interface.d.ts +13 -9
  118. package/lib/chain/interface.js.map +1 -1
  119. package/lib/chain/lightClient/index.js +16 -9
  120. package/lib/chain/lightClient/index.js.map +1 -1
  121. package/lib/chain/lightClient/proofs.js.map +1 -1
  122. package/lib/chain/opPools/aggregatedAttestationPool.js +14 -9
  123. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  124. package/lib/chain/opPools/attestationPool.js +8 -3
  125. package/lib/chain/opPools/attestationPool.js.map +1 -1
  126. package/lib/chain/opPools/index.d.ts +1 -1
  127. package/lib/chain/opPools/index.js +1 -1
  128. package/lib/chain/opPools/index.js.map +1 -1
  129. package/lib/chain/opPools/opPool.js +10 -12
  130. package/lib/chain/opPools/opPool.js.map +1 -1
  131. package/lib/chain/opPools/syncCommitteeMessagePool.js +9 -6
  132. package/lib/chain/opPools/syncCommitteeMessagePool.js.map +1 -1
  133. package/lib/chain/opPools/syncContributionAndProofPool.js +5 -2
  134. package/lib/chain/opPools/syncContributionAndProofPool.js.map +1 -1
  135. package/lib/chain/options.js +1 -1
  136. package/lib/chain/options.js.map +1 -1
  137. package/lib/chain/prepareNextSlot.js +141 -134
  138. package/lib/chain/prepareNextSlot.js.map +1 -1
  139. package/lib/chain/produceBlock/produceBlockBody.d.ts +1 -1
  140. package/lib/chain/produceBlock/produceBlockBody.js +3 -10
  141. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  142. package/lib/chain/regen/errors.js +1 -0
  143. package/lib/chain/regen/errors.js.map +1 -1
  144. package/lib/chain/regen/index.d.ts +1 -1
  145. package/lib/chain/regen/index.js +1 -1
  146. package/lib/chain/regen/index.js.map +1 -1
  147. package/lib/chain/regen/queued.js +35 -28
  148. package/lib/chain/regen/queued.js.map +1 -1
  149. package/lib/chain/regen/regen.js +1 -0
  150. package/lib/chain/regen/regen.js.map +1 -1
  151. package/lib/chain/reprocess.js +3 -1
  152. package/lib/chain/reprocess.js.map +1 -1
  153. package/lib/chain/seenCache/index.d.ts +1 -1
  154. package/lib/chain/seenCache/index.js +1 -1
  155. package/lib/chain/seenCache/index.js.map +1 -1
  156. package/lib/chain/seenCache/seenAggregateAndProof.js +7 -6
  157. package/lib/chain/seenCache/seenAggregateAndProof.js.map +1 -1
  158. package/lib/chain/seenCache/seenAttestationData.js +5 -2
  159. package/lib/chain/seenCache/seenAttestationData.js.map +1 -1
  160. package/lib/chain/seenCache/seenAttesters.js +2 -4
  161. package/lib/chain/seenCache/seenAttesters.js.map +1 -1
  162. package/lib/chain/seenCache/seenBlockProposers.js +2 -4
  163. package/lib/chain/seenCache/seenBlockProposers.js.map +1 -1
  164. package/lib/chain/seenCache/seenCommittee.js +1 -3
  165. package/lib/chain/seenCache/seenCommittee.js.map +1 -1
  166. package/lib/chain/seenCache/seenCommitteeContribution.js +3 -2
  167. package/lib/chain/seenCache/seenCommitteeContribution.js.map +1 -1
  168. package/lib/chain/seenCache/seenGossipBlockInput.d.ts +74 -78
  169. package/lib/chain/seenCache/seenGossipBlockInput.js +235 -369
  170. package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
  171. package/lib/chain/shufflingCache.js +5 -2
  172. package/lib/chain/shufflingCache.js.map +1 -1
  173. package/lib/chain/stateCache/blockStateCacheImpl.js +13 -7
  174. package/lib/chain/stateCache/blockStateCacheImpl.js.map +1 -1
  175. package/lib/chain/stateCache/datastore/db.js +1 -0
  176. package/lib/chain/stateCache/datastore/db.js.map +1 -1
  177. package/lib/chain/stateCache/datastore/file.js +1 -0
  178. package/lib/chain/stateCache/datastore/file.js.map +1 -1
  179. package/lib/chain/stateCache/datastore/index.d.ts +1 -1
  180. package/lib/chain/stateCache/datastore/index.js +1 -1
  181. package/lib/chain/stateCache/datastore/index.js.map +1 -1
  182. package/lib/chain/stateCache/fifoBlockStateCache.js +10 -0
  183. package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
  184. package/lib/chain/stateCache/inMemoryCheckpointsCache.js +10 -4
  185. package/lib/chain/stateCache/inMemoryCheckpointsCache.js.map +1 -1
  186. package/lib/chain/stateCache/index.d.ts +1 -1
  187. package/lib/chain/stateCache/index.js +1 -1
  188. package/lib/chain/stateCache/index.js.map +1 -1
  189. package/lib/chain/stateCache/mapMetrics.js +4 -4
  190. package/lib/chain/stateCache/mapMetrics.js.map +1 -1
  191. package/lib/chain/stateCache/persistentCheckpointsCache.js +14 -6
  192. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  193. package/lib/chain/validation/blobSidecar.d.ts +8 -3
  194. package/lib/chain/validation/blobSidecar.js +73 -31
  195. package/lib/chain/validation/blobSidecar.js.map +1 -1
  196. package/lib/chain/validation/dataColumnSidecar.d.ts +7 -9
  197. package/lib/chain/validation/dataColumnSidecar.js +95 -57
  198. package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
  199. package/lib/chain/validation/index.d.ts +1 -1
  200. package/lib/chain/validation/index.js +1 -1
  201. package/lib/chain/validation/index.js.map +1 -1
  202. package/lib/chain/validation/signatureSets/aggregateAndProof.d.ts +1 -2
  203. package/lib/chain/validation/signatureSets/aggregateAndProof.js.map +1 -1
  204. package/lib/chain/validatorMonitor.d.ts +1 -3
  205. package/lib/chain/validatorMonitor.js +2 -1
  206. package/lib/chain/validatorMonitor.js.map +1 -1
  207. package/lib/db/beacon.js +24 -0
  208. package/lib/db/beacon.js.map +1 -1
  209. package/lib/db/index.d.ts +1 -1
  210. package/lib/db/index.js.map +1 -1
  211. package/lib/db/repositories/blobSidecars.js.map +1 -1
  212. package/lib/db/repositories/blockArchive.js +4 -5
  213. package/lib/db/repositories/blockArchive.js.map +1 -1
  214. package/lib/db/repositories/blockArchiveIndex.d.ts +4 -0
  215. package/lib/db/repositories/blockArchiveIndex.js +13 -5
  216. package/lib/db/repositories/blockArchiveIndex.js.map +1 -1
  217. package/lib/db/repositories/dataColumnSidecar.js +8 -7
  218. package/lib/db/repositories/dataColumnSidecar.js.map +1 -1
  219. package/lib/db/repositories/dataColumnSidecarArchive.js +17 -7
  220. package/lib/db/repositories/dataColumnSidecarArchive.js.map +1 -1
  221. package/lib/db/repositories/depositDataRoot.js +1 -0
  222. package/lib/db/repositories/depositDataRoot.js.map +1 -1
  223. package/lib/db/repositories/index.d.ts +10 -10
  224. package/lib/db/repositories/index.js +9 -9
  225. package/lib/db/repositories/index.js.map +1 -1
  226. package/lib/db/repositories/stateArchive.js +3 -2
  227. package/lib/db/repositories/stateArchive.js.map +1 -1
  228. package/lib/db/repositories/stateArchiveIndex.d.ts +1 -0
  229. package/lib/db/repositories/stateArchiveIndex.js +6 -2
  230. package/lib/db/repositories/stateArchiveIndex.js.map +1 -1
  231. package/lib/db/single/preGenesisState.d.ts +1 -0
  232. package/lib/db/single/preGenesisState.js +11 -4
  233. package/lib/db/single/preGenesisState.js.map +1 -1
  234. package/lib/db/single/preGenesisStateLastProcessedBlock.d.ts +1 -0
  235. package/lib/db/single/preGenesisStateLastProcessedBlock.js +10 -4
  236. package/lib/db/single/preGenesisStateLastProcessedBlock.js.map +1 -1
  237. package/lib/eth1/eth1DataCache.js +2 -0
  238. package/lib/eth1/eth1DataCache.js.map +1 -1
  239. package/lib/eth1/eth1DepositDataTracker.js +18 -5
  240. package/lib/eth1/eth1DepositDataTracker.js.map +1 -1
  241. package/lib/eth1/eth1DepositsCache.js +3 -0
  242. package/lib/eth1/eth1DepositsCache.js.map +1 -1
  243. package/lib/eth1/eth1MergeBlockTracker.js +10 -4
  244. package/lib/eth1/eth1MergeBlockTracker.js.map +1 -1
  245. package/lib/eth1/index.js +2 -0
  246. package/lib/eth1/index.js.map +1 -1
  247. package/lib/eth1/provider/eth1Provider.d.ts +1 -2
  248. package/lib/eth1/provider/eth1Provider.js +6 -2
  249. package/lib/eth1/provider/eth1Provider.js.map +1 -1
  250. package/lib/eth1/provider/jsonRpcHttpClient.d.ts +1 -1
  251. package/lib/eth1/provider/jsonRpcHttpClient.js +16 -2
  252. package/lib/eth1/provider/jsonRpcHttpClient.js.map +1 -1
  253. package/lib/eth1/provider/jwt.js.map +1 -1
  254. package/lib/eth1/provider/utils.d.ts +5 -0
  255. package/lib/eth1/provider/utils.js +9 -1
  256. package/lib/eth1/provider/utils.js.map +1 -1
  257. package/lib/eth1/utils/deposits.js.map +1 -1
  258. package/lib/execution/builder/cache.js +6 -0
  259. package/lib/execution/builder/cache.js.map +1 -1
  260. package/lib/execution/builder/http.js +14 -8
  261. package/lib/execution/builder/http.js.map +1 -1
  262. package/lib/execution/builder/index.js.map +1 -1
  263. package/lib/execution/engine/disabled.js +2 -4
  264. package/lib/execution/engine/disabled.js.map +1 -1
  265. package/lib/execution/engine/http.d.ts +2 -2
  266. package/lib/execution/engine/http.js +43 -11
  267. package/lib/execution/engine/http.js.map +1 -1
  268. package/lib/execution/engine/interface.d.ts +2 -2
  269. package/lib/execution/engine/interface.js.map +1 -1
  270. package/lib/execution/engine/mock.d.ts +1 -0
  271. package/lib/execution/engine/mock.js +16 -12
  272. package/lib/execution/engine/mock.js.map +1 -1
  273. package/lib/execution/engine/payloadIdCache.js +1 -3
  274. package/lib/execution/engine/payloadIdCache.js.map +1 -1
  275. package/lib/execution/engine/types.d.ts +5 -1
  276. package/lib/execution/engine/types.js +37 -8
  277. package/lib/execution/engine/types.js.map +1 -1
  278. package/lib/execution/engine/utils.js +3 -3
  279. package/lib/execution/engine/utils.js.map +1 -1
  280. package/lib/execution/index.d.ts +2 -2
  281. package/lib/execution/index.js +2 -2
  282. package/lib/execution/index.js.map +1 -1
  283. package/lib/index.d.ts +6 -6
  284. package/lib/index.js +5 -5
  285. package/lib/index.js.map +1 -1
  286. package/lib/metrics/index.d.ts +1 -1
  287. package/lib/metrics/index.js +1 -1
  288. package/lib/metrics/index.js.map +1 -1
  289. package/lib/metrics/metrics/beacon.d.ts +11 -5
  290. package/lib/metrics/metrics/beacon.js +40 -20
  291. package/lib/metrics/metrics/beacon.js.map +1 -1
  292. package/lib/metrics/metrics/lodestar.d.ts +55 -13
  293. package/lib/metrics/metrics/lodestar.js +85 -8
  294. package/lib/metrics/metrics/lodestar.js.map +1 -1
  295. package/lib/metrics/metrics.d.ts +1 -1
  296. package/lib/metrics/metrics.js.map +1 -1
  297. package/lib/metrics/nodeJsMetrics.js +1 -1
  298. package/lib/metrics/nodeJsMetrics.js.map +1 -1
  299. package/lib/metrics/server/http.d.ts +1 -1
  300. package/lib/metrics/utils/avgMinMax.d.ts +1 -1
  301. package/lib/metrics/utils/avgMinMax.js +10 -6
  302. package/lib/metrics/utils/avgMinMax.js.map +1 -1
  303. package/lib/metrics/utils/gauge.d.ts +1 -1
  304. package/lib/metrics/utils/gauge.js +1 -4
  305. package/lib/metrics/utils/gauge.js.map +1 -1
  306. package/lib/metrics/utils/registryMetricCreator.d.ts +1 -1
  307. package/lib/metrics/utils/registryMetricCreator.js.map +1 -1
  308. package/lib/monitoring/properties.js +4 -0
  309. package/lib/monitoring/properties.js.map +1 -1
  310. package/lib/monitoring/service.js +13 -1
  311. package/lib/monitoring/service.js.map +1 -1
  312. package/lib/monitoring/system.js +25 -27
  313. package/lib/monitoring/system.js.map +1 -1
  314. package/lib/network/core/networkCore.d.ts +2 -2
  315. package/lib/network/core/networkCore.js +67 -50
  316. package/lib/network/core/networkCore.js.map +1 -1
  317. package/lib/network/core/networkCoreWorker.js +1 -1
  318. package/lib/network/core/networkCoreWorker.js.map +1 -1
  319. package/lib/network/core/networkCoreWorkerHandler.d.ts +2 -2
  320. package/lib/network/core/networkCoreWorkerHandler.js +5 -2
  321. package/lib/network/core/networkCoreWorkerHandler.js.map +1 -1
  322. package/lib/network/discv5/index.d.ts +2 -2
  323. package/lib/network/discv5/index.js +5 -2
  324. package/lib/network/discv5/index.js.map +1 -1
  325. package/lib/network/discv5/worker.js +3 -3
  326. package/lib/network/discv5/worker.js.map +1 -1
  327. package/lib/network/events.d.ts +2 -18
  328. package/lib/network/events.js +0 -7
  329. package/lib/network/events.js.map +1 -1
  330. package/lib/network/gossip/encoding.d.ts +1 -1
  331. package/lib/network/gossip/encoding.js +4 -2
  332. package/lib/network/gossip/encoding.js.map +1 -1
  333. package/lib/network/gossip/errors.js +1 -0
  334. package/lib/network/gossip/errors.js.map +1 -1
  335. package/lib/network/gossip/gossipsub.d.ts +1 -1
  336. package/lib/network/gossip/gossipsub.js +8 -1
  337. package/lib/network/gossip/gossipsub.js.map +1 -1
  338. package/lib/network/gossip/index.d.ts +2 -2
  339. package/lib/network/gossip/index.js +2 -2
  340. package/lib/network/gossip/index.js.map +1 -1
  341. package/lib/network/gossip/interface.d.ts +2 -2
  342. package/lib/network/gossip/topic.d.ts +125 -105
  343. package/lib/network/gossip/topic.js +2 -1
  344. package/lib/network/gossip/topic.js.map +1 -1
  345. package/lib/network/index.d.ts +3 -3
  346. package/lib/network/index.js +3 -3
  347. package/lib/network/index.js.map +1 -1
  348. package/lib/network/interface.d.ts +3 -2
  349. package/lib/network/libp2p/index.js +2 -2
  350. package/lib/network/libp2p/index.js.map +1 -1
  351. package/lib/network/metadata.js +4 -0
  352. package/lib/network/metadata.js.map +1 -1
  353. package/lib/network/network.d.ts +4 -2
  354. package/lib/network/network.js +89 -71
  355. package/lib/network/network.js.map +1 -1
  356. package/lib/network/options.js +1 -1
  357. package/lib/network/options.js.map +1 -1
  358. package/lib/network/peers/datastore.js +8 -2
  359. package/lib/network/peers/datastore.js.map +1 -1
  360. package/lib/network/peers/discover.js +75 -66
  361. package/lib/network/peers/discover.js.map +1 -1
  362. package/lib/network/peers/peerManager.js +154 -130
  363. package/lib/network/peers/peerManager.js.map +1 -1
  364. package/lib/network/peers/peersData.d.ts +1 -1
  365. package/lib/network/peers/peersData.js +1 -3
  366. package/lib/network/peers/peersData.js.map +1 -1
  367. package/lib/network/peers/score/index.d.ts +1 -1
  368. package/lib/network/peers/score/index.js +1 -1
  369. package/lib/network/peers/score/index.js.map +1 -1
  370. package/lib/network/peers/score/score.js +6 -0
  371. package/lib/network/peers/score/score.js.map +1 -1
  372. package/lib/network/peers/score/store.js +3 -0
  373. package/lib/network/peers/score/store.js.map +1 -1
  374. package/lib/network/peers/utils/prioritizePeers.js.map +1 -1
  375. package/lib/network/peers/utils/subnetMap.js +2 -4
  376. package/lib/network/peers/utils/subnetMap.js.map +1 -1
  377. package/lib/network/processor/aggregatorTracker.js +1 -3
  378. package/lib/network/processor/aggregatorTracker.js.map +1 -1
  379. package/lib/network/processor/gossipHandlers.js +145 -165
  380. package/lib/network/processor/gossipHandlers.js.map +1 -1
  381. package/lib/network/processor/gossipQueues/indexed.js +11 -9
  382. package/lib/network/processor/gossipQueues/indexed.js.map +1 -1
  383. package/lib/network/processor/gossipQueues/linear.js +9 -8
  384. package/lib/network/processor/gossipQueues/linear.js.map +1 -1
  385. package/lib/network/processor/index.d.ts +2 -1
  386. package/lib/network/processor/index.js +22 -8
  387. package/lib/network/processor/index.js.map +1 -1
  388. package/lib/network/reqresp/ReqRespBeaconNode.d.ts +1 -1
  389. package/lib/network/reqresp/ReqRespBeaconNode.js +11 -2
  390. package/lib/network/reqresp/ReqRespBeaconNode.js.map +1 -1
  391. package/lib/network/reqresp/handlers/beaconBlocksByRange.js +1 -2
  392. package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
  393. package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js.map +1 -1
  394. package/lib/network/reqresp/index.d.ts +1 -3
  395. package/lib/network/reqresp/index.js +1 -3
  396. package/lib/network/reqresp/index.js.map +1 -1
  397. package/lib/network/reqresp/rateLimit.js +11 -5
  398. package/lib/network/reqresp/rateLimit.js.map +1 -1
  399. package/lib/network/reqresp/utils/dataColumnResponseValidation.js +8 -4
  400. package/lib/network/reqresp/utils/dataColumnResponseValidation.js.map +1 -1
  401. package/lib/network/statusCache.js +1 -0
  402. package/lib/network/statusCache.js.map +1 -1
  403. package/lib/network/subnets/attnetsService.js +73 -65
  404. package/lib/network/subnets/attnetsService.js.map +1 -1
  405. package/lib/network/subnets/interface.js +1 -1
  406. package/lib/network/subnets/interface.js.map +1 -1
  407. package/lib/network/subnets/syncnetsService.js +29 -22
  408. package/lib/network/subnets/syncnetsService.js.map +1 -1
  409. package/lib/network/subnets/util.js +1 -2
  410. package/lib/network/subnets/util.js.map +1 -1
  411. package/lib/node/nodejs.d.ts +1 -1
  412. package/lib/node/nodejs.js +15 -0
  413. package/lib/node/nodejs.js.map +1 -1
  414. package/lib/node/notifier.js +1 -2
  415. package/lib/node/notifier.js.map +1 -1
  416. package/lib/node/options.js.map +1 -1
  417. package/lib/node/utils/interop/state.js +1 -2
  418. package/lib/node/utils/interop/state.js.map +1 -1
  419. package/lib/sync/backfill/backfill.d.ts +1 -1
  420. package/lib/sync/backfill/backfill.js +58 -16
  421. package/lib/sync/backfill/backfill.js.map +1 -1
  422. package/lib/sync/constants.d.ts +2 -1
  423. package/lib/sync/constants.js +2 -1
  424. package/lib/sync/constants.js.map +1 -1
  425. package/lib/sync/interface.d.ts +1 -59
  426. package/lib/sync/interface.js +0 -20
  427. package/lib/sync/interface.js.map +1 -1
  428. package/lib/sync/options.d.ts +1 -1
  429. package/lib/sync/range/batch.d.ts +48 -32
  430. package/lib/sync/range/batch.js +201 -55
  431. package/lib/sync/range/batch.js.map +1 -1
  432. package/lib/sync/range/chain.d.ts +15 -10
  433. package/lib/sync/range/chain.js +141 -70
  434. package/lib/sync/range/chain.js.map +1 -1
  435. package/lib/sync/range/range.d.ts +3 -3
  436. package/lib/sync/range/range.js +86 -54
  437. package/lib/sync/range/range.js.map +1 -1
  438. package/lib/sync/range/utils/hashBlocks.d.ts +2 -2
  439. package/lib/sync/range/utils/hashBlocks.js +6 -4
  440. package/lib/sync/range/utils/hashBlocks.js.map +1 -1
  441. package/lib/sync/range/utils/peerBalancer.js +18 -13
  442. package/lib/sync/range/utils/peerBalancer.js.map +1 -1
  443. package/lib/sync/sync.d.ts +1 -2
  444. package/lib/sync/sync.js +95 -87
  445. package/lib/sync/sync.js.map +1 -1
  446. package/lib/sync/types.d.ts +44 -0
  447. package/lib/sync/types.js +34 -0
  448. package/lib/sync/types.js.map +1 -0
  449. package/lib/sync/unknownBlock.d.ts +42 -28
  450. package/lib/sync/unknownBlock.js +404 -458
  451. package/lib/sync/unknownBlock.js.map +1 -1
  452. package/lib/sync/utils/downloadByRange.d.ts +186 -0
  453. package/lib/sync/utils/downloadByRange.js +457 -0
  454. package/lib/sync/utils/downloadByRange.js.map +1 -0
  455. package/lib/sync/utils/downloadByRoot.d.ts +119 -0
  456. package/lib/sync/utils/downloadByRoot.js +319 -0
  457. package/lib/sync/utils/downloadByRoot.js.map +1 -0
  458. package/lib/sync/utils/pendingBlocksTree.d.ts +14 -6
  459. package/lib/sync/utils/pendingBlocksTree.js +24 -18
  460. package/lib/sync/utils/pendingBlocksTree.js.map +1 -1
  461. package/lib/util/array.js +7 -3
  462. package/lib/util/array.js.map +1 -1
  463. package/lib/util/asyncIterableToEvents.js +6 -3
  464. package/lib/util/asyncIterableToEvents.js.map +1 -1
  465. package/lib/util/binarySearch.js +2 -0
  466. package/lib/util/binarySearch.js.map +1 -1
  467. package/lib/util/blobs.d.ts +2 -2
  468. package/lib/util/blobs.js +4 -4
  469. package/lib/util/blobs.js.map +1 -1
  470. package/lib/util/bufferPool.js +7 -2
  471. package/lib/util/bufferPool.js.map +1 -1
  472. package/lib/util/clock.d.ts +1 -1
  473. package/lib/util/clock.js +23 -18
  474. package/lib/util/clock.js.map +1 -1
  475. package/lib/util/dataColumns.d.ts +13 -10
  476. package/lib/util/dataColumns.js +92 -134
  477. package/lib/util/dataColumns.js.map +1 -1
  478. package/lib/util/execution.d.ts +20 -0
  479. package/lib/util/execution.js +148 -0
  480. package/lib/util/execution.js.map +1 -0
  481. package/lib/util/itTrigger.js +4 -4
  482. package/lib/util/itTrigger.js.map +1 -1
  483. package/lib/util/map.js +2 -0
  484. package/lib/util/map.js.map +1 -1
  485. package/lib/util/queue/index.d.ts +1 -1
  486. package/lib/util/queue/index.js +1 -1
  487. package/lib/util/queue/index.js.map +1 -1
  488. package/lib/util/queue/itemQueue.js +52 -49
  489. package/lib/util/queue/itemQueue.js.map +1 -1
  490. package/lib/util/serializedCache.js +1 -3
  491. package/lib/util/serializedCache.js.map +1 -1
  492. package/lib/util/set.js +2 -0
  493. package/lib/util/set.js.map +1 -1
  494. package/lib/util/sszBytes.d.ts +1 -0
  495. package/lib/util/sszBytes.js +1 -1
  496. package/lib/util/sszBytes.js.map +1 -1
  497. package/lib/util/timeSeries.js +3 -1
  498. package/lib/util/timeSeries.js.map +1 -1
  499. package/lib/util/types.d.ts +1 -1
  500. package/lib/util/types.js +2 -2
  501. package/lib/util/types.js.map +1 -1
  502. package/lib/util/wrapError.d.ts +7 -0
  503. package/package.json +22 -16
  504. package/lib/chain/seenCache/seenBlockInput.d.ts +0 -84
  505. package/lib/chain/seenCache/seenBlockInput.js +0 -225
  506. package/lib/chain/seenCache/seenBlockInput.js.map +0 -1
  507. package/lib/network/reqresp/beaconBlocksMaybeBlobsByRange.d.ts +0 -28
  508. package/lib/network/reqresp/beaconBlocksMaybeBlobsByRange.js +0 -328
  509. package/lib/network/reqresp/beaconBlocksMaybeBlobsByRange.js.map +0 -1
  510. package/lib/network/reqresp/beaconBlocksMaybeBlobsByRoot.d.ts +0 -49
  511. package/lib/network/reqresp/beaconBlocksMaybeBlobsByRoot.js +0 -499
  512. package/lib/network/reqresp/beaconBlocksMaybeBlobsByRoot.js.map +0 -1
@@ -1,405 +1,271 @@
1
- import { toHexString } from "@chainsafe/ssz";
2
- import { ForkName, NUMBER_OF_COLUMNS, isForkPostDeneb } from "@lodestar/params";
3
- import { ssz } from "@lodestar/types";
4
- import { pruneSetToMax } from "@lodestar/utils";
5
- import { RecoverResult, getDataColumnsFromExecution, hasSampledDataColumns, recoverDataColumnSidecars, } from "../../util/dataColumns.js";
6
- import { callInNextEventLoop } from "../../util/eventLoop.js";
7
- import { BlobsSource, BlockSource, DataColumnsSource, GossipedInputType, getBlockInput, getBlockInputBlobs, getBlockInputDataColumns, } from "../blocks/types.js";
1
+ import { isForkPostDeneb, isForkPostFulu } from "@lodestar/params";
2
+ import { computeStartSlotAtEpoch } from "@lodestar/state-transition";
3
+ import { LodestarError } from "@lodestar/utils";
4
+ import { BlockInputBlobs, BlockInputColumns, BlockInputPreData, DAType, isBlockInputBlobs, isBlockInputColumns, isDaOutOfRange, } from "../blocks/blockInput/index.js";
8
5
  import { ChainEvent } from "../emitter.js";
9
- import { DataColumnSidecarErrorCode, DataColumnSidecarGossipError } from "../errors/dataColumnSidecarError.js";
10
- import { GossipAction } from "../errors/gossipValidation.js";
11
- export var BlockInputAvailabilitySource;
12
- (function (BlockInputAvailabilitySource) {
13
- BlockInputAvailabilitySource["GOSSIP"] = "gossip";
14
- BlockInputAvailabilitySource["RECOVERED"] = "recovered";
15
- BlockInputAvailabilitySource["UNKNOWN_SYNC"] = "unknown_sync";
16
- })(BlockInputAvailabilitySource || (BlockInputAvailabilitySource = {}));
17
- // TODO(fulu): dedup with gossipHandlers.ts
18
- const BLOCK_AVAILABILITY_CUTOFF_MS = 3_000;
19
- const MAX_GOSSIPINPUT_CACHE = 5;
6
+ const MAX_BLOCK_INPUT_CACHE_SIZE = 5;
20
7
  /**
21
- * For predeneb, SeenGossipBlockInput only tracks and caches block so that we don't need to download known block
22
- * roots. From deneb, it serves same purpose plus tracks and caches the live blobs and blocks on the network to
23
- * solve data availability for the blockInput. If no block has been seen yet for some already seen blobs, it
24
- * responds will null, but on the first block or the consequent blobs it responds with blobs promise till all blobs
25
- * become available.
8
+ * Consumers that create BlockInputs or change types of old BlockInputs
26
9
  *
27
- * One can start processing block on blobs promise blockInput response and can await on the promise before
28
- * fully importing the block. The blobs promise is gets resolved as soon as all blobs corresponding to that
29
- * block are seen by SeenGossipBlockInput
10
+ * - gossipHandlers (block and blob)
11
+ * - beaconBlocksMaybeBlobsByRange
12
+ * - unavailableBeaconBlobsByRoot (beaconBlocksMaybeBlobsByRoot)
13
+ * - publishBlock in the beacon/blocks/index.ts API
14
+ * https://github.com/ChainSafe/lodestar/blob/unstable/packages/beacon-node/src/api/impl/beacon/blocks/index.ts#L62
15
+ * - maybeValidateBlobs in verifyBlocksDataAvailability (is_data_available spec function)
16
+ * https://github.com/ChainSafe/lodestar/blob/unstable/packages/beacon-node/src/chain/blocks/verifyBlocksDataAvailability.ts#L111
17
+ *
18
+ *
19
+ * Pruning management for SeenBlockInputCache
20
+ * ------------------------------------------
21
+ * There are four cases for how pruning needs to be handled
22
+ * - Normal operation following head via gossip (and/or reqresp). For this situation the consumer (process pipeline or
23
+ * caller of processBlock) will call the `prune` method to remove any processed BlockInputs from the cache. This will
24
+ * also remove any ancestors of the processed BlockInput as that will also need to have been successfully processed
25
+ * for import to work correctly
26
+ * - onFinalized event handler will help to prune any non-canonical forks once the chain finalizes. Any block-slots that
27
+ * are before the finalized checkpoint will be pruned.
28
+ * - Range-sync periods. The range process uses this cache to store and sync blocks with DA data as the chain is pulled
29
+ * from peers. We pull batches, by epoch, so 32 slots are pulled at a time and several batches are pulled concurrently.
30
+ * It is important to set the MAX_BLOCK_INPUT_CACHE_SIZE high enough to support range sync activities. Currently the
31
+ * value is set for 5 batches of 32 slots. As process block is called (similar to following head) the BlockInput and
32
+ * its ancestors will be pruned.
33
+ * - Non-Finality times. This is a bit more tricky. There can be long periods of non-finality and storing everything
34
+ * will cause OOM. The pruneToMax will help ensure a hard limit on the number of stored blocks (with DA) that are held
35
+ * in memory at any one time. The value for MAX_BLOCK_INPUT_CACHE_SIZE is set to accommodate range-sync but in
36
+ * practice this value may need to be massaged in the future if we find issues when debugging non-finality
30
37
  */
31
- export class SeenGossipBlockInput {
32
- constructor(custodyConfig, executionEngine, emitter, clock, logger) {
33
- this.blockInputCache = new Map();
34
- this.globalCacheId = 0;
38
+ export class SeenBlockInput {
39
+ config;
40
+ custodyConfig;
41
+ clock;
42
+ chainEvents;
43
+ signal;
44
+ metrics;
45
+ logger;
46
+ blockInputs = new Map();
47
+ constructor({ config, custodyConfig, clock, chainEvents, signal, metrics, logger }) {
48
+ this.config = config;
35
49
  this.custodyConfig = custodyConfig;
36
- this.executionEngine = executionEngine;
37
50
  this.clock = clock;
38
- this.emitter = emitter;
51
+ this.chainEvents = chainEvents;
52
+ this.signal = signal;
53
+ this.metrics = metrics;
39
54
  this.logger = logger;
55
+ if (metrics) {
56
+ metrics.seenCache.blockInput.blockInputCount.addCollect(() => metrics.seenCache.blockInput.blockInputCount.set(this.blockInputs.size));
57
+ }
58
+ this.chainEvents.on(ChainEvent.forkChoiceFinalized, this.onFinalized);
59
+ this.signal.addEventListener("abort", () => {
60
+ this.chainEvents.off(ChainEvent.forkChoiceFinalized, this.onFinalized);
61
+ });
40
62
  }
41
- prune() {
42
- pruneSetToMax(this.blockInputCache, MAX_GOSSIPINPUT_CACHE);
63
+ has(rootHex) {
64
+ return this.blockInputs.has(rootHex);
43
65
  }
44
- hasBlock(blockRoot) {
45
- return this.blockInputCache.has(blockRoot);
66
+ get(rootHex) {
67
+ return this.blockInputs.get(rootHex);
46
68
  }
47
69
  /**
48
- * Intended to be used for gossip validation, specifically this check:
49
- * [IGNORE] The sidecar is the first sidecar for the tuple (block_header.slot, block_header.proposer_index,
50
- * sidecar.index) with valid header signature, sidecar inclusion proof, and kzg proof
70
+ * Removes the single BlockInput from the cache
51
71
  */
52
- hasDataColumnSidecar(sidecar) {
53
- const blockRoot = ssz.phase0.BeaconBlockHeader.hashTreeRoot(sidecar.signedBlockHeader.message);
54
- const blockRootHex = toHexString(blockRoot);
55
- const blockCache = this.blockInputCache.get(blockRootHex);
56
- if (blockCache === undefined) {
57
- return false;
58
- }
59
- if (blockCache.cachedData === undefined || blockCache.cachedData.fork !== ForkName.fulu) {
60
- return false;
61
- }
62
- const existingSidecar = blockCache.cachedData.dataColumnsCache.get(sidecar.index);
63
- if (!existingSidecar) {
64
- return false;
65
- }
66
- return (sidecar.signedBlockHeader.message.slot === existingSidecar.dataColumn.signedBlockHeader.message.slot &&
67
- sidecar.index === existingSidecar.dataColumn.index &&
68
- sidecar.signedBlockHeader.message.proposerIndex ===
69
- existingSidecar.dataColumn.signedBlockHeader.message.proposerIndex);
72
+ remove(rootHex) {
73
+ this.blockInputs.delete(rootHex);
70
74
  }
71
- getGossipBlockInput(config, gossipedInput, metrics) {
72
- let blockHex;
73
- let blockCache;
74
- let fork;
75
- if (gossipedInput.type === GossipedInputType.block) {
76
- const { signedBlock } = gossipedInput;
77
- fork = config.getForkName(signedBlock.message.slot);
78
- blockHex = toHexString(config.getForkTypes(signedBlock.message.slot).BeaconBlock.hashTreeRoot(signedBlock.message));
79
- blockCache = this.blockInputCache.get(blockHex) ?? getEmptyBlockInputCacheEntry(fork, ++this.globalCacheId);
80
- blockCache.block = signedBlock;
75
+ /**
76
+ * Removes a processed BlockInput from the cache and also removes any ancestors of processed blocks
77
+ */
78
+ prune(rootHex) {
79
+ let blockInput = this.blockInputs.get(rootHex);
80
+ let parentRootHex = blockInput?.parentRootHex;
81
+ let deletedCount = 0;
82
+ while (blockInput) {
83
+ deletedCount++;
84
+ this.blockInputs.delete(blockInput.blockRootHex);
85
+ blockInput = this.blockInputs.get(parentRootHex ?? "");
86
+ parentRootHex = blockInput?.parentRootHex;
81
87
  }
82
- else if (gossipedInput.type === GossipedInputType.blob) {
83
- const { blobSidecar } = gossipedInput;
84
- const blockRoot = ssz.phase0.BeaconBlockHeader.hashTreeRoot(blobSidecar.signedBlockHeader.message);
85
- fork = config.getForkName(blobSidecar.signedBlockHeader.message.slot);
86
- blockHex = toHexString(blockRoot);
87
- blockCache = this.blockInputCache.get(blockHex) ?? getEmptyBlockInputCacheEntry(fork, ++this.globalCacheId);
88
- if (blockCache.cachedData?.fork !== ForkName.deneb && blockCache.cachedData?.fork !== ForkName.electra) {
89
- throw Error(`blob data at non deneb/electra fork=${blockCache.fork}`);
88
+ this.logger?.debug(`BlockInputCache.prune deleted ${deletedCount} cached BlockInputs`);
89
+ this.pruneToMaxSize();
90
+ }
91
+ onFinalized = (checkpoint) => {
92
+ let deletedCount = 0;
93
+ const cutoffSlot = computeStartSlotAtEpoch(checkpoint.epoch);
94
+ for (const [rootHex, blockInput] of this.blockInputs) {
95
+ if (blockInput.slot < cutoffSlot) {
96
+ deletedCount++;
97
+ this.blockInputs.delete(rootHex);
90
98
  }
91
- // TODO: freetheblobs check if its the same blob or a duplicate and throw/take actions
92
- blockCache.cachedData?.blobsCache.set(blobSidecar.index, blobSidecar);
93
99
  }
94
- else if (gossipedInput.type === GossipedInputType.dataColumn) {
95
- const { dataColumnSidecar, dataColumnBytes } = gossipedInput;
96
- const blockRoot = ssz.phase0.BeaconBlockHeader.hashTreeRoot(dataColumnSidecar.signedBlockHeader.message);
97
- fork = config.getForkName(dataColumnSidecar.signedBlockHeader.message.slot);
98
- blockHex = toHexString(blockRoot);
99
- blockCache = this.blockInputCache.get(blockHex) ?? getEmptyBlockInputCacheEntry(fork, ++this.globalCacheId);
100
- if (blockCache.cachedData?.fork !== ForkName.fulu) {
101
- throw Error(`data column data at non fulu fork=${blockCache.fork}`);
100
+ this.logger?.debug(`BlockInputCache.onFinalized deleted ${deletedCount} cached BlockInputs`);
101
+ this.pruneToMaxSize();
102
+ };
103
+ getByBlock({ blockRootHex, block, source, seenTimestampSec, peerIdStr }) {
104
+ // TODO(peerDAS): Why is it necessary to static cast this here. All conditional paths result in a valid value so should be defined correctly below
105
+ let blockInput = this.blockInputs.get(blockRootHex);
106
+ if (!blockInput) {
107
+ const { forkName, daOutOfRange } = this.buildCommonProps(block.message.slot);
108
+ if (!isForkPostDeneb(forkName)) {
109
+ blockInput = BlockInputPreData.createFromBlock({
110
+ block,
111
+ blockRootHex,
112
+ daOutOfRange,
113
+ forkName,
114
+ source,
115
+ seenTimestampSec,
116
+ peerIdStr,
117
+ });
102
118
  }
103
- if (this.hasDataColumnSidecar(dataColumnSidecar)) {
104
- throw new DataColumnSidecarGossipError(GossipAction.IGNORE, {
105
- code: DataColumnSidecarErrorCode.ALREADY_KNOWN,
106
- slot: dataColumnSidecar.signedBlockHeader.message.slot,
107
- columnIdx: dataColumnSidecar.index,
119
+ else if (isForkPostFulu(forkName)) {
120
+ blockInput = BlockInputColumns.createFromBlock({
121
+ block: block,
122
+ blockRootHex,
123
+ daOutOfRange,
124
+ forkName,
125
+ custodyColumns: this.custodyConfig.custodyColumns,
126
+ sampledColumns: this.custodyConfig.sampledColumns,
127
+ source,
128
+ seenTimestampSec,
129
+ peerIdStr,
108
130
  });
109
131
  }
110
- blockCache.cachedData?.dataColumnsCache.set(dataColumnSidecar.index, {
111
- dataColumn: dataColumnSidecar,
112
- // easily splice out the unsigned message as blob is a fixed length type
113
- dataColumnBytes: dataColumnBytes?.slice(0, dataColumnBytes.length) ?? null,
114
- });
132
+ else {
133
+ blockInput = BlockInputBlobs.createFromBlock({
134
+ block: block,
135
+ blockRootHex,
136
+ daOutOfRange,
137
+ forkName,
138
+ source,
139
+ seenTimestampSec,
140
+ peerIdStr,
141
+ });
142
+ }
143
+ this.blockInputs.set(blockInput.blockRootHex, blockInput);
144
+ }
145
+ if (!blockInput.hasBlock()) {
146
+ blockInput.addBlock({ block, blockRootHex, source, seenTimestampSec, peerIdStr });
115
147
  }
116
148
  else {
117
- // somehow helps resolve typescript that all types have been exausted
118
- throw Error("Invalid gossipedInput type");
149
+ this.logger?.debug("Attempt to cache block but is already cached on BlockInput", blockInput.getLogMeta());
150
+ this.metrics?.seenCache.blockInput.duplicateBlockCount.inc({ source });
119
151
  }
120
- if (!this.blockInputCache.has(blockHex)) {
121
- this.blockInputCache.set(blockHex, blockCache);
122
- callInNextEventLoop(() => {
123
- getDataColumnsFromExecution(config, this.custodyConfig, this.executionEngine, this.emitter, blockCache, metrics)
124
- .then((_success) => {
125
- // TODO: (@matthewkeil) add metrics collection point here
126
- })
127
- .catch((error) => {
128
- this.logger.warn("Error getting data columns from execution", { blockHex }, error);
129
- });
152
+ return blockInput;
153
+ }
154
+ getByBlob({ blockRootHex, blobSidecar, source, seenTimestampSec, peerIdStr, }, opts = {}) {
155
+ // TODO(peerDAS): Why is it necessary to static cast this here. All conditional paths result in a valid value so should be defined correctly below
156
+ let blockInput = this.blockInputs.get(blockRootHex);
157
+ let created = false;
158
+ if (!blockInput) {
159
+ created = true;
160
+ const { forkName, daOutOfRange } = this.buildCommonProps(blobSidecar.signedBlockHeader.message.slot);
161
+ blockInput = BlockInputBlobs.createFromBlob({
162
+ blobSidecar,
163
+ blockRootHex,
164
+ daOutOfRange,
165
+ forkName,
166
+ source,
167
+ seenTimestampSec,
168
+ peerIdStr,
130
169
  });
170
+ this.metrics?.seenCache.blockInput.createdByBlob.inc();
171
+ this.blockInputs.set(blockRootHex, blockInput);
131
172
  }
132
- const { block: signedBlock, blockInputPromise, resolveBlockInput, cachedData } = blockCache;
133
- if (signedBlock !== undefined) {
134
- if (!isForkPostDeneb(fork)) {
135
- return {
136
- blockInput: getBlockInput.preData(config, signedBlock, BlockSource.gossip),
137
- blockInputMeta: { pending: null, haveBlobs: 0, expectedBlobs: 0 },
138
- };
139
- }
140
- if (cachedData === undefined || !isForkPostDeneb(cachedData.fork)) {
141
- throw Error("Missing or Invalid fork cached Data for post-deneb block");
142
- }
143
- if (cachedData.fork === ForkName.deneb || cachedData.fork === ForkName.electra) {
144
- const { blobsCache, resolveAvailability } = cachedData;
145
- // block is available, check if all blobs have shown up
146
- const { slot, body } = signedBlock.message;
147
- const { blobKzgCommitments } = body;
148
- const blockInfo = `blockHex=${blockHex}, slot=${slot}`;
149
- if (blobKzgCommitments.length < blobsCache.size) {
150
- throw Error(`Received more blobs=${blobsCache.size} than commitments=${blobKzgCommitments.length} for ${blockInfo}`);
151
- }
152
- if (blobKzgCommitments.length === blobsCache.size) {
153
- const allBlobs = getBlockInputBlobs(blobsCache);
154
- const { blobs } = allBlobs;
155
- const blockData = {
156
- fork: cachedData.fork,
157
- ...allBlobs,
158
- blobsSource: BlobsSource.gossip,
159
- };
160
- resolveAvailability(blockData);
161
- metrics?.syncUnknownBlock.resolveAvailabilitySource.inc({ source: BlockInputAvailabilitySource.GOSSIP });
162
- const blockInput = getBlockInput.availableData(config, signedBlock, BlockSource.gossip, blockData);
163
- resolveBlockInput(blockInput);
164
- return {
165
- blockInput,
166
- blockInputMeta: { pending: null, haveBlobs: blobs.length, expectedBlobs: blobKzgCommitments.length },
167
- };
168
- }
169
- const blockInput = getBlockInput.dataPromise(config, signedBlock, BlockSource.gossip, cachedData);
170
- resolveBlockInput(blockInput);
171
- return {
172
- blockInput,
173
- blockInputMeta: {
174
- pending: GossipedInputType.blob,
175
- haveBlobs: blobsCache.size,
176
- expectedBlobs: blobKzgCommitments.length,
177
- },
178
- };
179
- }
180
- if (cachedData.fork === ForkName.fulu) {
181
- const { dataColumnsCache, resolveAvailability, calledRecover } = cachedData;
182
- // block is available, check if all blobs have shown up
183
- const { slot } = signedBlock.message;
184
- const blockInfo = `blockHex=${blockHex}, slot=${slot}`;
185
- if (NUMBER_OF_COLUMNS < dataColumnsCache.size) {
186
- throw Error(`Received more dataColumns=${dataColumnsCache.size} than columns=${NUMBER_OF_COLUMNS} for ${blockInfo}`);
187
- }
188
- // get the custody columns and see if we have got all the requisite columns
189
- const blobKzgCommitmentsLen = signedBlock.message.body.blobKzgCommitments.length;
190
- if (blobKzgCommitmentsLen === 0) {
191
- const blockData = {
192
- fork: cachedData.fork,
193
- dataColumns: [],
194
- dataColumnsBytes: [],
195
- dataColumnsSource: DataColumnsSource.gossip,
196
- };
197
- resolveAvailability(blockData);
198
- metrics?.syncUnknownBlock.resolveAvailabilitySource.inc({ source: BlockInputAvailabilitySource.GOSSIP });
199
- const blockInput = getBlockInput.availableData(config, signedBlock, BlockSource.gossip, blockData);
200
- resolveBlockInput(blockInput);
201
- return {
202
- blockInput,
203
- blockInputMeta: { pending: null, haveColumns: 0, expectedColumns: 0 },
204
- };
205
- }
206
- const resolveAvailabilityAndBlockInput = (source) => {
207
- const allDataColumns = getBlockInputDataColumns(dataColumnsCache, this.custodyConfig.sampledColumns);
208
- const blockData = {
209
- fork: cachedData.fork,
210
- ...allDataColumns,
211
- dataColumnsSource: DataColumnsSource.gossip,
212
- };
213
- resolveAvailability(blockData);
214
- // TODO(das): should not use syncUnknownBlock metrics here
215
- metrics?.syncUnknownBlock.resolveAvailabilitySource.inc({ source });
216
- metrics?.dataColumns.bySource.inc({ source: DataColumnsSource.gossip });
217
- const blockInput = getBlockInput.availableData(config, signedBlock, BlockSource.gossip, blockData);
218
- resolveBlockInput(blockInput);
219
- return blockInput;
220
- };
221
- const columnCount = dataColumnsCache.size;
222
- if (
223
- // only try to recover all columns with "--supernode"
224
- this.custodyConfig.sampledColumns.length === NUMBER_OF_COLUMNS &&
225
- columnCount >= NUMBER_OF_COLUMNS / 2 &&
226
- columnCount < NUMBER_OF_COLUMNS &&
227
- !calledRecover &&
228
- // doing recover right away is not efficient because it may delay data_column_sidecar validation
229
- this.clock.secFromSlot(slot) * 1000 >= BLOCK_AVAILABILITY_CUTOFF_MS) {
230
- // should call once per slot
231
- cachedData.calledRecover = true;
232
- callInNextEventLoop(async () => {
233
- const logCtx = {
234
- blockHex,
235
- slot,
236
- dataColumns: dataColumnsCache.size,
237
- };
238
- const recoverResult = await recoverDataColumnSidecars(dataColumnsCache, this.clock, metrics).catch((e) => {
239
- this.logger.error("Error recovering data column sidecars", logCtx, e);
240
- return RecoverResult.Failed;
241
- });
242
- metrics?.recoverDataColumnSidecars.reconstructionResult.inc({ result: recoverResult });
243
- switch (recoverResult) {
244
- case RecoverResult.SuccessResolved: {
245
- resolveAvailabilityAndBlockInput(BlockInputAvailabilitySource.RECOVERED);
246
- // Publish columns if and only if subscribed to them
247
- const sampledColumns = this.custodyConfig.sampledColumns.map((columnIndex) => {
248
- const dataColumn = dataColumnsCache.get(columnIndex)?.dataColumn;
249
- if (!dataColumn) {
250
- throw Error(`After recover, missing data column for index=${columnIndex} in cache`);
251
- }
252
- return dataColumn;
253
- });
254
- // for columns that we already seen, it will be ignored through `ignoreDuplicatePublishError` gossip option
255
- this.emitter.emit(ChainEvent.publishDataColumns, sampledColumns);
256
- this.logger.verbose("Recovered data column sidecars and resolved availability", logCtx);
257
- break;
258
- }
259
- case RecoverResult.SuccessLate:
260
- this.logger.verbose("Recovered data column sidecars but it's late to resolve availability", logCtx);
261
- break;
262
- case RecoverResult.Failed:
263
- this.logger.verbose("Failed to recover data column sidecars", logCtx);
264
- break;
265
- case RecoverResult.NotAttemptedFull:
266
- this.logger.verbose("Did not attempt because we have full column sidecars", logCtx);
267
- break;
268
- case RecoverResult.NotAttemptedLessThanHalf:
269
- this.logger.verbose("Did not attempt because we have too few column sidecars", logCtx);
270
- break;
271
- default:
272
- break;
273
- }
274
- });
275
- }
276
- if (hasSampledDataColumns(this.custodyConfig, dataColumnsCache)) {
277
- const blockInput = resolveAvailabilityAndBlockInput(BlockInputAvailabilitySource.GOSSIP);
278
- const allDataColumns = getBlockInputDataColumns(dataColumnsCache, this.custodyConfig.sampledColumns);
279
- const { dataColumns } = allDataColumns;
280
- return {
281
- blockInput,
282
- blockInputMeta: {
283
- pending: null,
284
- haveColumns: dataColumns.length,
285
- expectedColumns: this.custodyConfig.sampledColumns.length,
286
- },
287
- };
288
- }
289
- const blockInput = getBlockInput.dataPromise(config, signedBlock, BlockSource.gossip, cachedData);
290
- resolveBlockInput(blockInput);
291
- return {
292
- blockInput,
293
- blockInputMeta: {
294
- pending: GossipedInputType.dataColumn,
295
- haveColumns: dataColumnsCache.size,
296
- expectedColumns: this.custodyConfig.sampledColumns.length,
297
- },
298
- };
173
+ if (!isBlockInputBlobs(blockInput)) {
174
+ throw new SeenBlockInputCacheError({
175
+ code: SeenBlockInputCacheErrorCode.WRONG_BLOCK_INPUT_TYPE,
176
+ cachedType: blockInput.type,
177
+ requestedType: DAType.Blobs,
178
+ ...blockInput.getLogMeta(),
179
+ }, `BlockInputType mismatch adding blobIndex=${blobSidecar.index}`);
180
+ }
181
+ if (!blockInput.hasBlob(blobSidecar.index)) {
182
+ blockInput.addBlob({ blobSidecar, blockRootHex, source, seenTimestampSec, peerIdStr });
183
+ }
184
+ else if (!created) {
185
+ this.logger?.debug(`Attempt to cache blob index #${blobSidecar.index} but is already cached on BlockInput`, blockInput.getLogMeta());
186
+ this.metrics?.seenCache.blockInput.duplicateBlobCount.inc({ source });
187
+ if (opts.throwErrorIfAlreadyKnown) {
188
+ throw new SeenBlockInputCacheError({
189
+ code: SeenBlockInputCacheErrorCode.GOSSIP_BLOB_ALREADY_KNOWN,
190
+ ...blockInput.getLogMeta(),
191
+ });
299
192
  }
300
- throw Error(`Invalid fork=${fork}`);
301
193
  }
302
- // will need to wait for the block to showup
303
- if (cachedData === undefined) {
304
- throw Error("Missing cachedData for deneb+ blobs");
194
+ return blockInput;
195
+ }
196
+ getByColumn({ blockRootHex, columnSidecar, seenTimestampSec, source, peerIdStr, }, opts = {}) {
197
+ let blockInput = this.blockInputs.get(blockRootHex);
198
+ let created = false;
199
+ if (!blockInput) {
200
+ created = true;
201
+ const { forkName, daOutOfRange } = this.buildCommonProps(columnSidecar.signedBlockHeader.message.slot);
202
+ blockInput = BlockInputColumns.createFromColumn({
203
+ columnSidecar,
204
+ blockRootHex,
205
+ daOutOfRange,
206
+ forkName,
207
+ source,
208
+ seenTimestampSec,
209
+ peerIdStr,
210
+ custodyColumns: this.custodyConfig.custodyColumns,
211
+ sampledColumns: this.custodyConfig.sampledColumns,
212
+ });
213
+ this.metrics?.seenCache.blockInput.createdByBlob.inc();
214
+ this.blockInputs.set(blockRootHex, blockInput);
305
215
  }
306
- if (cachedData.fork === ForkName.deneb || cachedData.fork === ForkName.electra) {
307
- const { blobsCache } = cachedData;
308
- return {
309
- blockInput: {
310
- block: null,
311
- blockRootHex: blockHex,
312
- cachedData,
313
- blockInputPromise,
314
- },
315
- blockInputMeta: { pending: GossipedInputType.block, haveBlobs: blobsCache.size, expectedBlobs: null },
316
- };
216
+ if (!isBlockInputColumns(blockInput)) {
217
+ throw new SeenBlockInputCacheError({
218
+ code: SeenBlockInputCacheErrorCode.WRONG_BLOCK_INPUT_TYPE,
219
+ cachedType: blockInput.type,
220
+ requestedType: DAType.Columns,
221
+ ...blockInput.getLogMeta(),
222
+ }, `BlockInputType mismatch adding columnIndex=${columnSidecar.index}`);
317
223
  }
318
- if (fork === ForkName.fulu) {
319
- const { dataColumnsCache } = cachedData;
320
- return {
321
- blockInput: {
322
- block: null,
323
- blockRootHex: blockHex,
324
- cachedData,
325
- blockInputPromise,
326
- },
327
- blockInputMeta: { pending: GossipedInputType.block, haveColumns: dataColumnsCache.size, expectedColumns: null },
328
- };
224
+ if (!blockInput.hasColumn(columnSidecar.index)) {
225
+ blockInput.addColumn({ columnSidecar, blockRootHex, source, seenTimestampSec, peerIdStr });
329
226
  }
330
- throw Error(`invalid fork=${fork} data not implemented`);
331
- /**
332
- * TODO: @matthewkeil this code was unreachable. Commented to remove lint error but need to verify the condition
333
- * again to make sure this is not necessary before deleting it
334
- *
335
- * DO NOT DELETE until verified can be removed
336
- */
337
- // will need to wait for the block to showup
338
- // if (cachedData === undefined) {
339
- // throw Error("Missing cachedData for deneb+ blobs");
340
- // }
341
- // const {blobsCache} = cachedData as CachedBlobs;
342
- // return {
343
- // blockInput: {
344
- // block: null,
345
- // blockRootHex: blockHex,
346
- // cachedData: cachedData as CachedData,
347
- // blockInputPromise,
348
- // },
349
- // blockInputMeta: {pending: GossipedInputType.block, haveBlobs: blobsCache.size, expectedBlobs: null},
350
- // };
351
- }
352
- }
353
- export function getEmptyBlockInputCacheEntry(fork, globalCacheId) {
354
- // Capture both the promise and its callbacks for blockInput and final availability
355
- // It is not spec'ed but in tests in Firefox and NodeJS the promise constructor is run immediately
356
- let resolveBlockInput = null;
357
- const blockInputPromise = new Promise((resolveCB) => {
358
- resolveBlockInput = resolveCB;
359
- });
360
- if (resolveBlockInput === null) {
361
- throw Error("Promise Constructor was not executed immediately");
362
- }
363
- if (!isForkPostDeneb(fork)) {
364
- return { fork, blockInputPromise, resolveBlockInput };
365
- }
366
- if (fork === ForkName.deneb || fork === ForkName.electra) {
367
- let resolveAvailability = null;
368
- const availabilityPromise = new Promise((resolveCB) => {
369
- resolveAvailability = resolveCB;
370
- });
371
- if (resolveAvailability === null) {
372
- throw Error("Promise Constructor was not executed immediately");
227
+ else if (!created) {
228
+ this.logger?.debug(`Attempt to cache column index #${columnSidecar.index} but is already cached on BlockInput`, blockInput.getLogMeta());
229
+ this.metrics?.seenCache.blockInput.duplicateColumnCount.inc({ source });
230
+ if (opts.throwErrorIfAlreadyKnown) {
231
+ throw new SeenBlockInputCacheError({
232
+ code: SeenBlockInputCacheErrorCode.GOSSIP_COLUMN_ALREADY_KNOWN,
233
+ ...blockInput.getLogMeta(),
234
+ });
235
+ }
373
236
  }
374
- const blobsCache = new Map();
375
- const cachedData = {
376
- fork,
377
- blobsCache,
378
- availabilityPromise,
379
- resolveAvailability,
380
- cacheId: ++globalCacheId,
237
+ return blockInput;
238
+ }
239
+ buildCommonProps(slot) {
240
+ const forkName = this.config.getForkName(slot);
241
+ return {
242
+ forkName,
243
+ daOutOfRange: isDaOutOfRange(this.config, forkName, slot, this.clock.currentEpoch),
381
244
  };
382
- return { fork, blockInputPromise, resolveBlockInput, cachedData };
383
245
  }
384
- if (fork === ForkName.fulu) {
385
- let resolveAvailability = null;
386
- const availabilityPromise = new Promise((resolveCB) => {
387
- resolveAvailability = resolveCB;
388
- });
389
- if (resolveAvailability === null) {
390
- throw Error("Promise Constructor was not executed immediately");
246
+ /**
247
+ * Use custom implementation of pruneSetToMax to allow for sorting by slot
248
+ * and deleting via key/rootHex
249
+ */
250
+ pruneToMaxSize() {
251
+ let itemsToDelete = this.blockInputs.size - MAX_BLOCK_INPUT_CACHE_SIZE;
252
+ if (itemsToDelete > 0) {
253
+ const sorted = [...this.blockInputs.entries()].sort((a, b) => b[1].slot - a[1].slot);
254
+ for (const [rootHex] of sorted) {
255
+ this.blockInputs.delete(rootHex);
256
+ itemsToDelete--;
257
+ if (itemsToDelete <= 0)
258
+ return;
259
+ }
391
260
  }
392
- const dataColumnsCache = new Map();
393
- const cachedData = {
394
- fork,
395
- dataColumnsCache,
396
- availabilityPromise,
397
- resolveAvailability,
398
- cacheId: ++globalCacheId,
399
- calledRecover: false,
400
- };
401
- return { fork, blockInputPromise, resolveBlockInput, cachedData };
402
261
  }
403
- throw Error(`Invalid fork=${fork} for getEmptyBlockInputCacheEntry`);
262
+ }
263
+ var SeenBlockInputCacheErrorCode;
264
+ (function (SeenBlockInputCacheErrorCode) {
265
+ SeenBlockInputCacheErrorCode["WRONG_BLOCK_INPUT_TYPE"] = "BLOCK_INPUT_CACHE_ERROR_WRONG_BLOCK_INPUT_TYPE";
266
+ SeenBlockInputCacheErrorCode["GOSSIP_BLOB_ALREADY_KNOWN"] = "BLOCK_INPUT_CACHE_ERROR_GOSSIP_BLOB_ALREADY_KNOWN";
267
+ SeenBlockInputCacheErrorCode["GOSSIP_COLUMN_ALREADY_KNOWN"] = "BLOCK_INPUT_CACHE_ERROR_GOSSIP_COLUMN_ALREADY_KNOWN";
268
+ })(SeenBlockInputCacheErrorCode || (SeenBlockInputCacheErrorCode = {}));
269
+ class SeenBlockInputCacheError extends LodestarError {
404
270
  }
405
271
  //# sourceMappingURL=seenGossipBlockInput.js.map