@lodestar/beacon-node 1.40.0-dev.3be9500fa9 → 1.40.0-dev.45b04262dc

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 (445) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +23 -27
  3. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  4. package/lib/api/impl/config/constants.d.ts +3 -0
  5. package/lib/api/impl/config/constants.d.ts.map +1 -1
  6. package/lib/api/impl/config/constants.js +5 -1
  7. package/lib/api/impl/config/constants.js.map +1 -1
  8. package/lib/api/impl/debug/index.d.ts +1 -1
  9. package/lib/api/impl/debug/index.d.ts.map +1 -1
  10. package/lib/api/impl/debug/index.js +3 -6
  11. package/lib/api/impl/debug/index.js.map +1 -1
  12. package/lib/api/impl/lodestar/index.d.ts.map +1 -1
  13. package/lib/api/impl/lodestar/index.js +29 -2
  14. package/lib/api/impl/lodestar/index.js.map +1 -1
  15. package/lib/api/impl/validator/index.d.ts.map +1 -1
  16. package/lib/api/impl/validator/index.js +9 -8
  17. package/lib/api/impl/validator/index.js.map +1 -1
  18. package/lib/api/rest/base.d.ts.map +1 -1
  19. package/lib/api/rest/base.js +12 -10
  20. package/lib/api/rest/base.js.map +1 -1
  21. package/lib/chain/ColumnReconstructionTracker.d.ts +2 -0
  22. package/lib/chain/ColumnReconstructionTracker.d.ts.map +1 -1
  23. package/lib/chain/ColumnReconstructionTracker.js +7 -3
  24. package/lib/chain/ColumnReconstructionTracker.js.map +1 -1
  25. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
  26. package/lib/chain/archiveStore/historicalState/getHistoricalState.js +2 -1
  27. package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
  28. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
  29. package/lib/chain/archiveStore/utils/archiveBlocks.js +4 -0
  30. package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
  31. package/lib/chain/blocks/blockInput/blockInput.d.ts +30 -0
  32. package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
  33. package/lib/chain/blocks/blockInput/blockInput.js +44 -3
  34. package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
  35. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  36. package/lib/chain/blocks/importBlock.js +3 -7
  37. package/lib/chain/blocks/importBlock.js.map +1 -1
  38. package/lib/chain/blocks/index.d.ts.map +1 -1
  39. package/lib/chain/blocks/index.js +0 -14
  40. package/lib/chain/blocks/index.js.map +1 -1
  41. package/lib/chain/blocks/types.d.ts +0 -2
  42. package/lib/chain/blocks/types.d.ts.map +1 -1
  43. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  44. package/lib/chain/blocks/verifyBlock.js +1 -8
  45. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  46. package/lib/chain/blocks/verifyBlocksSignatures.d.ts +2 -2
  47. package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
  48. package/lib/chain/blocks/verifyBlocksSignatures.js +2 -2
  49. package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
  50. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
  51. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +1 -2
  52. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
  53. package/lib/chain/blocks/writeBlockInputToDb.d.ts +1 -4
  54. package/lib/chain/blocks/writeBlockInputToDb.d.ts.map +1 -1
  55. package/lib/chain/blocks/writeBlockInputToDb.js +28 -28
  56. package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
  57. package/lib/chain/bls/multithread/index.d.ts +3 -1
  58. package/lib/chain/bls/multithread/index.d.ts.map +1 -1
  59. package/lib/chain/bls/multithread/index.js +5 -3
  60. package/lib/chain/bls/multithread/index.js.map +1 -1
  61. package/lib/chain/bls/multithread/jobItem.d.ts +2 -2
  62. package/lib/chain/bls/multithread/jobItem.d.ts.map +1 -1
  63. package/lib/chain/bls/multithread/jobItem.js +2 -2
  64. package/lib/chain/bls/multithread/jobItem.js.map +1 -1
  65. package/lib/chain/bls/singleThread.d.ts +4 -2
  66. package/lib/chain/bls/singleThread.d.ts.map +1 -1
  67. package/lib/chain/bls/singleThread.js +4 -2
  68. package/lib/chain/bls/singleThread.js.map +1 -1
  69. package/lib/chain/bls/utils.d.ts +2 -2
  70. package/lib/chain/bls/utils.d.ts.map +1 -1
  71. package/lib/chain/bls/utils.js +9 -6
  72. package/lib/chain/bls/utils.js.map +1 -1
  73. package/lib/chain/chain.d.ts +22 -5
  74. package/lib/chain/chain.d.ts.map +1 -1
  75. package/lib/chain/chain.js +197 -44
  76. package/lib/chain/chain.js.map +1 -1
  77. package/lib/chain/errors/attestationError.d.ts +14 -1
  78. package/lib/chain/errors/attestationError.d.ts.map +1 -1
  79. package/lib/chain/errors/attestationError.js +8 -0
  80. package/lib/chain/errors/attestationError.js.map +1 -1
  81. package/lib/chain/errors/executionPayloadBid.d.ts +48 -0
  82. package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -0
  83. package/lib/chain/errors/executionPayloadBid.js +15 -0
  84. package/lib/chain/errors/executionPayloadBid.js.map +1 -0
  85. package/lib/chain/errors/executionPayloadEnvelope.d.ts +48 -0
  86. package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -0
  87. package/lib/chain/errors/executionPayloadEnvelope.js +16 -0
  88. package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -0
  89. package/lib/chain/errors/index.d.ts +3 -0
  90. package/lib/chain/errors/index.d.ts.map +1 -1
  91. package/lib/chain/errors/index.js +3 -0
  92. package/lib/chain/errors/index.js.map +1 -1
  93. package/lib/chain/errors/payloadAttestation.d.ts +34 -0
  94. package/lib/chain/errors/payloadAttestation.d.ts.map +1 -0
  95. package/lib/chain/errors/payloadAttestation.js +13 -0
  96. package/lib/chain/errors/payloadAttestation.js.map +1 -0
  97. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  98. package/lib/chain/forkChoice/index.js +18 -0
  99. package/lib/chain/forkChoice/index.js.map +1 -1
  100. package/lib/chain/initState.d.ts.map +1 -1
  101. package/lib/chain/initState.js +2 -2
  102. package/lib/chain/initState.js.map +1 -1
  103. package/lib/chain/interface.d.ts +21 -3
  104. package/lib/chain/interface.d.ts.map +1 -1
  105. package/lib/chain/interface.js.map +1 -1
  106. package/lib/chain/lightClient/index.d.ts.map +1 -1
  107. package/lib/chain/lightClient/index.js +1 -2
  108. package/lib/chain/lightClient/index.js.map +1 -1
  109. package/lib/chain/opPools/executionPayloadBidPool.d.ts +21 -0
  110. package/lib/chain/opPools/executionPayloadBidPool.d.ts.map +1 -0
  111. package/lib/chain/opPools/executionPayloadBidPool.js +57 -0
  112. package/lib/chain/opPools/executionPayloadBidPool.js.map +1 -0
  113. package/lib/chain/opPools/index.d.ts +2 -0
  114. package/lib/chain/opPools/index.d.ts.map +1 -1
  115. package/lib/chain/opPools/index.js +2 -0
  116. package/lib/chain/opPools/index.js.map +1 -1
  117. package/lib/chain/opPools/payloadAttestationPool.d.ts +24 -0
  118. package/lib/chain/opPools/payloadAttestationPool.d.ts.map +1 -0
  119. package/lib/chain/opPools/payloadAttestationPool.js +109 -0
  120. package/lib/chain/opPools/payloadAttestationPool.js.map +1 -0
  121. package/lib/chain/options.d.ts +0 -1
  122. package/lib/chain/options.d.ts.map +1 -1
  123. package/lib/chain/options.js +0 -1
  124. package/lib/chain/options.js.map +1 -1
  125. package/lib/chain/prepareNextSlot.js +6 -4
  126. package/lib/chain/prepareNextSlot.js.map +1 -1
  127. package/lib/chain/produceBlock/produceBlockBody.d.ts +3 -2
  128. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  129. package/lib/chain/produceBlock/produceBlockBody.js +5 -3
  130. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  131. package/lib/chain/regen/interface.d.ts +4 -9
  132. package/lib/chain/regen/interface.d.ts.map +1 -1
  133. package/lib/chain/regen/interface.js +1 -1
  134. package/lib/chain/regen/interface.js.map +1 -1
  135. package/lib/chain/regen/queued.d.ts +2 -3
  136. package/lib/chain/regen/queued.d.ts.map +1 -1
  137. package/lib/chain/regen/queued.js +2 -16
  138. package/lib/chain/regen/queued.js.map +1 -1
  139. package/lib/chain/regen/regen.d.ts +5 -7
  140. package/lib/chain/regen/regen.d.ts.map +1 -1
  141. package/lib/chain/regen/regen.js +7 -17
  142. package/lib/chain/regen/regen.js.map +1 -1
  143. package/lib/chain/seenCache/index.d.ts +3 -1
  144. package/lib/chain/seenCache/index.d.ts.map +1 -1
  145. package/lib/chain/seenCache/index.js +3 -1
  146. package/lib/chain/seenCache/index.js.map +1 -1
  147. package/lib/chain/seenCache/seenAttesters.d.ts +5 -0
  148. package/lib/chain/seenCache/seenAttesters.d.ts.map +1 -1
  149. package/lib/chain/seenCache/seenAttesters.js +5 -0
  150. package/lib/chain/seenCache/seenAttesters.js.map +1 -1
  151. package/lib/chain/seenCache/seenExecutionPayloadBids.d.ts +12 -0
  152. package/lib/chain/seenCache/seenExecutionPayloadBids.d.ts.map +1 -0
  153. package/lib/chain/seenCache/seenExecutionPayloadBids.js +30 -0
  154. package/lib/chain/seenCache/seenExecutionPayloadBids.js.map +1 -0
  155. package/lib/chain/seenCache/seenExecutionPayloadEnvelope.d.ts +15 -0
  156. package/lib/chain/seenCache/seenExecutionPayloadEnvelope.d.ts.map +1 -0
  157. package/lib/chain/seenCache/seenExecutionPayloadEnvelope.js +28 -0
  158. package/lib/chain/seenCache/seenExecutionPayloadEnvelope.js.map +1 -0
  159. package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
  160. package/lib/chain/seenCache/seenGossipBlockInput.js +3 -3
  161. package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
  162. package/lib/chain/serializeState.d.ts.map +1 -1
  163. package/lib/chain/serializeState.js +2 -1
  164. package/lib/chain/serializeState.js.map +1 -1
  165. package/lib/chain/stateCache/index.d.ts +0 -2
  166. package/lib/chain/stateCache/index.d.ts.map +1 -1
  167. package/lib/chain/stateCache/index.js +0 -2
  168. package/lib/chain/stateCache/index.js.map +1 -1
  169. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +2 -1
  170. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  171. package/lib/chain/stateCache/persistentCheckpointsCache.js +3 -0
  172. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  173. package/lib/chain/validation/aggregateAndProof.js +35 -14
  174. package/lib/chain/validation/aggregateAndProof.js.map +1 -1
  175. package/lib/chain/validation/attestation.d.ts +2 -2
  176. package/lib/chain/validation/attestation.d.ts.map +1 -1
  177. package/lib/chain/validation/attestation.js +27 -8
  178. package/lib/chain/validation/attestation.js.map +1 -1
  179. package/lib/chain/validation/attesterSlashing.d.ts.map +1 -1
  180. package/lib/chain/validation/attesterSlashing.js +1 -1
  181. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  182. package/lib/chain/validation/blobSidecar.d.ts.map +1 -1
  183. package/lib/chain/validation/blobSidecar.js +5 -5
  184. package/lib/chain/validation/blobSidecar.js.map +1 -1
  185. package/lib/chain/validation/block.d.ts.map +1 -1
  186. package/lib/chain/validation/block.js +6 -6
  187. package/lib/chain/validation/block.js.map +1 -1
  188. package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
  189. package/lib/chain/validation/dataColumnSidecar.js +5 -5
  190. package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
  191. package/lib/chain/validation/executionPayloadBid.d.ts +5 -0
  192. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -0
  193. package/lib/chain/validation/executionPayloadBid.js +104 -0
  194. package/lib/chain/validation/executionPayloadBid.js.map +1 -0
  195. package/lib/chain/validation/executionPayloadEnvelope.d.ts +5 -0
  196. package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -0
  197. package/lib/chain/validation/executionPayloadEnvelope.js +89 -0
  198. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -0
  199. package/lib/chain/validation/payloadAttestationMessage.d.ts +9 -0
  200. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -0
  201. package/lib/chain/validation/payloadAttestationMessage.js +72 -0
  202. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -0
  203. package/lib/chain/validation/proposerSlashing.js +1 -1
  204. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  205. package/lib/chain/validation/signatureSets/aggregateAndProof.d.ts +2 -3
  206. package/lib/chain/validation/signatureSets/aggregateAndProof.d.ts.map +1 -1
  207. package/lib/chain/validation/signatureSets/aggregateAndProof.js +8 -3
  208. package/lib/chain/validation/signatureSets/aggregateAndProof.js.map +1 -1
  209. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts +2 -2
  210. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts.map +1 -1
  211. package/lib/chain/validation/signatureSets/contributionAndProof.js +3 -3
  212. package/lib/chain/validation/signatureSets/contributionAndProof.js.map +1 -1
  213. package/lib/chain/validation/signatureSets/selectionProof.d.ts +2 -3
  214. package/lib/chain/validation/signatureSets/selectionProof.d.ts.map +1 -1
  215. package/lib/chain/validation/signatureSets/selectionProof.js +8 -3
  216. package/lib/chain/validation/signatureSets/selectionProof.js.map +1 -1
  217. package/lib/chain/validation/signatureSets/syncCommittee.d.ts +2 -2
  218. package/lib/chain/validation/signatureSets/syncCommittee.d.ts.map +1 -1
  219. package/lib/chain/validation/signatureSets/syncCommittee.js +3 -3
  220. package/lib/chain/validation/signatureSets/syncCommittee.js.map +1 -1
  221. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts +1 -2
  222. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts.map +1 -1
  223. package/lib/chain/validation/signatureSets/syncCommitteeContribution.js +2 -2
  224. package/lib/chain/validation/signatureSets/syncCommitteeContribution.js.map +1 -1
  225. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts +2 -2
  226. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts.map +1 -1
  227. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js +3 -3
  228. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js.map +1 -1
  229. package/lib/chain/validation/syncCommittee.js +1 -1
  230. package/lib/chain/validation/syncCommittee.js.map +1 -1
  231. package/lib/chain/validation/syncCommitteeContributionAndProof.d.ts.map +1 -1
  232. package/lib/chain/validation/syncCommitteeContributionAndProof.js +3 -5
  233. package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
  234. package/lib/chain/validation/voluntaryExit.js +1 -1
  235. package/lib/chain/validation/voluntaryExit.js.map +1 -1
  236. package/lib/chain/validatorMonitor.d.ts +2 -0
  237. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  238. package/lib/chain/validatorMonitor.js +49 -7
  239. package/lib/chain/validatorMonitor.js.map +1 -1
  240. package/lib/db/repositories/checkpointState.js +0 -1
  241. package/lib/db/repositories/checkpointState.js.map +1 -1
  242. package/lib/metrics/metrics/lodestar.d.ts +27 -0
  243. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  244. package/lib/metrics/metrics/lodestar.js +64 -0
  245. package/lib/metrics/metrics/lodestar.js.map +1 -1
  246. package/lib/network/core/networkCore.d.ts +3 -0
  247. package/lib/network/core/networkCore.d.ts.map +1 -1
  248. package/lib/network/core/networkCore.js +9 -0
  249. package/lib/network/core/networkCore.js.map +1 -1
  250. package/lib/network/core/networkCoreWorker.js +3 -0
  251. package/lib/network/core/networkCoreWorker.js.map +1 -1
  252. package/lib/network/core/networkCoreWorkerHandler.d.ts +3 -0
  253. package/lib/network/core/networkCoreWorkerHandler.d.ts.map +1 -1
  254. package/lib/network/core/networkCoreWorkerHandler.js +9 -0
  255. package/lib/network/core/networkCoreWorkerHandler.js.map +1 -1
  256. package/lib/network/core/types.d.ts +3 -0
  257. package/lib/network/core/types.d.ts.map +1 -1
  258. package/lib/network/gossip/gossipsub.d.ts +34 -0
  259. package/lib/network/gossip/gossipsub.d.ts.map +1 -1
  260. package/lib/network/gossip/gossipsub.js +123 -0
  261. package/lib/network/gossip/gossipsub.js.map +1 -1
  262. package/lib/network/gossip/interface.d.ts +20 -2
  263. package/lib/network/gossip/interface.d.ts.map +1 -1
  264. package/lib/network/gossip/interface.js +3 -0
  265. package/lib/network/gossip/interface.js.map +1 -1
  266. package/lib/network/gossip/scoringParameters.d.ts.map +1 -1
  267. package/lib/network/gossip/scoringParameters.js +38 -2
  268. package/lib/network/gossip/scoringParameters.js.map +1 -1
  269. package/lib/network/gossip/topic.d.ts +77 -1
  270. package/lib/network/gossip/topic.d.ts.map +1 -1
  271. package/lib/network/gossip/topic.js +20 -0
  272. package/lib/network/gossip/topic.js.map +1 -1
  273. package/lib/network/network.d.ts +3 -0
  274. package/lib/network/network.d.ts.map +1 -1
  275. package/lib/network/network.js +9 -0
  276. package/lib/network/network.js.map +1 -1
  277. package/lib/network/options.d.ts +6 -0
  278. package/lib/network/options.d.ts.map +1 -1
  279. package/lib/network/options.js.map +1 -1
  280. package/lib/network/peers/peerManager.d.ts.map +1 -1
  281. package/lib/network/peers/peerManager.js +9 -0
  282. package/lib/network/peers/peerManager.js.map +1 -1
  283. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  284. package/lib/network/processor/gossipHandlers.js +35 -4
  285. package/lib/network/processor/gossipHandlers.js.map +1 -1
  286. package/lib/network/processor/gossipQueues/index.d.ts.map +1 -1
  287. package/lib/network/processor/gossipQueues/index.js +16 -0
  288. package/lib/network/processor/gossipQueues/index.js.map +1 -1
  289. package/lib/network/processor/index.d.ts.map +1 -1
  290. package/lib/network/processor/index.js +3 -0
  291. package/lib/network/processor/index.js.map +1 -1
  292. package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
  293. package/lib/network/reqresp/handlers/beaconBlocksByRange.js +2 -4
  294. package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
  295. package/lib/network/reqresp/handlers/beaconBlocksByRoot.d.ts +1 -2
  296. package/lib/network/reqresp/handlers/beaconBlocksByRoot.d.ts.map +1 -1
  297. package/lib/network/reqresp/handlers/beaconBlocksByRoot.js +5 -26
  298. package/lib/network/reqresp/handlers/beaconBlocksByRoot.js.map +1 -1
  299. package/lib/network/reqresp/handlers/blobSidecarsByRoot.d.ts +1 -2
  300. package/lib/network/reqresp/handlers/blobSidecarsByRoot.d.ts.map +1 -1
  301. package/lib/network/reqresp/handlers/blobSidecarsByRoot.js +5 -7
  302. package/lib/network/reqresp/handlers/blobSidecarsByRoot.js.map +1 -1
  303. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
  304. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +1 -2
  305. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
  306. package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.d.ts.map +1 -1
  307. package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js +1 -5
  308. package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js.map +1 -1
  309. package/lib/network/reqresp/handlers/index.js +2 -2
  310. package/lib/network/reqresp/handlers/index.js.map +1 -1
  311. package/lib/sync/backfill/backfill.d.ts.map +1 -1
  312. package/lib/sync/backfill/backfill.js +3 -4
  313. package/lib/sync/backfill/backfill.js.map +1 -1
  314. package/lib/sync/backfill/verify.d.ts +1 -2
  315. package/lib/sync/backfill/verify.d.ts.map +1 -1
  316. package/lib/sync/backfill/verify.js +2 -2
  317. package/lib/sync/backfill/verify.js.map +1 -1
  318. package/lib/sync/range/chain.d.ts.map +1 -1
  319. package/lib/sync/range/chain.js +0 -1
  320. package/lib/sync/range/chain.js.map +1 -1
  321. package/lib/sync/range/range.d.ts.map +1 -1
  322. package/lib/sync/range/range.js +0 -3
  323. package/lib/sync/range/range.js.map +1 -1
  324. package/lib/sync/unknownBlock.d.ts.map +1 -1
  325. package/lib/sync/unknownBlock.js +0 -3
  326. package/lib/sync/unknownBlock.js.map +1 -1
  327. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  328. package/lib/sync/utils/downloadByRange.js +2 -2
  329. package/lib/sync/utils/downloadByRange.js.map +1 -1
  330. package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
  331. package/lib/sync/utils/downloadByRoot.js +1 -2
  332. package/lib/sync/utils/downloadByRoot.js.map +1 -1
  333. package/package.json +16 -16
  334. package/src/api/impl/beacon/blocks/index.ts +39 -37
  335. package/src/api/impl/config/constants.ts +8 -0
  336. package/src/api/impl/debug/index.ts +2 -6
  337. package/src/api/impl/lodestar/index.ts +35 -3
  338. package/src/api/impl/validator/index.ts +14 -12
  339. package/src/api/rest/base.ts +15 -13
  340. package/src/chain/ColumnReconstructionTracker.ts +8 -4
  341. package/src/chain/archiveStore/historicalState/getHistoricalState.ts +2 -1
  342. package/src/chain/archiveStore/utils/archiveBlocks.ts +4 -0
  343. package/src/chain/blocks/blockInput/blockInput.ts +55 -4
  344. package/src/chain/blocks/importBlock.ts +3 -7
  345. package/src/chain/blocks/index.ts +0 -19
  346. package/src/chain/blocks/types.ts +0 -2
  347. package/src/chain/blocks/verifyBlock.ts +0 -9
  348. package/src/chain/blocks/verifyBlocksSignatures.ts +4 -12
  349. package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +1 -2
  350. package/src/chain/blocks/writeBlockInputToDb.ts +33 -30
  351. package/src/chain/bls/multithread/index.ts +7 -4
  352. package/src/chain/bls/multithread/jobItem.ts +7 -3
  353. package/src/chain/bls/singleThread.ts +5 -3
  354. package/src/chain/bls/utils.ts +15 -7
  355. package/src/chain/chain.ts +227 -56
  356. package/src/chain/errors/attestationError.ts +11 -1
  357. package/src/chain/errors/executionPayloadBid.ts +35 -0
  358. package/src/chain/errors/executionPayloadEnvelope.ts +34 -0
  359. package/src/chain/errors/index.ts +3 -0
  360. package/src/chain/errors/payloadAttestation.ts +25 -0
  361. package/src/chain/forkChoice/index.ts +19 -0
  362. package/src/chain/initState.ts +2 -2
  363. package/src/chain/interface.ts +32 -1
  364. package/src/chain/lightClient/index.ts +1 -2
  365. package/src/chain/opPools/executionPayloadBidPool.ts +77 -0
  366. package/src/chain/opPools/index.ts +2 -0
  367. package/src/chain/opPools/payloadAttestationPool.ts +157 -0
  368. package/src/chain/options.ts +0 -2
  369. package/src/chain/prepareNextSlot.ts +6 -6
  370. package/src/chain/produceBlock/produceBlockBody.ts +7 -5
  371. package/src/chain/regen/interface.ts +3 -13
  372. package/src/chain/regen/queued.ts +3 -24
  373. package/src/chain/regen/regen.ts +10 -25
  374. package/src/chain/seenCache/index.ts +3 -1
  375. package/src/chain/seenCache/seenAttesters.ts +5 -0
  376. package/src/chain/seenCache/seenExecutionPayloadBids.ts +35 -0
  377. package/src/chain/seenCache/seenExecutionPayloadEnvelope.ts +34 -0
  378. package/src/chain/seenCache/seenGossipBlockInput.ts +3 -3
  379. package/src/chain/serializeState.ts +2 -1
  380. package/src/chain/stateCache/index.ts +0 -2
  381. package/src/chain/stateCache/persistentCheckpointsCache.ts +6 -2
  382. package/src/chain/validation/aggregateAndProof.ts +36 -14
  383. package/src/chain/validation/attestation.ts +33 -16
  384. package/src/chain/validation/attesterSlashing.ts +1 -6
  385. package/src/chain/validation/blobSidecar.ts +4 -9
  386. package/src/chain/validation/block.ts +6 -6
  387. package/src/chain/validation/dataColumnSidecar.ts +4 -9
  388. package/src/chain/validation/executionPayloadBid.ts +141 -0
  389. package/src/chain/validation/executionPayloadEnvelope.ts +122 -0
  390. package/src/chain/validation/payloadAttestationMessage.ts +109 -0
  391. package/src/chain/validation/proposerSlashing.ts +1 -6
  392. package/src/chain/validation/signatureSets/aggregateAndProof.ts +9 -14
  393. package/src/chain/validation/signatureSets/contributionAndProof.ts +2 -4
  394. package/src/chain/validation/signatureSets/selectionProof.ts +9 -9
  395. package/src/chain/validation/signatureSets/syncCommittee.ts +2 -4
  396. package/src/chain/validation/signatureSets/syncCommitteeContribution.ts +2 -3
  397. package/src/chain/validation/signatureSets/syncCommitteeSelectionProof.ts +2 -4
  398. package/src/chain/validation/syncCommittee.ts +1 -1
  399. package/src/chain/validation/syncCommitteeContributionAndProof.ts +3 -5
  400. package/src/chain/validation/voluntaryExit.ts +1 -1
  401. package/src/chain/validatorMonitor.ts +62 -8
  402. package/src/db/repositories/checkpointState.ts +1 -1
  403. package/src/metrics/metrics/lodestar.ts +65 -0
  404. package/src/network/core/networkCore.ts +12 -0
  405. package/src/network/core/networkCoreWorker.ts +3 -0
  406. package/src/network/core/networkCoreWorkerHandler.ts +9 -0
  407. package/src/network/core/types.ts +6 -0
  408. package/src/network/gossip/gossipsub.ts +147 -1
  409. package/src/network/gossip/interface.ts +17 -0
  410. package/src/network/gossip/scoringParameters.ts +44 -2
  411. package/src/network/gossip/topic.ts +21 -0
  412. package/src/network/network.ts +12 -0
  413. package/src/network/options.ts +6 -0
  414. package/src/network/peers/peerManager.ts +11 -0
  415. package/src/network/processor/gossipHandlers.ts +49 -4
  416. package/src/network/processor/gossipQueues/index.ts +16 -0
  417. package/src/network/processor/index.ts +3 -0
  418. package/src/network/reqresp/handlers/beaconBlocksByRange.ts +2 -4
  419. package/src/network/reqresp/handlers/beaconBlocksByRoot.ts +5 -32
  420. package/src/network/reqresp/handlers/blobSidecarsByRoot.ts +5 -9
  421. package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +5 -2
  422. package/src/network/reqresp/handlers/dataColumnSidecarsByRoot.ts +1 -5
  423. package/src/network/reqresp/handlers/index.ts +2 -2
  424. package/src/sync/backfill/backfill.ts +3 -4
  425. package/src/sync/backfill/verify.ts +2 -3
  426. package/src/sync/range/chain.ts +0 -1
  427. package/src/sync/range/range.ts +0 -3
  428. package/src/sync/unknownBlock.ts +0 -3
  429. package/src/sync/utils/downloadByRange.ts +2 -2
  430. package/src/sync/utils/downloadByRoot.ts +1 -2
  431. package/lib/chain/stateCache/blockStateCacheImpl.d.ts +0 -54
  432. package/lib/chain/stateCache/blockStateCacheImpl.d.ts.map +0 -1
  433. package/lib/chain/stateCache/blockStateCacheImpl.js +0 -130
  434. package/lib/chain/stateCache/blockStateCacheImpl.js.map +0 -1
  435. package/lib/chain/stateCache/inMemoryCheckpointsCache.d.ts +0 -60
  436. package/lib/chain/stateCache/inMemoryCheckpointsCache.d.ts.map +0 -1
  437. package/lib/chain/stateCache/inMemoryCheckpointsCache.js +0 -156
  438. package/lib/chain/stateCache/inMemoryCheckpointsCache.js.map +0 -1
  439. package/lib/util/bytes.d.ts +0 -3
  440. package/lib/util/bytes.d.ts.map +0 -1
  441. package/lib/util/bytes.js +0 -11
  442. package/lib/util/bytes.js.map +0 -1
  443. package/src/chain/stateCache/blockStateCacheImpl.ts +0 -149
  444. package/src/chain/stateCache/inMemoryCheckpointsCache.ts +0 -192
  445. package/src/util/bytes.ts +0 -11
