@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,10 +1,6 @@
1
- import {PublicKey, asyncAggregateWithRandomness} from "@chainsafe/blst";
2
- import {ISignatureSet, PubkeyCache, SignatureSetType} from "@lodestar/state-transition";
3
- import {Metrics} from "../../../metrics/metrics.js";
4
- import {LinkedList} from "../../../util/array.js";
5
- import {VerifySignatureOpts} from "../interface.js";
6
- import {getAggregatedPubkey} from "../utils.js";
7
- import {BlsWorkReq} from "./types.js";
1
+ import {ISignatureSet, toBlsSignatureSet} from "@lodestar/state-transition";
2
+ import {SameMessageSignatureSet, VerifySignatureOpts} from "../interface.js";
3
+ import {BlsWorkReq, JobQueueItemType} from "./types.js";
8
4
 
9
5
  export type JobQueueItem = JobQueueItemDefault | JobQueueItemSameMessage;
10
6
 
@@ -23,101 +19,35 @@ export type JobQueueItemSameMessage = {
23
19
  reject: (error?: Error) => void;
24
20
  addedTimeMs: number;
25
21
  opts: VerifySignatureOpts;
26
- sets: {publicKey: PublicKey; signature: Uint8Array}[];
22
+ sets: SameMessageSignatureSet[];
27
23
  message: Uint8Array;
28
24
  };
29
25
 
30
- export enum JobQueueItemType {
31
- default = "default",
32
- sameMessage = "same_message",
33
- }
34
-
35
26
  /**
36
27
  * Return count of signature sets from a JobQueueItem
37
28
  */
38
29
  export function jobItemSigSets(job: JobQueueItem): number {
39
- switch (job.type) {
40
- case JobQueueItemType.default:
41
- return job.sets.length;
42
- case JobQueueItemType.sameMessage:
43
- return 1;
44
- }
30
+ return job.sets.length;
45
31
  }
46
32
 
47
33
  /**
48
34
  * Prepare BlsWorkReq from JobQueueItem
49
35
  * WARNING: May throw with untrusted user input
50
36
  */
