@lodestar/beacon-node 1.40.0-dev.9e8478fc70 → 1.40.0-dev.ade3accfa0

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 (386) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +15 -9
  3. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  4. package/lib/api/impl/lodestar/index.d.ts.map +1 -1
  5. package/lib/api/impl/lodestar/index.js +24 -0
  6. package/lib/api/impl/lodestar/index.js.map +1 -1
  7. package/lib/api/impl/validator/index.d.ts.map +1 -1
  8. package/lib/api/impl/validator/index.js.map +1 -1
  9. package/lib/api/rest/base.d.ts.map +1 -1
  10. package/lib/api/rest/base.js +12 -10
  11. package/lib/api/rest/base.js.map +1 -1
  12. package/lib/chain/ColumnReconstructionTracker.d.ts +2 -0
  13. package/lib/chain/ColumnReconstructionTracker.d.ts.map +1 -1
  14. package/lib/chain/ColumnReconstructionTracker.js +7 -3
  15. package/lib/chain/ColumnReconstructionTracker.js.map +1 -1
  16. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  17. package/lib/chain/archiveStore/archiveStore.js +10 -4
  18. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  19. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
  20. package/lib/chain/archiveStore/historicalState/getHistoricalState.js +2 -1
  21. package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
  22. package/lib/chain/blocks/blockInput/blockInput.d.ts +28 -0
  23. package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
  24. package/lib/chain/blocks/blockInput/blockInput.js +38 -3
  25. package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
  26. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  27. package/lib/chain/blocks/importBlock.js +10 -2
  28. package/lib/chain/blocks/importBlock.js.map +1 -1
  29. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  30. package/lib/chain/blocks/verifyBlock.js +1 -1
  31. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  32. package/lib/chain/blocks/verifyBlocksSignatures.d.ts +2 -2
  33. package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
  34. package/lib/chain/blocks/verifyBlocksSignatures.js +2 -2
  35. package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
  36. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
  37. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +1 -2
  38. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
  39. package/lib/chain/blocks/writeBlockInputToDb.d.ts.map +1 -1
  40. package/lib/chain/blocks/writeBlockInputToDb.js +8 -0
  41. package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
  42. package/lib/chain/bls/multithread/index.d.ts +3 -1
  43. package/lib/chain/bls/multithread/index.d.ts.map +1 -1
  44. package/lib/chain/bls/multithread/index.js +5 -3
  45. package/lib/chain/bls/multithread/index.js.map +1 -1
  46. package/lib/chain/bls/multithread/jobItem.d.ts +2 -2
  47. package/lib/chain/bls/multithread/jobItem.d.ts.map +1 -1
  48. package/lib/chain/bls/multithread/jobItem.js +2 -2
  49. package/lib/chain/bls/multithread/jobItem.js.map +1 -1
  50. package/lib/chain/bls/singleThread.d.ts +4 -2
  51. package/lib/chain/bls/singleThread.d.ts.map +1 -1
  52. package/lib/chain/bls/singleThread.js +4 -2
  53. package/lib/chain/bls/singleThread.js.map +1 -1
  54. package/lib/chain/bls/utils.d.ts +2 -2
  55. package/lib/chain/bls/utils.d.ts.map +1 -1
  56. package/lib/chain/bls/utils.js +9 -6
  57. package/lib/chain/bls/utils.js.map +1 -1
  58. package/lib/chain/chain.d.ts +8 -3
  59. package/lib/chain/chain.d.ts.map +1 -1
  60. package/lib/chain/chain.js +44 -36
  61. package/lib/chain/chain.js.map +1 -1
  62. package/lib/chain/errors/attestationError.d.ts +14 -1
  63. package/lib/chain/errors/attestationError.d.ts.map +1 -1
  64. package/lib/chain/errors/attestationError.js +8 -0
  65. package/lib/chain/errors/attestationError.js.map +1 -1
  66. package/lib/chain/errors/executionPayloadBid.d.ts +48 -0
  67. package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -0
  68. package/lib/chain/errors/executionPayloadBid.js +15 -0
  69. package/lib/chain/errors/executionPayloadBid.js.map +1 -0
  70. package/lib/chain/errors/executionPayloadEnvelope.d.ts +48 -0
  71. package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -0
  72. package/lib/chain/errors/executionPayloadEnvelope.js +16 -0
  73. package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -0
  74. package/lib/chain/errors/index.d.ts +3 -0
  75. package/lib/chain/errors/index.d.ts.map +1 -1
  76. package/lib/chain/errors/index.js +3 -0
  77. package/lib/chain/errors/index.js.map +1 -1
  78. package/lib/chain/errors/payloadAttestation.d.ts +34 -0
  79. package/lib/chain/errors/payloadAttestation.d.ts.map +1 -0
  80. package/lib/chain/errors/payloadAttestation.js +13 -0
  81. package/lib/chain/errors/payloadAttestation.js.map +1 -0
  82. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  83. package/lib/chain/forkChoice/index.js +18 -0
  84. package/lib/chain/forkChoice/index.js.map +1 -1
  85. package/lib/chain/initState.d.ts.map +1 -1
  86. package/lib/chain/initState.js +2 -2
  87. package/lib/chain/initState.js.map +1 -1
  88. package/lib/chain/interface.d.ts +7 -2
  89. package/lib/chain/interface.d.ts.map +1 -1
  90. package/lib/chain/interface.js.map +1 -1
  91. package/lib/chain/lightClient/index.d.ts +2 -0
  92. package/lib/chain/lightClient/index.d.ts.map +1 -1
  93. package/lib/chain/lightClient/index.js +11 -6
  94. package/lib/chain/lightClient/index.js.map +1 -1
  95. package/lib/chain/opPools/executionPayloadBidPool.d.ts +21 -0
  96. package/lib/chain/opPools/executionPayloadBidPool.d.ts.map +1 -0
  97. package/lib/chain/opPools/executionPayloadBidPool.js +57 -0
  98. package/lib/chain/opPools/executionPayloadBidPool.js.map +1 -0
  99. package/lib/chain/opPools/index.d.ts +2 -0
  100. package/lib/chain/opPools/index.d.ts.map +1 -1
  101. package/lib/chain/opPools/index.js +2 -0
  102. package/lib/chain/opPools/index.js.map +1 -1
  103. package/lib/chain/opPools/payloadAttestationPool.d.ts +24 -0
  104. package/lib/chain/opPools/payloadAttestationPool.d.ts.map +1 -0
  105. package/lib/chain/opPools/payloadAttestationPool.js +109 -0
  106. package/lib/chain/opPools/payloadAttestationPool.js.map +1 -0
  107. package/lib/chain/options.d.ts +0 -1
  108. package/lib/chain/options.d.ts.map +1 -1
  109. package/lib/chain/options.js +0 -1
  110. package/lib/chain/options.js.map +1 -1
  111. package/lib/chain/regen/interface.d.ts +2 -1
  112. package/lib/chain/regen/interface.d.ts.map +1 -1
  113. package/lib/chain/regen/interface.js +1 -0
  114. package/lib/chain/regen/interface.js.map +1 -1
  115. package/lib/chain/regen/queued.d.ts +1 -1
  116. package/lib/chain/regen/queued.d.ts.map +1 -1
  117. package/lib/chain/regen/queued.js.map +1 -1
  118. package/lib/chain/regen/regen.d.ts +2 -0
  119. package/lib/chain/regen/regen.d.ts.map +1 -1
  120. package/lib/chain/regen/regen.js +4 -1
  121. package/lib/chain/regen/regen.js.map +1 -1
  122. package/lib/chain/seenCache/index.d.ts +3 -1
  123. package/lib/chain/seenCache/index.d.ts.map +1 -1
  124. package/lib/chain/seenCache/index.js +3 -1
  125. package/lib/chain/seenCache/index.js.map +1 -1
  126. package/lib/chain/seenCache/seenAttesters.d.ts +5 -0
  127. package/lib/chain/seenCache/seenAttesters.d.ts.map +1 -1
  128. package/lib/chain/seenCache/seenAttesters.js +5 -0
  129. package/lib/chain/seenCache/seenAttesters.js.map +1 -1
  130. package/lib/chain/seenCache/seenExecutionPayloadBids.d.ts +12 -0
  131. package/lib/chain/seenCache/seenExecutionPayloadBids.d.ts.map +1 -0
  132. package/lib/chain/seenCache/seenExecutionPayloadBids.js +30 -0
  133. package/lib/chain/seenCache/seenExecutionPayloadBids.js.map +1 -0
  134. package/lib/chain/seenCache/seenExecutionPayloadEnvelope.d.ts +15 -0
  135. package/lib/chain/seenCache/seenExecutionPayloadEnvelope.d.ts.map +1 -0
  136. package/lib/chain/seenCache/seenExecutionPayloadEnvelope.js +28 -0
  137. package/lib/chain/seenCache/seenExecutionPayloadEnvelope.js.map +1 -0
  138. package/lib/chain/seenCache/seenGossipBlockInput.d.ts +7 -7
  139. package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
  140. package/lib/chain/seenCache/seenGossipBlockInput.js +23 -12
  141. package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
  142. package/lib/chain/serializeState.d.ts.map +1 -1
  143. package/lib/chain/serializeState.js +2 -1
  144. package/lib/chain/serializeState.js.map +1 -1
  145. package/lib/chain/stateCache/index.d.ts +0 -2
  146. package/lib/chain/stateCache/index.d.ts.map +1 -1
  147. package/lib/chain/stateCache/index.js +0 -2
  148. package/lib/chain/stateCache/index.js.map +1 -1
  149. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +2 -1
  150. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  151. package/lib/chain/stateCache/persistentCheckpointsCache.js +3 -0
  152. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  153. package/lib/chain/validation/aggregateAndProof.js +35 -14
  154. package/lib/chain/validation/aggregateAndProof.js.map +1 -1
  155. package/lib/chain/validation/attestation.d.ts +2 -2
  156. package/lib/chain/validation/attestation.d.ts.map +1 -1
  157. package/lib/chain/validation/attestation.js +27 -8
  158. package/lib/chain/validation/attestation.js.map +1 -1
  159. package/lib/chain/validation/attesterSlashing.d.ts.map +1 -1
  160. package/lib/chain/validation/attesterSlashing.js +1 -1
  161. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  162. package/lib/chain/validation/blobSidecar.d.ts.map +1 -1
  163. package/lib/chain/validation/blobSidecar.js +4 -4
  164. package/lib/chain/validation/blobSidecar.js.map +1 -1
  165. package/lib/chain/validation/block.d.ts.map +1 -1
  166. package/lib/chain/validation/block.js +6 -6
  167. package/lib/chain/validation/block.js.map +1 -1
  168. package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
  169. package/lib/chain/validation/dataColumnSidecar.js +4 -4
  170. package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
  171. package/lib/chain/validation/executionPayloadBid.d.ts +5 -0
  172. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -0
  173. package/lib/chain/validation/executionPayloadBid.js +104 -0
  174. package/lib/chain/validation/executionPayloadBid.js.map +1 -0
  175. package/lib/chain/validation/executionPayloadEnvelope.d.ts +5 -0
  176. package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -0
  177. package/lib/chain/validation/executionPayloadEnvelope.js +89 -0
  178. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -0
  179. package/lib/chain/validation/payloadAttestationMessage.d.ts +9 -0
  180. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -0
  181. package/lib/chain/validation/payloadAttestationMessage.js +72 -0
  182. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -0
  183. package/lib/chain/validation/proposerSlashing.js +1 -1
  184. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  185. package/lib/chain/validation/signatureSets/aggregateAndProof.d.ts +2 -3
  186. package/lib/chain/validation/signatureSets/aggregateAndProof.d.ts.map +1 -1
  187. package/lib/chain/validation/signatureSets/aggregateAndProof.js +8 -3
  188. package/lib/chain/validation/signatureSets/aggregateAndProof.js.map +1 -1
  189. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts +2 -2
  190. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts.map +1 -1
  191. package/lib/chain/validation/signatureSets/contributionAndProof.js +3 -3
  192. package/lib/chain/validation/signatureSets/contributionAndProof.js.map +1 -1
  193. package/lib/chain/validation/signatureSets/selectionProof.d.ts +2 -3
  194. package/lib/chain/validation/signatureSets/selectionProof.d.ts.map +1 -1
  195. package/lib/chain/validation/signatureSets/selectionProof.js +8 -3
  196. package/lib/chain/validation/signatureSets/selectionProof.js.map +1 -1
  197. package/lib/chain/validation/signatureSets/syncCommittee.d.ts +2 -2
  198. package/lib/chain/validation/signatureSets/syncCommittee.d.ts.map +1 -1
  199. package/lib/chain/validation/signatureSets/syncCommittee.js +3 -3
  200. package/lib/chain/validation/signatureSets/syncCommittee.js.map +1 -1
  201. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts +1 -2
  202. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts.map +1 -1
  203. package/lib/chain/validation/signatureSets/syncCommitteeContribution.js +2 -2
  204. package/lib/chain/validation/signatureSets/syncCommitteeContribution.js.map +1 -1
  205. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts +2 -2
  206. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts.map +1 -1
  207. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js +3 -3
  208. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js.map +1 -1
  209. package/lib/chain/validation/syncCommittee.js +1 -1
  210. package/lib/chain/validation/syncCommittee.js.map +1 -1
  211. package/lib/chain/validation/syncCommitteeContributionAndProof.d.ts.map +1 -1
  212. package/lib/chain/validation/syncCommitteeContributionAndProof.js +3 -5
  213. package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
  214. package/lib/chain/validation/voluntaryExit.js +1 -1
  215. package/lib/chain/validation/voluntaryExit.js.map +1 -1
  216. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  217. package/lib/chain/validatorMonitor.js +7 -4
  218. package/lib/chain/validatorMonitor.js.map +1 -1
  219. package/lib/db/repositories/checkpointState.js +0 -1
  220. package/lib/db/repositories/checkpointState.js.map +1 -1
  221. package/lib/metrics/metrics/lodestar.d.ts +20 -0
  222. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  223. package/lib/metrics/metrics/lodestar.js +40 -0
  224. package/lib/metrics/metrics/lodestar.js.map +1 -1
  225. package/lib/network/core/networkCore.d.ts +3 -0
  226. package/lib/network/core/networkCore.d.ts.map +1 -1
  227. package/lib/network/core/networkCore.js +9 -0
  228. package/lib/network/core/networkCore.js.map +1 -1
  229. package/lib/network/core/networkCoreWorker.js +3 -0
  230. package/lib/network/core/networkCoreWorker.js.map +1 -1
  231. package/lib/network/core/networkCoreWorkerHandler.d.ts +3 -0
  232. package/lib/network/core/networkCoreWorkerHandler.d.ts.map +1 -1
  233. package/lib/network/core/networkCoreWorkerHandler.js +9 -0
  234. package/lib/network/core/networkCoreWorkerHandler.js.map +1 -1
  235. package/lib/network/core/types.d.ts +3 -0
  236. package/lib/network/core/types.d.ts.map +1 -1
  237. package/lib/network/gossip/gossipsub.d.ts +34 -0
  238. package/lib/network/gossip/gossipsub.d.ts.map +1 -1
  239. package/lib/network/gossip/gossipsub.js +123 -0
  240. package/lib/network/gossip/gossipsub.js.map +1 -1
  241. package/lib/network/gossip/interface.d.ts +20 -2
  242. package/lib/network/gossip/interface.d.ts.map +1 -1
  243. package/lib/network/gossip/interface.js +3 -0
  244. package/lib/network/gossip/interface.js.map +1 -1
  245. package/lib/network/gossip/scoringParameters.d.ts.map +1 -1
  246. package/lib/network/gossip/scoringParameters.js +38 -2
  247. package/lib/network/gossip/scoringParameters.js.map +1 -1
  248. package/lib/network/gossip/topic.d.ts +77 -1
  249. package/lib/network/gossip/topic.d.ts.map +1 -1
  250. package/lib/network/gossip/topic.js +20 -0
  251. package/lib/network/gossip/topic.js.map +1 -1
  252. package/lib/network/network.d.ts +3 -0
  253. package/lib/network/network.d.ts.map +1 -1
  254. package/lib/network/network.js +9 -0
  255. package/lib/network/network.js.map +1 -1
  256. package/lib/network/options.d.ts +6 -0
  257. package/lib/network/options.d.ts.map +1 -1
  258. package/lib/network/options.js.map +1 -1
  259. package/lib/network/peers/peerManager.d.ts.map +1 -1
  260. package/lib/network/peers/peerManager.js +9 -0
  261. package/lib/network/peers/peerManager.js.map +1 -1
  262. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  263. package/lib/network/processor/gossipHandlers.js +35 -1
  264. package/lib/network/processor/gossipHandlers.js.map +1 -1
  265. package/lib/network/processor/gossipQueues/index.d.ts.map +1 -1
  266. package/lib/network/processor/gossipQueues/index.js +16 -0
  267. package/lib/network/processor/gossipQueues/index.js.map +1 -1
  268. package/lib/network/processor/index.d.ts.map +1 -1
  269. package/lib/network/processor/index.js +3 -0
  270. package/lib/network/processor/index.js.map +1 -1
  271. package/lib/sync/backfill/backfill.d.ts.map +1 -1
  272. package/lib/sync/backfill/backfill.js +3 -4
  273. package/lib/sync/backfill/backfill.js.map +1 -1
  274. package/lib/sync/backfill/verify.d.ts +1 -2
  275. package/lib/sync/backfill/verify.d.ts.map +1 -1
  276. package/lib/sync/backfill/verify.js +2 -2
  277. package/lib/sync/backfill/verify.js.map +1 -1
  278. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  279. package/lib/sync/utils/downloadByRange.js +2 -2
  280. package/lib/sync/utils/downloadByRange.js.map +1 -1
  281. package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
  282. package/lib/sync/utils/downloadByRoot.js +1 -2
  283. package/lib/sync/utils/downloadByRoot.js.map +1 -1
  284. package/lib/util/queue/itemQueue.d.ts +10 -0
  285. package/lib/util/queue/itemQueue.d.ts.map +1 -1
  286. package/lib/util/queue/itemQueue.js +57 -0
  287. package/lib/util/queue/itemQueue.js.map +1 -1
  288. package/package.json +16 -16
  289. package/src/api/impl/beacon/blocks/index.ts +31 -19
  290. package/src/api/impl/lodestar/index.ts +29 -0
  291. package/src/api/impl/validator/index.ts +2 -1
  292. package/src/api/rest/base.ts +15 -13
  293. package/src/chain/ColumnReconstructionTracker.ts +8 -4
  294. package/src/chain/archiveStore/archiveStore.ts +10 -4
  295. package/src/chain/archiveStore/historicalState/getHistoricalState.ts +2 -1
  296. package/src/chain/blocks/blockInput/blockInput.ts +47 -4
  297. package/src/chain/blocks/importBlock.ts +10 -2
  298. package/src/chain/blocks/verifyBlock.ts +0 -1
  299. package/src/chain/blocks/verifyBlocksSignatures.ts +4 -12
  300. package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +1 -2
  301. package/src/chain/blocks/writeBlockInputToDb.ts +9 -0
  302. package/src/chain/bls/multithread/index.ts +7 -4
  303. package/src/chain/bls/multithread/jobItem.ts +7 -3
  304. package/src/chain/bls/singleThread.ts +5 -3
  305. package/src/chain/bls/utils.ts +15 -7
  306. package/src/chain/chain.ts +52 -38
  307. package/src/chain/errors/attestationError.ts +11 -1
  308. package/src/chain/errors/executionPayloadBid.ts +35 -0
  309. package/src/chain/errors/executionPayloadEnvelope.ts +34 -0
  310. package/src/chain/errors/index.ts +3 -0
  311. package/src/chain/errors/payloadAttestation.ts +25 -0
  312. package/src/chain/forkChoice/index.ts +19 -0
  313. package/src/chain/initState.ts +2 -2
  314. package/src/chain/interface.ts +16 -1
  315. package/src/chain/lightClient/index.ts +12 -6
  316. package/src/chain/opPools/executionPayloadBidPool.ts +77 -0
  317. package/src/chain/opPools/index.ts +2 -0
  318. package/src/chain/opPools/payloadAttestationPool.ts +157 -0
  319. package/src/chain/options.ts +0 -2
  320. package/src/chain/regen/interface.ts +2 -1
  321. package/src/chain/regen/queued.ts +1 -2
  322. package/src/chain/regen/regen.ts +6 -1
  323. package/src/chain/seenCache/index.ts +3 -1
  324. package/src/chain/seenCache/seenAttesters.ts +5 -0
  325. package/src/chain/seenCache/seenExecutionPayloadBids.ts +35 -0
  326. package/src/chain/seenCache/seenExecutionPayloadEnvelope.ts +34 -0
  327. package/src/chain/seenCache/seenGossipBlockInput.ts +31 -12
  328. package/src/chain/serializeState.ts +2 -1
  329. package/src/chain/stateCache/index.ts +0 -2
  330. package/src/chain/stateCache/persistentCheckpointsCache.ts +6 -2
  331. package/src/chain/validation/aggregateAndProof.ts +36 -14
  332. package/src/chain/validation/attestation.ts +33 -16
  333. package/src/chain/validation/attesterSlashing.ts +1 -6
  334. package/src/chain/validation/blobSidecar.ts +3 -8
  335. package/src/chain/validation/block.ts +6 -6
  336. package/src/chain/validation/dataColumnSidecar.ts +3 -8
  337. package/src/chain/validation/executionPayloadBid.ts +141 -0
  338. package/src/chain/validation/executionPayloadEnvelope.ts +122 -0
  339. package/src/chain/validation/payloadAttestationMessage.ts +109 -0
  340. package/src/chain/validation/proposerSlashing.ts +1 -6
  341. package/src/chain/validation/signatureSets/aggregateAndProof.ts +9 -14
  342. package/src/chain/validation/signatureSets/contributionAndProof.ts +2 -4
  343. package/src/chain/validation/signatureSets/selectionProof.ts +9 -9
  344. package/src/chain/validation/signatureSets/syncCommittee.ts +2 -4
  345. package/src/chain/validation/signatureSets/syncCommitteeContribution.ts +2 -3
  346. package/src/chain/validation/signatureSets/syncCommitteeSelectionProof.ts +2 -4
  347. package/src/chain/validation/syncCommittee.ts +1 -1
  348. package/src/chain/validation/syncCommitteeContributionAndProof.ts +3 -5
  349. package/src/chain/validation/voluntaryExit.ts +1 -1
  350. package/src/chain/validatorMonitor.ts +10 -5
  351. package/src/db/repositories/checkpointState.ts +1 -1
  352. package/src/metrics/metrics/lodestar.ts +40 -0
  353. package/src/network/core/networkCore.ts +12 -0
  354. package/src/network/core/networkCoreWorker.ts +3 -0
  355. package/src/network/core/networkCoreWorkerHandler.ts +9 -0
  356. package/src/network/core/types.ts +6 -0
  357. package/src/network/gossip/gossipsub.ts +147 -1
  358. package/src/network/gossip/interface.ts +17 -0
  359. package/src/network/gossip/scoringParameters.ts +44 -2
  360. package/src/network/gossip/topic.ts +21 -0
  361. package/src/network/network.ts +12 -0
  362. package/src/network/options.ts +6 -0
  363. package/src/network/peers/peerManager.ts +11 -0
  364. package/src/network/processor/gossipHandlers.ts +49 -1
  365. package/src/network/processor/gossipQueues/index.ts +16 -0
  366. package/src/network/processor/index.ts +3 -0
  367. package/src/sync/backfill/backfill.ts +3 -4
  368. package/src/sync/backfill/verify.ts +2 -3
  369. package/src/sync/utils/downloadByRange.ts +2 -2
  370. package/src/sync/utils/downloadByRoot.ts +1 -2
  371. package/src/util/queue/itemQueue.ts +62 -0
  372. package/lib/chain/stateCache/blockStateCacheImpl.d.ts +0 -54
  373. package/lib/chain/stateCache/blockStateCacheImpl.d.ts.map +0 -1
  374. package/lib/chain/stateCache/blockStateCacheImpl.js +0 -130
  375. package/lib/chain/stateCache/blockStateCacheImpl.js.map +0 -1
  376. package/lib/chain/stateCache/inMemoryCheckpointsCache.d.ts +0 -60
  377. package/lib/chain/stateCache/inMemoryCheckpointsCache.d.ts.map +0 -1
  378. package/lib/chain/stateCache/inMemoryCheckpointsCache.js +0 -156
  379. package/lib/chain/stateCache/inMemoryCheckpointsCache.js.map +0 -1
  380. package/lib/util/bytes.d.ts +0 -3
  381. package/lib/util/bytes.d.ts.map +0 -1
  382. package/lib/util/bytes.js +0 -11
  383. package/lib/util/bytes.js.map +0 -1
  384. package/src/chain/stateCache/blockStateCacheImpl.ts +0 -149
  385. package/src/chain/stateCache/inMemoryCheckpointsCache.ts +0 -192
  386. package/src/util/bytes.ts +0 -11
