@lodestar/beacon-node 1.47.0-dev.0bcaaaebb5 → 1.47.0-dev.101e2c290d

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 (332) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +6 -8
  3. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  4. package/lib/api/impl/beacon/pool/index.d.ts.map +1 -1
  5. package/lib/api/impl/beacon/pool/index.js +25 -2
  6. package/lib/api/impl/beacon/pool/index.js.map +1 -1
  7. package/lib/api/impl/beacon/state/utils.d.ts +2 -1
  8. package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
  9. package/lib/api/impl/beacon/state/utils.js.map +1 -1
  10. package/lib/api/impl/events/index.d.ts +1 -1
  11. package/lib/api/impl/events/index.d.ts.map +1 -1
  12. package/lib/api/impl/events/index.js +12 -3
  13. package/lib/api/impl/events/index.js.map +1 -1
  14. package/lib/api/impl/lodestar/index.js +1 -1
  15. package/lib/api/impl/lodestar/index.js.map +1 -1
  16. package/lib/api/impl/validator/index.js +1 -1
  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 +7 -0
  20. package/lib/api/rest/base.js.map +1 -1
  21. package/lib/chain/archiveStore/archiveStore.js +1 -1
  22. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  23. package/lib/chain/archiveStore/historicalState/metrics.d.ts.map +1 -1
  24. package/lib/chain/archiveStore/historicalState/metrics.js +21 -0
  25. package/lib/chain/archiveStore/historicalState/metrics.js.map +1 -1
  26. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  27. package/lib/chain/blocks/importBlock.js +2 -7
  28. package/lib/chain/blocks/importBlock.js.map +1 -1
  29. package/lib/chain/blocks/importExecutionPayload.d.ts +3 -2
  30. package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
  31. package/lib/chain/blocks/importExecutionPayload.js +11 -9
  32. package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
  33. package/lib/chain/blocks/index.d.ts.map +1 -1
  34. package/lib/chain/blocks/index.js +14 -6
  35. package/lib/chain/blocks/index.js.map +1 -1
  36. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +2 -1
  37. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
  38. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +6 -2
  39. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
  40. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +14 -5
  41. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
  42. package/lib/chain/blocks/payloadEnvelopeInput/types.js +5 -0
  43. package/lib/chain/blocks/payloadEnvelopeInput/types.js.map +1 -1
  44. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
  45. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +22 -12
  46. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
  47. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts +2 -2
  48. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -1
  49. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +2 -2
  50. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -1
  51. package/lib/chain/bls/index.d.ts +1 -1
  52. package/lib/chain/bls/index.d.ts.map +1 -1
  53. package/lib/chain/bls/interface.d.ts +5 -5
  54. package/lib/chain/bls/interface.d.ts.map +1 -1
  55. package/lib/chain/bls/multithread/index.d.ts +5 -11
  56. package/lib/chain/bls/multithread/index.d.ts.map +1 -1
  57. package/lib/chain/bls/multithread/index.js +116 -101
  58. package/lib/chain/bls/multithread/index.js.map +1 -1
  59. package/lib/chain/bls/multithread/jobItem.d.ts +5 -19
  60. package/lib/chain/bls/multithread/jobItem.d.ts.map +1 -1
  61. package/lib/chain/bls/multithread/jobItem.js +10 -65
  62. package/lib/chain/bls/multithread/jobItem.js.map +1 -1
  63. package/lib/chain/bls/multithread/types.d.ts +29 -8
  64. package/lib/chain/bls/multithread/types.d.ts.map +1 -1
  65. package/lib/chain/bls/multithread/types.js +12 -0
  66. package/lib/chain/bls/multithread/types.js.map +1 -1
  67. package/lib/chain/bls/multithread/utils.d.ts +4 -0
  68. package/lib/chain/bls/multithread/utils.d.ts.map +1 -1
  69. package/lib/chain/bls/multithread/utils.js +10 -0
  70. package/lib/chain/bls/multithread/utils.js.map +1 -1
  71. package/lib/chain/bls/multithread/worker.js +49 -23
  72. package/lib/chain/bls/multithread/worker.js.map +1 -1
  73. package/lib/chain/bls/singleThread.d.ts +4 -10
  74. package/lib/chain/bls/singleThread.d.ts.map +1 -1
  75. package/lib/chain/bls/singleThread.js +8 -45
  76. package/lib/chain/bls/singleThread.js.map +1 -1
  77. package/lib/chain/bls/utils.d.ts +4 -4
  78. package/lib/chain/bls/utils.d.ts.map +1 -1
  79. package/lib/chain/bls/utils.js +18 -19
  80. package/lib/chain/bls/utils.js.map +1 -1
  81. package/lib/chain/builderCircuitBreaker.d.ts +6 -5
  82. package/lib/chain/builderCircuitBreaker.d.ts.map +1 -1
  83. package/lib/chain/builderCircuitBreaker.js +28 -15
  84. package/lib/chain/builderCircuitBreaker.js.map +1 -1
  85. package/lib/chain/chain.d.ts +4 -2
  86. package/lib/chain/chain.d.ts.map +1 -1
  87. package/lib/chain/chain.js +16 -6
  88. package/lib/chain/chain.js.map +1 -1
  89. package/lib/chain/errors/blockError.d.ts +1 -0
  90. package/lib/chain/errors/blockError.d.ts.map +1 -1
  91. package/lib/chain/errors/blockError.js +6 -1
  92. package/lib/chain/errors/blockError.js.map +1 -1
  93. package/lib/chain/errors/proposerPreferences.d.ts +6 -0
  94. package/lib/chain/errors/proposerPreferences.d.ts.map +1 -1
  95. package/lib/chain/errors/proposerPreferences.js +1 -0
  96. package/lib/chain/errors/proposerPreferences.js.map +1 -1
  97. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  98. package/lib/chain/forkChoice/index.js +4 -0
  99. package/lib/chain/forkChoice/index.js.map +1 -1
  100. package/lib/chain/interface.d.ts +4 -2
  101. package/lib/chain/interface.d.ts.map +1 -1
  102. package/lib/chain/interface.js.map +1 -1
  103. package/lib/chain/opPools/aggregatedAttestationPool.js +1 -1
  104. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  105. package/lib/chain/opPools/attestationPool.d.ts +1 -1
  106. package/lib/chain/opPools/attestationPool.d.ts.map +1 -1
  107. package/lib/chain/opPools/attestationPool.js +1 -1
  108. package/lib/chain/opPools/attestationPool.js.map +1 -1
  109. package/lib/chain/opPools/deferredVoluntaryExitPool.d.ts +16 -0
  110. package/lib/chain/opPools/deferredVoluntaryExitPool.d.ts.map +1 -0
  111. package/lib/chain/opPools/deferredVoluntaryExitPool.js +57 -0
  112. package/lib/chain/opPools/deferredVoluntaryExitPool.js.map +1 -0
  113. package/lib/chain/opPools/index.d.ts +1 -0
  114. package/lib/chain/opPools/index.d.ts.map +1 -1
  115. package/lib/chain/opPools/index.js +1 -0
  116. package/lib/chain/opPools/index.js.map +1 -1
  117. package/lib/chain/opPools/payloadAttestationPool.js +3 -3
  118. package/lib/chain/opPools/payloadAttestationPool.js.map +1 -1
  119. package/lib/chain/opPools/syncCommitteeMessagePool.js +1 -1
  120. package/lib/chain/opPools/syncCommitteeMessagePool.js.map +1 -1
  121. package/lib/chain/opPools/syncContributionAndProofPool.js +1 -1
  122. package/lib/chain/opPools/syncContributionAndProofPool.js.map +1 -1
  123. package/lib/chain/opPools/utils.d.ts +1 -1
  124. package/lib/chain/opPools/utils.d.ts.map +1 -1
  125. package/lib/chain/opPools/utils.js +1 -1
  126. package/lib/chain/opPools/utils.js.map +1 -1
  127. package/lib/chain/options.d.ts +1 -1
  128. package/lib/chain/options.d.ts.map +1 -1
  129. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  130. package/lib/chain/prepareNextSlot.js +24 -6
  131. package/lib/chain/prepareNextSlot.js.map +1 -1
  132. package/lib/chain/regen/interface.d.ts +4 -2
  133. package/lib/chain/regen/interface.d.ts.map +1 -1
  134. package/lib/chain/regen/interface.js +2 -0
  135. package/lib/chain/regen/interface.js.map +1 -1
  136. package/lib/chain/regen/queued.d.ts +2 -2
  137. package/lib/chain/regen/queued.d.ts.map +1 -1
  138. package/lib/chain/regen/queued.js +5 -5
  139. package/lib/chain/regen/queued.js.map +1 -1
  140. package/lib/chain/seenCache/seenAttesters.d.ts +9 -5
  141. package/lib/chain/seenCache/seenAttesters.d.ts.map +1 -1
  142. package/lib/chain/seenCache/seenAttesters.js +25 -4
  143. package/lib/chain/seenCache/seenAttesters.js.map +1 -1
  144. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +28 -1
  145. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
  146. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +121 -13
  147. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
  148. package/lib/chain/stateCache/fifoBlockStateCache.d.ts +5 -1
  149. package/lib/chain/stateCache/fifoBlockStateCache.d.ts.map +1 -1
  150. package/lib/chain/stateCache/fifoBlockStateCache.js +6 -0
  151. package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
  152. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +47 -5
  153. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  154. package/lib/chain/stateCache/persistentCheckpointsCache.js +117 -7
  155. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  156. package/lib/chain/stateCache/types.d.ts +3 -3
  157. package/lib/chain/stateCache/types.d.ts.map +1 -1
  158. package/lib/chain/validation/attestation.d.ts.map +1 -1
  159. package/lib/chain/validation/attestation.js +1 -4
  160. package/lib/chain/validation/attestation.js.map +1 -1
  161. package/lib/chain/validation/attesterSlashing.d.ts.map +1 -1
  162. package/lib/chain/validation/attesterSlashing.js +1 -1
  163. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  164. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
  165. package/lib/chain/validation/executionPayloadBid.js +1 -2
  166. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  167. package/lib/chain/validation/executionPayloadEnvelope.js +1 -1
  168. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
  169. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
  170. package/lib/chain/validation/payloadAttestationMessage.js +5 -14
  171. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  172. package/lib/chain/validation/proposerPreferences.d.ts +1 -1
  173. package/lib/chain/validation/proposerPreferences.d.ts.map +1 -1
  174. package/lib/chain/validation/proposerPreferences.js +13 -4
  175. package/lib/chain/validation/proposerPreferences.js.map +1 -1
  176. package/lib/chain/validation/proposerSlashing.js +1 -1
  177. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  178. package/lib/chain/validation/voluntaryExit.d.ts +9 -1
  179. package/lib/chain/validation/voluntaryExit.d.ts.map +1 -1
  180. package/lib/chain/validation/voluntaryExit.js +46 -1
  181. package/lib/chain/validation/voluntaryExit.js.map +1 -1
  182. package/lib/execution/builder/http.d.ts +10 -7
  183. package/lib/execution/builder/http.d.ts.map +1 -1
  184. package/lib/execution/builder/http.js +11 -8
  185. package/lib/execution/builder/http.js.map +1 -1
  186. package/lib/metrics/metrics/beacon.d.ts +3 -3
  187. package/lib/metrics/metrics/beacon.d.ts.map +1 -1
  188. package/lib/metrics/metrics/beacon.js +9 -9
  189. package/lib/metrics/metrics/beacon.js.map +1 -1
  190. package/lib/metrics/metrics/lodestar.d.ts +72 -22
  191. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  192. package/lib/metrics/metrics/lodestar.js +130 -52
  193. package/lib/metrics/metrics/lodestar.js.map +1 -1
  194. package/lib/network/gossip/topic.d.ts +13 -0
  195. package/lib/network/gossip/topic.d.ts.map +1 -1
  196. package/lib/network/gossip/topic.js +37 -0
  197. package/lib/network/gossip/topic.js.map +1 -1
  198. package/lib/network/libp2p/index.d.ts.map +1 -1
  199. package/lib/network/libp2p/index.js +10 -2
  200. package/lib/network/libp2p/index.js.map +1 -1
  201. package/lib/network/network.d.ts.map +1 -1
  202. package/lib/network/network.js +22 -43
  203. package/lib/network/network.js.map +1 -1
  204. package/lib/network/processor/constants.d.ts +7 -0
  205. package/lib/network/processor/constants.d.ts.map +1 -0
  206. package/lib/network/processor/constants.js +7 -0
  207. package/lib/network/processor/constants.js.map +1 -0
  208. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  209. package/lib/network/processor/gossipHandlers.js +12 -3
  210. package/lib/network/processor/gossipHandlers.js.map +1 -1
  211. package/lib/network/processor/index.d.ts +3 -0
  212. package/lib/network/processor/index.d.ts.map +1 -1
  213. package/lib/network/processor/index.js +36 -15
  214. package/lib/network/processor/index.js.map +1 -1
  215. package/lib/network/reqresp/score.d.ts.map +1 -1
  216. package/lib/network/reqresp/score.js +5 -11
  217. package/lib/network/reqresp/score.js.map +1 -1
  218. package/lib/network/util.d.ts +0 -1
  219. package/lib/network/util.d.ts.map +1 -1
  220. package/lib/network/util.js +0 -4
  221. package/lib/network/util.js.map +1 -1
  222. package/lib/node/deferredVoluntaryExitPublisher.d.ts +15 -0
  223. package/lib/node/deferredVoluntaryExitPublisher.d.ts.map +1 -0
  224. package/lib/node/deferredVoluntaryExitPublisher.js +38 -0
  225. package/lib/node/deferredVoluntaryExitPublisher.js.map +1 -0
  226. package/lib/node/nodejs.d.ts +2 -1
  227. package/lib/node/nodejs.d.ts.map +1 -1
  228. package/lib/node/nodejs.js +2 -0
  229. package/lib/node/nodejs.js.map +1 -1
  230. package/lib/sync/range/batch.d.ts +23 -5
  231. package/lib/sync/range/batch.d.ts.map +1 -1
  232. package/lib/sync/range/batch.js +61 -22
  233. package/lib/sync/range/batch.js.map +1 -1
  234. package/lib/sync/range/chain.d.ts +2 -1
  235. package/lib/sync/range/chain.d.ts.map +1 -1
  236. package/lib/sync/range/chain.js +23 -10
  237. package/lib/sync/range/chain.js.map +1 -1
  238. package/lib/sync/types.d.ts +32 -0
  239. package/lib/sync/types.d.ts.map +1 -1
  240. package/lib/sync/types.js +33 -0
  241. package/lib/sync/types.js.map +1 -1
  242. package/lib/sync/unknownBlock.d.ts +13 -2
  243. package/lib/sync/unknownBlock.d.ts.map +1 -1
  244. package/lib/sync/unknownBlock.js +218 -63
  245. package/lib/sync/unknownBlock.js.map +1 -1
  246. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  247. package/lib/sync/utils/downloadByRange.js +16 -11
  248. package/lib/sync/utils/downloadByRange.js.map +1 -1
  249. package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
  250. package/lib/sync/utils/downloadByRoot.js +3 -1
  251. package/lib/sync/utils/downloadByRoot.js.map +1 -1
  252. package/package.json +35 -35
  253. package/src/api/impl/beacon/blocks/index.ts +7 -8
  254. package/src/api/impl/beacon/pool/index.ts +27 -2
  255. package/src/api/impl/beacon/state/utils.ts +2 -1
  256. package/src/api/impl/events/index.ts +12 -4
  257. package/src/api/impl/lodestar/index.ts +1 -1
  258. package/src/api/impl/validator/index.ts +1 -1
  259. package/src/api/rest/base.ts +7 -0
  260. package/src/chain/archiveStore/archiveStore.ts +1 -1
  261. package/src/chain/archiveStore/historicalState/metrics.ts +22 -0
  262. package/src/chain/blocks/importBlock.ts +1 -6
  263. package/src/chain/blocks/importExecutionPayload.ts +12 -11
  264. package/src/chain/blocks/index.ts +18 -6
  265. package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +8 -2
  266. package/src/chain/blocks/payloadEnvelopeInput/types.ts +17 -4
  267. package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +25 -16
  268. package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +1 -9
  269. package/src/chain/bls/index.ts +1 -1
  270. package/src/chain/bls/interface.ts +7 -3
  271. package/src/chain/bls/multithread/index.ts +148 -120
  272. package/src/chain/bls/multithread/jobItem.ts +12 -82
  273. package/src/chain/bls/multithread/types.ts +33 -8
  274. package/src/chain/bls/multithread/utils.ts +11 -0
  275. package/src/chain/bls/multithread/worker.ts +85 -27
  276. package/src/chain/bls/singleThread.ts +11 -55
  277. package/src/chain/bls/utils.ts +23 -24
  278. package/src/chain/builderCircuitBreaker.ts +31 -17
  279. package/src/chain/chain.ts +17 -6
  280. package/src/chain/errors/blockError.ts +8 -2
  281. package/src/chain/errors/proposerPreferences.ts +7 -0
  282. package/src/chain/forkChoice/index.ts +4 -0
  283. package/src/chain/interface.ts +4 -1
  284. package/src/chain/opPools/aggregatedAttestationPool.ts +1 -1
  285. package/src/chain/opPools/attestationPool.ts +1 -1
  286. package/src/chain/opPools/deferredVoluntaryExitPool.ts +65 -0
  287. package/src/chain/opPools/index.ts +1 -0
  288. package/src/chain/opPools/payloadAttestationPool.ts +3 -3
  289. package/src/chain/opPools/syncCommitteeMessagePool.ts +1 -1
  290. package/src/chain/opPools/syncContributionAndProofPool.ts +1 -1
  291. package/src/chain/opPools/utils.ts +1 -1
  292. package/src/chain/options.ts +1 -1
  293. package/src/chain/prepareNextSlot.ts +24 -6
  294. package/src/chain/regen/interface.ts +4 -2
  295. package/src/chain/regen/queued.ts +5 -5
  296. package/src/chain/seenCache/seenAttesters.ts +31 -5
  297. package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +143 -14
  298. package/src/chain/stateCache/fifoBlockStateCache.ts +8 -1
  299. package/src/chain/stateCache/persistentCheckpointsCache.ts +133 -8
  300. package/src/chain/stateCache/types.ts +3 -3
  301. package/src/chain/validation/attestation.ts +1 -7
  302. package/src/chain/validation/attesterSlashing.ts +1 -8
  303. package/src/chain/validation/executionPayloadBid.ts +1 -2
  304. package/src/chain/validation/executionPayloadEnvelope.ts +0 -1
  305. package/src/chain/validation/payloadAttestationMessage.ts +6 -17
  306. package/src/chain/validation/proposerPreferences.ts +15 -5
  307. package/src/chain/validation/proposerSlashing.ts +1 -1
  308. package/src/chain/validation/voluntaryExit.ts +59 -2
  309. package/src/execution/builder/http.ts +11 -11
  310. package/src/metrics/metrics/beacon.ts +9 -9
  311. package/src/metrics/metrics/lodestar.ts +142 -57
  312. package/src/network/gossip/topic.ts +38 -0
  313. package/src/network/libp2p/index.ts +11 -2
  314. package/src/network/network.ts +27 -55
  315. package/src/network/processor/constants.ts +6 -0
  316. package/src/network/processor/gossipHandlers.ts +14 -1
  317. package/src/network/processor/index.ts +42 -19
  318. package/src/network/reqresp/score.ts +5 -11
  319. package/src/network/util.ts +0 -5
  320. package/src/node/deferredVoluntaryExitPublisher.ts +54 -0
  321. package/src/node/nodejs.ts +5 -1
  322. package/src/sync/range/batch.ts +83 -28
  323. package/src/sync/range/chain.ts +26 -11
  324. package/src/sync/types.ts +36 -1
  325. package/src/sync/unknownBlock.ts +255 -70
  326. package/src/sync/utils/downloadByRange.ts +21 -12
  327. package/src/sync/utils/downloadByRoot.ts +3 -1
  328. package/lib/chain/bls/maybeBatch.d.ts +0 -12
  329. package/lib/chain/bls/maybeBatch.d.ts.map +0 -1
  330. package/lib/chain/bls/maybeBatch.js +0 -35
  331. package/lib/chain/bls/maybeBatch.js.map +0 -1
  332. package/src/chain/bls/maybeBatch.ts +0 -45