@@ -24,7 +24,7 @@ import {
24
24
  altair,
25
25
  deneb,
26
26
  } from "@lodestar/types";
27
- import {LogData, LogHandler, LogLevel, Logger, MapDef, MapDefMax, toRootHex} from "@lodestar/utils";
27
+ import {LogData, LogHandler, LogLevel, Logger, MapDef, MapDefMax, prettyPrintIndices, toRootHex} from "@lodestar/utils";
28
28
  import {GENESIS_SLOT} from "../constants/constants.js";
29
29
  import {RegistryMetricCreator} from "../metrics/index.js";
30
30
 
@@ -39,7 +39,8 @@ const MAX_CACHED_DISTINCT_TARGETS = 4;
39
39
  const LATE_ATTESTATION_SUBMISSION_BPS = 5000;
40
40
  const LATE_BLOCK_SUBMISSION_BPS = 2500;
41
41
 
42
- const RETAIN_REGISTERED_VALIDATORS_MS = 1 * 3600 * 1000; // 1 hour
42
+ /** Number of epochs to retain registered validators after their last registration */
43
+ const RETAIN_REGISTERED_VALIDATORS_EPOCHS = 2;
43
44
 
44
45
  type Seconds = number;
45
46
  export enum OpSource {
@@ -97,6 +98,8 @@ export type ValidatorMonitor = {
97
98
  ): void;
98
99
  onceEveryEndOfEpoch(state: CachedBeaconStateAllForks): void;
99
100
  scrapeMetrics(slotClock: Slot): void;
101
+ /** Returns the list of validator indices currently being monitored */
102
+ getMonitoredValidatorIndices(): ValidatorIndex[];
100
103
  };