@@ -133,21 +133,31 @@ export function getBeaconBlockApi({
133
133
 
134
134
  if (isBlockInputColumns(blockForImport)) {
135
135
  for (const dataColumnSidecar of dataColumnSidecars) {
136
- blockForImport.addColumn({
137
- blockRootHex: blockRoot,
138
- columnSidecar: dataColumnSidecar,
139
- source: BlockInputSource.api,
140
- seenTimestampSec,
141
- });
136
+ blockForImport.addColumn(
137
+ {
138
+ blockRootHex: blockRoot,
139
+ columnSidecar: dataColumnSidecar,
140
+ source: BlockInputSource.api,
141
+ seenTimestampSec,
142
+ },
143
+ // In multi-BN setups (DVT, fallback), the same block may be published to multiple nodes.
144
+ // Data columns may arrive via gossip from another node before the API publish completes,
145
+ // so we allow duplicates here instead of throwing an error.
146
+ {throwOnDuplicateAdd: false}
147
+ );
142
148
  }
143
149
  } else if (isBlockInputBlobs(blockForImport)) {
144
150
  for (const blobSidecar of blobSidecars) {
145
- blockForImport.addBlob({
146
- blockRootHex: blockRoot,
147
- blobSidecar,
148
- source: BlockInputSource.api,
149
- seenTimestampSec,
150
- });
151
+ blockForImport.addBlob(
152
+ {
153
+ blockRootHex: blockRoot,
154
+ blobSidecar,
155
+ source: BlockInputSource.api,
156
+ seenTimestampSec,
157
+ },
158
+ // Same as above for columns
159
+ {throwOnDuplicateAdd: false}
160
+ );
151
161
  }
152
162
  }
153
163
 
@@ -434,11 +444,13 @@ export function getBeaconBlockApi({
434
444
  const nonFinalizedBlocks = chain.forkChoice.getBlockSummariesByParentRoot(parentRoot);
435
445
  await Promise.all(
436
446
  nonFinalizedBlocks.map(async (summary) => {
437
- const block = await db.block.get(fromHex(summary.blockRoot));
438
- if (block) {
439
- const canonical = chain.forkChoice.getCanonicalBlockAtSlot(block.message.slot);
447
+ const blockResult = await chain.getBlockByRoot(summary.blockRoot);
448
+ if (blockResult) {
449
+ const canonical = chain.forkChoice.getCanonicalBlockAtSlot(blockResult.block.message.slot);
440
450
  if (canonical) {
441
- result.push(toBeaconHeaderResponse(config, block, canonical.blockRoot === summary.blockRoot));
451
+ result.push(
452
+ toBeaconHeaderResponse(config, blockResult.block, canonical.blockRoot === summary.blockRoot)
453
+ );
442
454
  if (isOptimisticBlock(canonical)) {
443
455
  executionOptimistic = true;
444
456
  }
@@ -492,9 +504,9 @@ export function getBeaconBlockApi({
492
504
  finalized = false;
493
505
 
494
506
  if (summary.blockRoot !== toRootHex(canonicalRoot)) {
495
- const block = await db.block.get(fromHex(summary.blockRoot));
496
- if (block) {
497
- result.push(toBeaconHeaderResponse(config, block));
507
+ const blockResult = await chain.getBlockByRoot(summary.blockRoot);
508
+ if (blockResult) {
509
+ result.push(toBeaconHeaderResponse(config, blockResult.block));
498
510
  }
499
511
  }
500
512
  })
@@ -154,6 +154,23 @@ export function getLodestarApi({
154
154
  await network.disconnectPeer(peerId);
155
155
  },
156
156
 
157
+ async addDirectPeer({peer}) {
158
+ const peerId = await network.addDirectPeer(peer);
159
+ if (peerId === null) {
160
+ throw new ApiError(400, `Failed to add direct peer: invalid peer address or ENR "${peer}"`);
161
+ }
162
+ return {data: {peerId}};
163
+ },
164
+
165
+ async removeDirectPeer({peerId}) {
166
+ const removed = await network.removeDirectPeer(peerId);
167
+ return {data: {removed}};
168
+ },
169
+
170
+ async getDirectPeers() {
171
+ return {data: await network.getDirectPeers()};
172
+ },
173
+
157
174
  async getPeers({state, direction}) {
158
175
  const peers = (await network.dumpPeers()).filter(
159
176
  (nodePeer) =>
@@ -244,6 +261,18 @@ export function getLodestarApi({
244
261
  data: chain.validatorMonitor?.getMonitoredValidatorIndices() ?? [],
245
262
  };
246
263
  },
264
+
265
+ async getCustodyInfo() {
266
+ const {custodyColumns, targetCustodyGroupCount} = chain.custodyConfig;
267
+
268
+ return {
269
+ data: {
270
+ earliestCustodiedSlot: chain.earliestAvailableSlot,
271
+ custodyGroupCount: targetCustodyGroupCount,
272
+ custodyColumns,
273
+ },
274
+ };
275
+ },
247
276
  };
248
277
  }
249
278
 
@@ -67,10 +67,11 @@ import {
67
67
  SyncCommitteeError,
68
68
  SyncCommitteeErrorCode,
69
69
  } from "../../../chain/errors/index.js";
70
- import {ChainEvent, CheckpointHex, CommonBlockBody} from "../../../chain/index.js";
70
+ import {ChainEvent, CommonBlockBody} from "../../../chain/index.js";
71
71
  import {PREPARE_NEXT_SLOT_BPS} from "../../../chain/prepareNextSlot.js";
72
72
  import {BlockType, ProduceFullDeneb} from "../../../chain/produceBlock/index.js";
73
73
  import {RegenCaller} from "../../../chain/regen/index.js";
74
+ import {CheckpointHex} from "../../../chain/stateCache/types.js";
74
75
  import {validateApiAggregateAndProof} from "../../../chain/validation/index.js";
75
76
  import {validateSyncCommitteeGossipContributionAndProof} from "../../../chain/validation/syncCommitteeContributionAndProof.js";
76
77
  import {ZERO_HASH} from "../../../constants/index.js";
@@ -1,6 +1,6 @@
1
1
  import bearerAuthPlugin from "@fastify/bearer-auth";
2
2
  import {fastifyCors} from "@fastify/cors";
3
- import {FastifyInstance, FastifyRequest, errorCodes, fastify} from "fastify";
3
+ import {FastifyError, FastifyInstance, FastifyRequest, errorCodes, fastify} from "fastify";
4
4
  import {parse as parseQueryString} from "qs";
5
5
  import {addSszContentTypeParser} from "@lodestar/api/server";
6
6
  import {ErrorAborted, Gauge, Histogram, Logger} from "@lodestar/utils";
@@ -73,15 +73,17 @@ export class RestApiServer {
73
73
  const server = fastify({
74
74
  logger: false,
75
75
  ajv: {customOptions: {coerceTypes: "array"}},
76
- querystringParser: (str) =>
77
- parseQueryString(str, {
78
- // Array as comma-separated values must be supported to be OpenAPI spec compliant
79
- comma: true,
80
- // Drop support for array query strings like `id[0]=1&id[1]=2&id[2]=3` as those are not required to
81
- // be OpenAPI spec compliant and results are inconsistent, see https://github.com/ljharb/qs/issues/331.
82
- // The schema validation will catch this and throw an error as parsed query string results in an object.
83
- parseArrays: false,
84
- }),
76
+ routerOptions: {
77
+ querystringParser: (str) =>
78
+ parseQueryString(str, {
79
+ // Array as comma-separated values must be supported to be OpenAPI spec compliant
80
+ comma: true,
81
+ // Drop support for array query strings like `id[0]=1&id[1]=2&id[2]=3` as those are not required to
82
+ // be OpenAPI spec compliant and results are inconsistent, see https://github.com/ljharb/qs/issues/331.
83
+ // The schema validation will catch this and throw an error as parsed query string results in an object.
84
+ parseArrays: false,
85
+ }),
86
+ },
85
87
  bodyLimit: opts.bodyLimit,
86
88
  http: {maxHeaderSize: opts.headerLimit},
87
89
  });
@@ -91,10 +93,10 @@ export class RestApiServer {
91
93
  this.activeSockets = new HttpActiveSocketsTracker(server.server, metrics);
92
94
 
93
95
  // To parse our ApiError -> statusCode
94
- server.setErrorHandler((err, _req, res) => {
96
+ server.setErrorHandler<FastifyError | Error>((err, _req, res) => {
95
97
  const stacktraces = opts.stacktraces ? err.stack?.split("\n") : undefined;
96
- if (err.validation) {
97
- const {instancePath, message} = err.validation[0];
98
+ if ("validation" in err && err.validation) {
99
+ const {instancePath = "unknown", message} = err.validation?.[0] ?? {};
98
100
  const payload: ErrorResponse = {
99
101
  code: 400,
100
102
  message: `${instancePath.substring(instancePath.lastIndexOf("/") + 1)} ${message}`,
@@ -8,12 +8,12 @@ import {ChainEventEmitter} from "./emitter.js";
8
8
  /**
9
9
  * Minimum time to wait before attempting reconstruction
10
10
  */
11
- const RECONSTRUCTION_DELAY_MIN_MS = 800;
11
+ const RECONSTRUCTION_DELAY_MIN_BPS = 667;
12
12
 
13
13
  /**
14
14
  * Maximum time to wait before attempting reconstruction
15
15
  */
16
- const RECONSTRUCTION_DELAY_MAX_MS = 1200;
16
+ const RECONSTRUCTION_DELAY_MAX_BPS = 1000;
17
17
 
18
18
  export type ColumnReconstructionTrackerInit = {
19
19
  logger: Logger;
@@ -41,11 +41,16 @@ export class ColumnReconstructionTracker {
41
41
  /** Track if a reconstruction attempt is in-flight */
42
42
  running = false;
43
43
 
44
+ private readonly minDelayMs: number;
45
+ private readonly maxDelayMs: number;
46
+
44
47
  constructor(init: ColumnReconstructionTrackerInit) {
45
48
  this.logger = init.logger;
46
49
  this.emitter = init.emitter;
47
50
  this.metrics = init.metrics;
48
51
  this.config = init.config;
52
+ this.minDelayMs = this.config.getSlotComponentDurationMs(RECONSTRUCTION_DELAY_MIN_BPS);
53
+ this.maxDelayMs = this.config.getSlotComponentDurationMs(RECONSTRUCTION_DELAY_MAX_BPS);
49
54
  }
50
55
 
51
56
  triggerColumnReconstruction(blockInput: BlockInputColumns): void {
@@ -61,8 +66,7 @@ export class ColumnReconstructionTracker {
61
66
  // just that it has been triggered for this block root.
62
67
  this.running = true;
63
68
  this.lastBlockRootHex = blockInput.blockRootHex;
64
- const delay =
65
- RECONSTRUCTION_DELAY_MIN_MS + Math.random() * (RECONSTRUCTION_DELAY_MAX_MS - RECONSTRUCTION_DELAY_MIN_MS);
69
+ const delay = this.minDelayMs + Math.random() * (this.maxDelayMs - this.minDelayMs);
66
70
  sleep(delay)
67
71
  .then(() => {
68
72
  const logCtx = {slot: blockInput.slot, root: blockInput.blockRootHex};
@@ -5,7 +5,7 @@ import {callFnWhenAwait} from "@lodestar/utils";
5
5
  import {IBeaconDb} from "../../db/index.js";
6
6
  import {Metrics} from "../../metrics/metrics.js";
7
7
  import {isOptimisticBlock} from "../../util/forkChoice.js";
8
- import {JobItemQueue} from "../../util/queue/index.js";
8
+ import {JobItemQueue, isQueueErrorAborted} from "../../util/queue/index.js";
9
9
  import {ChainEvent} from "../emitter.js";
10
10
  import {IBeaconChain} from "../interface.js";
11
11
  import {PROCESS_FINALIZED_CHECKPOINT_QUEUE_LENGTH} from "./constants.js";
@@ -165,8 +165,12 @@ export class ArchiveStore {
165
165
  //-------------------------------------------------------------------------
166
166
  // Event handlers
167
167
  //-------------------------------------------------------------------------
168
- private onFinalizedCheckpoint = async (finalized: CheckpointWithHex): Promise<void> => {
169
- return this.jobQueue.push(finalized);
168
+ private onFinalizedCheckpoint = (finalized: CheckpointWithHex): void => {
169
+ this.jobQueue.push(finalized).catch((e) => {
170
+ if (!isQueueErrorAborted(e)) {
171
+ this.logger.error("Error queuing finalized checkpoint", {epoch: finalized.epoch}, e as Error);
172
+ }
173
+ });
170
174
  };
171
175
 
172
176
  private onCheckpoint = (): void => {
@@ -243,7 +247,9 @@ export class ArchiveStore {
243
247
  prunedBlocks: prunedBlocks.length,
244
248
  });
245
249
  } catch (e) {
246
- this.logger.error("Error processing finalized checkpoint", {epoch: finalized.epoch}, e as Error);
250
+ if (!this.signal.aborted) {
251
+ this.logger.error("Error processing finalized checkpoint", {epoch: finalized.epoch}, e as Error);
252
+ }
247
253
  }
248
254
  };
249
255
  }
@@ -8,6 +8,7 @@ import {
8
8
  createCachedBeaconState,
9
9
  stateTransition,
10
10
  } from "@lodestar/state-transition";
11
+ import {byteArrayEquals} from "@lodestar/utils";
11
12
  import {IBeaconDb} from "../../../db/index.js";
12
13
  import {getStateTypeFromBytes} from "../../../util/multifork.js";
13
14
  import {HistoricalStateRegenMetrics} from "./metrics.js";
@@ -98,7 +99,7 @@ export async function getHistoricalState(
98
99
  throw e;
99
100
  }
100
101
  blockCount++;
101
- if (Buffer.compare(state.hashTreeRoot(), block.message.stateRoot) !== 0) {
102
+ if (!byteArrayEquals(state.hashTreeRoot(), block.message.stateRoot)) {
102
103
  metrics?.regenErrorCount.inc({reason: RegenErrorType.invalidStateRoot});
103
104
  }
104
105
  }
@@ -1,6 +1,6 @@
1
- import {ForkName, ForkPostFulu, ForkPreDeneb, ForkPreGloas} from "@lodestar/params";
1
+ import {ForkName, ForkPostFulu, ForkPreDeneb, ForkPreGloas, NUMBER_OF_COLUMNS} from "@lodestar/params";
2
2
  import {BeaconBlockBody, BlobIndex, ColumnIndex, SignedBeaconBlock, Slot, deneb, fulu} from "@lodestar/types";
3
- import {fromHex, prettyBytes, toRootHex, withTimeout} from "@lodestar/utils";
3
+ import {byteArrayEquals, fromHex, prettyBytes, toRootHex, withTimeout} from "@lodestar/utils";
4
4
  import {VersionedHashes} from "../../../execution/index.js";
5
5
  import {kzgCommitmentToVersionedHash} from "../../../util/blobs.js";
6
6
  import {BlockInputError, BlockInputErrorCode} from "./errors.js";
@@ -529,7 +529,7 @@ function blockAndBlobArePaired(block: SignedBeaconBlock<ForkBlobsDA>, blobSideca
529
529
  if (!blockCommitment || !blobSidecar.kzgCommitment) {
530
530
  return false;
531
531
  }
532
- return Buffer.compare(blockCommitment, blobSidecar.kzgCommitment) === 0;
532
+ return byteArrayEquals(blockCommitment, blobSidecar.kzgCommitment);
533
533
  }
534
534
 
535
535
  function assertBlockAndBlobArePaired(
@@ -561,6 +561,7 @@ type BlockInputColumnsState =
561
561
  | {
562
562
  hasBlock: true;
563
563
  hasAllData: true;
564
+ hasComputedAllData: boolean;
564
565
  versionedHashes: VersionedHashes;
565
566
  block: SignedBeaconBlock<ForkColumnsDA>;
566
567
  source: SourceMeta;
@@ -569,6 +570,7 @@ type BlockInputColumnsState =
569
570
  | {
570
571
  hasBlock: true;
571
572
  hasAllData: false;
573
+ hasComputedAllData: false;
572
574
  versionedHashes: VersionedHashes;
573
575
  block: SignedBeaconBlock<ForkColumnsDA>;
574
576
  source: SourceMeta;
@@ -576,11 +578,13 @@ type BlockInputColumnsState =
576
578
  | {
577
579
  hasBlock: false;
578
580
  hasAllData: true;
581
+ hasComputedAllData: boolean;
579
582
  versionedHashes: VersionedHashes;
580
583
  }
581
584
  | {
582
585
  hasBlock: false;
583
586
  hasAllData: false;
587
+ hasComputedAllData: false;
584
588
  versionedHashes: VersionedHashes;
585
589
  };
586
590
  /**
@@ -598,6 +602,12 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
598
602
  private columnsCache = new Map<ColumnIndex, ColumnWithSource>();
599
603
  private readonly sampledColumns: ColumnIndex[];
600
604
  private readonly custodyColumns: ColumnIndex[];
605
+ /**
606
+ * This promise resolves when all sampled columns are available
607
+ *
608
+ * This is different from `dataPromise` which resolves when all data is available or could become available (e.g. through reconstruction)
609
+ */
610
+ protected computedDataPromise = createPromise<fulu.DataColumnSidecars>();
601
611
 
602
612
  private constructor(
603
613
  init: BlockInputInit,
@@ -626,6 +636,7 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
626
636
  const state = {
627
637
  hasBlock: true,
628
638
  hasAllData,
639
+ hasComputedAllData: hasAllData,
629
640
  versionedHashes: props.block.message.body.blobKzgCommitments.map(kzgCommitmentToVersionedHash),
630
641
  block: props.block,
631
642
  source: {
@@ -649,6 +660,7 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
649
660
  blockInput.blockPromise.resolve(props.block);
650
661
  if (hasAllData) {
651
662
  blockInput.dataPromise.resolve([]);
663
+ blockInput.computedDataPromise.resolve([]);
652
664
  }
653
665
  return blockInput;
654
666
  }
@@ -661,6 +673,7 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
661
673
  const state: BlockInputColumnsState = {
662
674
  hasBlock: false,
663
675
  hasAllData,
676
+ hasComputedAllData: hasAllData as false,
664
677
  versionedHashes: props.columnSidecar.kzgCommitments.map(kzgCommitmentToVersionedHash),
665
678
  };
666
679
  const init: BlockInputInit = {
@@ -674,6 +687,7 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
674
687
  const blockInput = new BlockInputColumns(init, state, props.sampledColumns, props.custodyColumns);
675
688
  if (hasAllData) {
676
689
  blockInput.dataPromise.resolve([]);
690
+ blockInput.computedDataPromise.resolve([]);
677
691
  }
678
692
  return blockInput;
679
693
  }
@@ -722,11 +736,14 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
722
736
  const hasAllData =
723
737
  (props.block.message.body as BeaconBlockBody<ForkPostFulu & ForkPreGloas>).blobKzgCommitments.length === 0 ||
724
738
  this.state.hasAllData;
739
+ const hasComputedAllData =
740
+ props.block.message.body.blobKzgCommitments.length === 0 || this.state.hasComputedAllData;
725
741
 
726
742
  this.state = {
727
743
  ...this.state,
728
744
  hasBlock: true,
729
745
  hasAllData,
746
+ hasComputedAllData,
730
747
  block: props.block,
731
748
  source: {
732
749
  source: props.source,
@@ -774,17 +791,32 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
774
791
  this.columnsCache.set(columnSidecar.index, {columnSidecar, source, seenTimestampSec, peerIdStr});
775
792
 
776
793
  const sampledColumns = this.getSampledColumns();
777
- const hasAllData = this.state.hasAllData || sampledColumns.length === this.sampledColumns.length;
794
+ const hasAllData =
795
+ // already hasAllData
796
+ this.state.hasAllData ||
797
+ // has all sampled columns
798
+ sampledColumns.length === this.sampledColumns.length ||
799
+ // has enough columns to reconstruct the rest
800
+ this.columnsCache.size >= NUMBER_OF_COLUMNS / 2;
801
+
802
+ const hasComputedAllData =
803
+ // has all sampled columns
804
+ sampledColumns.length === this.sampledColumns.length;
778
805
 
779
806
  this.state = {
780
807
  ...this.state,
781
808
  hasAllData: hasAllData || this.state.hasAllData,
809
+ hasComputedAllData: hasComputedAllData || this.state.hasComputedAllData,
782
810
  timeCompleteSec: hasAllData ? seenTimestampSec : undefined,
783
811
  } as BlockInputColumnsState;
784
812
 
785
813
  if (hasAllData && sampledColumns !== null) {
786
814
  this.dataPromise.resolve(sampledColumns);
787
815
  }
816
+
817
+ if (hasComputedAllData && sampledColumns !== null) {
818
+ this.computedDataPromise.resolve(sampledColumns);
819
+ }
788
820
  }
789
821
 
790
822
  hasColumn(columnIndex: number): boolean {
@@ -859,4 +891,15 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
859
891
  versionedHashes: this.state.versionedHashes,
860
892
  };
861
893
  }
894
+
895
+ hasComputedAllData(): boolean {
896
+ return this.state.hasComputedAllData;
897
+ }
898
+
899
+ waitForComputedAllData(timeout: number, signal?: AbortSignal): Promise<fulu.DataColumnSidecars> {
900
+ if (!this.state.hasComputedAllData) {
901
+ return withTimeout(() => this.computedDataPromise.promise, timeout, signal);
902
+ }
903
+ return Promise.resolve(this.getSampledColumns());
904
+ }
862
905
  }
@@ -30,7 +30,7 @@ import type {BeaconChain} from "../chain.js";
30
30
  import {ChainEvent, ReorgEventData} from "../emitter.js";
31
31
  import {ForkchoiceCaller} from "../forkChoice/index.js";
32
32
  import {REPROCESS_MIN_TIME_TO_NEXT_SLOT_SEC} from "../reprocess.js";
33
- import {toCheckpointHex} from "../stateCache/index.js";
33
+ import {toCheckpointHex} from "../stateCache/persistentCheckpointsCache.js";
34
34
  import {isBlockInputBlobs, isBlockInputColumns} from "./blockInput/blockInput.js";
35
35
  import {AttestationImportOpt, FullyVerifiedBlock, ImportBlockOpts} from "./types.js";
36
36
  import {getCheckpointFromState} from "./utils/checkpoint.js";
@@ -91,7 +91,15 @@ export async function importBlock(
91
91
  }
92
92
 
93
93
  // 1. Persist block to hot DB (performed asynchronously to avoid blocking head selection)
94
- void this.unfinalizedBlockWrites.push([blockInput]);
94
+ // Wait for space in the write queue to apply backpressure during sync.
95
+ // Without this, a supernode syncing from behind can accumulate many blocks worth of column
96
+ // data in memory (up to 128 columns per block) causing OOM before persistence catches up.
97
+ await this.unfinalizedBlockWrites.waitForSpace();
98
+ this.unfinalizedBlockWrites.push([blockInput]).catch((e) => {
99
+ if (!isQueueErrorAborted(e)) {
100
+ this.logger.error("Error pushing block to unfinalized write queue", {slot: blockSlot}, e as Error);
101
+ }
102
+ });
95
103
 
96
104
  // Without forcefully clearing this cache, we would rely on WeakMap to evict memory which is not reliable
97
105
  this.serializedCache.clear();
@@ -145,7 +145,6 @@ export async function verifyBlocksInEpoch(
145
145
  opts.skipVerifyBlockSignatures !== true
146
146
  ? verifyBlocksSignatures(
147
147
  this.config,
148
- this.index2pubkey,
149
148
  this.bls,
150
149
  this.logger,
151
150
  this.metrics,
@@ -1,5 +1,5 @@
1
1
  import {BeaconConfig} from "@lodestar/config";
2
- import {CachedBeaconStateAllForks, Index2PubkeyCache, getBlockSignatureSets} from "@lodestar/state-transition";
2
+ import {CachedBeaconStateAllForks, getBlockSignatureSets} from "@lodestar/state-transition";
3
3
  import {IndexedAttestation, SignedBeaconBlock} from "@lodestar/types";
4
4
  import {Logger} from "@lodestar/utils";
5
5
  import {Metrics} from "../../metrics/metrics.js";
@@ -17,7 +17,6 @@ import {ImportBlockOpts} from "./types.js";
17
17
  */
18
18
  export async function verifyBlocksSignatures(
19
19
  config: BeaconConfig,
20
- index2pubkey: Index2PubkeyCache,
21
20
  bls: IBlsVerifier,
22
21
  logger: Logger,
23
22
  metrics: Metrics | null,
@@ -42,16 +41,9 @@ export async function verifyBlocksSignatures(
42
41
  : //
43
42
  // Verify signatures per block to track which block is invalid
44
43
  bls.verifySignatureSets(
45
- getBlockSignatureSets(
46
- config,
47
- index2pubkey,
48
- currentSyncCommitteeIndexed,
49
- block,
50
- indexedAttestationsByBlock[i],
51
- {
52
- skipProposerSignature: opts.validProposerSignature,
53
- }
54
- )
44
+ getBlockSignatureSets(config, currentSyncCommitteeIndexed, block, indexedAttestationsByBlock[i], {
45
+ skipProposerSignature: opts.validProposerSignature,
46
+ })
55
47
  );
56
48
 
57
49
  // getBlockSignatureSets() takes 45ms in benchmarks for 2022Q2 mainnet blocks (100 sigs). When syncing a 32 blocks
@@ -5,9 +5,8 @@ import {
5
5
  StateHashTreeRootSource,
6
6
  stateTransition,
7
7
  } from "@lodestar/state-transition";
8
- import {ErrorAborted, Logger} from "@lodestar/utils";
8
+ import {ErrorAborted, Logger, byteArrayEquals} from "@lodestar/utils";
9
9
  import {Metrics} from "../../metrics/index.js";
10
- import {byteArrayEquals} from "../../util/bytes.js";
11
10
  import {nextEventLoop} from "../../util/eventLoop.js";
12
11
  import {BlockError, BlockErrorCode} from "../errors/index.js";
13
12
  import {BlockProcessOpts} from "../options.js";
@@ -44,6 +44,15 @@ export async function writeBlockInputToDb(this: BeaconChain, blocksInputs: IBloc
44
44
 
45
45
  // NOTE: Old data is pruned on archive
46
46
  if (isBlockInputColumns(blockInput)) {
47
+ if (!blockInput.hasComputedAllData()) {
48
+ // Supernodes may only have a subset of the data columns by the time the block begins to be imported
49
+ // because full data availability can be assumed after NUMBER_OF_COLUMNS / 2 columns are available.
50
+ // Here, however, all data columns must be fully available/reconstructed before persisting to the DB.
51
+ await blockInput.waitForComputedAllData(BLOB_AVAILABILITY_TIMEOUT).catch(() => {
52
+ this.logger.debug("Failed to wait for computed all data", {slot, blockRoot: blockRootHex});
53
+ });
54
+ }
55
+
47
56
  const {custodyColumns} = this.custodyConfig;
48
57
  const blobsLen = (block.message as fulu.BeaconBlock).body.blobKzgCommitments.length;
49
58
  let dataColumnsLen: number;
@@ -7,7 +7,7 @@ import {Worker, spawn} from "@chainsafe/threads";
7
7
  self = undefined;
8
8
 
9
9
  import {PublicKey} from "@chainsafe/blst";
10
- import {ISignatureSet} from "@lodestar/state-transition";
10
+ import {ISignatureSet, Index2PubkeyCache} from "@lodestar/state-transition";
11
11
  import {Logger} from "@lodestar/utils";
12
12
  import {Metrics} from "../../../metrics/index.js";
13
13
  import {LinkedList} from "../../../util/array.js";
@@ -34,6 +34,7 @@ const workerDir = process.env.NODE_ENV === "test" ? "../../../../lib/chain/bls/m
34
34
  export type BlsMultiThreadWorkerPoolModules = {
35
35
  logger: Logger;
36
36
  metrics: Metrics | null;
37
+ index2pubkey: Index2PubkeyCache;
37
38
  };
38
39
 
39
40
  export type BlsMultiThreadWorkerPoolOptions = {
@@ -113,6 +114,7 @@ type WorkerDescriptor = {
113
114
  export class BlsMultiThreadWorkerPool implements IBlsVerifier {
114
115
  private readonly logger: Logger;
115
116
  private readonly metrics: Metrics | null;
117
+ private readonly index2pubkey: Index2PubkeyCache;
116
118
 
117
119
  private readonly workers: WorkerDescriptor[];
118
120
  private readonly jobs = new LinkedList<JobQueueItem>();
@@ -128,9 +130,10 @@ export class BlsMultiThreadWorkerPool implements IBlsVerifier {
128
130
  private workersBusy = 0;
129
131
 
130
132
  constructor(options: BlsMultiThreadWorkerPoolOptions, modules: BlsMultiThreadWorkerPoolModules) {
131
- const {logger, metrics} = modules;
133
+ const {logger, metrics, index2pubkey} = modules;
132
134
  this.logger = logger;
133
135
  this.metrics = metrics;
136
+ this.index2pubkey = index2pubkey;
134
137
  this.blsVerifyAllMultiThread = options.blsVerifyAllMultiThread ?? false;
135
138
 
136
139
  // Use compressed for herumi for now.
@@ -170,7 +173,7 @@ export class BlsMultiThreadWorkerPool implements IBlsVerifier {
170
173
  try {
171
174
  return verifySignatureSetsMaybeBatch(
172
175
  sets.map((set) => ({
173
- publicKey: getAggregatedPubkey(set),
176
+ publicKey: getAggregatedPubkey(set, this.index2pubkey),
174
177
  message: set.signingRoot.valueOf(),
175
178
  signature: set.signature,
176
179
  }))
@@ -395,7 +398,7 @@ export class BlsMultiThreadWorkerPool implements IBlsVerifier {
395
398
  try {
396
399
  // Note: This can throw, must be handled per-job.
397
400
  // Pubkey and signature aggregation is defered here
398
- workReq = await jobItemWorkReq(job, this.metrics);
401
+ workReq = await jobItemWorkReq(job, this.index2pubkey, this.metrics);
399
402
  } catch (e) {
400
403
  this.metrics?.blsThreadPool.errorAggregateSignatureSetsCount.inc({type: job.type});
401
404
 
@@ -1,5 +1,5 @@
1
1
  import {PublicKey, asyncAggregateWithRandomness} from "@chainsafe/blst";
2
- import {ISignatureSet, SignatureSetType} from "@lodestar/state-transition";
2
+ import {ISignatureSet, Index2PubkeyCache, SignatureSetType} from "@lodestar/state-transition";
3
3
  import {Metrics} from "../../../metrics/metrics.js";
4
4
  import {LinkedList} from "../../../util/array.js";
5
5
  import {VerifySignatureOpts} from "../interface.js";
@@ -48,14 +48,18 @@ export function jobItemSigSets(job: JobQueueItem): number {
48
48
  * Prepare BlsWorkReq from JobQueueItem
49
49
  * WARNING: May throw with untrusted user input
50
50
  */
51
- export async function jobItemWorkReq(job: JobQueueItem, metrics: Metrics | null): Promise<BlsWorkReq> {
51
+ export async function jobItemWorkReq(
52
+ job: JobQueueItem,
53
+ index2pubkey: Index2PubkeyCache,
54
+ metrics: Metrics | null
55
+ ): Promise<BlsWorkReq> {
52
56
  switch (job.type) {
53
57
  case JobQueueItemType.default:
54
58
  return {
55
59
  opts: job.opts,
56
60
  sets: job.sets.map((set) => ({
57
61
  // this can throw, handled in the consumer code
58
- publicKey: getAggregatedPubkey(set, metrics).toBytes(),
62
+ publicKey: getAggregatedPubkey(set, index2pubkey, metrics).toBytes(),
59
63
  signature: set.signature,
60
64
  message: set.signingRoot,
61
65
  })),
@@ -1,5 +1,5 @@
1
1
  import {PublicKey, Signature, aggregatePublicKeys, aggregateSignatures, verify} from "@chainsafe/blst";
2
- import {ISignatureSet} from "@lodestar/state-transition";
2
+ import {ISignatureSet, Index2PubkeyCache} from "@lodestar/state-transition";
3
3
  import {Metrics} from "../../metrics/index.js";
4
4
  import {IBlsVerifier} from "./interface.js";
5
5
  import {verifySignatureSetsMaybeBatch} from "./maybeBatch.js";
@@ -7,16 +7,18 @@ import {getAggregatedPubkey, getAggregatedPubkeysCount} from "./utils.js";
7
7
 
8
8
  export class BlsSingleThreadVerifier implements IBlsVerifier {
9
9
  private readonly metrics: Metrics | null;
10
+ private readonly index2pubkey: Index2PubkeyCache;
10
11
 
11
- constructor({metrics = null}: {metrics: Metrics | null}) {
12
+ constructor({metrics = null, index2pubkey}: {metrics: Metrics | null; index2pubkey: Index2PubkeyCache}) {
12
13
  this.metrics = metrics;
14
+ this.index2pubkey = index2pubkey;
13
15
  }
14
16
 
15
17
  async verifySignatureSets(sets: ISignatureSet[]): Promise<boolean> {
16
18
  this.metrics?.bls.aggregatedPubkeys.inc(getAggregatedPubkeysCount(sets));
17
19
 
18
20
  const setsAggregated = sets.map((set) => ({
19
- publicKey: getAggregatedPubkey(set),
21
+ publicKey: getAggregatedPubkey(set, this.index2pubkey, this.metrics),
20
22
  message: set.signingRoot,
21
23
  signature: set.signature,
22
24
  }));