@@ -1,9 +1,9 @@
1
1
  import {IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
2
- import {GENESIS_EPOCH, GENESIS_SLOT, MIN_SEED_LOOKAHEAD, SLOTS_PER_EPOCH} from "@lodestar/params";
2
+ import {GENESIS_EPOCH, GENESIS_SLOT, MIN_SEED_LOOKAHEAD, SLOTS_PER_EPOCH, isForkPostGloas} from "@lodestar/params";
3
3
  import {
4
4
  computeEpochAtSlot,
5
5
  computeStartSlotAtEpoch,
6
- createSingleSignatureSetFromComponents,
6
+ createIndexedSignatureSetFromComponents,
7
7
  getProposerPreferencesSigningRoot,
8
8
  } from "@lodestar/state-transition";
9
9
  import {Epoch, Slot, ValidatorIndex, gloas} from "@lodestar/types";
@@ -13,7 +13,7 @@ import {IBeaconChain} from "../index.js";
13
13
 
14
14
  /**
15
15
  * Validates a gossiped `SignedProposerPreferences` per
16
- * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.13/specs/gloas/p2p-interface.md#new-proposer_preferences
16
+ * https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.14/specs/gloas/p2p-interface.md#new-proposer_preferences
17
17
  */
18
18
  export async function validateGossipProposerPreferences(
19
19
  chain: IBeaconChain,
@@ -24,6 +24,16 @@ export async function validateGossipProposerPreferences(
24
24
  const dependentRootHex = toRootHex(dependentRoot);
25
25
  const proposalEpoch = computeEpochAtSlot(proposalSlot);
26
26
 
27
+ // [IGNORE] The proposal epoch is after the Gloas upgrade
28
+ const proposalFork = chain.config.getForkName(proposalSlot);
29
+ if (!isForkPostGloas(proposalFork)) {
30
+ throw new ProposerPreferencesError(GossipAction.IGNORE, {
31
+ code: ProposerPreferencesErrorCode.PRE_GLOAS_PROPOSAL_SLOT,
32
+ proposalSlot,
33
+ proposalFork,
34
+ });
35
+ }
36
+
27
37
  // [IGNORE] `preferences.proposal_slot` is within the proposer lookahead,
28
38
  // allowing for `MAXIMUM_GOSSIP_CLOCK_DISPARITY`.
29
39
  const currentEpoch = computeEpochAtSlot(chain.clock.currentSlotWithGossipDisparity);
@@ -129,8 +139,8 @@ export async function validateGossipProposerPreferences(
129
139
  }
130
140
 
131
141
  // [REJECT] `signed_proposer_preferences.signature` is valid with respect to the validator's public key.
132
- const signatureSet = createSingleSignatureSetFromComponents(
133
- chain.pubkeyCache.getOrThrow(validatorIndex),
142
+ const signatureSet = createIndexedSignatureSetFromComponents(
143
+ validatorIndex,
134
144
  getProposerPreferencesSigningRoot(chain.config, preferences),
135
145
  signedProposerPreferences.signature
136
146
  );
@@ -37,7 +37,7 @@ async function validateProposerSlashing(
37
37
  try {
38
38
  const proposer = state.getValidator(proposerSlashing.signedHeader1.message.proposerIndex);
39
39
  // verifySignature = false, verified in batch below
40
- assertValidProposerSlashing(chain.config, chain.pubkeyCache, state.slot, proposerSlashing, proposer, false);
40
+ assertValidProposerSlashing(chain.config, state.slot, proposerSlashing, proposer, false);
41
41
  } catch (e) {
42
42
  throw new ProposerSlashingError(GossipAction.REJECT, {
43
43
  code: ProposerSlashingErrorCode.INVALID,
@@ -9,12 +9,69 @@ import {
9
9
  import {IBeaconChain} from "../index.js";
10
10
  import {RegenCaller} from "../regen/index.js";
11
11
 
12
+ export type ApiVoluntaryExitResult = {status: "published"} | {status: "deferred"; validity: VoluntaryExitValidity};
13
+
14
+ // Variants that can become valid in a future epoch without user action.
15
+ // - earlyEpoch: exit.message.epoch is in the future; valid once current epoch catches up
16
+ // - shortTimeActive: validator active < SHARD_COMMITTEE_PERIOD; valid once enough time passes
17
+ // - pendingWithdrawals: Electra; valid once pending partial withdrawals drain
18
+ // Note: VoluntaryExitValidity.inactive is intentionally excluded. It conflates
19
+ // "validator does not exist" (permanent) with "validator not yet activated"
20
+ // (transient), and cleanly classifying it requires splitting the enum variant
21
+ // upstream. Left for a future follow-up.
22
+
23
+ export function isTransientExitValidity(v: VoluntaryExitValidity): boolean {
24
+ switch (v) {
25
+ case VoluntaryExitValidity.earlyEpoch:
26
+ case VoluntaryExitValidity.shortTimeActive:
27
+ case VoluntaryExitValidity.pendingWithdrawals:
28
+ return true;
29
+ case VoluntaryExitValidity.valid:
30
+ case VoluntaryExitValidity.inactive:
31
+ case VoluntaryExitValidity.alreadyExited:
32
+ case VoluntaryExitValidity.invalidSignature:
33
+ return false;
34
+ }
35
+ }
36
+
37
+ // Comments for each call are present inside `validateVoluntaryExit`.
12
38
  export async function validateApiVoluntaryExit(
13
39
  chain: IBeaconChain,
14
40
  voluntaryExit: phase0.SignedVoluntaryExit
15
- ): Promise<void> {
41
+ ): Promise<ApiVoluntaryExitResult> {
16
42
  const prioritizeBls = true;
17
- return validateVoluntaryExit(chain, voluntaryExit, prioritizeBls);
43
+
44
+ if (
45
+ chain.opPool.hasSeenVoluntaryExit(voluntaryExit.message.validatorIndex) ||
46
+ chain.deferredVoluntaryExitPool.has(voluntaryExit.message.validatorIndex)
47
+ ) {
48
+ throw new VoluntaryExitError(GossipAction.IGNORE, {
49
+ code: VoluntaryExitErrorCode.ALREADY_EXISTS,
50
+ });
51
+ }
52
+
53
+ const state = await chain.getHeadStateAtCurrentEpoch(RegenCaller.validateApiVoluntaryExit);
54
+ const validity = state.getVoluntaryExitValidity(voluntaryExit, false);
55
+
56
+ if (validity !== VoluntaryExitValidity.valid && !isTransientExitValidity(validity)) {
57
+ throw new VoluntaryExitError(GossipAction.REJECT, {
58
+ code: voluntaryExitValidityToErrorCode(validity),
59
+ });
60
+ }
61
+
62
+ const signatureSet = getVoluntaryExitSignatureSet(chain.config, state, voluntaryExit);
63
+ if (!(await chain.bls.verifySignatureSets([signatureSet], {batchable: true, priority: prioritizeBls}))) {
64
+ throw new VoluntaryExitError(GossipAction.REJECT, {
65
+ code: VoluntaryExitErrorCode.INVALID_SIGNATURE,
66
+ });
67
+ }
68
+
69
+ if (validity !== VoluntaryExitValidity.valid) {
70
+ // Transient failure — signature is good, defer
71
+ return {status: "deferred", validity};
72
+ }
73
+
74
+ return {status: "published"};
18
75
  }
19
76
 
20
77
  export async function validateGossipVoluntaryExit(
@@ -71,15 +71,18 @@ export class NoBidReceived extends Error {
71
71
  }
72
72
 
73
73
  /**
74
- * Beacon clients select randomized values from the following ranges when initializing
75
- * the circuit breaker (so at boot time and once for each unique boot).
74
+ * Default circuit breaker parameters:
76
75
  *
77
- * ALLOWED_FAULTS: between 1 and SLOTS_PER_EPOCH // 4
78
- * FAULT_INSPECTION_WINDOW: between SLOTS_PER_EPOCH and 2 * SLOTS_PER_EPOCH
76
+ * SLOTS_PER_EPOCH <= FAULT_INSPECTION_WINDOW < 2 * SLOTS_PER_EPOCH (randomized at initialization)
77
+ * ALLOWED_FAULTS: FAULT_INSPECTION_WINDOW // 4
79
78
  *
80
- * The values are randomized per node so builders cannot predict when a given proposer will
81
- * fall back to local blocks. With fixed thresholds a builder could withhold payloads right up
82
- * to the limit without ever tripping the breaker.
79
+ * e.g. on mainnet SLOTS_PER_EPOCH is 32, so FAULT_INSPECTION_WINDOW is between 32 and 63,
80
+ * and a window of 40 results in ALLOWED_FAULTS = 10.
81
+ *
82
+ * The randomized default window keeps the exact slots under inspection unpredictable per node,
83
+ * so a builder cannot tell when past faults age out of a given proposer's window and time
84
+ * withholding around trip or recovery points. Explicitly configured windows are clamped to at
85
+ * least SLOTS_PER_EPOCH, and configured allowedFaults is capped at the default ~25% budget.
83
86
  */
84
87
  export function getFaultInspectionParams(opts: {faultInspectionWindow?: number; allowedFaults?: number}): {
85
88
  faultInspectionWindow: number;
@@ -90,10 +93,7 @@ export function getFaultInspectionParams(opts: {faultInspectionWindow?: number;
90
93
  SLOTS_PER_EPOCH
91
94
  );
92
95
  // allowedFaults should be < faultInspectionWindow, limiting them to faultInspectionWindow/4
93
- const allowedFaults = Math.min(
94
- opts.allowedFaults ?? Math.floor(faultInspectionWindow / 4),
95
- Math.floor(faultInspectionWindow / 4)
96
- );
96
+ const allowedFaults = Math.min(opts.allowedFaults ?? Infinity, Math.floor(faultInspectionWindow / 4));
97
97
  return {faultInspectionWindow, allowedFaults};
98
98
  }
99
99
 
@@ -143,17 +143,17 @@ export function createBeaconMetrics(register: RegistryMetricCreator) {
143
143
  name: "beacon_builder_circuit_breaker_active",
144
144
  help: "Whether the builder circuit breaker is active (1) causing builder bids to be ignored",
145
145
  }),
146
- faults: register.gauge({
147
- name: "beacon_builder_circuit_breaker_faults",
148
- help: "Count of blocks with unrevealed payloads in the fault inspection window",
146
+ canonicalBlocks: register.gauge({
147
+ name: "beacon_builder_circuit_breaker_canonical_blocks",
148
+ help: "Count of canonical FULL and EMPTY blocks in the fault inspection window",
149
149
  }),
150
- blocksPresent: register.gauge({
151
- name: "beacon_builder_circuit_breaker_blocks_present",
152
- help: "Count of blocks present in the fault inspection window",
150
+ fullBlocks: register.gauge({
151
+ name: "beacon_builder_circuit_breaker_full_blocks",
152
+ help: "Count of canonical FULL blocks in the fault inspection window",
153
153
  }),
154
- payloadsRevealed: register.gauge({
155
- name: "beacon_builder_circuit_breaker_payloads_revealed",
156
- help: "Count of blocks with revealed payloads in the fault inspection window",
154
+ emptyBlocks: register.gauge({
155
+ name: "beacon_builder_circuit_breaker_empty_blocks",
156
+ help: "Count of canonical EMPTY blocks in the fault inspection window",
157
157
  }),
158
158
  },
159
159
 
@@ -4,7 +4,10 @@ import {ArchiveStoreTask} from "../../chain/archiveStore/archiveStore.js";
4
4
  import {FrequencyStateArchiveStep} from "../../chain/archiveStore/strategies/frequencyStateArchiveStrategy.js";
5
5
  import {BlockInputSource} from "../../chain/blocks/blockInput/index.js";
6
6
  import {PayloadErrorCode} from "../../chain/blocks/importExecutionPayload.js";
7
- import {PayloadEnvelopeInputSource} from "../../chain/blocks/payloadEnvelopeInput/index.js";
7
+ import {
8
+ PayloadEnvelopeInputPruneReason,
9
+ PayloadEnvelopeInputSource,
10
+ } from "../../chain/blocks/payloadEnvelopeInput/index.js";
8
11
  import {JobQueueItemType} from "../../chain/bls/index.js";
9
12
  import {AttestationErrorCode, BlockErrorCode} from "../../chain/errors/index.js";
10
13
  import {
@@ -21,7 +24,7 @@ import {ExecutionPayloadStatus} from "../../execution/index.js";
21
24
  import {GossipType} from "../../network/index.js";
22
25
  import {CannotAcceptWorkReason, ReprocessRejectReason} from "../../network/processor/index.js";
23
26
  import {BackfillSyncMethod} from "../../sync/backfill/backfill.js";
24
- import {PendingBlockType} from "../../sync/types.js";
27
+ import {DroppedItemReason, PendingBlockType} from "../../sync/types.js";
25
28
  import {PeerSyncType, RangeSyncType} from "../../sync/utils/remoteSyncType.js";
26
29
  import {AllocSource} from "../../util/bufferPool.js";
27
30
  import {DataColumnReconstructionCode} from "../../util/dataColumns.js";
@@ -31,6 +34,10 @@ import {RegistryMetricCreator} from "../utils/registryMetricCreator.js";
31
34
 
32
35
  export type LodestarMetrics = ReturnType<typeof createLodestarMetrics>;
33
36
 
37
+ type BlsJobOutcome = "valid" | "invalid" | "prepError" | "verifyError" | "workerError";
38
+ type BlsBufferFlushReason = "size" | "timeout";
39
+ type BlsVerificationCallOperation = "batch" | "single" | "fallback" | "same_message";
40
+
34
41
  /**
35
42
  * Extra Lodestar custom metrics
36
43
  */
@@ -396,86 +403,108 @@ export function createLodestarMetrics(
396
403
  // BLS verifier thread pool and queue
397
404
 
398
405
  bls: {
399
- aggregatedPubkeys: register.gauge({
406
+ aggregatedPubkeys: register.counter({
400
407
  name: "lodestar_bls_aggregated_pubkeys_total",
401
- help: "Total aggregated pubkeys for BLS validation",
408
+ help: "Total validator public keys used as inputs to aggregate signature sets",
409
+ }),
410
+ pubkeyCacheSize: register.gauge({
411
+ name: "lodestar_bls_pubkey_cache_size",
412
+ help: "Current number of validator public keys in the native cache",
413
+ }),
414
+ pubkeyCacheCapacity: register.gauge({
415
+ name: "lodestar_bls_pubkey_cache_capacity",
416
+ help: "Number of validator public keys the native cache can hold without growing",
402
417
  }),
403
418
  },
404
419
 
405
420
  blsThreadPool: {
406
- jobsWorkerTime: register.gauge<{workerId: number}>({
421
+ jobsWorkerTime: register.counter<{workerId: number}>({
407
422
  name: "lodestar_bls_thread_pool_time_seconds_sum",
408
- help: "Total time spent verifying signature sets measured on the worker",
423
+ help: "Cumulative wall time spent processing BLS dispatch groups by worker",
409
424
  labelNames: ["workerId"],
410
425
  }),
411
- successJobsSignatureSetsCount: register.gauge({
426
+ successJobsSignatureSetsCount: register.counter({
412
427
  name: "lodestar_bls_thread_pool_success_jobs_signature_sets_count",
413
- help: "Count of total verified signature sets",
414
- }),
415
- errorAggregateSignatureSetsCount: register.gauge<{type: JobQueueItemType}>({
416
- name: "lodestar_bls_thread_pool_error_aggregate_signature_sets_count",
417
- help: "Count of error when aggregating pubkeys or signatures",
418
- labelNames: ["type"],
428
+ help: "Count of signature sets completed without an operational error",
419
429
  }),
420
- errorJobsSignatureSetsCount: register.gauge({
430
+ errorJobsSignatureSetsCount: register.counter({
421
431
  name: "lodestar_bls_thread_pool_error_jobs_signature_sets_count",
422
- help: "Count of total error-ed signature sets",
432
+ help: "Count of signature sets that ended in an input, binding, or worker error",
423
433
  }),
424
- jobWaitTime: register.histogram({
434
+ jobWaitTime: register.histogram<{type: JobQueueItemType}>({
425
435
  name: "lodestar_bls_thread_pool_queue_job_wait_time_seconds",
426
- help: "Time from job added to the queue to starting the job in seconds",
427
- buckets: [0.01, 0.02, 0.1, 0.3, 0.5, 1],
436
+ help: "Time from adding a BLS job until it is selected for a worker dispatch group",
437
+ labelNames: ["type"],
438
+ buckets: [0.005, 0.01, 0.025, 0.05, 0.1, 0.2, 0.5, 1, 2],
439
+ }),
440
+ jobDuration: register.histogram<{type: JobQueueItemType}>({
441
+ name: "lodestar_bls_thread_pool_job_duration_seconds",
442
+ help: "End-to-end duration of a BLS job from submission through completion",
443
+ labelNames: ["type"],
444
+ buckets: [0.005, 0.01, 0.025, 0.05, 0.1, 0.2, 0.5, 1, 2],
445
+ }),
446
+ jobResults: register.counter<{type: JobQueueItemType; outcome: BlsJobOutcome}>({
447
+ name: "lodestar_bls_thread_pool_job_results_total",
448
+ help: "Count of completed BLS jobs by cryptographic or operational outcome",
449
+ labelNames: ["type", "outcome"],
428
450
  }),
429
451
  queueLength: register.gauge({
430
452
  name: "lodestar_bls_thread_pool_queue_length",
431
- help: "Count of total block processor queue length",
453
+ help: "Count of ready BLS jobs waiting for a worker",
454
+ }),
455
+ bufferedQueueLength: register.gauge({
456
+ name: "lodestar_bls_thread_pool_buffered_queue_length",
457
+ help: "Count of BLS jobs waiting in the intentional batching buffer",
432
458
  }),
433
459
  workersBusy: register.gauge({
434
460
  name: "lodestar_bls_thread_pool_workers_busy",
435
461
  help: "Count of current busy workers",
436
462
  }),
437
- totalJobsGroupsStarted: register.gauge({
463
+ totalJobsGroupsStarted: register.counter({
438
464
  name: "lodestar_bls_thread_pool_job_groups_started_total",
439
- help: "Count of total jobs groups started in bls thread pool, job groups include +1 jobs",
465
+ help: "Count of worker dispatch groups started by the BLS thread pool",
440
466
  }),
441
- totalJobsStarted: register.gauge<{type: JobQueueItemType}>({
467
+ totalJobsStarted: register.counter<{type: JobQueueItemType}>({
442
468
  name: "lodestar_bls_thread_pool_jobs_started_total",
443
- help: "Count of total jobs started in bls thread pool, jobs include +1 signature sets",
469
+ help: "Count of jobs started by the BLS thread pool",
444
470
  labelNames: ["type"],
445
471
  }),
446
- totalSigSetsStarted: register.gauge<{type: JobQueueItemType}>({
472
+ totalSigSetsStarted: register.counter<{type: JobQueueItemType}>({
447
473
  name: "lodestar_bls_thread_pool_sig_sets_started_total",
448
- help: "Count of total signature sets started in bls thread pool, sig sets include 1 pk, msg, sig",
474
+ help: "Count of signature sets started by the BLS thread pool",
449
475
  labelNames: ["type"],
450
476
  }),
451
477
  // Re-verifying a batch means doing double work. This number must be very low or it can be a waste of CPU resources
452
- batchRetries: register.gauge({
478
+ batchRetries: register.counter({
453
479
  name: "lodestar_bls_thread_pool_batch_retries_total",
454
- help: "Count of total batches that failed and had to be verified again.",
480
+ help: "Count of combined batches that failed and required per-job fallback",
455
481
  }),
456
482
  // To count how many sigs are being validated with the optimization of batching them
457
- batchSigsSuccess: register.gauge({
483
+ batchSigsSuccess: register.counter({
458
484
  name: "lodestar_bls_thread_pool_batch_sigs_success_total",
459
- help: "Count of total batches that failed and had to be verified again.",
485
+ help: "Count of signature sets accepted by combined batch verification without fallback",
460
486
  }),
461
- sameMessageRetryJobs: register.gauge({
462
- name: "lodestar_bls_thread_pool_same_message_jobs_retries_total",
463
- help: "Count of total same message jobs that failed and had to be verified again.",
487
+ bufferFlushes: register.counter<{reason: BlsBufferFlushReason}>({
488
+ name: "lodestar_bls_thread_pool_buffer_flushes_total",
489
+ help: "Count of batching-buffer flushes by trigger",
490
+ labelNames: ["reason"],
464
491
  }),
465
- sameMessageRetrySets: register.gauge({
466
- name: "lodestar_bls_thread_pool_same_message_sets_retries_total",
467
- help: "Count of total same message sets that failed and had to be verified again.",
492
+ bufferedSignatureSets: register.histogram({
493
+ name: "lodestar_bls_thread_pool_buffered_signature_sets",
494
+ help: "Count of signature sets included in each batching-buffer flush",
495
+ buckets: [1, 8, 16, 24, 28, 32, 36, 40, 44, 48, 64, 128],
468
496
  }),
469
497
  // To measure the time cost of main thread <-> worker message passing
470
498
  latencyToWorker: register.histogram({
471
499
  name: "lodestar_bls_thread_pool_latency_to_worker",
472
500
  help: "Time from sending the job to the worker and the worker receiving it",
473
- buckets: [0.001, 0.003, 0.01, 0.03, 0.1],
501
+ // The dashboard treats 20ms as slow; values above 100ms only need severe-stall classification.
502
+ buckets: [0.00025, 0.001, 0.005, 0.02, 0.1],
474
503
  }),
475
504
  latencyFromWorker: register.histogram({
476
505
  name: "lodestar_bls_thread_pool_latency_from_worker",
477
506
  help: "Time from the worker sending the result and the main thread receiving it",
478
- buckets: [0.001, 0.003, 0.01, 0.03, 0.1],
507
+ buckets: [0.00025, 0.001, 0.005, 0.02, 0.1],
479
508
  }),
480
509
  mainThreadDurationInThreadPool: register.histogram({
481
510
  name: "lodestar_bls_thread_pool_main_thread_time_seconds",
@@ -485,32 +514,40 @@ export function createLodestarMetrics(
485
514
  }),
486
515
  timePerSigSet: register.histogram({
487
516
  name: "lodestar_bls_worker_thread_time_per_sigset_seconds",
488
- help: "Time to verify each sigset with worker thread mode",
517
+ help: "Average BLS worker dispatch wall time per original signature set",
489
518
  // Time per sig ~0.9ms on good machines
490
- buckets: [0.5e-3, 0.75e-3, 1e-3, 1.5e-3, 2e-3, 5e-3],
491
- }),
492
- totalSigSets: register.gauge({
519
+ buckets: [0.5e-3, 0.75e-3, 1e-3, 1.5e-3, 2e-3, 5e-3, 10e-3, 20e-3, 50e-3, 100e-3],
520
+ }),
521
+ workRequestPreparationDuration: register.histogram({
522
+ name: "lodestar_bls_thread_pool_work_request_preparation_duration_seconds",
523
+ help: "Main-thread time spent converting one worker dispatch group to binding inputs",
524
+ // Normal requests take microseconds; the dashboard treats 1ms as a main-thread stall.
525
+ buckets: [0.000005, 0.000025, 0.0001, 0.0005, 0.001, 0.005, 0.025],
526
+ }),
527
+ verificationCallDuration: register.histogram<{operation: BlsVerificationCallOperation}>({
528
+ name: "lodestar_bls_thread_pool_verification_call_duration_seconds",
529
+ help: "Duration of one worker-side lodestar-z verification binding call, including input conversion",
530
+ labelNames: ["operation"],
531
+ // Verification ranges from sub-millisecond calls to large batches; above 500ms is uniformly severe.
532
+ buckets: [0.00025, 0.001, 0.005, 0.02, 0.1, 0.5],
533
+ }),
534
+ verificationCallSignatureSets: register.counter<{operation: BlsVerificationCallOperation}>({
535
+ name: "lodestar_bls_thread_pool_verification_call_signature_sets_total",
536
+ help: "Count of signature sets passed to worker-side lodestar-z verification binding calls",
537
+ labelNames: ["operation"],
538
+ }),
539
+ totalSigSets: register.counter({
493
540
  name: "lodestar_bls_thread_pool_sig_sets_total",
494
541
  help: "Count of total signature sets",
495
542
  }),
496
- prioritizedSigSets: register.gauge({
543
+ prioritizedSigSets: register.counter({
497
544
  name: "lodestar_bls_thread_pool_prioritized_sig_sets_total",
498
545
  help: "Count of total prioritized signature sets",
499
546
  }),
500
- batchableSigSets: register.gauge({
547
+ batchableSigSets: register.counter({
501
548
  name: "lodestar_bls_thread_pool_batchable_sig_sets_total",
502
549
  help: "Count of total batchable signature sets",
503
550
  }),
504
- aggregateWithRandomnessAsyncDuration: register.histogram({
505
- name: "lodestar_bls_thread_pool_aggregate_with_randomness_async_time_seconds",
506
- help: "Total time performing aggregateWithRandomness async",
507
- buckets: [0.001, 0.005, 0.01, 0.1, 0.3],
508
- }),
509
- pubkeysAggregationMainThreadDuration: register.histogram({
510
- name: "lodestar_bls_thread_pool_pubkeys_aggregation_main_thread_time_seconds",
511
- help: "Total time spent aggregating pubkeys on main thread",
512
- buckets: [0.001, 0.005, 0.01, 0.1],
513
- }),
514
551
  },
515
552
 
516
553
  // BLS time on single thread mode
@@ -643,9 +680,15 @@ export function createLodestarMetrics(
643
680
  name: "lodestar_sync_unknown_block_downloaded_blocks_error_total",
644
681
  help: "Total number of downloaded blocks errors in UnknownBlockSync",
645
682
  }),
646
- removedBlocks: register.gauge({
683
+ removedBlocks: register.gauge<{reason: DroppedItemReason}>({
647
684
  name: "lodestar_sync_unknown_block_removed_blocks_total",
648
- help: "Total number of removed bad blocks in UnknownBlockSync",
685
+ help: "Total pending blocks dropped from BlockInputSync without completing, by reason",
686
+ labelNames: ["reason"],
687
+ }),
688
+ removedPayloads: register.gauge<{reason: DroppedItemReason}>({
689
+ name: "lodestar_sync_unknown_block_removed_payloads_total",
690
+ help: "Total pending payloads dropped from BlockInputSync without completing, by reason",
691
+ labelNames: ["reason"],
649
692
  }),
650
693
  elapsedTimeTillReceived: register.histogram({
651
694
  name: "lodestar_sync_unknown_block_elapsed_time_till_received",
@@ -908,6 +951,22 @@ export function createLodestarMetrics(
908
951
  labelNames: ["error"],
909
952
  }),
910
953
  },
954
+ gossipExecutionPayloadBid: {
955
+ elapsedTimeTillReceived: register.histogram<{source: OpSource}>({
956
+ name: "lodestar_gossip_execution_payload_bid_elapsed_time_till_received_seconds",
957
+ help: "Time elapsed between the bid's slot start and the time the execution payload bid was received (negative = received before its slot, broadcast in the previous slot; positive = received during its own slot, late)",
958
+ labelNames: ["source"],
959
+ buckets: [-6, -3, -1, 0, 3],
960
+ }),
961
+ },
962
+ gossipPayloadAttestationMessage: {
963
+ elapsedTimeTillReceived: register.histogram<{source: OpSource}>({
964
+ name: "lodestar_gossip_payload_attestation_message_elapsed_time_till_received_seconds",
965
+ help: "Time elapsed between slot time and the time the payload attestation message was received",
966
+ labelNames: ["source"],
967
+ buckets: [3, 6, 9, 12],
968
+ }),
969
+ },
911
970
  // recovery in the case of specific blob rows required
912
971
  recoverBlobSidecars: {
913
972
  blobsReconstructed: register.counter({
@@ -1175,6 +1234,12 @@ export function createLodestarMetrics(
1175
1234
  name: "lodestar_oppool_attester_slashing_pool_size",
1176
1235
  help: "Current size of the AttesterSlashingPool",
1177
1236
  }),
1237
+ deferredVoluntaryExitPool: {
1238
+ size: register.gauge({
1239
+ name: "lodestar_oppool_deferred_voluntary_exit_pool_size",
1240
+ help: "Current size of the DeferredVoluntaryExitPool",
1241
+ }),
1242
+ },
1178
1243
  proposerSlashingPoolSize: register.gauge({
1179
1244
  name: "lodestar_oppool_proposer_slashing_pool_size",
1180
1245
  help: "Current size of the ProposerSlashingPool",
@@ -1379,6 +1444,16 @@ export function createLodestarMetrics(
1379
1444
  help: "Checkpoint state cache size",
1380
1445
  labelNames: ["type"],
1381
1446
  }),
1447
+ persistentTierEpochs: register.gauge<{tier: number}>({
1448
+ name: "lodestar_cp_state_cache_persistent_tier_epochs",
1449
+ help: "Number of epoch keys retained in each on-disk checkpoint state retention tier",
1450
+ labelNames: ["tier"],
1451
+ }),
1452
+ persistentTierStates: register.gauge<{tier: number}>({
1453
+ name: "lodestar_cp_state_cache_persistent_tier_states",
1454
+ help: "Number of persisted checkpoint states retained in each on-disk retention tier",
1455
+ labelNames: ["tier"],
1456
+ }),
1382
1457
  reads: register.avgMinMax({
1383
1458
  name: "lodestar_cp_state_epoch_reads",
1384
1459
  help: "Avg min max of all state cache items total read count",
@@ -1593,9 +1668,15 @@ export function createLodestarMetrics(
1593
1668
  name: "lodestar_seen_payload_envelope_input_cache_serialized_object_refs",
1594
1669
  help: "Number of serialized-cache object refs retained by cached PayloadEnvelopeInputs",
1595
1670
  }),
1596
- created: register.counter({
1671
+ created: register.counter<{source: PayloadEnvelopeInputSource}>({
1597
1672
  name: "lodestar_seen_payload_envelope_input_cache_items_created_total",
1598
- help: "Number of PayloadEnvelopeInputs created",
1673
+ help: "Number of PayloadEnvelopeInputs created by source",
1674
+ labelNames: ["source"],
1675
+ }),
1676
+ pruned: register.counter<{reason: PayloadEnvelopeInputPruneReason}>({
1677
+ name: "lodestar_seen_payload_envelope_input_cache_items_pruned_total",
1678
+ help: "Number of PayloadEnvelopeInputs evicted by reason",
1679
+ labelNames: ["reason"],
1599
1680
  }),
1600
1681
  },
1601
1682
  },
@@ -1705,6 +1786,10 @@ export function createLodestarMetrics(
1705
1786
  name: "lodestar_precompute_next_epoch_transition_waste_total",
1706
1787
  help: "Total number of precomputing next epoch transition wasted",
1707
1788
  }),
1789
+ predictedReorg: register.counter({
1790
+ name: "lodestar_precompute_next_epoch_transition_predicted_reorg_total",
1791
+ help: "Predicted epoch-boundary reorgs where the strong parent was dialed instead of the weak head",
1792
+ }),
1708
1793
  duration: register.histogram({
1709
1794
  name: "lodestar_precompute_next_epoch_transition_duration_seconds",
1710
1795
  help: "Duration of precomputeNextEpochTransition, including epoch transition and hashTreeRoot",
@@ -414,3 +414,41 @@ export const gossipTopicIgnoreDuplicatePublishError: Record<GossipType, boolean>
414
414
  [GossipType.execution_payload_bid]: true,
415
415
  [GossipType.proposer_preferences]: true,
416
416
  };
417
+
418
+ /**
419
+ * Whether a publish that reached zero subscribed peers is an acceptable outcome for a topic.
420
+ *
421
+ * Publishing to a topic with no subscribed peers throws `PublishError.NoPeersSubscribedToTopic`, which
422
+ * propagates to the caller and, for messages submitted through the beacon API, is surfaced to the
423
+ * validator client. That is the right default: a message that reached nobody is a failed broadcast, and a
424
+ * VC configured with several beacon nodes can fall back to another one.
425
+ *
426
+ * Only topics that have a concrete reason to tolerate it opt out here, ie. are set to `true`, and the
427
+ * reason is named on the entry. Everything else is `false` and keeps raising. Note this is applied per
428
+ * publish, a topic set to `false` still honors the global `--network.allowPublishToZeroPeers` flag.
429
+ */
430
+ export const gossipTopicAllowPublishToZeroPeers: Record<GossipType, boolean> = {
431
+ [GossipType.beacon_block]: false,
432
+ [GossipType.blob_sidecar]: false,
433
+ // data_column_sidecar: we ensure having all topic peers via prioritizePeers(). Even with 0 peers on the
434
+ // topic the overall publish can still succeed, because a supernode rebuilds and publishes the missing
435
+ // columns for us, so track sent peers as 0 instead of raising
436
+ [GossipType.data_column_sidecar]: true,
437
+ [GossipType.beacon_aggregate_and_proof]: false,
438
+ [GossipType.beacon_attestation]: false,
439
+ [GossipType.voluntary_exit]: false,
440
+ [GossipType.proposer_slashing]: false,
441
+ [GossipType.attester_slashing]: false,
442
+ [GossipType.sync_committee_contribution_and_proof]: false,
443
+ [GossipType.sync_committee]: false,
444
+ // light_client_finality_update and light_client_optimistic_update: non-mandatory route on most of the
445
+ // network as of Oct 2022, there may be no peer subscribed to the topic at all. Reason carried over from
446
+ // the handlers in network.ts, which used to swallow the error instead
447
+ [GossipType.light_client_finality_update]: true,
448
+ [GossipType.light_client_optimistic_update]: true,
449
+ [GossipType.bls_to_execution_change]: false,
450
+ [GossipType.execution_payload]: false,
451
+ [GossipType.payload_attestation_message]: false,
452
+ [GossipType.execution_payload_bid]: false,
453
+ [GossipType.proposer_preferences]: false,
454
+ };
@@ -1,3 +1,4 @@
1
+ import {getCiphers} from "node:crypto";
1
2
  import {bootstrap} from "@libp2p/bootstrap";
2
3
  import {identify} from "@libp2p/identify";
3
4
  import type {PrivateKey} from "@libp2p/interface";
@@ -9,12 +10,20 @@ import {Libp2pInit, createLibp2p} from "libp2p";
9
10
  import {Registry} from "prom-client";
10
11
  import {ENR} from "@chainsafe/enr";
11
12
  import {noise} from "@chainsafe/libp2p-noise";
12
- import {defaultCrypto} from "@chainsafe/libp2p-noise/crypto";
13
+ import {asCrypto, defaultCrypto} from "@chainsafe/libp2p-noise/crypto";
13
14
  import {quic} from "@chainsafe/libp2p-quic";
14
15
  import {Libp2p, LodestarComponents} from "../interface.js";
15
16
  import {NetworkOptions, defaultNetworkOptions} from "../options.js";
16
17
  import {Eth2PeerDataStore} from "../peers/datastore.js";
17
18
 
19
+ const noiseCrypto = getCiphers().includes("chacha20-poly1305")
20
+ ? defaultCrypto
21
+ : {
22
+ ...defaultCrypto,
23
+ chaCha20Poly1305Encrypt: asCrypto.chaCha20Poly1305Encrypt,
24
+ chaCha20Poly1305Decrypt: asCrypto.chaCha20Poly1305Decrypt,
25
+ };
26
+
18
27
  export type NodeJsLibp2pOpts = {
19
28
  peerStoreDir?: string;
20
29
  disablePeerDiscovery?: boolean;
@@ -122,7 +131,7 @@ export async function createNodeJsLibp2p(
122
131
  listen: localMultiaddrs,
123
132
  announce: [],
124
133
  },
125
- connectionEncrypters: [noise({crypto: defaultCrypto})],
134
+ connectionEncrypters: [noise({crypto: noiseCrypto})],
126
135
  transports,
127
136
  streamMuxers: [mplex({disconnectThreshold})],
128
137
  peerDiscovery,