51
- export async function jobItemWorkReq(
52
- job: JobQueueItem,
53
- pubkeyCache: PubkeyCache,
54
- metrics: Metrics | null
55
- ): Promise<BlsWorkReq> {
37
+ export function jobItemWorkReq(job: JobQueueItem): BlsWorkReq {
56
38
  switch (job.type) {
57
39
  case JobQueueItemType.default:
58
40
  return {
41
+ type: JobQueueItemType.default,
59
42
  opts: job.opts,
60
- sets: job.sets.map((set) => ({
61
- // this can throw, handled in the consumer code
62
- publicKey: getAggregatedPubkey(set, pubkeyCache, metrics).toBytes(),
63
- signature: set.signature,
64
- message: set.signingRoot,
65
- })),
43
+ sets: job.sets.map(toBlsSignatureSet),
66
44
  };
67
- case JobQueueItemType.sameMessage: {
68
- const timer = metrics?.blsThreadPool.aggregateWithRandomnessAsyncDuration.startTimer();
69
- const {pk, sig} = await asyncAggregateWithRandomness(
70
- job.sets.map((set) => ({pk: set.publicKey, sig: set.signature}))
71
- );
72
- timer?.();
73
-
45
+ case JobQueueItemType.sameMessage:
74
46
  return {
47
+ type: JobQueueItemType.sameMessage,
75
48
  opts: job.opts,
76
- sets: [
77
- {
78
- publicKey: pk.toBytes(),
79
- signature: sig.toBytes(),
80
- message: job.message,
81
- },
82
- ],
49
+ sets: job.sets,
50
+ message: job.message,
83
51
  };
84
- }
85
52
  }
86
53
  }
87
-
88
- /**
89
- * Convert a JobQueueItemSameMessage into multiple JobQueueItemDefault linked to the original promise
90
- */
91
- export function jobItemSameMessageToMultiSet(job: JobQueueItemSameMessage): LinkedList<JobQueueItemDefault> {
92
- // Retry each individually
93
- // Create new jobs for each pubkey set, and Promise.all all the results
94
- const promises: Promise<boolean>[] = [];
95
- const jobs = new LinkedList<JobQueueItemDefault>();
96
-
97
- for (const set of job.sets) {
98
- promises.push(
99
- new Promise<boolean>((resolve, reject) => {
100
- jobs.push({
101
- type: JobQueueItemType.default,
102
- resolve,
103
- reject,
104
- addedTimeMs: job.addedTimeMs,
105
- opts: {batchable: false, priority: job.opts.priority},
106
- sets: [
107
- {
108
- type: SignatureSetType.single,
109
- pubkey: set.publicKey,
110
- signature: set.signature,
111
- signingRoot: job.message,
112
- },
113
- ],
114
- });
115
- })
116
- );
117
- }
118
-
119
- // Connect jobs to main job
120
- Promise.all(promises).then(job.resolve, job.reject);
121
-
122
- return jobs;
123
- }
@@ -1,25 +1,48 @@
1
- import {VerifySignatureOpts} from "../interface.js";
1
+ import {type BlsSignatureSet} from "@chainsafe/lodestar-z/bls-verifier";
2
+ import {SameMessageSignatureSet, VerifySignatureOpts} from "../interface.js";
2
3
 
3
4
  export type WorkerData = {
4
5
  workerId: number;
5
6
  };
6
7
 
7
- export type SerializedSet = {
8
- publicKey: Uint8Array;
9
- message: Uint8Array;
10
- signature: Uint8Array;
8
+ export enum JobQueueItemType {
9
+ default = "default",
10
+ sameMessage = "same_message",
11
+ }
12
+
13
+ export type BlsWorkReqDefault = {
14
+ type: JobQueueItemType.default;
15
+ opts: VerifySignatureOpts;
16
+ sets: BlsSignatureSet[];
11
17
  };
12
18
 
13
- export type BlsWorkReq = {
19
+ export type BlsWorkReqSameMessage = {
20
+ type: JobQueueItemType.sameMessage;
14
21
  opts: VerifySignatureOpts;
15
- sets: SerializedSet[];
22
+ sets: SameMessageSignatureSet[];
23
+ message: Uint8Array;
16
24
  };
17
25
 
26
+ export type BlsWorkReq = BlsWorkReqDefault | BlsWorkReqSameMessage;
27
+
18
28
  export enum WorkResultCode {
19
29
  success = "success",
20
30
  error = "error",
21
31
  }
22
32
 
33
+ export enum VerificationCallOperation {
34
+ batch = "batch",
35
+ single = "single",
36
+ fallback = "fallback",
37
+ sameMessage = "same_message",
38
+ }
39
+
40
+ export type VerificationCall = {
41
+ operation: VerificationCallOperation;
42
+ duration: number;
43
+ signatureSets: number;
44
+ };
45
+
23
46
  export type WorkResultError = {code: WorkResultCode.error; error: Error};
24
47
  export type WorkResult<R> = {code: WorkResultCode.success; result: R} | WorkResultError;
25
48
 
@@ -30,9 +53,11 @@ export type BlsWorkResult = {
30
53
  batchRetries: number;
31
54
  /** Total num of sigs that have been successfully verified with batching */
32
55
  batchSigsSuccess: number;
56
+ /** Every lodestar-z verification call made while processing this work group */
57
+ verificationCalls: VerificationCall[];
33
58
  /** Time worker function starts - UNIX timestamp in seconds and nanoseconds */
34
59
  workerStartTime: [number, number];
35
60
  /** Time worker function ends - UNIX timestamp in seconds and nanoseconds */
36
61
  workerEndTime: [number, number];
37
- results: WorkResult<boolean>[];
62
+ results: WorkResult<boolean[]>[];
38
63
  };
@@ -17,3 +17,14 @@ export function chunkifyMaximizeChunkSize<T>(arr: T[], minPerChunk: number): T[]
17
17
 
18
18
  return arrArr;
19
19
  }
20
+
21
+ /**
22
+ * Splits an array into chunks that do not exceed a maximum size.
23
+ */
24
+ export function chunkifyMaxChunkSize<T>(arr: T[], maxPerChunk: number): T[][] {
25
+ const chunks: T[][] = [];
26
+ for (let i = 0; i < arr.length; i += maxPerChunk) {
27
+ chunks.push(arr.slice(i, i + maxPerChunk));
28
+ }
29
+ return chunks;
30
+ }
@@ -1,8 +1,20 @@
1
1
  import worker from "node:worker_threads";
2
- import {PublicKey} from "@chainsafe/blst";
2
+ import {
3
+ type BlsSignatureSet,
4
+ verifySignatureSets,
5
+ verifySignatureSetsSameMessage,
6
+ } from "@chainsafe/lodestar-z/bls-verifier";
3
7
  import {expose} from "@chainsafe/threads/worker";
4
- import {SignatureSetDeserialized, verifySignatureSetsMaybeBatch} from "../maybeBatch.js";
5
- import {BlsWorkReq, BlsWorkResult, SerializedSet, WorkResult, WorkResultCode, WorkerData} from "./types.js";
8
+ import {
9
+ BlsWorkReq,
10
+ BlsWorkResult,
11
+ JobQueueItemType,
12
+ VerificationCall,
13
+ VerificationCallOperation,
14
+ WorkResult,
15
+ WorkResultCode,
16
+ WorkerData,
17
+ } from "./types.js";
6
18
  import {chunkifyMaximizeChunkSize} from "./utils.js";
7
19
 
8
20
  /**
@@ -27,23 +39,45 @@ expose({
27
39
 
28
40
  function verifyManySignatureSets(workReqArr: BlsWorkReq[]): BlsWorkResult {
29
41
  const [startSec, startNs] = process.hrtime();
30
- const results: WorkResult<boolean>[] = [];
42
+ const results: WorkResult<boolean[]>[] = [];
43
+ const verificationCalls: VerificationCall[] = [];
31
44
  let batchRetries = 0;
32
45
  let batchSigsSuccess = 0;
33
46
 
34
47
  // If there are multiple batchable sets attempt batch verification with them
35
- const batchableSets: {idx: number; sets: SignatureSetDeserialized[]}[] = [];
36
- const nonBatchableSets: {idx: number; sets: SignatureSetDeserialized[]}[] = [];
48
+ const batchableSets: {idx: number; sets: BlsSignatureSet[]}[] = [];
49
+ const nonBatchableSets: {
50
+ idx: number;
51
+ sets: BlsSignatureSet[];
52
+ operation: VerificationCallOperation.single | VerificationCallOperation.fallback;
53
+ }[] = [];
37
54
 
38
55
  // Split sets between batchable and non-batchable preserving their original index in the req array
39
56
  for (let i = 0; i < workReqArr.length; i++) {
40
57
  const workReq = workReqArr[i];
41
- const sets = workReq.sets.map(deserializeSet);
42
-
43
- if (workReq.opts.batchable) {
44
- batchableSets.push({idx: i, sets});
45
- } else {
46
- nonBatchableSets.push({idx: i, sets});
58
+ switch (workReq.type) {
59
+ case JobQueueItemType.default: {
60
+ const {sets} = workReq;
61
+ if (workReq.opts.batchable) {
62
+ batchableSets.push({idx: i, sets});
63
+ } else {
64
+ nonBatchableSets.push({idx: i, sets, operation: VerificationCallOperation.single});
65
+ }
66
+ break;
67
+ }
68
+ case JobQueueItemType.sameMessage:
69
+ try {
70
+ const result = recordVerificationCall(
71
+ verificationCalls,
72
+ VerificationCallOperation.sameMessage,
73
+ workReq.sets.length,
74
+ () => verifySignatureSetsSameMessage(workReq.sets, workReq.message)
75
+ );
76
+ results[i] = {code: WorkResultCode.success, result};
77
+ } catch (e) {
78
+ results[i] = {code: WorkResultCode.error, error: e as Error};
79
+ }
80
+ break;
47
81
  }
48
82
  }
49
83
 
@@ -52,7 +86,7 @@ function verifyManySignatureSets(workReqArr: BlsWorkReq[]): BlsWorkResult {
52
86
  const batchableChunks = chunkifyMaximizeChunkSize(batchableSets, BATCHABLE_MIN_PER_CHUNK);
53
87
 
54
88
  for (const batchableChunk of batchableChunks) {
55
- const allSets: SignatureSetDeserialized[] = [];
89
+ const allSets: BlsSignatureSet[] = [];
56
90
  for (const {sets} of batchableChunk) {
57
91
  for (const set of sets) {
58
92
  allSets.push(set);
@@ -61,33 +95,49 @@ function verifyManySignatureSets(workReqArr: BlsWorkReq[]): BlsWorkResult {
61
95
 
62
96
  try {
63
97
  // Attempt to verify multiple sets at once
64
- const isValid = verifySignatureSetsMaybeBatch(allSets);
98
+ const isValid = recordVerificationCall(verificationCalls, VerificationCallOperation.batch, allSets.length, () =>
99
+ verifySignatureSets(allSets)
100
+ );
65
101
 
66
102
  if (isValid) {
67
103
  // The entire batch is valid, return success to all
68
104
  for (const {idx, sets} of batchableChunk) {
69
105
  batchSigsSuccess += sets.length;
70
- results[idx] = {code: WorkResultCode.success, result: isValid};
106
+ results[idx] = {code: WorkResultCode.success, result: [isValid]};
71
107
  }
72
108
  } else {
73
109
  batchRetries++;
74
110
  // Re-verify all sigs
75
- nonBatchableSets.push(...batchableChunk);
111
+ nonBatchableSets.push(
112
+ ...batchableChunk.map(({idx, sets}) => ({
113
+ idx,
114
+ sets,
115
+ operation: VerificationCallOperation.fallback as const,
116
+ }))
117
+ );
76
118
  }
77
119
  } catch (_e) {
78
120
  // TODO: Ignore this error expecting that the same error will happen when re-verifying the set individually
79
- // It's not ideal but '@chainsafe/blst' may throw errors on some conditions
121
+ // It's not ideal but the BLS implementation may throw errors on some conditions
80
122
  batchRetries++;
81
123
  // Re-verify all sigs
82
- nonBatchableSets.push(...batchableChunk);
124
+ nonBatchableSets.push(
125
+ ...batchableChunk.map(({idx, sets}) => ({
126
+ idx,
127
+ sets,
128
+ operation: VerificationCallOperation.fallback as const,
129
+ }))
130
+ );
83
131
  }
84
132
  }
85
133
  }
86
134
 
87
- for (const {idx, sets} of nonBatchableSets) {
135
+ for (const {idx, sets, operation} of nonBatchableSets) {
88
136
  try {
89
- const isValid = verifySignatureSetsMaybeBatch(sets);
90
- results[idx] = {code: WorkResultCode.success, result: isValid};
137
+ const isValid = recordVerificationCall(verificationCalls, operation, sets.length, () =>
138
+ verifySignatureSets(sets)
139
+ );
140
+ results[idx] = {code: WorkResultCode.success, result: [isValid]};
91
141
  } catch (e) {
92
142
  results[idx] = {code: WorkResultCode.error, error: e as Error};
93
143
  }
@@ -99,16 +149,24 @@ function verifyManySignatureSets(workReqArr: BlsWorkReq[]): BlsWorkResult {
99
149
  workerId,
100
150
  batchRetries,
101
151
  batchSigsSuccess,
152
+ verificationCalls,
102
153
  workerStartTime: [startSec, startNs],
103
154
  workerEndTime: [workerEndSec, workerEndNs],
104
155
  results,
105
156
  };
106
157
  }
107
158
 
108
- function deserializeSet(set: SerializedSet): SignatureSetDeserialized {
109
- return {
110
- publicKey: PublicKey.fromBytes(set.publicKey),
111
- message: set.message,
112
- signature: set.signature,
113
- };
159
+ function recordVerificationCall<T>(
160
+ calls: VerificationCall[],
161
+ operation: VerificationCallOperation,
162
+ signatureSets: number,
163
+ verify: () => T
164
+ ): T {
165
+ const startTime = process.hrtime();
166
+ try {
167
+ return verify();
168
+ } finally {
169
+ const [seconds, nanoseconds] = process.hrtime(startTime);
170
+ calls.push({operation, signatureSets, duration: seconds + nanoseconds / 1e9});
171
+ }
114
172
  }
@@ -1,31 +1,20 @@
1
- import {PublicKey, Signature, aggregatePublicKeys, aggregateSignatures, verify} from "@chainsafe/blst";
2
- import {ISignatureSet, PubkeyCache} from "@lodestar/state-transition";
1
+ import {verifySignatureSetsSameMessage} from "@chainsafe/lodestar-z/bls-verifier";
2
+ import {ISignatureSet} from "@lodestar/state-transition";
3
3
  import {Metrics} from "../../metrics/index.js";
4
- import {IBlsVerifier} from "./interface.js";
5
- import {verifySignatureSetsMaybeBatch} from "./maybeBatch.js";
6
- import {getAggregatedPubkey, getAggregatedPubkeysCount} from "./utils.js";
4
+ import {IBlsVerifier, SameMessageSignatureSet} from "./interface.js";
5
+ import {chunkSameMessageSignatureSets, getAggregatedPubkeysCount, verifySignatureSetsInBatches} from "./utils.js";
7
6
 
8
7
  export class BlsSingleThreadVerifier implements IBlsVerifier {
9
8
  private readonly metrics: Metrics | null;
10
- private readonly pubkeyCache: PubkeyCache;
11
-
12
- constructor({metrics = null, pubkeyCache}: {metrics: Metrics | null; pubkeyCache: PubkeyCache}) {
9
+ constructor({metrics = null}: {metrics: Metrics | null}) {
13
10
  this.metrics = metrics;
14
- this.pubkeyCache = pubkeyCache;
15
11
  }
16
12
 
17
13
  async verifySignatureSets(sets: ISignatureSet[]): Promise<boolean> {
18
14
  this.metrics?.bls.aggregatedPubkeys.inc(getAggregatedPubkeysCount(sets));
19
15
 
20
- const setsAggregated = sets.map((set) => ({
21
- publicKey: getAggregatedPubkey(set, this.pubkeyCache, this.metrics),
22
- message: set.signingRoot,
23
- signature: set.signature,
24
- }));
25
-
26
- // Count time after aggregating
27
16
  const timer = this.metrics?.blsThreadPool.mainThreadDurationInThreadPool.startTimer();
28
- const isValid = verifySignatureSetsMaybeBatch(setsAggregated);
17
+ const isValid = verifySignatureSetsInBatches(sets);
29
18
 
30
19
  // Don't use a try/catch, only count run without exceptions
31
20
  if (timer) {
@@ -35,46 +24,13 @@ export class BlsSingleThreadVerifier implements IBlsVerifier {
35
24
  return isValid;
36
25
  }
37
26
 
38
- async verifySignatureSetsSameMessage(
39
- sets: {publicKey: PublicKey; signature: Uint8Array}[],
40
- message: Uint8Array
41
- ): Promise<boolean[]> {
27
+ async verifySignatureSetsSameMessage(sets: SameMessageSignatureSet[], message: Uint8Array): Promise<boolean[]> {
42
28
  const timer = this.metrics?.blsThreadPool.mainThreadDurationInThreadPool.startTimer();
43
- const pubkey = aggregatePublicKeys(sets.map((set) => set.publicKey));
44
- let isAllValid = true;
45
- // validate signature = true
46
- const signatures = sets.map((set) => {
47
- try {
48
- return Signature.fromBytes(set.signature, true);
49
- } catch (_) {
50
- // at least one set has malformed signature
51
- isAllValid = false;
52
- return null;
53
- }
54
- });
55
-
56
- if (isAllValid) {
57
- const signature = aggregateSignatures(signatures as Signature[]);
58
- isAllValid = verify(message, pubkey, signature);
59
- }
60
-
61
- let result: boolean[];
62
- if (isAllValid) {
63
- result = sets.map(() => true);
64
- } else {
65
- result = sets.map((set, i) => {
66
- const sig = signatures[i];
67
- if (sig === null) {
68
- return false;
69
- }
70
- return verify(message, set.publicKey, sig);
71
- });
29
+ const result: boolean[] = [];
30
+ for (const setsChunk of chunkSameMessageSignatureSets(sets)) {
31
+ result.push(...verifySignatureSetsSameMessage(setsChunk, message));
72
32
  }
73
-
74
- if (timer) {
75
- timer();
76
- }
77
-
33
+ timer?.();
78
34
  return result;
79
35
  }
80
36
 
@@ -1,33 +1,32 @@
1
- import {PublicKey, aggregatePublicKeys} from "@chainsafe/blst";
2
- import {ISignatureSet, PubkeyCache, SignatureSetType} from "@lodestar/state-transition";
3
- import {Metrics} from "../../metrics/metrics.js";
1
+ import {
2
+ BLS_VERIFIER_MAX_BATCH_SIZE,
3
+ BLS_VERIFIER_MAX_SAME_MESSAGE_BATCH_SIZE,
4
+ verifySignatureSets,
5
+ } from "@chainsafe/lodestar-z/bls-verifier";
6
+ import {ISignatureSet, SignatureSetType, toBlsSignatureSet} from "@lodestar/state-transition";
7
+ import {SameMessageSignatureSet} from "./interface.js";
4
8
 
5
- export function getAggregatedPubkey(
6
- signatureSet: ISignatureSet,
7
- pubkeyCache: PubkeyCache,
8
- metrics: Metrics | null = null
9
- ): PublicKey {
10
- switch (signatureSet.type) {
11
- case SignatureSetType.single:
12
- return signatureSet.pubkey;
9
+ export function verifySignatureSetsInBatches(signatureSets: ISignatureSet[]): boolean {
10
+ if (signatureSets.length === 0) {
11
+ return false;
12
+ }
13
13
 
14
- case SignatureSetType.indexed: {
15
- return pubkeyCache.getOrThrow(signatureSet.index);
14
+ for (let start = 0; start < signatureSets.length; start += BLS_VERIFIER_MAX_BATCH_SIZE) {
15
+ const sets = signatureSets.slice(start, start + BLS_VERIFIER_MAX_BATCH_SIZE).map(toBlsSignatureSet);
16
+ if (!verifySignatureSets(sets)) {
17
+ return false;
16
18
  }
19
+ }
17
20
 
18
- case SignatureSetType.aggregate: {
19
- const timer = metrics?.blsThreadPool.pubkeysAggregationMainThreadDuration.startTimer();
20
- const pubkeys = signatureSet.indices.map((i) => {
21
- return pubkeyCache.getOrThrow(i);
22
- });
23
- const aggregated = aggregatePublicKeys(pubkeys);
24
- timer?.();
25
- return aggregated;
26
- }
21
+ return true;
22
+ }
27
23
 
28
- default:
29
- throw Error("Unknown signature set type");
24
+ export function chunkSameMessageSignatureSets(sets: SameMessageSignatureSet[]): SameMessageSignatureSet[][] {
25
+ const chunks: SameMessageSignatureSet[][] = [];
26
+ for (let start = 0; start < sets.length; start += BLS_VERIFIER_MAX_SAME_MESSAGE_BATCH_SIZE) {
27
+ chunks.push(sets.slice(start, start + BLS_VERIFIER_MAX_SAME_MESSAGE_BATCH_SIZE));
30
28
  }
29
+ return chunks;
31
30
  }
32
31
 
33
32
  export function getAggregatedPubkeysCount(signatureSets: ISignatureSet[]): number {
@@ -1,4 +1,4 @@
1
- import {IForkChoice} from "@lodestar/fork-choice";
1
+ import {IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
2
2
  import {Slot} from "@lodestar/types";
3
3
  import {Logger} from "@lodestar/utils";
4
4
  import {getFaultInspectionParams} from "../execution/builder/http.js";
@@ -15,11 +15,15 @@ export type BuilderCircuitBreakerModules = {
15
15
  metrics: Metrics | null;
16
16
  };
17
17
 
18
+ /** Four observations is the minimum useful recovery sample for the default ~25% fault budget */
19
+ const MIN_BLOCKS_TO_DEACTIVATE = 4;
20
+
18
21
  /**
19
22
  * Post-gloas circuit breaker for builder bids. The beacon block is produced by the proposer
20
23
  * regardless of bid source, so missed blocks are not a useful builder health signal. Instead
21
- * count blocks whose payload was never revealed and stop selecting builder bids while the
22
- * non-reveal rate in the fault inspection window is too high.
24
+ * count canonical blocks selected as EMPTY. Activate when the proportion of EMPTY blocks exceeds
25
+ * the fault budget, and resume selecting builder bids only when the observed blocks are within
26
+ * budget and meet the minimum recovery sample size.
23
27
  */
24
28
  export class BuilderCircuitBreaker {
25
29
  readonly faultInspectionWindow: number;
@@ -35,39 +39,49 @@ export class BuilderCircuitBreaker {
35
39
  const {faultInspectionWindow, allowedFaults} = getFaultInspectionParams(opts);
36
40
  this.faultInspectionWindow = faultInspectionWindow;
37
41
  this.allowedFaults = allowedFaults;
42
+ this.modules.logger.info("Builder circuit breaker initialized", {faultInspectionWindow, allowedFaults});
38
43
  }
39
44
 
40
45
  /** Whether builder bids must be ignored for a block produced at clockSlot */
41
- isActive(clockSlot: Slot): boolean {
42
- this.update(clockSlot);
46
+ isActive(clockSlot: Slot, head: ProtoBlock): boolean {
47
+ this.update(clockSlot, head);
43
48
  return this.active;
44
49
  }
45
50
 
46
- update(clockSlot: Slot): void {
51
+ update(clockSlot: Slot, head: ProtoBlock): void {
47
52
  if (clockSlot <= this.lastUpdatedSlot) {
48
53
  return;
49
54
  }
50
55
  this.lastUpdatedSlot = clockSlot;
51
56
 
52
- // Exclude clockSlot itself, its payload reveal may still be in flight
53
- const {blocksPresent, payloadsRevealed} = this.modules.forkChoice.getPayloadRevealCounts(
57
+ // Exclude clockSlot itself, its payload status may still be unresolved
58
+ const {full, empty} = this.modules.forkChoice.getCanonicalPayloadCounts(
54
59
  Math.max(clockSlot - this.faultInspectionWindow, 0),
55
- clockSlot - 1
60
+ clockSlot - 1,
61
+ head
56
62
  );
57
- const faults = blocksPresent - payloadsRevealed;
63
+ const canonicalBlocks = full + empty;
58
64
 
59
65
  const wasActive = this.active;
60
- // Scale the fault budget by blocks present so sparse windows still trigger on high non-reveal rates
61
- this.active = faults * this.faultInspectionWindow > this.allowedFaults * blocksPresent;
66
+ // Scale the fault budget by canonical blocks so sparse windows still trigger on high EMPTY rates
67
+ const exceedsFaultBudget = empty * this.faultInspectionWindow > this.allowedFaults * canonicalBlocks;
68
+ if (exceedsFaultBudget) {
69
+ this.active = true;
70
+ } else if (canonicalBlocks >= MIN_BLOCKS_TO_DEACTIVATE) {
71
+ // Require a minimum sample within the fault budget before accepting builder bids again
72
+ this.active = false;
73
+ }
62
74
 
63
75
  this.modules.metrics?.builderCircuitBreaker.active.set(this.active ? 1 : 0);
64
- this.modules.metrics?.builderCircuitBreaker.faults.set(faults);
65
- this.modules.metrics?.builderCircuitBreaker.blocksPresent.set(blocksPresent);
66
- this.modules.metrics?.builderCircuitBreaker.payloadsRevealed.set(payloadsRevealed);
76
+ this.modules.metrics?.builderCircuitBreaker.canonicalBlocks.set(canonicalBlocks);
77
+ this.modules.metrics?.builderCircuitBreaker.fullBlocks.set(full);
78
+ this.modules.metrics?.builderCircuitBreaker.emptyBlocks.set(empty);
67
79
 
68
80
  const logCtx = {
69
- blocksPresent,
70
- faults,
81
+ clockSlot,
82
+ canonicalBlocks,
83
+ full,
84
+ empty,
71
85
  faultInspectionWindow: this.faultInspectionWindow,
72
86
  allowedFaults: this.allowedFaults,
73
87
  };