@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
@@ -0,0 +1,157 @@
1
+ import {Signature, aggregateSignatures} from "@chainsafe/blst";
2
+ import {BitArray} from "@chainsafe/ssz";
3
+ import {ChainForkConfig} from "@lodestar/config";
4
+ import {MAX_COMMITTEES_PER_SLOT, PTC_SIZE} from "@lodestar/params";
5
+ import {RootHex, Slot, gloas} from "@lodestar/types";
6
+ import {MapDef, toRootHex} from "@lodestar/utils";
7
+ import {Metrics} from "../../metrics/metrics.js";
8
+ import {IClock} from "../../util/clock.js";
9
+ import {InsertOutcome, OpPoolError, OpPoolErrorCode} from "./types.js";
10
+ import {pruneBySlot, signatureFromBytesNoCheck} from "./utils.js";
11
+
12
+ /**
13
+ * TODO GLOAS: Revisit this value and add rational for choosing it
14
+ */
15
+ const SLOTS_RETAINED = 2;
16
+
17
+ /**
18
+ * The maximum number of distinct `PayloadAttestationData` that will be stored in each slot.
19
+ *
20
+ * This is a DoS protection measure.
21
+ */
22
+ // TODO GLOAS: Revisit this value. Educated guess would be MAX_ATTESTATIONS_PER_SLOT in AttestationPool divided by MAX_COMMITTEES_PER_SLOT
23
+ const MAX_PAYLOAD_ATTESTATIONS_PER_SLOT = 16_384 / MAX_COMMITTEES_PER_SLOT;
24
+
25
+ type DataRootHex = string;
26
+ type BlockRootHex = string;
27
+
28
+ type AggregateFast = {
29
+ aggregationBits: BitArray;
30
+ data: gloas.PayloadAttestationData;
31
+ signature: Signature;
32
+ };
33
+
34
+ export class PayloadAttestationPool {
35
+ private readonly aggregateByDataRootByBlockRootBySlot = new MapDef<
36
+ Slot,
37
+ Map<BlockRootHex, Map<DataRootHex, AggregateFast>>
38
+ >(() => new Map<BlockRootHex, Map<DataRootHex, AggregateFast>>());
39
+ private lowestPermissibleSlot = 0;
40
+
41
+ constructor(
42
+ private readonly config: ChainForkConfig,
43
+ private readonly clock: IClock,
44
+ private readonly metrics: Metrics | null = null
45
+ ) {}
46
+
47
+ get size(): number {
48
+ let count = 0;
49
+ for (const aggregateByDataRootByBlockRoot of this.aggregateByDataRootByBlockRootBySlot.values()) {
50
+ for (const aggregateByDataRoot of aggregateByDataRootByBlockRoot.values()) {
51
+ count += aggregateByDataRoot.size;
52
+ }
53
+ }
54
+ return count;
55
+ }
56
+
57
+ add(
58
+ message: gloas.PayloadAttestationMessage,
59
+ payloadAttDataRootHex: RootHex,
60
+ validatorCommitteeIndex: number
61
+ ): InsertOutcome {
62
+ const slot = message.data.slot;
63
+ const lowestPermissibleSlot = this.lowestPermissibleSlot;
64
+
65
+ if (slot < lowestPermissibleSlot) {
66
+ return InsertOutcome.Old;
67
+ }
68
+
69
+ if (slot < this.clock.slotWithPastTolerance(this.config.MAXIMUM_GOSSIP_CLOCK_DISPARITY / 1000)) {
70
+ return InsertOutcome.Late;
71
+ }
72
+
73
+ const aggregateByDataRootByBlockRoot = this.aggregateByDataRootByBlockRootBySlot.getOrDefault(slot);
74
+ let aggregateByDataRoot = aggregateByDataRootByBlockRoot.get(toRootHex(message.data.beaconBlockRoot));
75
+
76
+ if (!aggregateByDataRoot) {
77
+ aggregateByDataRoot = new Map<DataRootHex, AggregateFast>();
78
+ aggregateByDataRootByBlockRoot.set(toRootHex(message.data.beaconBlockRoot), aggregateByDataRoot);
79
+ }
80
+
81
+ if (aggregateByDataRoot.size >= MAX_PAYLOAD_ATTESTATIONS_PER_SLOT) {
82
+ throw new OpPoolError({code: OpPoolErrorCode.REACHED_MAX_PER_SLOT});
83
+ }
84
+
85
+ const aggregate = aggregateByDataRoot.get(payloadAttDataRootHex);
86
+ if (aggregate) {
87
+ // Aggregate msg into aggregate
88
+ return aggregateMessageInto(message, validatorCommitteeIndex, aggregate);
89
+ }
90
+ // Create a new aggregate with data
91
+ aggregateByDataRoot.set(payloadAttDataRootHex, messageToAggregate(message, validatorCommitteeIndex));
92
+
93
+ return InsertOutcome.NewData;
94
+ }
95
+
96
+ /**
97
+ * Get payload attestations to be included in a block.
98
+ * Pick the top `maxAttestation` number of attestations with the most votes
99
+ */
100
+ getPayloadAttestationsForBlock(
101
+ beaconBlockRoot: BlockRootHex,
102
+ slot: Slot,
103
+ maxAttestation: number
104
+ ): gloas.PayloadAttestation[] {
105
+ const aggregateByDataRootByBlockRoot = this.aggregateByDataRootByBlockRootBySlot.get(slot);
106
+
107
+ if (!aggregateByDataRootByBlockRoot) {
108
+ this.metrics?.opPool.payloadAttestationPool.getPayloadAttestationsCacheMisses.inc();
109
+ return [];
110
+ }
111
+
112
+ const aggregateByDataRoot = aggregateByDataRootByBlockRoot.get(beaconBlockRoot);
113
+
114
+ if (!aggregateByDataRoot) {
115
+ this.metrics?.opPool.payloadAttestationPool.getPayloadAttestationsCacheMisses.inc();
116
+ return [];
117
+ }
118
+
119
+ return Array.from(aggregateByDataRoot.values())
120
+ .slice()
121
+ .sort((a, b) => b.aggregationBits.getTrueBitIndexes().length - a.aggregationBits.getTrueBitIndexes().length)
122
+ .slice(0, maxAttestation)
123
+ .map(fastToPayloadAttestation);
124
+ }
125
+
126
+ prune(clockSlot: Slot): void {
127
+ pruneBySlot(this.aggregateByDataRootByBlockRootBySlot, clockSlot, SLOTS_RETAINED);
128
+ this.lowestPermissibleSlot = clockSlot;
129
+ }
130
+ }
131
+
132
+ function messageToAggregate(message: gloas.PayloadAttestationMessage, validatorCommitteeIndex: number): AggregateFast {
133
+ return {
134
+ aggregationBits: BitArray.fromSingleBit(PTC_SIZE, validatorCommitteeIndex),
135
+ data: message.data,
136
+ signature: signatureFromBytesNoCheck(message.signature),
137
+ };
138
+ }
139
+
140
+ function aggregateMessageInto(
141
+ message: gloas.PayloadAttestationMessage,
142
+ validatorCommitteeIndex: number,
143
+ aggregate: AggregateFast
144
+ ): InsertOutcome {
145
+ if (aggregate.aggregationBits.get(validatorCommitteeIndex) === true) {
146
+ return InsertOutcome.AlreadyKnown;
147
+ }
148
+
149
+ aggregate.aggregationBits.set(validatorCommitteeIndex, true);
150
+ aggregate.signature = aggregateSignatures([aggregate.signature, signatureFromBytesNoCheck(message.signature)]);
151
+
152
+ return InsertOutcome.Aggregated;
153
+ }
154
+
155
+ function fastToPayloadAttestation(aggFast: AggregateFast): gloas.PayloadAttestation {
156
+ return {...aggFast, signature: aggFast.signature.toBytes()};
157
+ }
@@ -45,7 +45,6 @@ export type IChainOptions = BlockProcessOpts &
45
45
  broadcastValidationStrictness?: string;
