@lodestar/beacon-node 1.40.0-dev.63c5c3e7f7 → 1.40.0-dev.6cfc0a8631

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 (313) 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 +10 -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/chain/ColumnReconstructionTracker.d.ts +2 -0
  10. package/lib/chain/ColumnReconstructionTracker.d.ts.map +1 -1
  11. package/lib/chain/ColumnReconstructionTracker.js +7 -3
  12. package/lib/chain/ColumnReconstructionTracker.js.map +1 -1
  13. package/lib/chain/blocks/blockInput/blockInput.d.ts +28 -0
  14. package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
  15. package/lib/chain/blocks/blockInput/blockInput.js +36 -1
  16. package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
  17. package/lib/chain/blocks/importBlock.js +1 -1
  18. package/lib/chain/blocks/importBlock.js.map +1 -1
  19. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  20. package/lib/chain/blocks/verifyBlock.js +1 -1
  21. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  22. package/lib/chain/blocks/verifyBlocksSignatures.d.ts +2 -2
  23. package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
  24. package/lib/chain/blocks/verifyBlocksSignatures.js +2 -2
  25. package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
  26. package/lib/chain/blocks/writeBlockInputToDb.d.ts.map +1 -1
  27. package/lib/chain/blocks/writeBlockInputToDb.js +8 -0
  28. package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
  29. package/lib/chain/bls/multithread/index.d.ts +3 -1
  30. package/lib/chain/bls/multithread/index.d.ts.map +1 -1
  31. package/lib/chain/bls/multithread/index.js +5 -3
  32. package/lib/chain/bls/multithread/index.js.map +1 -1
  33. package/lib/chain/bls/multithread/jobItem.d.ts +2 -2
  34. package/lib/chain/bls/multithread/jobItem.d.ts.map +1 -1
  35. package/lib/chain/bls/multithread/jobItem.js +2 -2
  36. package/lib/chain/bls/multithread/jobItem.js.map +1 -1
  37. package/lib/chain/bls/singleThread.d.ts +4 -2
  38. package/lib/chain/bls/singleThread.d.ts.map +1 -1
  39. package/lib/chain/bls/singleThread.js +4 -2
  40. package/lib/chain/bls/singleThread.js.map +1 -1
  41. package/lib/chain/bls/utils.d.ts +2 -2
  42. package/lib/chain/bls/utils.d.ts.map +1 -1
  43. package/lib/chain/bls/utils.js +9 -6
  44. package/lib/chain/bls/utils.js.map +1 -1
  45. package/lib/chain/chain.d.ts +8 -3
  46. package/lib/chain/chain.d.ts.map +1 -1
  47. package/lib/chain/chain.js +39 -34
  48. package/lib/chain/chain.js.map +1 -1
  49. package/lib/chain/errors/attestationError.d.ts +14 -1
  50. package/lib/chain/errors/attestationError.d.ts.map +1 -1
  51. package/lib/chain/errors/attestationError.js +8 -0
  52. package/lib/chain/errors/attestationError.js.map +1 -1
  53. package/lib/chain/errors/executionPayloadBid.d.ts +48 -0
  54. package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -0
  55. package/lib/chain/errors/executionPayloadBid.js +15 -0
  56. package/lib/chain/errors/executionPayloadBid.js.map +1 -0
  57. package/lib/chain/errors/executionPayloadEnvelope.d.ts +48 -0
  58. package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -0
  59. package/lib/chain/errors/executionPayloadEnvelope.js +16 -0
  60. package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -0
  61. package/lib/chain/errors/index.d.ts +3 -0
  62. package/lib/chain/errors/index.d.ts.map +1 -1
  63. package/lib/chain/errors/index.js +3 -0
  64. package/lib/chain/errors/index.js.map +1 -1
  65. package/lib/chain/errors/payloadAttestation.d.ts +34 -0
  66. package/lib/chain/errors/payloadAttestation.d.ts.map +1 -0
  67. package/lib/chain/errors/payloadAttestation.js +13 -0
  68. package/lib/chain/errors/payloadAttestation.js.map +1 -0
  69. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  70. package/lib/chain/forkChoice/index.js +18 -0
  71. package/lib/chain/forkChoice/index.js.map +1 -1
  72. package/lib/chain/interface.d.ts +7 -2
  73. package/lib/chain/interface.d.ts.map +1 -1
  74. package/lib/chain/interface.js.map +1 -1
  75. package/lib/chain/opPools/executionPayloadBidPool.d.ts +21 -0
  76. package/lib/chain/opPools/executionPayloadBidPool.d.ts.map +1 -0
  77. package/lib/chain/opPools/executionPayloadBidPool.js +57 -0
  78. package/lib/chain/opPools/executionPayloadBidPool.js.map +1 -0
  79. package/lib/chain/opPools/index.d.ts +2 -0
  80. package/lib/chain/opPools/index.d.ts.map +1 -1
  81. package/lib/chain/opPools/index.js +2 -0
  82. package/lib/chain/opPools/index.js.map +1 -1
  83. package/lib/chain/opPools/payloadAttestationPool.d.ts +24 -0
  84. package/lib/chain/opPools/payloadAttestationPool.d.ts.map +1 -0
  85. package/lib/chain/opPools/payloadAttestationPool.js +109 -0
  86. package/lib/chain/opPools/payloadAttestationPool.js.map +1 -0
  87. package/lib/chain/options.d.ts +0 -1
  88. package/lib/chain/options.d.ts.map +1 -1
  89. package/lib/chain/options.js +0 -1
  90. package/lib/chain/options.js.map +1 -1
  91. package/lib/chain/regen/interface.d.ts +2 -1
  92. package/lib/chain/regen/interface.d.ts.map +1 -1
  93. package/lib/chain/regen/interface.js +1 -0
  94. package/lib/chain/regen/interface.js.map +1 -1
  95. package/lib/chain/regen/queued.d.ts +1 -1
  96. package/lib/chain/regen/queued.d.ts.map +1 -1
  97. package/lib/chain/regen/queued.js.map +1 -1
  98. package/lib/chain/regen/regen.d.ts +2 -0
  99. package/lib/chain/regen/regen.d.ts.map +1 -1
  100. package/lib/chain/regen/regen.js +4 -1
  101. package/lib/chain/regen/regen.js.map +1 -1
  102. package/lib/chain/seenCache/index.d.ts +3 -1
  103. package/lib/chain/seenCache/index.d.ts.map +1 -1
  104. package/lib/chain/seenCache/index.js +3 -1
  105. package/lib/chain/seenCache/index.js.map +1 -1
  106. package/lib/chain/seenCache/seenAttesters.d.ts +5 -0
  107. package/lib/chain/seenCache/seenAttesters.d.ts.map +1 -1
  108. package/lib/chain/seenCache/seenAttesters.js +5 -0
  109. package/lib/chain/seenCache/seenAttesters.js.map +1 -1
  110. package/lib/chain/seenCache/seenExecutionPayloadBids.d.ts +12 -0
  111. package/lib/chain/seenCache/seenExecutionPayloadBids.d.ts.map +1 -0
  112. package/lib/chain/seenCache/seenExecutionPayloadBids.js +30 -0
  113. package/lib/chain/seenCache/seenExecutionPayloadBids.js.map +1 -0
  114. package/lib/chain/seenCache/seenExecutionPayloadEnvelope.d.ts +15 -0
  115. package/lib/chain/seenCache/seenExecutionPayloadEnvelope.d.ts.map +1 -0
  116. package/lib/chain/seenCache/seenExecutionPayloadEnvelope.js +28 -0
  117. package/lib/chain/seenCache/seenExecutionPayloadEnvelope.js.map +1 -0
  118. package/lib/chain/seenCache/seenGossipBlockInput.js +1 -1
  119. package/lib/chain/stateCache/index.d.ts +0 -2
  120. package/lib/chain/stateCache/index.d.ts.map +1 -1
  121. package/lib/chain/stateCache/index.js +0 -2
  122. package/lib/chain/stateCache/index.js.map +1 -1
  123. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +2 -1
  124. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  125. package/lib/chain/stateCache/persistentCheckpointsCache.js +3 -0
  126. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  127. package/lib/chain/validation/aggregateAndProof.js +35 -14
  128. package/lib/chain/validation/aggregateAndProof.js.map +1 -1
  129. package/lib/chain/validation/attestation.d.ts +2 -2
  130. package/lib/chain/validation/attestation.d.ts.map +1 -1
  131. package/lib/chain/validation/attestation.js +27 -8
  132. package/lib/chain/validation/attestation.js.map +1 -1
  133. package/lib/chain/validation/attesterSlashing.d.ts.map +1 -1
  134. package/lib/chain/validation/attesterSlashing.js +1 -1
  135. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  136. package/lib/chain/validation/blobSidecar.d.ts.map +1 -1
  137. package/lib/chain/validation/blobSidecar.js +2 -2
  138. package/lib/chain/validation/blobSidecar.js.map +1 -1
  139. package/lib/chain/validation/block.d.ts.map +1 -1
  140. package/lib/chain/validation/block.js +6 -6
  141. package/lib/chain/validation/block.js.map +1 -1
  142. package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
  143. package/lib/chain/validation/dataColumnSidecar.js +2 -2
  144. package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
  145. package/lib/chain/validation/executionPayloadBid.d.ts +5 -0
  146. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -0
  147. package/lib/chain/validation/executionPayloadBid.js +104 -0
  148. package/lib/chain/validation/executionPayloadBid.js.map +1 -0
  149. package/lib/chain/validation/executionPayloadEnvelope.d.ts +5 -0
  150. package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -0
  151. package/lib/chain/validation/executionPayloadEnvelope.js +89 -0
  152. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -0
  153. package/lib/chain/validation/payloadAttestationMessage.d.ts +9 -0
  154. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -0
  155. package/lib/chain/validation/payloadAttestationMessage.js +72 -0
  156. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -0
  157. package/lib/chain/validation/proposerSlashing.js +1 -1
  158. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  159. package/lib/chain/validation/signatureSets/aggregateAndProof.d.ts +2 -3
  160. package/lib/chain/validation/signatureSets/aggregateAndProof.d.ts.map +1 -1
  161. package/lib/chain/validation/signatureSets/aggregateAndProof.js +8 -3
  162. package/lib/chain/validation/signatureSets/aggregateAndProof.js.map +1 -1
  163. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts +2 -2
  164. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts.map +1 -1
  165. package/lib/chain/validation/signatureSets/contributionAndProof.js +3 -3
  166. package/lib/chain/validation/signatureSets/contributionAndProof.js.map +1 -1
  167. package/lib/chain/validation/signatureSets/selectionProof.d.ts +2 -3
  168. package/lib/chain/validation/signatureSets/selectionProof.d.ts.map +1 -1
  169. package/lib/chain/validation/signatureSets/selectionProof.js +8 -3
  170. package/lib/chain/validation/signatureSets/selectionProof.js.map +1 -1
  171. package/lib/chain/validation/signatureSets/syncCommittee.d.ts +2 -2
  172. package/lib/chain/validation/signatureSets/syncCommittee.d.ts.map +1 -1
  173. package/lib/chain/validation/signatureSets/syncCommittee.js +3 -3
  174. package/lib/chain/validation/signatureSets/syncCommittee.js.map +1 -1
  175. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts +1 -2
  176. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts.map +1 -1
  177. package/lib/chain/validation/signatureSets/syncCommitteeContribution.js +2 -2
  178. package/lib/chain/validation/signatureSets/syncCommitteeContribution.js.map +1 -1
  179. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts +2 -2
  180. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts.map +1 -1
  181. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js +3 -3
  182. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js.map +1 -1
  183. package/lib/chain/validation/syncCommittee.js +1 -1
  184. package/lib/chain/validation/syncCommittee.js.map +1 -1
  185. package/lib/chain/validation/syncCommitteeContributionAndProof.d.ts.map +1 -1
  186. package/lib/chain/validation/syncCommitteeContributionAndProof.js +3 -5
  187. package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
  188. package/lib/chain/validation/voluntaryExit.js +1 -1
  189. package/lib/chain/validation/voluntaryExit.js.map +1 -1
  190. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  191. package/lib/chain/validatorMonitor.js +7 -4
  192. package/lib/chain/validatorMonitor.js.map +1 -1
  193. package/lib/db/repositories/checkpointState.js +0 -1
  194. package/lib/db/repositories/checkpointState.js.map +1 -1
  195. package/lib/metrics/metrics/lodestar.d.ts +20 -0
  196. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  197. package/lib/metrics/metrics/lodestar.js +40 -0
  198. package/lib/metrics/metrics/lodestar.js.map +1 -1
  199. package/lib/network/gossip/gossipsub.d.ts +19 -0
  200. package/lib/network/gossip/gossipsub.d.ts.map +1 -1
  201. package/lib/network/gossip/gossipsub.js +71 -0
  202. package/lib/network/gossip/gossipsub.js.map +1 -1
  203. package/lib/network/gossip/interface.d.ts +20 -2
  204. package/lib/network/gossip/interface.d.ts.map +1 -1
  205. package/lib/network/gossip/interface.js +3 -0
  206. package/lib/network/gossip/interface.js.map +1 -1
  207. package/lib/network/gossip/scoringParameters.d.ts.map +1 -1
  208. package/lib/network/gossip/scoringParameters.js +38 -2
  209. package/lib/network/gossip/scoringParameters.js.map +1 -1
  210. package/lib/network/gossip/topic.d.ts +77 -1
  211. package/lib/network/gossip/topic.d.ts.map +1 -1
  212. package/lib/network/gossip/topic.js +20 -0
  213. package/lib/network/gossip/topic.js.map +1 -1
  214. package/lib/network/options.d.ts +6 -0
  215. package/lib/network/options.d.ts.map +1 -1
  216. package/lib/network/options.js.map +1 -1
  217. package/lib/network/peers/peerManager.d.ts.map +1 -1
  218. package/lib/network/peers/peerManager.js +9 -0
  219. package/lib/network/peers/peerManager.js.map +1 -1
  220. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  221. package/lib/network/processor/gossipHandlers.js +35 -1
  222. package/lib/network/processor/gossipHandlers.js.map +1 -1
  223. package/lib/network/processor/gossipQueues/index.d.ts.map +1 -1
  224. package/lib/network/processor/gossipQueues/index.js +16 -0
  225. package/lib/network/processor/gossipQueues/index.js.map +1 -1
  226. package/lib/network/processor/index.d.ts.map +1 -1
  227. package/lib/network/processor/index.js +3 -0
  228. package/lib/network/processor/index.js.map +1 -1
  229. package/lib/sync/backfill/backfill.js +2 -2
  230. package/lib/sync/backfill/backfill.js.map +1 -1
  231. package/lib/sync/backfill/verify.d.ts +1 -2
  232. package/lib/sync/backfill/verify.d.ts.map +1 -1
  233. package/lib/sync/backfill/verify.js +2 -2
  234. package/lib/sync/backfill/verify.js.map +1 -1
  235. package/package.json +15 -15
  236. package/src/api/impl/beacon/blocks/index.ts +31 -19
  237. package/src/api/impl/lodestar/index.ts +12 -0
  238. package/src/api/impl/validator/index.ts +2 -1
  239. package/src/chain/ColumnReconstructionTracker.ts +8 -4
  240. package/src/chain/blocks/blockInput/blockInput.ts +45 -2
  241. package/src/chain/blocks/importBlock.ts +1 -1
  242. package/src/chain/blocks/verifyBlock.ts +0 -1
  243. package/src/chain/blocks/verifyBlocksSignatures.ts +4 -12
  244. package/src/chain/blocks/writeBlockInputToDb.ts +9 -0
  245. package/src/chain/bls/multithread/index.ts +7 -4
  246. package/src/chain/bls/multithread/jobItem.ts +7 -3
  247. package/src/chain/bls/singleThread.ts +5 -3
  248. package/src/chain/bls/utils.ts +15 -7
  249. package/src/chain/chain.ts +47 -36
  250. package/src/chain/errors/attestationError.ts +11 -1
  251. package/src/chain/errors/executionPayloadBid.ts +35 -0
  252. package/src/chain/errors/executionPayloadEnvelope.ts +34 -0
  253. package/src/chain/errors/index.ts +3 -0
  254. package/src/chain/errors/payloadAttestation.ts +25 -0
  255. package/src/chain/forkChoice/index.ts +19 -0
  256. package/src/chain/interface.ts +16 -1
  257. package/src/chain/opPools/executionPayloadBidPool.ts +77 -0
  258. package/src/chain/opPools/index.ts +2 -0
  259. package/src/chain/opPools/payloadAttestationPool.ts +157 -0
  260. package/src/chain/options.ts +0 -2
  261. package/src/chain/regen/interface.ts +2 -1
  262. package/src/chain/regen/queued.ts +1 -2
  263. package/src/chain/regen/regen.ts +6 -1
  264. package/src/chain/seenCache/index.ts +3 -1
  265. package/src/chain/seenCache/seenAttesters.ts +5 -0
  266. package/src/chain/seenCache/seenExecutionPayloadBids.ts +35 -0
  267. package/src/chain/seenCache/seenExecutionPayloadEnvelope.ts +34 -0
  268. package/src/chain/seenCache/seenGossipBlockInput.ts +1 -1
  269. package/src/chain/stateCache/index.ts +0 -2
  270. package/src/chain/stateCache/persistentCheckpointsCache.ts +6 -2
  271. package/src/chain/validation/aggregateAndProof.ts +36 -14
  272. package/src/chain/validation/attestation.ts +33 -16
  273. package/src/chain/validation/attesterSlashing.ts +1 -6
  274. package/src/chain/validation/blobSidecar.ts +1 -6
  275. package/src/chain/validation/block.ts +6 -6
  276. package/src/chain/validation/dataColumnSidecar.ts +1 -6
  277. package/src/chain/validation/executionPayloadBid.ts +141 -0
  278. package/src/chain/validation/executionPayloadEnvelope.ts +122 -0
  279. package/src/chain/validation/payloadAttestationMessage.ts +109 -0
  280. package/src/chain/validation/proposerSlashing.ts +1 -6
  281. package/src/chain/validation/signatureSets/aggregateAndProof.ts +9 -14
  282. package/src/chain/validation/signatureSets/contributionAndProof.ts +2 -4
  283. package/src/chain/validation/signatureSets/selectionProof.ts +9 -9
  284. package/src/chain/validation/signatureSets/syncCommittee.ts +2 -4
  285. package/src/chain/validation/signatureSets/syncCommitteeContribution.ts +2 -3
  286. package/src/chain/validation/signatureSets/syncCommitteeSelectionProof.ts +2 -4
  287. package/src/chain/validation/syncCommittee.ts +1 -1
  288. package/src/chain/validation/syncCommitteeContributionAndProof.ts +3 -5
  289. package/src/chain/validation/voluntaryExit.ts +1 -1
  290. package/src/chain/validatorMonitor.ts +10 -5
  291. package/src/db/repositories/checkpointState.ts +1 -1
  292. package/src/metrics/metrics/lodestar.ts +40 -0
  293. package/src/network/gossip/gossipsub.ts +86 -1
  294. package/src/network/gossip/interface.ts +17 -0
  295. package/src/network/gossip/scoringParameters.ts +44 -2
  296. package/src/network/gossip/topic.ts +21 -0
  297. package/src/network/options.ts +6 -0
  298. package/src/network/peers/peerManager.ts +11 -0
  299. package/src/network/processor/gossipHandlers.ts +49 -1
  300. package/src/network/processor/gossipQueues/index.ts +16 -0
  301. package/src/network/processor/index.ts +3 -0
  302. package/src/sync/backfill/backfill.ts +2 -2
  303. package/src/sync/backfill/verify.ts +2 -3
  304. package/lib/chain/stateCache/blockStateCacheImpl.d.ts +0 -54
  305. package/lib/chain/stateCache/blockStateCacheImpl.d.ts.map +0 -1
  306. package/lib/chain/stateCache/blockStateCacheImpl.js +0 -130
  307. package/lib/chain/stateCache/blockStateCacheImpl.js.map +0 -1
  308. package/lib/chain/stateCache/inMemoryCheckpointsCache.d.ts +0 -60
  309. package/lib/chain/stateCache/inMemoryCheckpointsCache.d.ts.map +0 -1
  310. package/lib/chain/stateCache/inMemoryCheckpointsCache.js +0 -156
  311. package/lib/chain/stateCache/inMemoryCheckpointsCache.js.map +0 -1
  312. package/src/chain/stateCache/blockStateCacheImpl.ts +0 -149
  313. package/src/chain/stateCache/inMemoryCheckpointsCache.ts +0 -192