101
104
 
102
105
  export type ValidatorMonitorOpts = {
@@ -284,6 +287,9 @@ export function createValidatorMonitor(
284
287
  logger[logLevel](message, context);
285
288
  };
286
289
 
290
+ // Calculate retain time dynamically based on slot duration (2 epochs)
291
+ const retainRegisteredValidatorsMs = SLOTS_PER_EPOCH * config.SLOT_DURATION_MS * RETAIN_REGISTERED_VALIDATORS_EPOCHS;
292
+
287
293
  /** The validators that require additional monitoring. */
288
294
  const validators = new MapDef<ValidatorIndex, MonitoredValidator>(() => ({
289
295
  summaries: new Map<Epoch, EpochSummary>(),
@@ -306,11 +312,19 @@ export function createValidatorMonitor(
306
312
 
307
313
  let lastRegisteredStatusEpoch = -1;
308
314
 
315
+ // Track validator additions/removals per epoch for logging
316
+ const addedValidatorsInEpoch: Set<ValidatorIndex> = new Set();
317
+ const removedValidatorsInEpoch: Set<ValidatorIndex> = new Set();
318
+
309
319
  const validatorMonitorMetrics = metricsRegister ? createValidatorMonitorMetrics(metricsRegister) : null;
310
320
 
311
321
  const validatorMonitor: ValidatorMonitor = {
312
322
  registerLocalValidator(index) {
323
+ const isNewValidator = !validators.has(index);
313
324
  validators.getOrDefault(index).lastRegisteredTimeMs = Date.now();
325
+ if (isNewValidator) {
326
+ addedValidatorsInEpoch.add(index);
327
+ }
314
328
  },
315
329
 
316
330
  registerLocalValidatorInSyncCommittee(index, untilEpoch) {
@@ -333,6 +347,9 @@ export function createValidatorMonitor(
333
347
  return;
334
348
  }
335
349
 
350
+ // Track total balance instead of per-validator balance to reduce metric cardinality
351
+ let totalBalance = 0;
352
+
336
353
  for (const [index, monitoredValidator] of validators.entries()) {
337
354
  // We subtract two from the state of the epoch that generated these summaries.
338
355
  //
@@ -391,7 +408,7 @@ export function createValidatorMonitor(
391
408
 
392
409
  const balance = balances?.[index];
393
410
  if (balance !== undefined) {
394
- validatorMonitorMetrics?.prevEpochOnChainBalance.set({index}, balance);
411
+ totalBalance += balance;
395
412
  }
396
413
 
397
414
  if (!summary.isPrevSourceAttester || !summary.isPrevTargetAttester || !summary.isPrevHeadAttester) {
@@ -406,6 +423,10 @@ export function createValidatorMonitor(
406
423
  });
407
424
  }
408
425
  }
426
+
427
+ if (balances !== undefined) {
428
+ validatorMonitorMetrics?.prevEpochOnChainBalance.set(totalBalance);
429
+ }
409
430
  },
410
431
 
411
432
  registerBeaconBlock(src, delaySec, block) {
@@ -673,11 +694,29 @@ export function createValidatorMonitor(
673
694
 
674
695
  // Prune validators not seen in a while
675
696
  for (const [index, validator] of validators.entries()) {
676
- if (Date.now() - validator.lastRegisteredTimeMs > RETAIN_REGISTERED_VALIDATORS_MS) {
697
+ if (Date.now() - validator.lastRegisteredTimeMs > retainRegisteredValidatorsMs) {
677
698
  validators.delete(index);
699
+ removedValidatorsInEpoch.add(index);
678
700
  }
679
701
  }
680
702
 
703
+ // Log validator monitor status every epoch
704
+ const allIndices = Array.from(validators.keys()).sort((a, b) => a - b);
705
+ const addedIndices = Array.from(addedValidatorsInEpoch).sort((a, b) => a - b);
706
+ const removedIndices = Array.from(removedValidatorsInEpoch).sort((a, b) => a - b);
707
+
708
+ log("Validator monitor status", {
709
+ epoch: computeEpochAtSlot(headState.slot),
710
+ added: addedIndices.length > 0 ? prettyPrintIndices(addedIndices) : "none",
711
+ removed: removedIndices.length > 0 ? prettyPrintIndices(removedIndices) : "none",
712
+ total: validators.size,
713
+ indices: prettyPrintIndices(allIndices),
714
+ });
715
+
716
+ // Clear tracking sets for next epoch
717
+ addedValidatorsInEpoch.clear();
718
+ removedValidatorsInEpoch.clear();
719
+
681
720
  // Compute summaries of previous epoch attestation performance
682
721
  const prevEpoch = computeEpochAtSlot(headState.slot) - 1;
683
722
 
@@ -736,6 +775,13 @@ export function createValidatorMonitor(
736
775
  scrapeMetrics(slotClock) {
737
776
  validatorMonitorMetrics?.validatorsConnected.set(validators.size);
738
777
 
778
+ // Update static metric with connected validator indices
779
+ if (validatorMonitorMetrics?.validatorsConnectedIndices) {
780
+ validatorMonitorMetrics.validatorsConnectedIndices.reset();
781
+ const allIndices = Array.from(validators.keys()).sort((a, b) => a - b);
782
+ validatorMonitorMetrics.validatorsConnectedIndices.set({indices: prettyPrintIndices(allIndices)}, 1);
783
+ }
784
+
739
785
  const epoch = computeEpochAtSlot(slotClock);
740
786
  const slotInEpoch = slotClock % SLOTS_PER_EPOCH;
741
787
 
@@ -815,6 +861,10 @@ export function createValidatorMonitor(
815
861
  validatorMonitorMetrics?.prevEpochSyncCommitteeHits.set(prevEpochSyncCommitteeHits);
816
862
  validatorMonitorMetrics?.prevEpochSyncCommitteeMisses.set(prevEpochSyncCommitteeMisses);
817
863
  },
864
+
865
+ getMonitoredValidatorIndices() {
866
+ return Array.from(validators.keys()).sort((a, b) => a - b);
867
+ },
818
868
  };
819
869
 
820
870
  // Register a single collect() function to run all validatorMonitor metrics
@@ -1098,17 +1148,21 @@ function createValidatorMonitorMetrics(register: RegistryMetricCreator) {
1098
1148
  help: "Count of validators that are specifically monitored by this beacon node",
1099
1149
  }),
1100
1150
 
1151
+ validatorsConnectedIndices: register.gauge<{indices: string}>({
1152
+ name: "validator_monitor_indices",
1153
+ help: "Static metric with connected validator indices as label, value is always 1",
1154
+ labelNames: ["indices"],
1155
+ }),
1156
+
1101
1157
  validatorsInSyncCommittee: register.gauge({
1102
1158
  name: "validator_monitor_validators_in_sync_committee",
1103
1159
  help: "Count of validators monitored by this beacon node that are part of sync committee",
1104
1160
  }),
1105
1161
 
1106
1162
  // Validator Monitor Metrics (per-epoch summaries)
1107
- // Only track prevEpochOnChainBalance per index
1108
- prevEpochOnChainBalance: register.gauge<{index: number}>({
1163
+ prevEpochOnChainBalance: register.gauge({
1109
1164
  name: "validator_monitor_prev_epoch_on_chain_balance",
1110
- help: "Balance of validator after an epoch",
1111
- labelNames: ["index"],
1165
+ help: "Total balance of all monitored validators after an epoch",
1112
1166
  }),
1113
1167
  prevEpochOnChainAttesterHit: register.gauge({
1114
1168
  name: "validator_monitor_prev_epoch_on_chain_attester_hit_total",
@@ -9,7 +9,7 @@ import {Bucket, getBucketNameByValue} from "../buckets.js";
9
9
  export class CheckpointStateRepository extends BinaryRepository<Uint8Array> {
10
10
  constructor(config: ChainForkConfig, db: Db) {
11
11
  const bucket = Bucket.allForks_checkpointState;
12
- // biome-ignore lint/suspicious/noExplicitAny: The type is complex to specify a proper override
12
+
13
13
  super(config, db, bucket, getBucketNameByValue(bucket));
14
14
  }
15
15
  }
@@ -212,6 +212,31 @@ export function createLodestarMetrics(
212
212
  }),
213
213
  },
214
214
 
215
+ unfinalizedBlockWritesQueue: {
216
+ length: register.gauge({
217
+ name: "lodestar_unfinalized_block_writes_queue_length",
218
+ help: "Count of total unfinalized block writes queue length",
219
+ }),
220
+ droppedJobs: register.gauge({
221
+ name: "lodestar_unfinalized_block_writes_queue_dropped_jobs_total",
222
+ help: "Count of total unfinalized block writes queue dropped jobs",
223
+ }),
224
+ jobTime: register.histogram({
225
+ name: "lodestar_unfinalized_block_writes_queue_job_time_seconds",
226
+ help: "Time to process unfinalized block writes queue job in seconds",
227
+ buckets: [0.01, 0.1, 1, 4, 12],
228
+ }),
229
+ jobWaitTime: register.histogram({
230
+ name: "lodestar_unfinalized_block_writes_queue_job_wait_time_seconds",
231
+ help: "Time from job added to the unfinalized block writes queue to starting in seconds",
232
+ buckets: [0.01, 0.1, 1, 4, 12],
233
+ }),
234
+ concurrency: register.gauge({
235
+ name: "lodestar_unfinalized_block_writes_queue_concurrency",
236
+ help: "Current concurrency of unfinalized block writes queue",
237
+ }),
238
+ },
239
+
215
240
  engineHttpProcessorQueue: {
216
241
  length: register.gauge({
217
242
  name: "lodestar_engine_http_processor_queue_length",
@@ -1116,6 +1141,46 @@ export function createLodestarMetrics(
1116
1141
  help: "Total number of empty returns in SyncContributionAndProofPool.getAggregate(slot, root)",
1117
1142
  }),
1118
1143
  },
1144
+ payloadAttestationPool: {
1145
+ size: register.gauge({
1146
+ name: "lodestar_oppool_payload_attestation_pool_size",
1147
+ help: "Current size of the PayloadAttestationPool = total payload attestations unique by data and slot",
1148
+ }),
1149
+ payloadAttDataPerSlot: register.gauge({
1150
+ name: "lodestar_oppool_payload_attestation_pool_payload_attestation_data_per_slot_total",
1151
+ help: "Total number of payload attestation data per slot in PayloadAttestationPool",
1152
+ }),
1153
+ gossipInsertOutcome: register.counter<{insertOutcome: InsertOutcome}>({
1154
+ name: "lodestar_oppool_payload_attestation_pool_gossip_insert_outcome_total",
1155
+ help: "Total number of InsertOutcome as a result of adding a payload attestation message from gossip to the pool",
1156
+ labelNames: ["insertOutcome"],
1157
+ }),
1158
+ apiInsertOutcome: register.counter<{insertOutcome: InsertOutcome}>({
1159
+ name: "lodestar_oppool_payload_attestation_pool_api_insert_outcome_total",
1160
+ help: "Total number of InsertOutcome as a result of adding a payload attestation message from api to the pool",
1161
+ labelNames: ["insertOutcome"],
1162
+ }),
1163
+ getPayloadAttestationsCacheMisses: register.counter({
1164
+ name: "lodestar_oppool_payload_attestation_pool_get_payload_attestations_cache_misses_total",
1165
+ help: "Total number of getPayloadAttestationsForBlock calls with no aggregate for slot and payload attestation data root",
1166
+ }),
1167
+ },
1168
+ executionPayloadBidPool: {
1169
+ size: register.gauge({
1170
+ name: "lodestar_oppool_execution_payload_bid_pool_size",
1171
+ help: "Current size of the ExecutionPayloadBidPool = total number of bids",
1172
+ }),
1173
+ gossipInsertOutcome: register.counter<{insertOutcome: InsertOutcome}>({
1174
+ name: "lodestar_oppool_execution_payload_bid_pool_gossip_insert_outcome_total",
1175
+ help: "Total number of InsertOutcome as a result of adding an execution payload bid from gossip to the pool",
1176
+ labelNames: ["insertOutcome"],
1177
+ }),
1178
+ apiInsertOutcome: register.counter<{insertOutcome: InsertOutcome}>({
1179
+ name: "lodestar_oppool_execution_payload_bid_pool_api_insert_outcome_total",
1180
+ help: "Total number of InsertOutcome as a result of adding an execution payload bid from api to the pool",
1181
+ labelNames: ["insertOutcome"],
1182
+ }),
1183
+ },
1119
1184
  },
1120
1185
 
1121
1186
  chain: {
@@ -454,6 +454,18 @@ export class NetworkCore implements INetworkCore {
454
454
  await this.libp2p.hangUp(peerIdFromString(peerIdStr));
455
455
  }
456
456
 
457
+ async addDirectPeer(peer: routes.lodestar.DirectPeer): Promise<string | null> {
458
+ return this.gossip.addDirectPeer(peer);
459
+ }
460
+
461
+ async removeDirectPeer(peerIdStr: PeerIdStr): Promise<boolean> {
462
+ return this.gossip.removeDirectPeer(peerIdStr);
463
+ }
464
+
465
+ async getDirectPeers(): Promise<string[]> {
466
+ return this.gossip.getDirectPeers();
467
+ }
468
+
457
469
  private _dumpPeer(peerIdStr: string, connections: Connection[]): routes.lodestar.LodestarNodePeer {
458
470
  const peerData = this.peersData.connectedPeers.get(peerIdStr);
459
471
  const fork = this.config.getForkName(this.clock.currentSlot);
@@ -153,6 +153,9 @@ const libp2pWorkerApi: NetworkWorkerApi = {
153
153
  getConnectedPeerCount: () => core.getConnectedPeerCount(),
154
154
  connectToPeer: (peer, multiaddr) => core.connectToPeer(peer, multiaddr),
155
155
  disconnectPeer: (peer) => core.disconnectPeer(peer),
156
+ addDirectPeer: (peer) => core.addDirectPeer(peer),
157
+ removeDirectPeer: (peerId) => core.removeDirectPeer(peerId),
158
+ getDirectPeers: () => core.getDirectPeers(),
156
159
  dumpPeers: () => core.dumpPeers(),
157
160
  dumpPeer: (peerIdStr) => core.dumpPeer(peerIdStr),
158
161
  dumpPeerScoreStats: () => core.dumpPeerScoreStats(),
@@ -247,6 +247,15 @@ export class WorkerNetworkCore implements INetworkCore {
247
247
  disconnectPeer(peer: PeerIdStr): Promise<void> {
248
248
  return this.getApi().disconnectPeer(peer);
249
249
  }
250
+ addDirectPeer(peer: routes.lodestar.DirectPeer): Promise<string | null> {
251
+ return this.getApi().addDirectPeer(peer);
252
+ }
253
+ removeDirectPeer(peerId: PeerIdStr): Promise<boolean> {
254
+ return this.getApi().removeDirectPeer(peerId);
255
+ }
256
+ getDirectPeers(): Promise<string[]> {
257
+ return this.getApi().getDirectPeers();
258
+ }
250
259
  dumpPeers(): Promise<routes.lodestar.LodestarNodePeer[]> {
251
260
  return this.getApi().dumpPeers();
252
261
  }
@@ -30,6 +30,12 @@ export interface INetworkCorePublic {
30
30
  // Debug
31
31
  connectToPeer(peer: PeerIdStr, multiaddr: MultiaddrStr[]): Promise<void>;
32
32
  disconnectPeer(peer: PeerIdStr): Promise<void>;
33
+
34
+ // Direct peers management
35
+ addDirectPeer(peer: routes.lodestar.DirectPeer): Promise<string | null>;
36
+ removeDirectPeer(peerId: PeerIdStr): Promise<boolean>;
37
+ getDirectPeers(): Promise<string[]>;
38
+
33
39
  dumpPeers(): Promise<routes.lodestar.LodestarNodePeer[]>;
34
40
  dumpPeer(peerIdStr: PeerIdStr): Promise<routes.lodestar.LodestarNodePeer | undefined>;
35
41
  dumpPeerScoreStats(): Promise<PeerScoreStats>;
@@ -1,7 +1,11 @@
1
+ import {peerIdFromString} from "@libp2p/peer-id";
2
+ import {multiaddr} from "@multiformats/multiaddr";
3
+ import {ENR} from "@chainsafe/enr";
1
4
  import {GossipSub, GossipsubEvents} from "@chainsafe/libp2p-gossipsub";
2
5
  import {MetricsRegister, TopicLabel, TopicStrToLabel} from "@chainsafe/libp2p-gossipsub/metrics";
3
6
  import {PeerScoreParams} from "@chainsafe/libp2p-gossipsub/score";
4
- import {SignaturePolicy, TopicStr} from "@chainsafe/libp2p-gossipsub/types";
7
+ import {AddrInfo, SignaturePolicy, TopicStr} from "@chainsafe/libp2p-gossipsub/types";
8
+ import {routes} from "@lodestar/api";
5
9
  import {BeaconConfig, ForkBoundary} from "@lodestar/config";
6
10
  import {ATTESTATION_SUBNET_COUNT, SLOTS_PER_EPOCH, SYNC_COMMITTEE_SUBNET_COUNT} from "@lodestar/params";
7
11
  import {SubnetID} from "@lodestar/types";
@@ -55,6 +59,12 @@ export type Eth2GossipsubOpts = {
55
59
  disableFloodPublish?: boolean;
56
60
  skipParamsLog?: boolean;
57
61
  disableLightClientServer?: boolean;
62
+ /**
63
+ * Direct peers for GossipSub - these peers maintain permanent mesh connections without GRAFT/PRUNE.
64
+ * Supports multiaddr strings with peer ID (e.g., "/ip4/192.168.1.1/tcp/9000/p2p/16Uiu2HAmKLhW7...")
65
+ * or ENR strings (e.g., "enr:-IS4QHCYrYZbAKWCBRlAy5zzaDZXJBGkcnh4MHcBFZntXNFrdvJjX04jRzjzCBOo...")
66
+ */
67
+ directPeers?: string[];
58
68
  };
59
69
 
60
70
  export type ForkBoundaryLabel = string;
@@ -78,6 +88,7 @@ export class Eth2Gossipsub extends GossipSub {
78
88
  private readonly logger: Logger;
79
89
  private readonly peersData: PeersData;
80
90
  private readonly events: NetworkEventBus;
91
+ private readonly libp2p: Libp2p;
81
92
 
82
93
  // Internal caches
83
94
  private readonly gossipTopicCache: GossipTopicCache;
@@ -97,6 +108,9 @@ export class Eth2Gossipsub extends GossipSub {
97
108
  );
98
109
  }
99
110
 
111
+ // Parse direct peers from multiaddr strings to AddrInfo objects
112
+ const directPeers = parseDirectPeers(opts.directPeers ?? [], logger);
113
+
100
114
  // Gossipsub parameters defined here:
101
115
  // https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/phase0/p2p-interface.md#the-gossip-domain-gossipsub
102
116
  super(modules.libp2p.services.components, {
@@ -106,6 +120,7 @@ export class Eth2Gossipsub extends GossipSub {
106
120
  Dlo: gossipsubDLow ?? GOSSIP_D_LOW,
107
121
  Dhi: gossipsubDHigh ?? GOSSIP_D_HIGH,
108
122
  Dlazy: 6,
123
+ directPeers,
109
124
  heartbeatInterval: GOSSIPSUB_HEARTBEAT_INTERVAL,
110
125
  fanoutTTL: 60 * 1000,
111
126
  mcacheLength: 6,
@@ -146,6 +161,7 @@ export class Eth2Gossipsub extends GossipSub {
146
161
  this.logger = logger;
147
162
  this.peersData = peersData;
148
163
  this.events = events;
164
+ this.libp2p = modules.libp2p;
149
165
  this.gossipTopicCache = gossipTopicCache;
150
166
 
151
167
  this.addEventListener("gossipsub:message", this.onGossipsubMessage.bind(this));
@@ -328,6 +344,64 @@ export class Eth2Gossipsub extends GossipSub {
328
344
  this.reportMessageValidationResult(data.msgId, data.propagationSource, data.acceptance);
329
345
  });
330
346
  }
347
+
348
+ /**
349
+ * Add a peer as a direct peer at runtime. Accepts multiaddr with peer ID or ENR string.
350
+ * Direct peers maintain permanent mesh connections without GRAFT/PRUNE negotiation.
351
+ */
352
+ async addDirectPeer(peerStr: routes.lodestar.DirectPeer): Promise<string | null> {
353
+ const parsed = parseDirectPeers([peerStr], this.logger);
354
+ if (parsed.length === 0) {
355
+ return null;
356
+ }
357
+
358
+ const {id: peerId, addrs} = parsed[0];
359
+ const peerIdStr = peerId.toString();
360
+
361
+ // Prevent adding self as a direct peer
362
+ if (peerId.equals(this.libp2p.peerId)) {
363
+ this.logger.warn("Cannot add self as a direct peer", {peerId: peerIdStr});
364
+ return null;
365
+ }
366
+
367
+ // Direct peers need addresses to connect - reject if none provided
368
+ if (addrs.length === 0) {
369
+ this.logger.warn("Cannot add direct peer without addresses", {peerId: peerIdStr});
370
+ return null;
371
+ }
372
+
373
+ // Add addresses to peer store first so we can connect
374
+ try {
375
+ await this.libp2p.peerStore.merge(peerId, {multiaddrs: addrs});
376
+ } catch (e) {
377
+ this.logger.warn("Failed to add direct peer addresses to peer store", {peerId: peerIdStr}, e as Error);
378
+ return null;
379
+ }
380
+
381
+ // Add to direct peers set only after addresses are stored
382
+ this.direct.add(peerIdStr);
383
+
384
+ this.logger.info("Added direct peer via API", {peerId: peerIdStr});
385
+ return peerIdStr;
386
+ }
387
+
388
+ /**
389
+ * Remove a peer from direct peers.
390
+ */
391
+ removeDirectPeer(peerIdStr: string): boolean {
392
+ const removed = this.direct.delete(peerIdStr);
393
+ if (removed) {
394
+ this.logger.info("Removed direct peer via API", {peerId: peerIdStr});
395
+ }
396
+ return removed;
397
+ }
398
+
399
+ /**
400
+ * Get list of current direct peer IDs.
401
+ */
402
+ getDirectPeers(): string[] {
403
+ return Array.from(this.direct);
404
+ }
331
405
  }
332
406
 
333
407
  /**
@@ -381,3 +455,75 @@ function getForkBoundaryLabel(boundary: ForkBoundary): ForkBoundaryLabel {
381
455
 
382
456
  return label;
383
457
  }
458
+
459
+ /**
460
+ * Parse direct peer strings into AddrInfo objects for GossipSub.
461
+ * Direct peers maintain permanent mesh connections without GRAFT/PRUNE negotiation.
462
+ *
463
+ * Supported formats:
464
+ * - Multiaddr with peer ID: `/ip4/192.168.1.1/tcp/9000/p2p/16Uiu2HAmKLhW7...`
465
+ * - ENR: `enr:-IS4QHCYrYZbAKWCBRlAy5zzaDZXJBGkcnh4MHcBFZntXNFrdvJjX04jRzjzCBOo...`
466
+ *
467
+ * For multiaddrs, the string must contain a /p2p/ component with the peer ID.
468
+ * For ENRs, the TCP multiaddr and peer ID are extracted from the encoded record.
469
+ */
470
+ export function parseDirectPeers(directPeerStrs: routes.lodestar.DirectPeer[], logger: Logger): AddrInfo[] {
471
+ const directPeers: AddrInfo[] = [];
472
+
473
+ for (const peerStr of directPeerStrs) {
474
+ // Check if this is an ENR (starts with "enr:")
475
+ if (peerStr.startsWith("enr:")) {
476
+ try {
477
+ const enr = ENR.decodeTxt(peerStr);
478
+ const peerId = enr.peerId;
479
+
480
+ // Get TCP multiaddr from ENR
481
+ const multiaddrTCP = enr.getLocationMultiaddr("tcp");
482
+ if (!multiaddrTCP) {
483
+ logger.warn("ENR does not contain TCP multiaddr", {enr: peerStr});
484
+ continue;
485
+ }
486
+
487
+ directPeers.push({
488
+ id: peerId,
489
+ addrs: [multiaddrTCP],
490
+ });
491
+
492
+ logger.info("Added direct peer from ENR", {peerId: peerId.toString(), addr: multiaddrTCP.toString()});
493
+ } catch (e) {
494
+ logger.warn("Failed to parse direct peer ENR", {enr: peerStr}, e as Error);
495
+ }
496
+ } else {
497
+ // Parse as multiaddr
498
+ try {
499
+ const ma = multiaddr(peerStr);
500
+
501
+ const peerIdStr = ma.getPeerId();
502
+ if (!peerIdStr) {
503
+ logger.warn("Direct peer multiaddr must contain /p2p/ component with peer ID", {multiaddr: peerStr});
504
+ continue;
505
+ }
506
+
507
+ try {
508
+ const peerId = peerIdFromString(peerIdStr);
509
+
510
+ // Get the address without the /p2p/ component
511
+ const addr = ma.decapsulate("/p2p/" + peerIdStr);
512
+
513
+ directPeers.push({
514
+ id: peerId,
515
+ addrs: [addr],
516
+ });
517
+
518
+ logger.info("Added direct peer", {peerId: peerIdStr, addr: addr.toString()});
519
+ } catch (e) {
520
+ logger.warn("Invalid peer ID in direct peer multiaddr", {multiaddr: peerStr, peerId: peerIdStr}, e as Error);
521
+ }
522
+ } catch (e) {
523
+ logger.warn("Failed to parse direct peer multiaddr", {multiaddr: peerStr}, e as Error);
524
+ }
525
+ }
526
+ }
527
+
528
+ return directPeers;
529
+ }
@@ -15,6 +15,7 @@ import {
15
15
  capella,
16
16
  deneb,
17
17
  fulu,
18
+ gloas,
18
19
  phase0,
19
20
  } from "@lodestar/types";
20
21
  import {Logger} from "@lodestar/utils";
@@ -37,6 +38,9 @@ export enum GossipType {
37
38
  light_client_finality_update = "light_client_finality_update",
38
39
  light_client_optimistic_update = "light_client_optimistic_update",
39
40
  bls_to_execution_change = "bls_to_execution_change",
41
+ execution_payload = "execution_payload",
42
+ payload_attestation_message = "payload_attestation_message",
43
+ execution_payload_bid = "execution_payload_bid",
40
44
  }
41
45
 
42
46
  export type SequentialGossipType = Exclude<GossipType, GossipType.beacon_attestation>;
@@ -71,6 +75,9 @@ export type GossipTopicTypeMap = {
71
75
  [GossipType.light_client_finality_update]: {type: GossipType.light_client_finality_update};
72
76
  [GossipType.light_client_optimistic_update]: {type: GossipType.light_client_optimistic_update};
73
77
  [GossipType.bls_to_execution_change]: {type: GossipType.bls_to_execution_change};
78
+ [GossipType.execution_payload]: {type: GossipType.execution_payload};
79
+ [GossipType.payload_attestation_message]: {type: GossipType.payload_attestation_message};
80
+ [GossipType.execution_payload_bid]: {type: GossipType.execution_payload_bid};
74
81
  };
75
82
 
76
83
  export type GossipTopicMap = {
@@ -100,6 +107,9 @@ export type GossipTypeMap = {
100
107
  [GossipType.light_client_finality_update]: LightClientFinalityUpdate;
101
108
  [GossipType.light_client_optimistic_update]: LightClientOptimisticUpdate;
102
109
  [GossipType.bls_to_execution_change]: capella.SignedBLSToExecutionChange;
110
+ [GossipType.execution_payload]: gloas.SignedExecutionPayloadEnvelope;
111
+ [GossipType.payload_attestation_message]: gloas.PayloadAttestationMessage;
112
+ [GossipType.execution_payload_bid]: gloas.SignedExecutionPayloadBid;
103
113
  };
104
114
 
105
115
  export type GossipFnByType = {
@@ -124,6 +134,13 @@ export type GossipFnByType = {
124
134
  [GossipType.bls_to_execution_change]: (
125
135
  blsToExecutionChange: capella.SignedBLSToExecutionChange
126
136
  ) => Promise<void> | void;
137
+ [GossipType.execution_payload]: (
138
+ executionPayloadEnvelope: gloas.SignedExecutionPayloadEnvelope
139
+ ) => Promise<void> | void;
140
+ [GossipType.payload_attestation_message]: (
141
+ payloadAttestationMessage: gloas.PayloadAttestationMessage
142
+ ) => Promise<void> | void;
143
+ [GossipType.execution_payload_bid]: (executionPayloadBid: gloas.SignedExecutionPayloadBid) => Promise<void> | void;
127
144
  };
128
145
 
129
146
  export type GossipFn = GossipFnByType[keyof GossipFnByType];
@@ -5,7 +5,7 @@ import {
5
5
  defaultTopicScoreParams,
6
6
  } from "@chainsafe/libp2p-gossipsub/score";
7
7
  import {BeaconConfig} from "@lodestar/config";
8
- import {ATTESTATION_SUBNET_COUNT, SLOTS_PER_EPOCH, TARGET_AGGREGATORS_PER_COMMITTEE} from "@lodestar/params";
8
+ import {ATTESTATION_SUBNET_COUNT, PTC_SIZE, SLOTS_PER_EPOCH, TARGET_AGGREGATORS_PER_COMMITTEE} from "@lodestar/params";
9
9
  import {computeCommitteeCount} from "@lodestar/state-transition";
10
10
  import {getActiveForkBoundaries} from "../forks.js";
11
11
  import {Eth2Context} from "./gossipsub.js";
@@ -24,6 +24,9 @@ const VOLUNTARY_EXIT_WEIGHT = 0.05;
24
24
  const PROPOSER_SLASHING_WEIGHT = 0.05;
25
25
  const ATTESTER_SLASHING_WEIGHT = 0.05;
26
26
  const BLS_TO_EXECUTION_CHANGE_WEIGHT = 0.05;
27
+ const EXECUTION_PAYLOAD_WEIGHT = 0.5;
28
+ const PAYLOAD_ATTESTATION_WEIGHT = 0.05;
29
+ const EXECUTION_PAYLOAD_BID_WEIGHT = 0.05;
27
30
 
28
31
  const beaconAttestationSubnetWeight = 1 / ATTESTATION_SUBNET_COUNT;
29
32
  const maxPositiveScore =
@@ -34,7 +37,10 @@ const maxPositiveScore =
34
37
  VOLUNTARY_EXIT_WEIGHT +
35
38
  PROPOSER_SLASHING_WEIGHT +
36
39
  ATTESTER_SLASHING_WEIGHT +
37
- BLS_TO_EXECUTION_CHANGE_WEIGHT);
40
+ BLS_TO_EXECUTION_CHANGE_WEIGHT +
41
+ EXECUTION_PAYLOAD_WEIGHT +
42
+ PAYLOAD_ATTESTATION_WEIGHT +
43
+ EXECUTION_PAYLOAD_BID_WEIGHT);
38
44
 
39
45
  /**
40
46
  * The following params is implemented by Lighthouse at
@@ -172,6 +178,26 @@ function getAllTopicsScoreParams(
172
178
  expectedMessageRate: 1 / 5 / SLOTS_PER_EPOCH,
173
179
  firstMessageDecayTime: epochDurationMs * 100,
174
180
  });
181
+ topicsParams[
182
+ stringifyGossipTopic(config, {
183
+ type: GossipType.payload_attestation_message,
184
+ boundary,
185
+ })
186
+ ] = getTopicScoreParams(config, precomputedParams, {
187
+ topicWeight: PAYLOAD_ATTESTATION_WEIGHT,
188
+ expectedMessageRate: PTC_SIZE,
189
+ firstMessageDecayTime: epochDurationMs * 100,
190
+ });
191
+ topicsParams[
192
+ stringifyGossipTopic(config, {
193
+ type: GossipType.execution_payload_bid,
194
+ boundary,
195
+ })
196
+ ] = getTopicScoreParams(config, precomputedParams, {
197
+ topicWeight: EXECUTION_PAYLOAD_BID_WEIGHT,
198
+ expectedMessageRate: 1024, // TODO GLOAS: Need an estimate for this
199
+ firstMessageDecayTime: epochDurationMs * 100,
200
+ });
175
201
 
176
202
  // other topics
177
203
  topicsParams[
@@ -190,6 +216,22 @@ function getAllTopicsScoreParams(
190
216
  currentSlot: eth2Context.currentSlot,
191
217
  },
192
218
  });
219
+ topicsParams[
220
+ stringifyGossipTopic(config, {
221
+ type: GossipType.execution_payload,
222
+ boundary,
223
+ })
224
+ ] = getTopicScoreParams(config, precomputedParams, {
225
+ topicWeight: EXECUTION_PAYLOAD_WEIGHT,
226
+ expectedMessageRate: 1,
227
+ firstMessageDecayTime: epochDurationMs * 20,
228
+ meshMessageInfo: {
229
+ decaySlots: SLOTS_PER_EPOCH * 5,
230
+ capFactor: 3,
231
+ activationWindow: epochDurationMs,
232
+ currentSlot: eth2Context.currentSlot,
233
+ },
234
+ });
193
235
 
194
236
  const activeValidatorCount = eth2Context.activeValidatorCount;
195
237
  const {aggregatorsPerslot, committeesPerSlot} = expectedAggregatorCountPerSlot(activeValidatorCount);