46
46
  minSameMessageSignatureSetsToBatch: number;
47
47
  archiveDateEpochs?: number;
48
- nHistoricalStates?: boolean;
49
48
  nHistoricalStatesFileDataStore?: boolean;
50
49
  };
51
50
 
@@ -119,7 +118,6 @@ export const defaultChainOptions: IChainOptions = {
119
118
  // batching too much may block the I/O thread so if useWorker=false, suggest this value to be 32
120
119
  // since this batch attestation work is designed to work with useWorker=true, make this the lowest value
121
120
  minSameMessageSignatureSetsToBatch: 2,
122
- nHistoricalStates: true,
123
121
  // as of Feb 2025, this option turned out to be very useful:
124
122
  // - it allows to share a persisted checkpoint state to other nodes
125
123
  // - users can prune the persisted checkpoint state files manually to save disc space
@@ -2,7 +2,7 @@ import {routes} from "@lodestar/api";
2
2
  import {ProtoBlock} from "@lodestar/fork-choice";
3
3
  import {CachedBeaconStateAllForks} from "@lodestar/state-transition";
4
4
  import {BeaconBlock, Epoch, RootHex, Slot, phase0} from "@lodestar/types";
5
- import {CheckpointHex} from "../stateCache/index.js";
5
+ import {CheckpointHex} from "../stateCache/types.js";
6
6
 
7
7
  export enum RegenCaller {
8
8
  getDuties = "getDuties",
@@ -18,6 +18,7 @@ export enum RegenCaller {
18
18
  validateGossipAggregateAndProof = "validateGossipAggregateAndProof",
19
19
  validateGossipAttestation = "validateGossipAttestation",
20
20
  validateGossipVoluntaryExit = "validateGossipVoluntaryExit",
21
+ validateGossipExecutionPayloadBid = "validateGossipExecutionPayloadBid",
21
22
  onForkChoiceFinalized = "onForkChoiceFinalized",
22
23
  restApi = "restApi",
23
24
  }
@@ -5,8 +5,7 @@ import {BeaconBlock, Epoch, RootHex, Slot, phase0} from "@lodestar/types";
5
5
  import {Logger, toRootHex} from "@lodestar/utils";
6
6
  import {Metrics} from "../../metrics/index.js";
7
7
  import {JobItemQueue} from "../../util/queue/index.js";
8
- import {CheckpointHex} from "../stateCache/index.js";
9
- import {BlockStateCache, CheckpointStateCache} from "../stateCache/types.js";
8
+ import {BlockStateCache, CheckpointHex, CheckpointStateCache} from "../stateCache/types.js";
10
9
  import {RegenError, RegenErrorCode} from "./errors.js";
11
10
  import {
12
11
  IStateRegenerator,
@@ -18,6 +18,7 @@ import {Metrics} from "../../metrics/index.js";
18
18
  import {nextEventLoop} from "../../util/eventLoop.js";
19
19
  import {getCheckpointFromState} from "../blocks/utils/checkpoint.js";
20
20
  import {ChainEvent, ChainEventEmitter} from "../emitter.js";
21
+ import {SeenBlockInput} from "../seenCache/seenGossipBlockInput.js";
21
22
  import {BlockStateCache, CheckpointStateCache} from "../stateCache/types.js";
22
23
  import {ValidatorMonitor} from "../validatorMonitor.js";
23
24
  import {RegenError, RegenErrorCode} from "./errors.js";
@@ -28,6 +29,7 @@ export type RegenModules = {
28
29
  forkChoice: IForkChoice;
29
30
  blockStateCache: BlockStateCache;
30
31
  checkpointStateCache: CheckpointStateCache;
32
+ seenBlockInputCache: SeenBlockInput;
31
33
  config: ChainForkConfig;
32
34
  emitter: ChainEventEmitter;
33
35
  logger: Logger;
@@ -191,7 +193,10 @@ export class StateRegenerator implements IStateRegeneratorInternal {
191
193
  const protoBlocksAsc = blocksToReplay.reverse();
192
194
  for (const [i, protoBlock] of protoBlocksAsc.entries()) {
193
195
  replaySlots[i] = protoBlock.slot;
194
- blockPromises[i] = this.modules.db.block.get(fromHex(protoBlock.blockRoot));
196
+ const blockInput = this.modules.seenBlockInputCache.get(protoBlock.blockRoot);
197
+ blockPromises[i] = blockInput?.hasBlock()
198
+ ? Promise.resolve(blockInput.getBlock())
199
+ : this.modules.db.block.get(fromHex(protoBlock.blockRoot));
195
200
  }
196
201
 
197
202
  const logCtx = {stateRoot, caller, replaySlots: replaySlots.join(",")};
@@ -1,5 +1,7 @@
1
- export {SeenAggregators, SeenAttesters} from "./seenAttesters.js";
1
+ export {SeenAggregators, SeenAttesters, SeenPayloadAttesters} from "./seenAttesters.js";
2
2
  export {SeenBlockProposers} from "./seenBlockProposers.js";
3
3
  export {SeenSyncCommitteeMessages} from "./seenCommittee.js";
4
4
  export {SeenContributionAndProof} from "./seenCommitteeContribution.js";
5
+ export {SeenExecutionPayloadBids} from "./seenExecutionPayloadBids.js";
6
+ export {SeenExecutionPayloadEnvelopes} from "./seenExecutionPayloadEnvelope.js";
5
7
  export {SeenBlockInput} from "./seenGossipBlockInput.js";
@@ -56,3 +56,8 @@ export class SeenAttesters {
56
56
  * Keeps a cache to filter aggregated attestations from the same aggregators in the same epoch
57
57
  */
58
58
  export class SeenAggregators extends SeenAttesters {}
59
+
60
+ /**
61
+ * Keeps a cache to filter payload attestations from the same attesters in the same epoch
62
+ */
63
+ export class SeenPayloadAttesters extends SeenAttesters {}
@@ -0,0 +1,35 @@
1
+ import {BuilderIndex, Slot} from "@lodestar/types";
2
+ import {MapDef} from "@lodestar/utils";
3
+
4
+ /**
5
+ * TODO GLOAS: Revisit this value and add rational for choosing it
6
+ */
7
+ const SLOTS_RETAINED = 2;
8
+
9
+ /**
10
+ * Tracks execution payload bids we've already seen per (slot, builder).
11
+ */
12
+ export class SeenExecutionPayloadBids {
13
+ private readonly builderIndexesBySlot = new MapDef<Slot, Set<BuilderIndex>>(() => new Set<BuilderIndex>());
14
+ private lowestPermissibleSlot: Slot = 0;
15
+
16
+ isKnown(slot: Slot, builderIndex: BuilderIndex): boolean {
17
+ return this.builderIndexesBySlot.get(slot)?.has(builderIndex) === true;
18
+ }
19
+
20
+ add(slot: Slot, builderIndex: BuilderIndex): void {
21
+ if (slot < this.lowestPermissibleSlot) {
22
+ throw Error(`slot ${slot} < lowestPermissibleSlot ${this.lowestPermissibleSlot}`);
23
+ }
24
+ this.builderIndexesBySlot.getOrDefault(slot).add(builderIndex);
25
+ }
26
+
27
+ prune(currentSlot: Slot): void {
28
+ this.lowestPermissibleSlot = Math.max(currentSlot - SLOTS_RETAINED, 0);
29
+ for (const slot of this.builderIndexesBySlot.keys()) {
30
+ if (slot < this.lowestPermissibleSlot) {
31
+ this.builderIndexesBySlot.delete(slot);
32
+ }
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,34 @@
1
+ import {RootHex, Slot} from "@lodestar/types";
2
+
3
+ /**
4
+ * Cache to prevent processing multiple execution payload envelopes for the same block root.
5
+ * Only one builder qualifies to submit an execution payload for a given slot.
6
+ * We only keep track of envelopes of unfinalized slots.
7
+ * [IGNORE] The node has not seen another valid `SignedExecutionPayloadEnvelope` for this block root.
8
+ */
9
+ export class SeenExecutionPayloadEnvelopes {
10
+ private readonly slotByBlockRoot = new Map<RootHex, Slot>();
11
+ private finalizedSlot: Slot = 0;
12
+
13
+ isKnown(blockRoot: RootHex): boolean {
14
+ return this.slotByBlockRoot.has(blockRoot);
15
+ }
16
+
17
+ add(blockRoot: RootHex, slot: Slot): void {
18
+ if (slot < this.finalizedSlot) {
19
+ throw Error(`slot ${slot} < finalizedSlot ${this.finalizedSlot}`);
20
+ }
21
+
22
+ this.slotByBlockRoot.set(blockRoot, slot);
23
+ }
24
+
25
+ prune(finalizedSlot: Slot): void {
26
+ this.finalizedSlot = finalizedSlot;
27
+
28
+ for (const [blockRoot, slot] of this.slotByBlockRoot.entries()) {
29
+ if (slot < finalizedSlot) {
30
+ this.slotByBlockRoot.delete(blockRoot);
31
+ }
32
+ }
33
+ }
34
+ }
@@ -1,10 +1,19 @@
1
1
  import {ChainForkConfig} from "@lodestar/config";
2
2
  import {CheckpointWithHex} from "@lodestar/fork-choice";
3
- import {ForkName, ForkPostFulu, ForkPreGloas, isForkPostDeneb, isForkPostFulu, isForkPostGloas} from "@lodestar/params";
3
+ import {
4
+ ForkName,
5
+ ForkPostFulu,
6
+ ForkPreGloas,
7
+ SLOTS_PER_EPOCH,
8
+ isForkPostDeneb,
9
+ isForkPostFulu,
10
+ isForkPostGloas,
11
+ } from "@lodestar/params";
4
12
  import {computeStartSlotAtEpoch} from "@lodestar/state-transition";
5
13
  import {BLSSignature, RootHex, SignedBeaconBlock, Slot, deneb, fulu} from "@lodestar/types";
6
- import {LodestarError, Logger, pruneSetToMax} from "@lodestar/utils";
14
+ import {LodestarError, Logger, byteArrayEquals, pruneSetToMax} from "@lodestar/utils";
7
15
  import {Metrics} from "../../metrics/metrics.js";
16
+ import {MAX_LOOK_AHEAD_EPOCHS} from "../../sync/constants.js";
8
17
  import {IClock} from "../../util/clock.js";
9
18
  import {CustodyConfig} from "../../util/dataColumns.js";
10
19
  import {
@@ -26,7 +35,17 @@ import {
26
35
  } from "../blocks/blockInput/index.js";
27
36
  import {ChainEvent, ChainEventEmitter} from "../emitter.js";
28
37
 
29
- const MAX_BLOCK_INPUT_CACHE_SIZE = 5;
38
+ // Target size for the block input cache, enforced by pruneToMaxSize() which runs after prune()
39
+ // and onFinalized() — NOT on insertion. The cache can temporarily exceed this during range sync
40
+ // (e.g. 32 blocks inserted per batch) but is trimmed back after blocks are processed.
41
+ //
42
+ // Must be large enough to hold blocks from all concurrently downloaded range sync batches.
43
+ // Range sync downloads up to MAX_LOOK_AHEAD_EPOCHS batches ahead of the processing head,
44
+ // so up to (MAX_LOOK_AHEAD_EPOCHS + 1) batches (current + look-ahead) of SLOTS_PER_EPOCH
45
+ // blocks can be in the cache simultaneously. If this value is too small, pruneToMaxSize()
46
+ // will evict blocks from the batch being processed before they are persisted to the database,
47
+ // causing errors when async handlers like onForkChoiceFinalized run.
48
+ const MAX_BLOCK_INPUT_CACHE_SIZE = (MAX_LOOK_AHEAD_EPOCHS + 1) * SLOTS_PER_EPOCH;
30
49
 
31
50
  export type SeenBlockInputCacheModules = {
32
51
  config: ChainForkConfig;
@@ -64,14 +83,14 @@ export type GetByBlobOptions = {
64
83
  * - onFinalized event handler will help to prune any non-canonical forks once the chain finalizes. Any block-slots that
65
84
  * are before the finalized checkpoint will be pruned.
66
85
  * - Range-sync periods. The range process uses this cache to store and sync blocks with DA data as the chain is pulled
67
- * from peers. We pull batches, by epoch, so 32 slots are pulled at a time and several batches are pulled concurrently.
68
- * It is important to set the MAX_BLOCK_INPUT_CACHE_SIZE high enough to support range sync activities. Currently the
69
- * value is set for 5 batches of 32 slots. As process block is called (similar to following head) the BlockInput and
70
- * its ancestors will be pruned.
86
+ * from peers. We pull batches, by epoch, so 32 slots are pulled at a time and several batches are downloaded
87
+ * concurrently (up to MAX_LOOK_AHEAD_EPOCHS ahead). All downloaded blocks are added to this shared cache, so it
88
+ * must be large enough to hold blocks from all concurrent batches. If pruneToMaxSize() evicts blocks from the batch
89
+ * currently being processed, those blocks may not yet be persisted to the database, causing getBlockByRoot() to fail
90
+ * when async event handlers (e.g. onForkChoiceFinalized) try to look them up.
71
91
  * - Non-Finality times. This is a bit more tricky. There can be long periods of non-finality and storing everything
72
- * will cause OOM. The pruneToMax will help ensure a hard limit on the number of stored blocks (with DA) that are held
73
- * in memory at any one time. The value for MAX_BLOCK_INPUT_CACHE_SIZE is set to accommodate range-sync but in
74
- * practice this value may need to be massaged in the future if we find issues when debugging non-finality
92
+ * will cause OOM. The pruneToMaxSize will help ensure the number of stored blocks (with DA) is trimmed back to
93
+ * MAX_BLOCK_INPUT_CACHE_SIZE after each prune() or onFinalized() call
75
94
  */
76
95
 
77
96
  export class SeenBlockInput {
@@ -344,7 +363,7 @@ export class SeenBlockInput {
344
363
  return false;
345
364
  }
346
365
  // Only consider verified if the signature matches
347
- return Buffer.compare(cachedSignature, signature) === 0;
366
+ return byteArrayEquals(cachedSignature, signature);
348
367
  }
349
368
 
350
369
  /**
@@ -379,7 +398,7 @@ export class SeenBlockInput {
379
398
  let itemsToDelete = this.blockInputs.size - MAX_BLOCK_INPUT_CACHE_SIZE;
380
399
 
381
400
  if (itemsToDelete > 0) {
382
- const sorted = [...this.blockInputs.entries()].sort((a, b) => b[1].slot - a[1].slot);
401
+ const sorted = [...this.blockInputs.entries()].sort((a, b) => a[1].slot - b[1].slot);
383
402
  for (const [rootHex] of sorted) {
384
403
  this.blockInputs.delete(rootHex);
385
404
  itemsToDelete--;
@@ -20,7 +20,8 @@ export async function serializeState<T>(
20
20
  stateBytes = bufferWithKey.buffer;
21
21
  const dataView = new DataView(stateBytes.buffer, stateBytes.byteOffset, stateBytes.byteLength);
22
22
  state.serializeToBytes({uint8Array: stateBytes, dataView}, 0);
23
- return processFn(stateBytes);
23
+ // Await to ensure buffer is not released back to pool until processFn completes
24
+ return await processFn(stateBytes);
24
25
  }
25
26
  // release the buffer back to the pool automatically
26
27
  }
@@ -1,3 +1 @@
1
- export * from "./blockStateCacheImpl.js";
2
1
  export * from "./fifoBlockStateCache.js";
3
- export * from "./inMemoryCheckpointsCache.js";
@@ -31,7 +31,7 @@ type PersistentCheckpointStateCacheModules = {
31
31
  signal?: AbortSignal;
32
32
  datastore: CPStateDatastore;
33
33
  blockStateCache: BlockStateCache;
34
- bufferPool?: BufferPool | null;
34
+ bufferPool?: BufferPool;
35
35
  };
36
36
 
37
37
  /** checkpoint serialized as a string */
@@ -119,7 +119,7 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
119
119
  private readonly maxEpochsOnDisk: number;
120
120
  private readonly datastore: CPStateDatastore;
121
121
  private readonly blockStateCache: BlockStateCache;
122
- private readonly bufferPool?: BufferPool | null;
122
+ private readonly bufferPool?: BufferPool;
123
123
 
124
124
  constructor(
125
125
  {
@@ -851,6 +851,10 @@ export function toCheckpointHex(checkpoint: phase0.Checkpoint): CheckpointHex {
851
851
  };
852
852
  }
853
853
 
854
+ export function toCheckpointKey(cp: CheckpointHex): string {
855
+ return `${cp.rootHex}:${cp.epoch}`;
856
+ }
857
+
854
858
  function toCacheKey(cp: CheckpointHex | phase0.Checkpoint): CacheKey {
855
859
  if (isCheckpointHex(cp)) {
856
860
  return `${cp.rootHex}_${cp.epoch}`;
@@ -71,11 +71,34 @@ async function validateAggregateAndProof(
71
71
  const attData = aggregate.data;
72
72
  const attSlot = attData.slot;
73
73
 
74
- let attIndex: number | null;
75
- if (ForkSeq[fork] >= ForkSeq.electra) {
76
- attIndex = (aggregate as electra.Attestation).committeeBits.getSingleTrueBit();
74
+ let committeeIndex: number | null;
75
+ if (ForkSeq[fork] >= ForkSeq.gloas) {
76
+ // [REJECT] `aggregate.data.index < 2`.
77
+ if (attData.index >= 2) {
78
+ throw new AttestationError(GossipAction.REJECT, {
79
+ code: AttestationErrorCode.INVALID_PAYLOAD_STATUS_VALUE,
80
+ attDataIndex: attData.index,
81
+ });
82
+ }
83
+ // [REJECT] `aggregate.data.index == 0` if `block.slot == aggregate.data.slot`.
84
+ const block = chain.forkChoice.getBlock(attData.beaconBlockRoot);
85
+
86
+ // If block is unknown, we don't handle it here. It will throw error later on at `verifyHeadBlockAndTargetRoot()`
87
+ if (block !== null && block.slot === attData.slot && attData.index !== 0) {
88
+ throw new AttestationError(GossipAction.REJECT, {
89
+ code: AttestationErrorCode.PREMATURELY_INDICATED_PAYLOAD_PRESENT,
90
+ });
91
+ }
92
+
93
+ // [REJECT] len(committee_indices) == 1, where committee_indices = get_committee_indices(aggregate)
94
+ committeeIndex = (aggregate as electra.Attestation).committeeBits.getSingleTrueBit();
95
+ if (committeeIndex === null) {
96
+ throw new AttestationError(GossipAction.REJECT, {code: AttestationErrorCode.NOT_EXACTLY_ONE_COMMITTEE_BIT_SET});
97
+ }
98
+ } else if (ForkSeq[fork] >= ForkSeq.electra) {
99
+ committeeIndex = (aggregate as electra.Attestation).committeeBits.getSingleTrueBit();
77
100
  // [REJECT] len(committee_indices) == 1, where committee_indices = get_committee_indices(aggregate)
78
- if (attIndex === null) {
101
+ if (committeeIndex === null) {
79
102
  throw new AttestationError(GossipAction.REJECT, {code: AttestationErrorCode.NOT_EXACTLY_ONE_COMMITTEE_BIT_SET});
80
103
  }
81
104
  // [REJECT] aggregate.data.index == 0
@@ -83,11 +106,11 @@ async function validateAggregateAndProof(
83
106
  throw new AttestationError(GossipAction.REJECT, {code: AttestationErrorCode.NON_ZERO_ATTESTATION_DATA_INDEX});
84
107
  }
85
108
  } else {
86
- attIndex = attData.index;
109
+ committeeIndex = attData.index;
87
110
  }
88
111
 
89
112
  const seenAttDataKey = serializedData ? getSeenAttDataKeyFromSignedAggregateAndProof(fork, serializedData) : null;
90
- const cachedAttData = seenAttDataKey ? chain.seenAttestationDatas.get(attSlot, attIndex, seenAttDataKey) : null;
113
+ const cachedAttData = seenAttDataKey ? chain.seenAttestationDatas.get(attSlot, committeeIndex, seenAttDataKey) : null;
91
114
 
92
115
  const attEpoch = computeEpochAtSlot(attSlot);
93
116
  const attTarget = attData.target;
@@ -136,7 +159,7 @@ async function validateAggregateAndProof(
136
159
  : toRootHex(ssz.phase0.AttestationData.hashTreeRoot(attData));
137
160
  if (
138
161
  !skipValidationKnownAttesters &&
139
- chain.seenAggregatedAttestations.isKnown(targetEpoch, attIndex, attDataRootHex, aggregationBits)
162
+ chain.seenAggregatedAttestations.isKnown(targetEpoch, committeeIndex, attDataRootHex, aggregationBits)
140
163
  ) {
141
164
  throw new AttestationError(GossipAction.IGNORE, {
142
165
  code: AttestationErrorCode.ATTESTERS_ALREADY_KNOWN,
@@ -177,7 +200,7 @@ async function validateAggregateAndProof(
177
200
  // -- i.e. data.index < get_committee_count_per_slot(state, data.target.epoch)
178
201
  const committeeValidatorIndices = cachedAttData
179
202
  ? cachedAttData.committeeValidatorIndices
180
- : getCommitteeValidatorIndices(shuffling, attSlot, attIndex);
203
+ : getCommitteeValidatorIndices(shuffling, attSlot, committeeIndex);
181
204
 
182
205
  // [REJECT] The number of aggregation bits matches the committee size
183
206
  // -- i.e. `len(aggregation_bits) == len(get_beacon_committee(state, aggregate.data.slot, index))`.
@@ -216,16 +239,15 @@ async function validateAggregateAndProof(
216
239
  // by the validator with index aggregate_and_proof.aggregator_index.
217
240
  // [REJECT] The aggregator signature, signed_aggregate_and_proof.signature, is valid.
218
241
  // [REJECT] The signature of aggregate is valid.
219
- const aggregator = chain.index2pubkey[aggregateAndProof.aggregatorIndex];
220
242
  const signingRoot = cachedAttData ? cachedAttData.signingRoot : getAttestationDataSigningRoot(chain.config, attData);
221
243
  const indexedAttestationSignatureSet = createAggregateSignatureSetFromComponents(
222
- indexedAttestation.attestingIndices.map((i) => chain.index2pubkey[i]),
244
+ indexedAttestation.attestingIndices,
223
245
  signingRoot,
224
246
  indexedAttestation.signature
225
247
  );
226
248
  const signatureSets = [
227
- getSelectionProofSignatureSet(chain.config, attSlot, aggregator, signedAggregateAndProof),
228
- getAggregateAndProofSignatureSet(chain.config, attEpoch, aggregator, signedAggregateAndProof),
249
+ getSelectionProofSignatureSet(chain.config, attSlot, aggregatorIndex, signedAggregateAndProof),
250
+ getAggregateAndProofSignatureSet(chain.config, attEpoch, aggregatorIndex, signedAggregateAndProof),
229
251
  indexedAttestationSignatureSet,
230
252
  ];
231
253
  // no need to write to SeenAttestationDatas
@@ -248,7 +270,7 @@ async function validateAggregateAndProof(
248
270
  // Same race-condition check as above for seen aggregators
249
271
  if (
250
272
  !skipValidationKnownAttesters &&
251
- chain.seenAggregatedAttestations.isKnown(targetEpoch, attIndex, attDataRootHex, aggregationBits)
273
+ chain.seenAggregatedAttestations.isKnown(targetEpoch, committeeIndex, attDataRootHex, aggregationBits)
252
274
  ) {
253
275
  throw new AttestationError(GossipAction.IGNORE, {
254
276
  code: AttestationErrorCode.ATTESTERS_ALREADY_KNOWN,
@@ -260,7 +282,7 @@ async function validateAggregateAndProof(
260
282
  chain.seenAggregators.add(targetEpoch, aggregatorIndex);
261
283
  chain.seenAggregatedAttestations.add(
262
284
  targetEpoch,
263
- attIndex,
285
+ committeeIndex,
264
286
  attDataRootHex,
265
287
  {aggregationBits, trueBitCount: attestingIndices.length},
266
288
  false
@@ -10,16 +10,17 @@ import {
10
10
  ForkSeq,
11
11
  SLOTS_PER_EPOCH,
12
12
  isForkPostElectra,
13
+ isForkPostGloas,
13
14
  } from "@lodestar/params";
14
15
  import {
15
16
  EpochShuffling,
17
+ IndexedSignatureSet,
16
18
  ShufflingError,
17
19
  ShufflingErrorCode,
18
- SingleSignatureSet,
19
20
  computeEpochAtSlot,
20
21
  computeSigningRoot,
21
22
  computeStartSlotAtEpoch,
22
- createSingleSignatureSetFromComponents,
23
+ createIndexedSignatureSetFromComponents,
23
24
  } from "@lodestar/state-transition";
24
25
  import {
25
26
  CommitteeIndex,
@@ -89,7 +90,7 @@ export type GossipAttestation = {
89
90
  };
90
91
 
91
92
  export type Step0Result = AttestationValidationResult & {
92
- signatureSet: SingleSignatureSet;
93
+ signatureSet: IndexedSignatureSet;
93
94
  validatorIndex: number;
94
95
  };
95
96
 
@@ -124,7 +125,7 @@ export async function validateGossipAttestationsSameAttData(
124
125
  // step1: verify signatures of all valid attestations
125
126
  // map new index to index in resultOrErrors
126
127
  const newIndexToOldIndex = new Map<number, number>();
127
- const signatureSets: SingleSignatureSet[] = [];
128
+ const signatureSets: IndexedSignatureSet[] = [];
128
129
  let newIndex = 0;
129
130
  const step0Results: Step0Result[] = [];
130
131
  for (const [i, resultOrError] of step0ResultOrErrors.entries()) {
@@ -142,7 +143,7 @@ export async function validateGossipAttestationsSameAttData(
142
143
  if (batchableBls) {
143
144
  // all signature sets should have same signing root since we filtered in network processor
144
145
  signatureValids = await chain.bls.verifySignatureSetsSameMessage(
145
- signatureSets.map((set) => ({publicKey: set.pubkey, signature: set.signature})),
146
+ signatureSets.map((set) => ({publicKey: chain.index2pubkey[set.index], signature: set.signature})),
146
147
  signatureSets[0].signingRoot
147
148
  );
148
149
  } else {
@@ -293,9 +294,29 @@ async function validateAttestationNoSignatureCheck(
293
294
  // api or first time validation of a gossip attestation
294
295
  committeeIndex = attestationOrCache.attestation.committeeIndex;
295
296
 
296
- // [REJECT] attestation.data.index == 0
297
- if (attData.index !== 0) {
298
- throw new AttestationError(GossipAction.REJECT, {code: AttestationErrorCode.NON_ZERO_ATTESTATION_DATA_INDEX});
297
+ if (isForkPostGloas(fork)) {
298
+ // [REJECT] `attestation.data.index < 2`.
299
+ if (attData.index >= 2) {
300
+ throw new AttestationError(GossipAction.REJECT, {
301
+ code: AttestationErrorCode.INVALID_PAYLOAD_STATUS_VALUE,
302
+ attDataIndex: attData.index,
303
+ });
304
+ }
305
+
306
+ // [REJECT] `attestation.data.index == 0` if `block.slot == attestation.data.slot`.
307
+ const block = chain.forkChoice.getBlock(attData.beaconBlockRoot);
308
+
309
+ // block being null will be handled by `verifyHeadBlockAndTargetRoot`
310
+ if (block !== null && block.slot === attSlot && attData.index !== 0) {
311
+ throw new AttestationError(GossipAction.REJECT, {
312
+ code: AttestationErrorCode.PREMATURELY_INDICATED_PAYLOAD_PRESENT,
313
+ });
314
+ }
315
+ } else {
316
+ // [REJECT] attestation.data.index == 0
317
+ if (attData.index !== 0) {
318
+ throw new AttestationError(GossipAction.REJECT, {code: AttestationErrorCode.NON_ZERO_ATTESTATION_DATA_INDEX});
319
+ }
299
320
  }
300
321
  } else {
301
322
  // phase0 attestation
@@ -477,7 +498,7 @@ async function validateAttestationNoSignatureCheck(
477
498
 
478
499
  // [REJECT] The signature of attestation is valid.
479
500
  const attestingIndices = [validatorIndex];
480
- let signatureSet: SingleSignatureSet;
501
+ let signatureSet: IndexedSignatureSet;
481
502
  let attDataRootHex: RootHex;
482
503
  const signature = attestationOrCache.attestation
483
504
  ? attestationOrCache.attestation.signature
@@ -492,18 +513,14 @@ async function validateAttestationNoSignatureCheck(
492
513
 
493
514
  if (attestationOrCache.cache) {
494
515
  // there could be up to 6% of cpu time to compute signing root if we don't clone the signature set
495
- signatureSet = createSingleSignatureSetFromComponents(
496
- chain.index2pubkey[validatorIndex],
516
+ signatureSet = createIndexedSignatureSetFromComponents(
517
+ validatorIndex,
497
518
  attestationOrCache.cache.signingRoot,
498
519
  signature
499
520
  );
500
521
  attDataRootHex = attestationOrCache.cache.attDataRootHex;
501
522
  } else {
502
- signatureSet = createSingleSignatureSetFromComponents(
503
- chain.index2pubkey[validatorIndex],
504
- getSigningRoot(),
505
- signature
506
- );
523
+ signatureSet = createIndexedSignatureSetFromComponents(validatorIndex, getSigningRoot(), signature);
507
524
 
508
525
  // add cached attestation data before verifying signature
509
526
  attDataRootHex = toRootHex(ssz.phase0.AttestationData.hashTreeRoot(attData));