@@ -347,6 +347,9 @@ export function createValidatorMonitor(
347
347
  return;
348
348
  }
349
349
 
350
+ // Track total balance instead of per-validator balance to reduce metric cardinality
351
+ let totalBalance = 0;
352
+
350
353
  for (const [index, monitoredValidator] of validators.entries()) {
351
354
  // We subtract two from the state of the epoch that generated these summaries.
352
355
  //
@@ -405,7 +408,7 @@ export function createValidatorMonitor(
405
408
 
406
409
  const balance = balances?.[index];
407
410
  if (balance !== undefined) {
408
- validatorMonitorMetrics?.prevEpochOnChainBalance.set({index}, balance);
411
+ totalBalance += balance;
409
412
  }
410
413
 
411
414
  if (!summary.isPrevSourceAttester || !summary.isPrevTargetAttester || !summary.isPrevHeadAttester) {
@@ -420,6 +423,10 @@ export function createValidatorMonitor(
420
423
  });
421
424
  }
422
425
  }
426
+
427
+ if (balances !== undefined) {
428
+ validatorMonitorMetrics?.prevEpochOnChainBalance.set(totalBalance);
429
+ }
423
430
  },
424
431
 
425
432
  registerBeaconBlock(src, delaySec, block) {
@@ -1153,11 +1160,9 @@ function createValidatorMonitorMetrics(register: RegistryMetricCreator) {
1153
1160
  }),
1154
1161
 
1155
1162
  // Validator Monitor Metrics (per-epoch summaries)
1156
- // Only track prevEpochOnChainBalance per index
1157
- prevEpochOnChainBalance: register.gauge<{index: number}>({
1163
+ prevEpochOnChainBalance: register.gauge({
1158
1164
  name: "validator_monitor_prev_epoch_on_chain_balance",
1159
- help: "Balance of validator after an epoch",
1160
- labelNames: ["index"],
1165
+ help: "Total balance of all monitored validators after an epoch",
1161
1166
  }),
1162
1167
  prevEpochOnChainAttesterHit: register.gauge({
1163
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
  }
@@ -1141,6 +1141,46 @@ export function createLodestarMetrics(
1141
1141
  help: "Total number of empty returns in SyncContributionAndProofPool.getAggregate(slot, root)",
1142
1142
  }),
1143
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
+ },
1144
1184
  },
1145
1185
 
1146
1186
  chain: {
@@ -1,7 +1,10 @@
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";
5
8
  import {BeaconConfig, ForkBoundary} from "@lodestar/config";
6
9
  import {ATTESTATION_SUBNET_COUNT, SLOTS_PER_EPOCH, SYNC_COMMITTEE_SUBNET_COUNT} from "@lodestar/params";
7
10
  import {SubnetID} from "@lodestar/types";
@@ -55,6 +58,12 @@ export type Eth2GossipsubOpts = {
55
58
  disableFloodPublish?: boolean;
56
59
  skipParamsLog?: boolean;
57
60
  disableLightClientServer?: boolean;
61
+ /**
62
+ * Direct peers for GossipSub - these peers maintain permanent mesh connections without GRAFT/PRUNE.
63
+ * Supports multiaddr strings with peer ID (e.g., "/ip4/192.168.1.1/tcp/9000/p2p/16Uiu2HAmKLhW7...")
64
+ * or ENR strings (e.g., "enr:-IS4QHCYrYZbAKWCBRlAy5zzaDZXJBGkcnh4MHcBFZntXNFrdvJjX04jRzjzCBOo...")
65
+ */
66
+ directPeers?: string[];
58
67
  };
59
68
 
60
69
  export type ForkBoundaryLabel = string;
@@ -97,6 +106,9 @@ export class Eth2Gossipsub extends GossipSub {
97
106
  );
98
107
  }
99
108
 
109
+ // Parse direct peers from multiaddr strings to AddrInfo objects
110
+ const directPeers = parseDirectPeers(opts.directPeers ?? [], logger);
111
+
100
112
  // Gossipsub parameters defined here:
101
113
  // https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/phase0/p2p-interface.md#the-gossip-domain-gossipsub
102
114
  super(modules.libp2p.services.components, {
@@ -106,6 +118,7 @@ export class Eth2Gossipsub extends GossipSub {
106
118
  Dlo: gossipsubDLow ?? GOSSIP_D_LOW,
107
119
  Dhi: gossipsubDHigh ?? GOSSIP_D_HIGH,
108
120
  Dlazy: 6,
121
+ directPeers,
109
122
  heartbeatInterval: GOSSIPSUB_HEARTBEAT_INTERVAL,
110
123
  fanoutTTL: 60 * 1000,
111
124
  mcacheLength: 6,
@@ -381,3 +394,75 @@ function getForkBoundaryLabel(boundary: ForkBoundary): ForkBoundaryLabel {
381
394
 
382
395
  return label;
383
396
  }
397
+
398
+ /**
399
+ * Parse direct peer strings into AddrInfo objects for GossipSub.
400
+ * Direct peers maintain permanent mesh connections without GRAFT/PRUNE negotiation.
401
+ *
402
+ * Supported formats:
403
+ * - Multiaddr with peer ID: `/ip4/192.168.1.1/tcp/9000/p2p/16Uiu2HAmKLhW7...`
404
+ * - ENR: `enr:-IS4QHCYrYZbAKWCBRlAy5zzaDZXJBGkcnh4MHcBFZntXNFrdvJjX04jRzjzCBOo...`
405
+ *
406
+ * For multiaddrs, the string must contain a /p2p/ component with the peer ID.
407
+ * For ENRs, the TCP multiaddr and peer ID are extracted from the encoded record.
408
+ */
409
+ export function parseDirectPeers(directPeerStrs: string[], logger: Logger): AddrInfo[] {
410
+ const directPeers: AddrInfo[] = [];
411
+
412
+ for (const peerStr of directPeerStrs) {
413
+ // Check if this is an ENR (starts with "enr:")
414
+ if (peerStr.startsWith("enr:")) {
415
+ try {
416
+ const enr = ENR.decodeTxt(peerStr);
417
+ const peerId = enr.peerId;
418
+
419
+ // Get TCP multiaddr from ENR
420
+ const multiaddrTCP = enr.getLocationMultiaddr("tcp");
421
+ if (!multiaddrTCP) {
422
+ logger.warn("ENR does not contain TCP multiaddr", {enr: peerStr});
423
+ continue;
424
+ }
425
+
426
+ directPeers.push({
427
+ id: peerId,
428
+ addrs: [multiaddrTCP],
429
+ });
430
+
431
+ logger.info("Added direct peer from ENR", {peerId: peerId.toString(), addr: multiaddrTCP.toString()});
432
+ } catch (e) {
433
+ logger.warn("Failed to parse direct peer ENR", {enr: peerStr}, e as Error);
434
+ }
435
+ } else {
436
+ // Parse as multiaddr
437
+ try {
438
+ const ma = multiaddr(peerStr);
439
+
440
+ const peerIdStr = ma.getPeerId();
441
+ if (!peerIdStr) {
442
+ logger.warn("Direct peer multiaddr must contain /p2p/ component with peer ID", {multiaddr: peerStr});
443
+ continue;
444
+ }
445
+
446
+ try {
447
+ const peerId = peerIdFromString(peerIdStr);
448
+
449
+ // Get the address without the /p2p/ component
450
+ const addr = ma.decapsulate("/p2p/" + peerIdStr);
451
+
452
+ directPeers.push({
453
+ id: peerId,
454
+ addrs: [addr],
455
+ });
456
+
457
+ logger.info("Added direct peer", {peerId: peerIdStr, addr: addr.toString()});
458
+ } catch (e) {
459
+ logger.warn("Invalid peer ID in direct peer multiaddr", {multiaddr: peerStr, peerId: peerIdStr}, e as Error);
460
+ }
461
+ } catch (e) {
462
+ logger.warn("Failed to parse direct peer multiaddr", {multiaddr: peerStr}, e as Error);
463
+ }
464
+ }
465
+ }
466
+
467
+ return directPeers;
468
+ }
@@ -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);
@@ -69,6 +69,9 @@ function stringifyGossipTopicType(topic: GossipTopic): string {
69
69
  case GossipType.light_client_finality_update:
70
70
  case GossipType.light_client_optimistic_update:
71
71
  case GossipType.bls_to_execution_change:
72
+ case GossipType.execution_payload:
73
+ case GossipType.payload_attestation_message:
74
+ case GossipType.execution_payload_bid:
72
75
  return topic.type;
73
76
  case GossipType.beacon_attestation:
74
77
  case GossipType.sync_committee:
@@ -114,6 +117,12 @@ export function getGossipSSZType(topic: GossipTopic) {
114
117
  : ssz.altair.LightClientFinalityUpdate;
115
118
  case GossipType.bls_to_execution_change:
116
119
  return ssz.capella.SignedBLSToExecutionChange;
120
+ case GossipType.execution_payload:
121
+ return ssz.gloas.SignedExecutionPayloadEnvelope;
122
+ case GossipType.payload_attestation_message:
123
+ return ssz.gloas.PayloadAttestationMessage;
124
+ case GossipType.execution_payload_bid:
125
+ return ssz.gloas.SignedExecutionPayloadBid;
117
126
  }
118
127
  }
119
128
 
@@ -190,6 +199,9 @@ export function parseGossipTopic(forkDigestContext: ForkDigestContext, topicStr:
190
199
  case GossipType.light_client_finality_update:
191
200
  case GossipType.light_client_optimistic_update:
192
201
  case GossipType.bls_to_execution_change:
202
+ case GossipType.execution_payload:
203
+ case GossipType.payload_attestation_message:
204
+ case GossipType.execution_payload_bid:
193
205
  return {type: gossipTypeStr, boundary, encoding};
194
206
  }
195
207
 
@@ -240,6 +252,12 @@ export function getCoreTopicsAtFork(
240
252
  {type: GossipType.attester_slashing},
241
253
  ];
242
254
 
255
+ if (ForkSeq[fork] >= ForkSeq.gloas) {
256
+ topics.push({type: GossipType.execution_payload});
257
+ topics.push({type: GossipType.payload_attestation_message});
258
+ topics.push({type: GossipType.execution_payload_bid});
259
+ }
260
+
243
261
  // After fulu also track data_column_sidecar_{index}
244
262
  if (ForkSeq[fork] >= ForkSeq.fulu) {
245
263
  topics.push(...getDataColumnSidecarTopics(networkConfig));
@@ -329,4 +347,7 @@ export const gossipTopicIgnoreDuplicatePublishError: Record<GossipType, boolean>
329
347
  [GossipType.light_client_finality_update]: false,
330
348
  [GossipType.light_client_optimistic_update]: false,
331
349
  [GossipType.bls_to_execution_change]: true,
350
+ [GossipType.execution_payload]: true,
351
+ [GossipType.payload_attestation_message]: true,
352
+ [GossipType.execution_payload_bid]: true,
332
353
  };
@@ -15,6 +15,12 @@ export interface NetworkOptions
15
15
  Omit<Eth2GossipsubOpts, "disableLightClientServer"> {
16
16
  localMultiaddrs: string[];
17
17
  bootMultiaddrs?: string[];
18
+ /**
19
+ * Direct peers for GossipSub - these peers maintain permanent mesh connections without GRAFT/PRUNE.
20
+ * Format: multiaddr strings with peer ID, e.g., "/ip4/192.168.1.1/tcp/9000/p2p/16Uiu2HAmKLhW7..."
21
+ * Both peers must configure each other as direct peers for the feature to work properly.
22
+ */
23
+ directPeers?: string[];
18
24
  subscribeAllSubnets?: boolean;
19
25
  mdns?: boolean;
20
26
  connectToDiscv5Bootnodes?: boolean;
@@ -721,6 +721,17 @@ export class PeerManager {
721
721
  // NOTE: libp2p may emit two "peer:connect" events: One for inbound, one for outbound
722
722
  // If that happens, it's okay. Only the "outbound" connection triggers immediate action
723
723
  const now = Date.now();
724
+
725
+ // Ethereum uses secp256k1 for node IDs, reject peers with other key types
726
+ if (remotePeer.type !== "secp256k1") {
727
+ this.logger.debug("Peer does not have secp256k1 key, disconnecting", {
728
+ peer: remotePeerPrettyStr,
729
+ type: remotePeer.type,
730
+ });
731
+ void this.goodbyeAndDisconnect(remotePeer, GoodByeReasonCode.IRRELEVANT_NETWORK);
732
+ return;
733
+ }
734
+
724
735
  const nodeId = computeNodeId(remotePeer);
725
736
  const peerData: PeerData = {
726
737
  lastReceivedMsgUnixTsMs: direction === "outbound" ? 0 : now,
@@ -48,6 +48,8 @@ import {
48
48
  import {IBeaconChain} from "../../chain/interface.js";
49
49
  import {validateGossipBlobSidecar} from "../../chain/validation/blobSidecar.js";
50
50
  import {validateGossipDataColumnSidecar} from "../../chain/validation/dataColumnSidecar.js";
51
+ import {validateGossipExecutionPayloadBid} from "../../chain/validation/executionPayloadBid.js";
52
+ import {validateGossipExecutionPayloadEnvelope} from "../../chain/validation/executionPayloadEnvelope.js";
51
53
  import {
52
54
  AggregateAndProofValidationResult,
53
55
  GossipAttestation,
@@ -64,6 +66,7 @@ import {
64
66
  } from "../../chain/validation/index.js";
65
67
  import {validateLightClientFinalityUpdate} from "../../chain/validation/lightClientFinalityUpdate.js";
66
68
  import {validateLightClientOptimisticUpdate} from "../../chain/validation/lightClientOptimisticUpdate.js";
69
+ import {validateGossipPayloadAttestationMessage} from "../../chain/validation/payloadAttestationMessage.js";
67
70
  import {OpSource} from "../../chain/validatorMonitor.js";
68
71
  import {Metrics} from "../../metrics/index.js";
69
72
  import {kzgCommitmentToVersionedHash} from "../../util/blobs.js";
@@ -576,7 +579,7 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
576
579
  break;
577
580
  }
578
581
 
579
- if (!blockInput.hasAllData()) {
582
+ if (!blockInput.hasComputedAllData()) {
580
583
  // immediately attempt fetch of data columns from execution engine
581
584
  chain.getBlobsTracker.triggerGetBlobs(blockInput);
582
585
  // if we've received at least half of the columns, trigger reconstruction of the rest
@@ -815,6 +818,51 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
815
818
 
816
819
  chain.emitter.emit(routes.events.EventType.blsToExecutionChange, blsToExecutionChange);
817
820
  },
821
+ [GossipType.execution_payload]: async ({
822
+ gossipData,
823
+ topic,
824
+ }: GossipHandlerParamGeneric<GossipType.execution_payload>) => {
825
+ const {serializedData} = gossipData;
826
+ const executionPayloadEnvelope = sszDeserialize(topic, serializedData);
827
+ await validateGossipExecutionPayloadEnvelope(chain, executionPayloadEnvelope);
828
+
829
+ // TODO GLOAS: Handle valid envelope. Need an import flow that calls `processExecutionPayloadEnvelope` and fork choice
830
+ },
831
+ [GossipType.payload_attestation_message]: async ({
832
+ gossipData,
833
+ topic,
834
+ }: GossipHandlerParamGeneric<GossipType.payload_attestation_message>) => {
835
+ const {serializedData} = gossipData;
836
+ const payloadAttestationMessage = sszDeserialize(topic, serializedData);
837
+ const validationResult = await validateGossipPayloadAttestationMessage(chain, payloadAttestationMessage);
838
+
839
+ try {
840
+ const insertOutcome = chain.payloadAttestationPool.add(
841
+ payloadAttestationMessage,
842
+ validationResult.attDataRootHex,
843
+ validationResult.validatorCommitteeIndex
844
+ );
845
+ metrics?.opPool.payloadAttestationPool.gossipInsertOutcome.inc({insertOutcome});
846
+ } catch (e) {
847
+ logger.error("Error adding to payloadAttestation pool", {}, e as Error);
848
+ }
849
+ },
850
+ [GossipType.execution_payload_bid]: async ({
851
+ gossipData,
852
+ topic,
853
+ }: GossipHandlerParamGeneric<GossipType.execution_payload_bid>) => {
854
+ const {serializedData} = gossipData;
855
+ const executionPayloadBid = sszDeserialize(topic, serializedData);
856
+ await validateGossipExecutionPayloadBid(chain, executionPayloadBid);
857
+
858
+ // Handle valid payload bid by storing in a bid pool
859
+ try {
860
+ const insertOutcome = chain.executionPayloadBidPool.add(executionPayloadBid.message);
861
+ metrics?.opPool.executionPayloadBidPool.gossipInsertOutcome.inc({insertOutcome});
862
+ } catch (e) {
863
+ logger.error("Error adding to executionPayloadBid pool", {}, e as Error);
864
+ }
865
+ },
818
866
  };
819
867
  }
820
868
 
@@ -67,6 +67,22 @@ const linearGossipQueueOpts: {
67
67
  type: QueueType.FIFO,
68
68
  dropOpts: {type: DropType.count, count: 1},
69
69
  },
70
+ [GossipType.execution_payload]: {
71
+ maxLength: 1024,
72
+ type: QueueType.FIFO,
73
+ dropOpts: {type: DropType.count, count: 1},
74
+ },
75
+ [GossipType.payload_attestation_message]: {
76
+ maxLength: 1024,
77
+ type: QueueType.FIFO,
78
+ dropOpts: {type: DropType.count, count: 1},
79
+ },
80
+ // TODO GLOAS: It is hard to predict how many bids are there. Put 1024 for max length for now
81
+ [GossipType.execution_payload_bid]: {
82
+ maxLength: 1024,
83
+ type: QueueType.FIFO,
84
+ dropOpts: {type: DropType.count, count: 1},
85
+ },
70
86
  };
71
87
 
72
88
  const indexedGossipQueueOpts: {
@@ -78,6 +78,9 @@ const executeGossipWorkOrderObj: Record<GossipType, WorkOpts> = {
78
78
  [GossipType.sync_committee]: {},
79
79
  [GossipType.light_client_finality_update]: {},
80
80
  [GossipType.light_client_optimistic_update]: {},
81
+ [GossipType.execution_payload]: {bypassQueue: true},
82
+ [GossipType.payload_attestation_message]: {},
83
+ [GossipType.execution_payload_bid]: {},
81
84
  };
82
85
  const executeGossipWorkOrder = Object.keys(executeGossipWorkOrderObj) as (keyof typeof executeGossipWorkOrderObj)[];
83
86
 
@@ -750,7 +750,7 @@ export class BackfillSync extends (EventEmitter as {new (): BackfillSyncEmitter}
750
750
 
751
751
  // GENESIS_SLOT doesn't has valid signature
752
752
  if (anchorBlock.message.slot === GENESIS_SLOT) return;
753
- await verifyBlockProposerSignature(this.chain.config, this.chain.index2pubkey, this.chain.bls, [anchorBlock]);
753
+ await verifyBlockProposerSignature(this.chain.config, this.chain.bls, [anchorBlock]);
754
754
 
755
755
  // We can write to the disk if this is ahead of prevFinalizedCheckpointBlock otherwise
756
756
  // we will need to go make checks on the top of sync loop before writing as it might
@@ -815,7 +815,7 @@ export class BackfillSync extends (EventEmitter as {new (): BackfillSyncEmitter}
815
815
 
816
816
  // If any of the block's proposer signature fail, we can't trust this peer at all
817
817
  if (verifiedBlocks.length > 0) {
818
- await verifyBlockProposerSignature(this.chain.config, this.chain.index2pubkey, this.chain.bls, verifiedBlocks);
818
+ await verifyBlockProposerSignature(this.chain.config, this.chain.bls, verifiedBlocks);
819
819
 
820
820
  // This is bad, like super bad. Abort the backfill
821
821
  if (!nextAnchor)
@@ -1,6 +1,6 @@
1
1
  import {BeaconConfig} from "@lodestar/config";
2
2
  import {GENESIS_SLOT} from "@lodestar/params";
3
- import {ISignatureSet, Index2PubkeyCache, getBlockProposerSignatureSet} from "@lodestar/state-transition";
3
+ import {ISignatureSet, getBlockProposerSignatureSet} from "@lodestar/state-transition";
4
4
  import {Root, SignedBeaconBlock, Slot, ssz} from "@lodestar/types";
5
5
  import {IBlsVerifier} from "../../chain/bls/index.js";
6
6
  import {BackfillSyncError, BackfillSyncErrorCode} from "./errors.js";
@@ -42,14 +42,13 @@ export function verifyBlockSequence(
42
42
 
43
43
  export async function verifyBlockProposerSignature(
44
44
  config: BeaconConfig,
45
- index2pubkey: Index2PubkeyCache,
46
45
  bls: IBlsVerifier,
47
46
  blocks: SignedBeaconBlock[]
48
47
  ): Promise<void> {
49
48
  if (blocks.length === 1 && blocks[0].message.slot === GENESIS_SLOT) return;
50
49
  const signatures = blocks.reduce((sigs: ISignatureSet[], block) => {
51
50
  // genesis block doesn't have valid signature
52
- if (block.message.slot !== GENESIS_SLOT) sigs.push(getBlockProposerSignatureSet(config, index2pubkey, block));
51
+ if (block.message.slot !== GENESIS_SLOT) sigs.push(getBlockProposerSignatureSet(config, block));
53
52
  return sigs;
54
53
  }, []);
55
54
 
@@ -1,54 +0,0 @@
1
- import { routes } from "@lodestar/api";
2
- import { CachedBeaconStateAllForks } from "@lodestar/state-transition";
3
- import { Epoch, RootHex } from "@lodestar/types";
4
- import { Metrics } from "../../metrics/index.js";
5
- import { BlockStateCache } from "./types.js";
6
- /**
7
- * Old implementation of StateCache (used to call `StateContextCache`)
8
- * - Prune per checkpoint so number of states ranges from 96 to 128
9
- * - Keep a separate head state to make sure it is always available
10
- */
11
- export declare class BlockStateCacheImpl implements BlockStateCache {
12
- /**
13
- * Max number of states allowed in the cache
14
- */
15
- readonly maxStates: number;
16
- private readonly cache;
17
- /** Epoch -> Set<blockRoot> */
18
- private readonly epochIndex;
19
- private readonly metrics;
20
- /**
21
- * Strong reference to prevent head state from being pruned.
22
- * null if head state is being regen and not available at the moment.
23
- */
24
- private head;
25
- constructor({ maxStates, metrics }: {
26
- maxStates?: number;
27
- metrics?: Metrics | null;
28
- });
29
- get(rootHex: RootHex): CachedBeaconStateAllForks | null;
30
- add(item: CachedBeaconStateAllForks): void;
31
- setHeadState(item: CachedBeaconStateAllForks | null): void;
32
- /**
33
- * Get a seed state for state reload.
34
- * This is to conform to the api only as this cache is not used in n-historical state.
35
- * See ./fifoBlockStateCache.ts for implementation
36
- */
37
- getSeedState(): CachedBeaconStateAllForks;
38
- clear(): void;
39
- get size(): number;
40
- /**
41
- * TODO make this more robust.
42
- * Without more thought, this currently breaks our assumptions about recent state availablity
43
- */
44
- prune(headStateRootHex: RootHex): void;
45
- /**
46
- * Prune per finalized epoch.
47
- */
48
- deleteAllBeforeEpoch(finalizedEpoch: Epoch): void;
49
- /** ONLY FOR DEBUGGING PURPOSES. For lodestar debug API */
50
- dumpSummary(): routes.lodestar.StateCacheItem[];
51
- getStates(): IterableIterator<CachedBeaconStateAllForks>;
52
- private deleteAllEpochItems;
53
- }
54
- //# sourceMappingURL=blockStateCacheImpl.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"blockStateCacheImpl.d.ts","sourceRoot":"","sources":["../../../src/chain/stateCache/blockStateCacheImpl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,eAAe,CAAC;AACrC,OAAO,EAAC,yBAAyB,EAAC,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAC,KAAK,EAAE,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAE/C,OAAO,EAAC,OAAO,EAAC,MAAM,wBAAwB,CAAC;AAE/C,OAAO,EAAC,eAAe,EAAC,MAAM,YAAY,CAAC;AAI3C;;;;GAIG;AACH,qBAAa,mBAAoB,YAAW,eAAe;IACzD;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgD;IACtE,8BAA8B;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiC;IAC5D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2C;IACnE;;;OAGG;IACH,OAAO,CAAC,IAAI,CAAuE;gBAEvE,EAAC,SAAsB,EAAE,OAAO,EAAC,EAAE;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;KAAC;IAS7F,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,yBAAyB,GAAG,IAAI;IAavD,GAAG,CAAC,IAAI,EAAE,yBAAyB,GAAG,IAAI;IAgB1C,YAAY,CAAC,IAAI,EAAE,yBAAyB,GAAG,IAAI,GAAG,IAAI;IAS1D;;;;OAIG;IACH,YAAY,IAAI,yBAAyB;IAIzC,KAAK,IAAI,IAAI;IAKb,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;OAGG;IACH,KAAK,CAAC,gBAAgB,EAAE,OAAO,GAAG,IAAI;IAgBtC;;OAEG;IACH,oBAAoB,CAAC,cAAc,EAAE,KAAK,GAAG,IAAI;IAQjD,0DAA0D;IAC1D,WAAW,IAAI,MAAM,CAAC,QAAQ,CAAC,cAAc,EAAE;IAU/C,SAAS,IAAI,gBAAgB,CAAC,yBAAyB,CAAC;IAIxD,OAAO,CAAC,mBAAmB;CAM5B"}