@lodestar/beacon-node 1.42.0-dev.98c97772c8 → 1.42.0-dev.b10dfaca8d

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 (335) hide show
  1. package/lib/api/impl/beacon/blocks/index.js +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  3. package/lib/api/impl/beacon/pool/index.js +1 -1
  4. package/lib/api/impl/beacon/pool/index.js.map +1 -1
  5. package/lib/api/impl/beacon/state/index.d.ts.map +1 -1
  6. package/lib/api/impl/beacon/state/index.js +27 -32
  7. package/lib/api/impl/beacon/state/index.js.map +1 -1
  8. package/lib/api/impl/beacon/state/utils.d.ts +4 -4
  9. package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
  10. package/lib/api/impl/beacon/state/utils.js +7 -10
  11. package/lib/api/impl/beacon/state/utils.js.map +1 -1
  12. package/lib/api/impl/lodestar/index.d.ts.map +1 -1
  13. package/lib/api/impl/lodestar/index.js +4 -6
  14. package/lib/api/impl/lodestar/index.js.map +1 -1
  15. package/lib/api/impl/proof/index.d.ts.map +1 -1
  16. package/lib/api/impl/proof/index.js +2 -6
  17. package/lib/api/impl/proof/index.js.map +1 -1
  18. package/lib/api/impl/validator/index.d.ts.map +1 -1
  19. package/lib/api/impl/validator/index.js +27 -27
  20. package/lib/api/impl/validator/index.js.map +1 -1
  21. package/lib/api/impl/validator/utils.d.ts +2 -2
  22. package/lib/api/impl/validator/utils.d.ts.map +1 -1
  23. package/lib/api/impl/validator/utils.js +3 -3
  24. package/lib/api/impl/validator/utils.js.map +1 -1
  25. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts +2 -6
  26. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
  27. package/lib/chain/archiveStore/historicalState/getHistoricalState.js +3 -23
  28. package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
  29. package/lib/chain/archiveStore/historicalState/worker.js +1 -0
  30. package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
  31. package/lib/chain/balancesCache.d.ts +2 -2
  32. package/lib/chain/balancesCache.d.ts.map +1 -1
  33. package/lib/chain/balancesCache.js +4 -4
  34. package/lib/chain/balancesCache.js.map +1 -1
  35. package/lib/chain/blocks/blockInput/types.d.ts +1 -0
  36. package/lib/chain/blocks/blockInput/types.d.ts.map +1 -1
  37. package/lib/chain/blocks/blockInput/types.js +1 -0
  38. package/lib/chain/blocks/blockInput/types.js.map +1 -1
  39. package/lib/chain/blocks/importBlock.d.ts +3 -3
  40. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  41. package/lib/chain/blocks/importBlock.js +9 -9
  42. package/lib/chain/blocks/importBlock.js.map +1 -1
  43. package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
  44. package/lib/chain/blocks/importExecutionPayload.js +4 -5
  45. package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
  46. package/lib/chain/blocks/index.js +1 -1
  47. package/lib/chain/blocks/index.js.map +1 -1
  48. package/lib/chain/blocks/types.d.ts +2 -2
  49. package/lib/chain/blocks/types.d.ts.map +1 -1
  50. package/lib/chain/blocks/types.js.map +1 -1
  51. package/lib/chain/blocks/utils/checkpoint.d.ts +2 -2
  52. package/lib/chain/blocks/utils/checkpoint.d.ts.map +1 -1
  53. package/lib/chain/blocks/utils/checkpoint.js.map +1 -1
  54. package/lib/chain/blocks/verifyBlock.d.ts +2 -2
  55. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  56. package/lib/chain/blocks/verifyBlock.js +4 -4
  57. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  58. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts +3 -3
  59. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
  60. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +3 -3
  61. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
  62. package/lib/chain/blocks/verifyBlocksSignatures.d.ts +2 -2
  63. package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
  64. package/lib/chain/blocks/verifyBlocksSignatures.js +1 -1
  65. package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
  66. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts +3 -3
  67. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
  68. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +3 -3
  69. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
  70. package/lib/chain/chain.d.ts +12 -12
  71. package/lib/chain/chain.d.ts.map +1 -1
  72. package/lib/chain/chain.js +47 -39
  73. package/lib/chain/chain.js.map +1 -1
  74. package/lib/chain/emitter.d.ts +2 -2
  75. package/lib/chain/emitter.d.ts.map +1 -1
  76. package/lib/chain/errors/blockError.d.ts +4 -4
  77. package/lib/chain/errors/blockError.d.ts.map +1 -1
  78. package/lib/chain/forkChoice/index.d.ts +4 -4
  79. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  80. package/lib/chain/forkChoice/index.js +27 -23
  81. package/lib/chain/forkChoice/index.js.map +1 -1
  82. package/lib/chain/initState.d.ts +2 -2
  83. package/lib/chain/initState.d.ts.map +1 -1
  84. package/lib/chain/initState.js +1 -1
  85. package/lib/chain/initState.js.map +1 -1
  86. package/lib/chain/interface.d.ts +11 -12
  87. package/lib/chain/interface.d.ts.map +1 -1
  88. package/lib/chain/lightClient/index.d.ts +2 -2
  89. package/lib/chain/lightClient/index.d.ts.map +1 -1
  90. package/lib/chain/lightClient/index.js +4 -4
  91. package/lib/chain/lightClient/index.js.map +1 -1
  92. package/lib/chain/opPools/aggregatedAttestationPool.d.ts +6 -6
  93. package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
  94. package/lib/chain/opPools/aggregatedAttestationPool.js +10 -13
  95. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  96. package/lib/chain/opPools/opPool.d.ts +3 -3
  97. package/lib/chain/opPools/opPool.d.ts.map +1 -1
  98. package/lib/chain/opPools/opPool.js +7 -7
  99. package/lib/chain/opPools/opPool.js.map +1 -1
  100. package/lib/chain/opPools/utils.d.ts +2 -2
  101. package/lib/chain/opPools/utils.d.ts.map +1 -1
  102. package/lib/chain/opPools/utils.js +1 -1
  103. package/lib/chain/opPools/utils.js.map +1 -1
  104. package/lib/chain/prepareNextSlot.d.ts +2 -2
  105. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  106. package/lib/chain/prepareNextSlot.js +3 -3
  107. package/lib/chain/prepareNextSlot.js.map +1 -1
  108. package/lib/chain/produceBlock/computeNewStateRoot.d.ts +4 -4
  109. package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
  110. package/lib/chain/produceBlock/computeNewStateRoot.js +3 -4
  111. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  112. package/lib/chain/produceBlock/produceBlockBody.d.ts +5 -5
  113. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  114. package/lib/chain/produceBlock/produceBlockBody.js +12 -16
  115. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  116. package/lib/chain/regen/interface.d.ts +13 -13
  117. package/lib/chain/regen/interface.d.ts.map +1 -1
  118. package/lib/chain/regen/queued.d.ts +14 -14
  119. package/lib/chain/regen/queued.d.ts.map +1 -1
  120. package/lib/chain/regen/queued.js.map +1 -1
  121. package/lib/chain/regen/regen.d.ts +6 -5
  122. package/lib/chain/regen/regen.d.ts.map +1 -1
  123. package/lib/chain/regen/regen.js +6 -6
  124. package/lib/chain/regen/regen.js.map +1 -1
  125. package/lib/chain/serializeState.d.ts +2 -2
  126. package/lib/chain/serializeState.d.ts.map +1 -1
  127. package/lib/chain/serializeState.js +1 -1
  128. package/lib/chain/serializeState.js.map +1 -1
  129. package/lib/chain/shufflingCache.d.ts +2 -2
  130. package/lib/chain/shufflingCache.d.ts.map +1 -1
  131. package/lib/chain/shufflingCache.js +3 -4
  132. package/lib/chain/shufflingCache.js.map +1 -1
  133. package/lib/chain/stateCache/fifoBlockStateCache.d.ts +6 -6
  134. package/lib/chain/stateCache/fifoBlockStateCache.d.ts.map +1 -1
  135. package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
  136. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +11 -11
  137. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  138. package/lib/chain/stateCache/persistentCheckpointsCache.js +12 -16
  139. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  140. package/lib/chain/stateCache/types.d.ts +14 -14
  141. package/lib/chain/stateCache/types.d.ts.map +1 -1
  142. package/lib/chain/stateCache/types.js.map +1 -1
  143. package/lib/chain/validation/attesterSlashing.js +3 -3
  144. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  145. package/lib/chain/validation/blobSidecar.js +1 -1
  146. package/lib/chain/validation/blobSidecar.js.map +1 -1
  147. package/lib/chain/validation/block.d.ts.map +1 -1
  148. package/lib/chain/validation/block.js +3 -3
  149. package/lib/chain/validation/block.js.map +1 -1
  150. package/lib/chain/validation/blsToExecutionChange.js +2 -2
  151. package/lib/chain/validation/blsToExecutionChange.js.map +1 -1
  152. package/lib/chain/validation/dataColumnSidecar.js +1 -1
  153. package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
  154. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
  155. package/lib/chain/validation/executionPayloadBid.js +4 -4
  156. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  157. package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
  158. package/lib/chain/validation/executionPayloadEnvelope.js +2 -3
  159. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
  160. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
  161. package/lib/chain/validation/payloadAttestationMessage.js +1 -2
  162. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  163. package/lib/chain/validation/proposerSlashing.js +1 -1
  164. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  165. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts +2 -2
  166. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts.map +1 -1
  167. package/lib/chain/validation/signatureSets/contributionAndProof.js +1 -1
  168. package/lib/chain/validation/signatureSets/contributionAndProof.js.map +1 -1
  169. package/lib/chain/validation/signatureSets/syncCommittee.d.ts +2 -2
  170. package/lib/chain/validation/signatureSets/syncCommittee.d.ts.map +1 -1
  171. package/lib/chain/validation/signatureSets/syncCommittee.js +1 -1
  172. package/lib/chain/validation/signatureSets/syncCommittee.js.map +1 -1
  173. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts +2 -2
  174. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts.map +1 -1
  175. package/lib/chain/validation/signatureSets/syncCommitteeContribution.js.map +1 -1
  176. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts +2 -2
  177. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts.map +1 -1
  178. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js +1 -1
  179. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js.map +1 -1
  180. package/lib/chain/validation/syncCommittee.d.ts +3 -3
  181. package/lib/chain/validation/syncCommittee.d.ts.map +1 -1
  182. package/lib/chain/validation/syncCommittee.js +1 -1
  183. package/lib/chain/validation/syncCommittee.js.map +1 -1
  184. package/lib/chain/validation/syncCommitteeContributionAndProof.d.ts.map +1 -1
  185. package/lib/chain/validation/syncCommitteeContributionAndProof.js +1 -1
  186. package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
  187. package/lib/chain/validation/voluntaryExit.d.ts.map +1 -1
  188. package/lib/chain/validation/voluntaryExit.js +3 -3
  189. package/lib/chain/validation/voluntaryExit.js.map +1 -1
  190. package/lib/chain/validatorMonitor.d.ts +3 -3
  191. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  192. package/lib/chain/validatorMonitor.js +9 -7
  193. package/lib/chain/validatorMonitor.js.map +1 -1
  194. package/lib/metrics/metrics/lodestar.d.ts +12 -4
  195. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  196. package/lib/metrics/metrics/lodestar.js +19 -15
  197. package/lib/metrics/metrics/lodestar.js.map +1 -1
  198. package/lib/network/interface.d.ts +4 -2
  199. package/lib/network/interface.d.ts.map +1 -1
  200. package/lib/network/network.d.ts +4 -2
  201. package/lib/network/network.d.ts.map +1 -1
  202. package/lib/network/network.js +9 -3
  203. package/lib/network/network.js.map +1 -1
  204. package/lib/network/processor/extractSlotRootFns.d.ts +1 -1
  205. package/lib/network/processor/extractSlotRootFns.js +1 -1
  206. package/lib/network/processor/gossipHandlers.js +1 -1
  207. package/lib/network/processor/gossipHandlers.js.map +1 -1
  208. package/lib/network/processor/index.d.ts +12 -7
  209. package/lib/network/processor/index.d.ts.map +1 -1
  210. package/lib/network/processor/index.js +99 -78
  211. package/lib/network/processor/index.js.map +1 -1
  212. package/lib/network/reqresp/ReqRespBeaconNode.d.ts.map +1 -1
  213. package/lib/network/reqresp/ReqRespBeaconNode.js +9 -0
  214. package/lib/network/reqresp/ReqRespBeaconNode.js.map +1 -1
  215. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts +8 -0
  216. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts.map +1 -0
  217. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +69 -0
  218. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -0
  219. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.d.ts +6 -0
  220. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.d.ts.map +1 -0
  221. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js +28 -0
  222. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js.map +1 -0
  223. package/lib/network/reqresp/handlers/index.d.ts.map +1 -1
  224. package/lib/network/reqresp/handlers/index.js +11 -1
  225. package/lib/network/reqresp/handlers/index.js.map +1 -1
  226. package/lib/network/reqresp/protocols.d.ts +2 -0
  227. package/lib/network/reqresp/protocols.d.ts.map +1 -1
  228. package/lib/network/reqresp/protocols.js +10 -0
  229. package/lib/network/reqresp/protocols.js.map +1 -1
  230. package/lib/network/reqresp/rateLimit.d.ts.map +1 -1
  231. package/lib/network/reqresp/rateLimit.js +8 -0
  232. package/lib/network/reqresp/rateLimit.js.map +1 -1
  233. package/lib/network/reqresp/score.d.ts.map +1 -1
  234. package/lib/network/reqresp/score.js +2 -0
  235. package/lib/network/reqresp/score.js.map +1 -1
  236. package/lib/network/reqresp/types.d.ts +8 -2
  237. package/lib/network/reqresp/types.d.ts.map +1 -1
  238. package/lib/network/reqresp/types.js +7 -1
  239. package/lib/network/reqresp/types.js.map +1 -1
  240. package/lib/node/nodejs.d.ts +2 -2
  241. package/lib/node/nodejs.d.ts.map +1 -1
  242. package/lib/node/nodejs.js +1 -4
  243. package/lib/node/nodejs.js.map +1 -1
  244. package/lib/node/notifier.d.ts.map +1 -1
  245. package/lib/node/notifier.js +3 -3
  246. package/lib/node/notifier.js.map +1 -1
  247. package/lib/sync/backfill/backfill.d.ts +2 -2
  248. package/lib/sync/backfill/backfill.d.ts.map +1 -1
  249. package/lib/sync/backfill/backfill.js +2 -2
  250. package/lib/sync/backfill/backfill.js.map +1 -1
  251. package/lib/sync/unknownBlock.d.ts +1 -1
  252. package/lib/sync/unknownBlock.js +1 -1
  253. package/lib/util/types.d.ts +2 -0
  254. package/lib/util/types.d.ts.map +1 -1
  255. package/lib/util/types.js +1 -0
  256. package/lib/util/types.js.map +1 -1
  257. package/package.json +15 -15
  258. package/src/api/impl/beacon/blocks/index.ts +1 -1
  259. package/src/api/impl/beacon/pool/index.ts +1 -1
  260. package/src/api/impl/beacon/state/index.ts +29 -41
  261. package/src/api/impl/beacon/state/utils.ts +11 -25
  262. package/src/api/impl/lodestar/index.ts +4 -8
  263. package/src/api/impl/proof/index.ts +2 -9
  264. package/src/api/impl/validator/index.ts +29 -41
  265. package/src/api/impl/validator/utils.ts +4 -7
  266. package/src/chain/archiveStore/historicalState/getHistoricalState.ts +6 -36
  267. package/src/chain/archiveStore/historicalState/worker.ts +1 -0
  268. package/src/chain/balancesCache.ts +5 -11
  269. package/src/chain/blocks/blockInput/types.ts +1 -0
  270. package/src/chain/blocks/importBlock.ts +11 -14
  271. package/src/chain/blocks/importExecutionPayload.ts +6 -11
  272. package/src/chain/blocks/index.ts +1 -1
  273. package/src/chain/blocks/types.ts +2 -2
  274. package/src/chain/blocks/utils/checkpoint.ts +2 -2
  275. package/src/chain/blocks/verifyBlock.ts +5 -10
  276. package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +5 -10
  277. package/src/chain/blocks/verifyBlocksSignatures.ts +3 -3
  278. package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +6 -8
  279. package/src/chain/chain.ts +75 -67
  280. package/src/chain/emitter.ts +2 -2
  281. package/src/chain/errors/blockError.ts +4 -4
  282. package/src/chain/forkChoice/index.ts +33 -42
  283. package/src/chain/initState.ts +7 -2
  284. package/src/chain/interface.ts +12 -13
  285. package/src/chain/lightClient/index.ts +9 -22
  286. package/src/chain/opPools/aggregatedAttestationPool.ts +15 -21
  287. package/src/chain/opPools/opPool.ts +13 -14
  288. package/src/chain/opPools/utils.ts +3 -3
  289. package/src/chain/prepareNextSlot.ts +6 -8
  290. package/src/chain/produceBlock/computeNewStateRoot.ts +6 -10
  291. package/src/chain/produceBlock/produceBlockBody.ts +22 -49
  292. package/src/chain/regen/interface.ts +13 -17
  293. package/src/chain/regen/queued.ts +16 -20
  294. package/src/chain/regen/regen.ts +16 -17
  295. package/src/chain/serializeState.ts +3 -3
  296. package/src/chain/shufflingCache.ts +5 -7
  297. package/src/chain/stateCache/fifoBlockStateCache.ts +7 -7
  298. package/src/chain/stateCache/persistentCheckpointsCache.ts +27 -42
  299. package/src/chain/stateCache/types.ts +14 -18
  300. package/src/chain/validation/attesterSlashing.ts +3 -3
  301. package/src/chain/validation/blobSidecar.ts +1 -1
  302. package/src/chain/validation/block.ts +2 -4
  303. package/src/chain/validation/blsToExecutionChange.ts +2 -2
  304. package/src/chain/validation/dataColumnSidecar.ts +1 -1
  305. package/src/chain/validation/executionPayloadBid.ts +3 -7
  306. package/src/chain/validation/executionPayloadEnvelope.ts +2 -8
  307. package/src/chain/validation/payloadAttestationMessage.ts +2 -4
  308. package/src/chain/validation/proposerSlashing.ts +1 -1
  309. package/src/chain/validation/signatureSets/contributionAndProof.ts +2 -7
  310. package/src/chain/validation/signatureSets/syncCommittee.ts +2 -7
  311. package/src/chain/validation/signatureSets/syncCommitteeContribution.ts +2 -2
  312. package/src/chain/validation/signatureSets/syncCommitteeSelectionProof.ts +2 -7
  313. package/src/chain/validation/syncCommittee.ts +6 -6
  314. package/src/chain/validation/syncCommitteeContributionAndProof.ts +5 -10
  315. package/src/chain/validation/voluntaryExit.ts +3 -8
  316. package/src/chain/validatorMonitor.ts +12 -11
  317. package/src/metrics/metrics/lodestar.ts +23 -19
  318. package/src/network/interface.ts +15 -2
  319. package/src/network/network.ts +32 -4
  320. package/src/network/processor/extractSlotRootFns.ts +1 -1
  321. package/src/network/processor/gossipHandlers.ts +1 -1
  322. package/src/network/processor/index.ts +110 -89
  323. package/src/network/reqresp/ReqRespBeaconNode.ts +13 -0
  324. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +94 -0
  325. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRoot.ts +43 -0
  326. package/src/network/reqresp/handlers/index.ts +12 -0
  327. package/src/network/reqresp/protocols.ts +12 -0
  328. package/src/network/reqresp/rateLimit.ts +18 -0
  329. package/src/network/reqresp/score.ts +2 -0
  330. package/src/network/reqresp/types.ts +13 -0
  331. package/src/node/nodejs.ts +3 -5
  332. package/src/node/notifier.ts +4 -10
  333. package/src/sync/backfill/backfill.ts +3 -3
  334. package/src/sync/unknownBlock.ts +1 -1
  335. package/src/util/types.ts +6 -0
@@ -1,5 +1,5 @@
1
1
  import {SYNC_COMMITTEE_SUBNET_SIZE} from "@lodestar/params";
2
- import {CachedBeaconStateAltair, isSyncCommitteeAggregator} from "@lodestar/state-transition";
2
+ import {IBeaconStateView, isSyncCommitteeAggregator} from "@lodestar/state-transition";
3
3
  import {ValidatorIndex, altair} from "@lodestar/types";
4
4
  import {GossipAction, SyncCommitteeError, SyncCommitteeErrorCode} from "../errors/index.js";
5
5
  import {IBeaconChain} from "../interface.js";
@@ -53,7 +53,7 @@ export async function validateSyncCommitteeGossipContributionAndProof(
53
53
  }
54
54
 
55
55
  // [REJECT] The contribution has participants -- that is, any(contribution.aggregation_bits)
56
- const syncCommitteeParticipantIndices = getContributionIndices(headState as CachedBeaconStateAltair, contribution);
56
+ const syncCommitteeParticipantIndices = getContributionIndices(headState, contribution);
57
57
  if (syncCommitteeParticipantIndices.length === 0) {
58
58
  throw new SyncCommitteeError(GossipAction.REJECT, {
59
59
  code: SyncCommitteeErrorCode.NO_PARTICIPANT,
@@ -83,12 +83,7 @@ export async function validateSyncCommitteeGossipContributionAndProof(
83
83
 
84
84
  // [REJECT] The aggregate signature is valid for the message beacon_block_root and aggregate pubkey derived from
85
85
  // the participation info in aggregation_bits for the subcommittee specified by the contribution.subcommittee_index.
86
- getSyncCommitteeContributionSignatureSet(
87
- chain.config,
88
- headState as CachedBeaconStateAltair,
89
- contribution,
90
- syncCommitteeParticipantIndices
91
- ),
86
+ getSyncCommitteeContributionSignatureSet(chain.config, headState, contribution, syncCommitteeParticipantIndices),
92
87
  ];
93
88
 
94
89
  if (!(await chain.bls.verifySignatureSets(signatureSets, {batchable: true}))) {
@@ -109,12 +104,12 @@ export async function validateSyncCommitteeGossipContributionAndProof(
109
104
  * - pubkeyCache
110
105
  */
111
106
  function getContributionIndices(
112
- state: CachedBeaconStateAltair,
107
+ state: IBeaconStateView,
113
108
  contribution: altair.SyncCommitteeContribution
114
109
  ): ValidatorIndex[] {
115
110
  const startIndex = contribution.subcommitteeIndex * SYNC_COMMITTEE_SUBNET_SIZE;
116
111
 
117
- const syncCommittee = state.epochCtx.getIndexedSyncCommittee(contribution.slot);
112
+ const syncCommittee = state.getIndexedSyncCommittee(contribution.slot);
118
113
  // The bits in contribution.aggregationBits select validatorIndexes in the subcommittee starting at startIndex
119
114
  const subcommitteeValidatorIndices = syncCommittee.validatorIndices.slice(
120
115
  startIndex,
@@ -1,9 +1,4 @@
1
- import {
2
- BeaconStateView,
3
- VoluntaryExitValidity,
4
- getVoluntaryExitSignatureSet,
5
- getVoluntaryExitValidity,
6
- } from "@lodestar/state-transition";
1
+ import {VoluntaryExitValidity, getVoluntaryExitSignatureSet} from "@lodestar/state-transition";
7
2
  import {phase0} from "@lodestar/types";
8
3
  import {
9
4
  GossipAction,
@@ -53,14 +48,14 @@ async function validateVoluntaryExit(
53
48
 
54
49
  // [REJECT] All of the conditions within process_voluntary_exit pass validation.
55
50
  // verifySignature = false, verified in batch below
56
- const validity = getVoluntaryExitValidity(chain.config.getForkSeq(state.slot), state, voluntaryExit, false);
51
+ const validity = state.getVoluntaryExitValidity(voluntaryExit, false);
57
52
  if (validity !== VoluntaryExitValidity.valid) {
58
53
  throw new VoluntaryExitError(GossipAction.REJECT, {
59
54
  code: voluntaryExitValidityToErrorCode(validity),
60
55
  });
61
56
  }
62
57
 
63
- const signatureSet = getVoluntaryExitSignatureSet(chain.config, new BeaconStateView(state), voluntaryExit);
58
+ const signatureSet = getVoluntaryExitSignatureSet(chain.config, state, voluntaryExit);
64
59
  if (!(await chain.bls.verifySignatureSets([signatureSet], {batchable: true, priority: prioritizeBls}))) {
65
60
  throw new VoluntaryExitError(GossipAction.REJECT, {
66
61
  code: VoluntaryExitErrorCode.INVALID_SIGNATURE,
@@ -1,13 +1,11 @@
1
1
  import {ChainForkConfig} from "@lodestar/config";
2
2
  import {ForkSeq, MIN_ATTESTATION_INCLUSION_DELAY, SLOTS_PER_EPOCH} from "@lodestar/params";
3
3
  import {
4
- CachedBeaconStateAllForks,
5
- CachedBeaconStateAltair,
4
+ IBeaconStateView,
6
5
  ParticipationFlags,
7
6
  computeEpochAtSlot,
8
7
  computeStartSlotAtEpoch,
9
8
  computeTimeAtSlot,
10
- getBlockRootAtSlot,
11
9
  getCurrentSlot,
12
10
  parseAttesterFlags,
13
11
  parseParticipationFlags,
@@ -102,7 +100,7 @@ export type ValidatorMonitor = {
102
100
  syncAggregate: altair.SyncAggregate,
103
101
  syncCommitteeIndices: Uint32Array
104
102
  ): void;
105
- onceEveryEndOfEpoch(state: CachedBeaconStateAllForks): void;
103
+ onceEveryEndOfEpoch(state: IBeaconStateView): void;
106
104
  scrapeMetrics(slotClock: Slot): void;
107
105
  /** Returns the list of validator indices currently being monitored */
108
106
  getMonitoredValidatorIndices(): ValidatorIndex[];
@@ -736,16 +734,19 @@ export function createValidatorMonitor(
736
734
  return;
737
735
  }
738
736
 
737
+ if (validators.size === 0) {
738
+ return;
739
+ }
740
+
739
741
  const rootCache = new RootHexCache(headState);
740
742
 
741
743
  if (config.getForkSeq(headState.slot) >= ForkSeq.altair) {
742
- const {previousEpochParticipation} = headState as CachedBeaconStateAltair;
743
744
  const prevEpochStartSlot = computeStartSlotAtEpoch(prevEpoch);
744
- const prevEpochTargetRoot = toRootHex(getBlockRootAtSlot(headState, prevEpochStartSlot));
745
+ const prevEpochTargetRoot = toRootHex(headState.getBlockRootAtSlot(prevEpochStartSlot));
745
746
 
746
747
  // Check attestation performance
747
748
  for (const [index, validator] of validators.entries()) {
748
- const flags = parseParticipationFlags(previousEpochParticipation.get(index));
749
+ const flags = parseParticipationFlags(headState.getPreviousEpochParticipation(index));
749
750
  const attestationSummary = validator.attestations.get(prevEpoch)?.get(prevEpochTargetRoot);
750
751
  const summary = renderAttestationSummary(config, rootCache, attestationSummary, flags);
751
752
  validatorMonitorMetrics?.prevEpochAttestationSummary.inc({summary});
@@ -757,9 +758,9 @@ export function createValidatorMonitor(
757
758
  }
758
759
  }
759
760
 
760
- if (headState.epochCtx.proposersPrevEpoch !== null) {
761
+ if (headState.previousProposers !== null) {
761
762
  // proposersPrevEpoch is null on the first epoch of `headState` being generated
762
- for (const [slotIndex, validatorIndex] of headState.epochCtx.proposersPrevEpoch.entries()) {
763
+ for (const [slotIndex, validatorIndex] of headState.previousProposers.entries()) {
763
764
  const validator = validators.get(validatorIndex);
764
765
  if (validator) {
765
766
  // If expected proposer is a tracked validator
@@ -1139,12 +1140,12 @@ function renderBlockProposalSummary(
1139
1140
  export class RootHexCache {
1140
1141
  private readonly blockRootSlotCache = new Map<Slot, RootHex>();
1141
1142
 
1142
- constructor(private readonly state: CachedBeaconStateAllForks) {}
1143
+ constructor(private readonly state: IBeaconStateView) {}
1143
1144
 
1144
1145
  getBlockRootAtSlot(slot: Slot): RootHex {
1145
1146
  let root = this.blockRootSlotCache.get(slot);
1146
1147
  if (!root) {
1147
- root = toRootHex(getBlockRootAtSlot(this.state, slot));
1148
+ root = toRootHex(this.state.getBlockRootAtSlot(slot));
1148
1149
  this.blockRootSlotCache.set(slot, root);
1149
1150
  }
1150
1151
  return root;
@@ -1712,33 +1712,37 @@ export function createLodestarMetrics(
1712
1712
  }),
1713
1713
  },
1714
1714
 
1715
- // reprocess gossip attestations
1716
- reprocessGossipAttestations: {
1717
- total: register.gauge({
1718
- name: "lodestar_reprocess_gossip_attestations_total",
1719
- help: "Total number of gossip attestations waiting to reprocess",
1715
+ // some gossip messages need to wait for block to be processed before they can be processed
1716
+ awaitingBlockGossipMessages: {
1717
+ queue: register.gauge<{topic: GossipType}>({
1718
+ name: "lodestar_awaiting_block_gossip_messages_total",
1719
+ help: "Total number of gossip messages waiting for block to be processed",
1720
+ labelNames: ["topic"],
1720
1721
  }),
1721
1722
  countPerSlot: register.gauge({
1722
- name: "lodestar_reprocess_gossip_attestations_per_slot_total",
1723
- help: "Total number of gossip attestations waiting to reprocess pet slot",
1723
+ name: "lodestar_awaiting_block_gossip_messages_per_slot_total",
1724
+ help: "Total number of gossip messages waiting for block to be processed per slot",
1724
1725
  }),
1725
- resolve: register.gauge({
1726
- name: "lodestar_reprocess_gossip_attestations_resolve_total",
1727
- help: "Total number of gossip attestations are reprocessed",
1726
+ resolve: register.gauge<{topic: GossipType}>({
1727
+ name: "lodestar_awaiting_block_gossip_messages_resolve_total",
1728
+ help: "Total number of gossip messages are reprocessed",
1729
+ labelNames: ["topic"],
1728
1730
  }),
1729
- waitSecBeforeResolve: register.gauge({
1730
- name: "lodestar_reprocess_gossip_attestations_wait_time_resolve_seconds",
1731
+ waitSecBeforeResolve: register.gauge<{topic: GossipType}>({
1732
+ name: "lodestar_awaiting_block_gossip_messages_wait_time_resolve_seconds",
1731
1733
  help: "Time to wait for unknown block in seconds",
1734
+ labelNames: ["topic"],
1732
1735
  }),
1733
- reject: register.gauge<{reason: ReprocessRejectReason}>({
1734
- name: "lodestar_reprocess_gossip_attestations_reject_total",
1735
- help: "Total number of attestations are rejected to reprocess",
1736
- labelNames: ["reason"],
1736
+ // having 2 labels here is not great for performance, however it's rarely happening and having the reason label is important for debugging
1737
+ reject: register.gauge<{reason: ReprocessRejectReason; topic: GossipType}>({
1738
+ name: "lodestar_awaiting_block_gossip_messages_reject_total",
1739
+ help: "Total number of gossip messages are rejected to reprocess",
1740
+ labelNames: ["reason", "topic"],
1737
1741
  }),
1738
- waitSecBeforeReject: register.gauge<{reason: ReprocessRejectReason}>({
1739
- name: "lodestar_reprocess_gossip_attestations_wait_time_reject_seconds",
1742
+ waitSecBeforeReject: register.gauge<{reason: ReprocessRejectReason; topic: GossipType}>({
1743
+ name: "lodestar_awaiting_block_gossip_messages_wait_time_reject_seconds",
1740
1744
  help: "Time to wait for unknown block before being rejected",
1741
- labelNames: ["reason"],
1745
+ labelNames: ["reason", "topic"],
1742
1746
  }),
1743
1747
  },
1744
1748
 
@@ -38,7 +38,12 @@ import {
38
38
  import {BlockInputSource} from "../chain/blocks/blockInput/types.js";
39
39
  import {CustodyConfig} from "../util/dataColumns.js";
40
40
  import {PeerIdStr} from "../util/peerId.js";
41
- import {BeaconBlocksByRootRequest, BlobSidecarsByRootRequest, DataColumnSidecarsByRootRequest} from "../util/types.js";
41
+ import {
42
+ BeaconBlocksByRootRequest,
43
+ BlobSidecarsByRootRequest,
44
+ DataColumnSidecarsByRootRequest,
45
+ ExecutionPayloadEnvelopesByRootRequest,
46
+ } from "../util/types.js";
42
47
  import {INetworkCorePublic} from "./core/types.js";
43
48
  import {INetworkEventBus} from "./events.js";
44
49
  import {GossipType} from "./gossip/interface.js";
@@ -68,7 +73,7 @@ export interface INetwork extends INetworkCorePublic {
68
73
  reportPeer(peer: PeerIdStr, action: PeerAction, actionName: string): void;
69
74
  shouldAggregate(subnet: SubnetID, slot: Slot): boolean;
70
75
  reStatusPeers(peers: PeerIdStr[]): Promise<void>;
71
- searchUnknownSlotRoot(slotRoot: SlotRootHex, source: BlockInputSource, peer?: PeerIdStr): void;
76
+ searchUnknownBlock(slotRoot: SlotRootHex, source: BlockInputSource, peer?: PeerIdStr): void;
72
77
  // ReqResp
73
78
  sendBeaconBlocksByRange(peerId: PeerIdStr, request: phase0.BeaconBlocksByRangeRequest): Promise<SignedBeaconBlock[]>;
74
79
  sendBeaconBlocksByRoot(peerId: PeerIdStr, request: BeaconBlocksByRootRequest): Promise<SignedBeaconBlock[]>;
@@ -82,6 +87,14 @@ export interface INetwork extends INetworkCorePublic {
82
87
  peerId: PeerIdStr,
83
88
  request: DataColumnSidecarsByRootRequest
84
89
  ): Promise<fulu.DataColumnSidecar[]>;
90
+ sendExecutionPayloadEnvelopesByRange(
91
+ peerId: PeerIdStr,
92
+ request: gloas.ExecutionPayloadEnvelopesByRangeRequest
93
+ ): Promise<gloas.SignedExecutionPayloadEnvelope[]>;
94
+ sendExecutionPayloadEnvelopesByRoot(
95
+ peerId: PeerIdStr,
96
+ request: ExecutionPayloadEnvelopesByRootRequest
97
+ ): Promise<gloas.SignedExecutionPayloadEnvelope[]>;
85
98
 
86
99
  // Gossip
87
100
  publishBeaconBlock(signedBlock: SignedBeaconBlock): Promise<number>;
@@ -40,7 +40,12 @@ import {IClock} from "../util/clock.js";
40
40
  import {CustodyConfig} from "../util/dataColumns.js";
41
41
  import {PeerIdStr, peerIdToString} from "../util/peerId.js";
42
42
  import {promiseAllMaybeAsync} from "../util/promises.js";
43
- import {BeaconBlocksByRootRequest, BlobSidecarsByRootRequest, DataColumnSidecarsByRootRequest} from "../util/types.js";
43
+ import {
44
+ BeaconBlocksByRootRequest,
45
+ BlobSidecarsByRootRequest,
46
+ DataColumnSidecarsByRootRequest,
47
+ ExecutionPayloadEnvelopesByRootRequest,
48
+ } from "../util/types.js";
44
49
  import {INetworkCore, NetworkCore, WorkerNetworkCore} from "./core/index.js";
45
50
  import {INetworkEventBus, NetworkEvent, NetworkEventBus, NetworkEventData} from "./events.js";
46
51
  import {getActiveForkBoundaries} from "./forks.js";
@@ -161,7 +166,7 @@ export class Network implements INetwork {
161
166
  const events = new NetworkEventBus();
162
167
  const aggregatorTracker = new AggregatorTracker();
163
168
 
164
- const activeValidatorCount = chain.getHeadState().epochCtx.currentShuffling.activeIndices.length;
169
+ const activeValidatorCount = chain.getHeadState().activeValidatorCount;
165
170
  const initialStatus = chain.getStatus();
166
171
  const initialCustodyGroupCount = chain.custodyConfig.targetCustodyGroupCount;
167
172
 
@@ -277,8 +282,8 @@ export class Network implements INetwork {
277
282
  return this.core.reStatusPeers(peers);
278
283
  }
279
284
 
280
- searchUnknownSlotRoot(slotRoot: SlotRootHex, source: BlockInputSource, peer?: PeerIdStr): void {
281
- this.networkProcessor.searchUnknownSlotRoot(slotRoot, source, peer);
285
+ searchUnknownBlock(slotRoot: SlotRootHex, source: BlockInputSource, peer?: PeerIdStr): void {
286
+ this.networkProcessor.searchUnknownBlock(slotRoot, source, peer);
282
287
  }
283
288
 
284
289
  async reportPeer(peer: PeerIdStr, action: PeerAction, actionName: string): Promise<void> {
@@ -636,6 +641,29 @@ export class Network implements INetwork {
636
641
  );
637
642
  }
638
643
 
644
+ async sendExecutionPayloadEnvelopesByRange(
645
+ peerId: PeerIdStr,
646
+ request: gloas.ExecutionPayloadEnvelopesByRangeRequest
647
+ ): Promise<gloas.SignedExecutionPayloadEnvelope[]> {
648
+ return collectMaxResponseTyped(
649
+ this.sendReqRespRequest(peerId, ReqRespMethod.ExecutionPayloadEnvelopesByRange, [Version.V1], request),
650
+ request.count,
651
+ responseSszTypeByMethod[ReqRespMethod.ExecutionPayloadEnvelopesByRange]
652
+ );
653
+ }
654
+
655
+ async sendExecutionPayloadEnvelopesByRoot(
656
+ peerId: PeerIdStr,
657
+ request: ExecutionPayloadEnvelopesByRootRequest
658
+ ): Promise<gloas.SignedExecutionPayloadEnvelope[]> {
659
+ return collectMaxResponseTyped(
660
+ this.sendReqRespRequest(peerId, ReqRespMethod.ExecutionPayloadEnvelopesByRoot, [Version.V1], request),
661
+ request.length,
662
+ responseSszTypeByMethod[ReqRespMethod.ExecutionPayloadEnvelopesByRoot],
663
+ this.chain.serializedCache
664
+ );
665
+ }
666
+
639
667
  private sendReqRespRequest<Req>(
640
668
  peerId: PeerIdStr,
641
669
  method: ReqRespMethod,
@@ -17,7 +17,7 @@ import {ExtractSlotRootFns} from "./types.js";
17
17
 
18
18
  /**
19
19
  * Extract the slot and block root of a gossip message form serialized data.
20
- * Only applicable for beacon_attestation and beacon_aggregate_and_proof topics.
20
+ * Not applicable for all topics.
21
21
  */
22
22
  export function createExtractBlockSlotRootFns(): ExtractSlotRootFns {
23
23
  return {
@@ -1044,7 +1044,7 @@ export async function validateGossipFnRetryUnknownRoot<T>(
1044
1044
  if (unknownBlockRootRetries === 0) {
1045
1045
  // Trigger unknown block root search here
1046
1046
  const rootHex = toRootHex(blockRoot);
1047
- network.searchUnknownSlotRoot({slot, root: rootHex}, BlockInputSource.gossip);
1047
+ network.searchUnknownBlock({slot, root: rootHex}, BlockInputSource.gossip);
1048
1048
  }
1049
1049
 
1050
1050
  if (unknownBlockRootRetries++ < MAX_UNKNOWN_BLOCK_ROOT_RETRIES) {
@@ -2,7 +2,7 @@ import {routes} from "@lodestar/api";
2
2
  import {ForkSeq} from "@lodestar/params";
3
3
  import {computeStartSlotAtEpoch} from "@lodestar/state-transition";
4
4
  import {RootHex, Slot, SlotRootHex} from "@lodestar/types";
5
- import {Logger, MapDef, mapValues, pruneSetToMax, sleep} from "@lodestar/utils";
5
+ import {Logger, MapDef, mapValues, sleep} from "@lodestar/utils";
6
6
  import {BlockInputSource} from "../../chain/blocks/blockInput/types.js";
7
7
  import {ChainEvent} from "../../chain/emitter.js";
8
8
  import {GossipErrorCode} from "../../chain/errors/gossipValidation.js";
@@ -87,27 +87,27 @@ const executeGossipWorkOrder = Object.keys(executeGossipWorkOrderObj) as (keyof
87
87
  // TODO: Arbitrary constant, check metrics
88
88
  const MAX_JOBS_SUBMITTED_PER_TICK = 128;
89
89
 
90
- // How many attestations (aggregate + unaggregate) we keep before new ones get dropped.
90
+ // How many gossip messages we keep before new ones get dropped.
91
91
  const MAX_QUEUED_UNKNOWN_BLOCK_GOSSIP_OBJECTS = 16_384;
92
92
 
93
- // We don't want to process too many attestations in a single tick
94
- // As seen on mainnet, attestation concurrency metric ranges from 1000 to 2000
93
+ // We don't want to process too many gossip messages in a single tick
94
+ // As seen on mainnet, gossip messages concurrency metric ranges from 1000 to 2000
95
95
  // so make this constant a little bit conservative
96
- const MAX_UNKNOWN_BLOCK_GOSSIP_OBJECTS_PER_TICK = 1024;
96
+ const MAX_AWAITING_GOSSIP_OBJECTS_PER_TICK = 1024;
97
97
 
98
98
  // Same motivation to JobItemQueue, we don't want to block the event loop
99
- const PROCESS_UNKNOWN_BLOCK_GOSSIP_OBJECTS_YIELD_EVERY_MS = 50;
99
+ const AWAITING_GOSSIP_OBJECTS_YIELD_EVERY_MS = 50;
100
100
 
101
101
  /**
102
102
  * Reprocess reject reason for metrics
103
103
  */
104
104
  export enum ReprocessRejectReason {
105
105
  /**
106
- * There are too many attestations that have unknown block root.
106
+ * There are too many gossip messages that have unknown block root.
107
107
  */
108
108
  reached_limit = "reached_limit",
109
109
  /**
110
- * The awaiting attestation is pruned per clock slot.
110
+ * The awaiting gossip message is pruned per clock slot.
111
111
  */
112
112
  expired = "expired",
113
113
  }
@@ -137,7 +137,7 @@ export enum CannotAcceptWorkReason {
137
137
  *
138
138
  * ### PendingGossipsubMessage beacon_attestation example
139
139
  *
140
- * For attestations, processing the message includes the steps:
140
+ * For gossip messages, processing the message includes the steps:
141
141
  * 1. Pre shuffling sync validation
142
142
  * 2. Retrieve shuffling: async + goes into the regen queue and can be expensive
143
143
  * 3. Pre sig validation sync validation
@@ -156,11 +156,10 @@ export class NetworkProcessor {
156
156
  private readonly gossipQueues: ReturnType<typeof createGossipQueues>;
157
157
  private readonly gossipTopicConcurrency: {[K in GossipType]: number};
158
158
  private readonly extractBlockSlotRootFns = createExtractBlockSlotRootFns();
159
- // we may not receive the block for Attestation and SignedAggregateAndProof messages, in that case PendingGossipsubMessage needs
159
+ // we may not receive the block for messages like Attestation and SignedAggregateAndProof messages, in that case PendingGossipsubMessage needs
160
160
  // to be stored in this Map and reprocessed once the block comes
161
- private readonly awaitingGossipsubMessagesByRootBySlot: MapDef<Slot, MapDef<RootHex, Set<PendingGossipsubMessage>>>;
162
- private unknownBlockGossipsubMessagesCount = 0;
163
- private unknownRootsBySlot = new MapDef<Slot, Set<RootHex>>(() => new Set());
161
+ private readonly awaitingMessagesByBlockRoot: MapDef<RootHex, Set<PendingGossipsubMessage>>;
162
+ private unknownBlocksBySlot = new MapDef<Slot, Set<RootHex>>(() => new Set());
164
163
 
165
164
  constructor(
166
165
  modules: NetworkProcessorModules,
@@ -184,9 +183,7 @@ export class NetworkProcessor {
184
183
  this.chain.emitter.on(routes.events.EventType.block, this.onBlockProcessed.bind(this));
185
184
  this.chain.clock.on(ClockEvent.slot, this.onClockSlot.bind(this));
186
185
 
187
- this.awaitingGossipsubMessagesByRootBySlot = new MapDef(
188
- () => new MapDef<RootHex, Set<PendingGossipsubMessage>>(() => new Set())
189
- );
186
+ this.awaitingMessagesByBlockRoot = new MapDef<RootHex, Set<PendingGossipsubMessage>>(() => new Set());
190
187
 
191
188
  // TODO: Implement queues and priorization for ReqResp incoming requests
192
189
  // Listens to NetworkEvent.reqRespIncomingRequest event
@@ -198,7 +195,7 @@ export class NetworkProcessor {
198
195
  metrics.gossipValidationQueue.keySize.set({topic}, this.gossipQueues[topic].keySize);
199
196
  metrics.gossipValidationQueue.concurrency.set({topic}, this.gossipTopicConcurrency[topic]);
200
197
  }
201
- metrics.reprocessGossipAttestations.countPerSlot.set(this.unknownBlockGossipsubMessagesCount);
198
+ metrics.awaitingBlockGossipMessages.countPerSlot.set(this.unknownBlockGossipsubMessagesCount);
202
199
  // specific metric for beacon_attestation topic
203
200
  metrics.gossipValidationQueue.keyAge.reset();
204
201
  for (const ageMs of this.gossipQueues.beacon_attestation.getDataAgeMs()) {
@@ -233,64 +230,77 @@ export class NetworkProcessor {
233
230
  return queue.getAll();
234
231
  }
235
232
 
236
- searchUnknownSlotRoot({slot, root}: SlotRootHex, source: BlockInputSource, peer?: PeerIdStr): void {
237
- if (this.chain.seenBlock(root) || this.unknownRootsBySlot.getOrDefault(slot).has(root)) {
233
+ /**
234
+ * Search block via `ChainEvent.unknownBlockRoot` event
235
+ * Note that slot is not necessarily the same to the block's slot but it can be used for a good prune strategy.
236
+ * In the rare case, if 2 messages on 2 slots search for the same root (for example beacon_attestation) we may emit the same root twice but BlockInputSync should handle it well.
237
+ */
238
+ searchUnknownBlock({slot, root}: SlotRootHex, source: BlockInputSource, peer?: PeerIdStr): void {
239
+ if (
240
+ this.chain.seenBlock(root) ||
241
+ this.awaitingMessagesByBlockRoot.has(root) ||
242
+ this.unknownBlocksBySlot.getOrDefault(slot).has(root)
243
+ ) {
238
244
  return;
239
245
  }
240
246
  // Search for the unknown block
241
- this.unknownRootsBySlot.getOrDefault(slot).add(root);
247
+ this.unknownBlocksBySlot.getOrDefault(slot).add(root);
242
248
  this.chain.emitter.emit(ChainEvent.unknownBlockRoot, {rootHex: root, peer, source});
243
249
  }
244
250
 
245
251
  private onPendingGossipsubMessage(message: PendingGossipsubMessage): void {
246
252
  const topicType = message.topic.type;
247
253
  const extractBlockSlotRootFn = this.extractBlockSlotRootFns[topicType];
248
- // check block root of Attestation and SignedAggregateAndProof messages
249
- if (extractBlockSlotRootFn) {
250
- const slotRoot = extractBlockSlotRootFn(message.msg.data, message.topic.boundary.fork);
251
- // if slotRoot is null, it means the msg.data is invalid
252
- // in that case message will be rejected when deserializing data in later phase (gossipValidatorFn)
253
- if (slotRoot) {
254
- // DOS protection: avoid processing messages that are too old
255
- const {slot, root} = slotRoot;
256
- const clockSlot = this.chain.clock.currentSlot;
257
- const {fork} = message.topic.boundary;
258
- let earliestPermissableSlot = clockSlot - DEFAULT_EARLIEST_PERMISSIBLE_SLOT_DISTANCE;
259
- if (ForkSeq[fork] >= ForkSeq.deneb && topicType === GossipType.beacon_attestation) {
260
- // post deneb, the attestations could be in current or previous epoch
261
- earliestPermissableSlot = computeStartSlotAtEpoch(this.chain.clock.currentEpoch - 1);
262
- }
263
- if (slot < earliestPermissableSlot) {
264
- // TODO: Should report the dropped job to gossip? It will be eventually pruned from the mcache
265
- this.metrics?.networkProcessor.gossipValidationError.inc({
266
- topic: topicType,
267
- error: GossipErrorCode.PAST_SLOT,
268
- });
269
- return;
270
- }
271
- message.msgSlot = slot;
272
- // check if we processed a block with this root
273
- // no need to check if root is a descendant of the current finalized block, it will be checked once we validate the message if needed
274
- if (root && !this.chain.forkChoice.hasBlockHexUnsafe(root)) {
275
- this.searchUnknownSlotRoot({slot, root}, BlockInputSource.gossip, message.propagationSource.toString());
276
-
277
- if (this.unknownBlockGossipsubMessagesCount > MAX_QUEUED_UNKNOWN_BLOCK_GOSSIP_OBJECTS) {
278
- // TODO: Should report the dropped job to gossip? It will be eventually pruned from the mcache
279
- this.metrics?.reprocessGossipAttestations.reject.inc({reason: ReprocessRejectReason.reached_limit});
280
- return;
281
- }
254
+ const slotRoot = extractBlockSlotRootFn
255
+ ? extractBlockSlotRootFn(message.msg.data, message.topic.boundary.fork)
256
+ : null;
257
+ if (slotRoot === null) {
258
+ // some messages don't have slot and root
259
+ // if the msg.data is invalid, message will be rejected when deserializing data in later phase (gossipValidatorFn)
260
+ this.pushPendingGossipsubMessageToQueue(message);
261
+ return;
262
+ }
282
263
 
283
- this.metrics?.reprocessGossipAttestations.total.inc();
284
- const awaitingGossipsubMessagesByRoot = this.awaitingGossipsubMessagesByRootBySlot.getOrDefault(slot);
285
- const awaitingGossipsubMessages = awaitingGossipsubMessagesByRoot.getOrDefault(root);
286
- awaitingGossipsubMessages.add(message);
287
- this.unknownBlockGossipsubMessagesCount++;
288
- return;
289
- }
264
+ // common check for all topics
265
+ // DOS protection: avoid processing messages that are too old
266
+ const {slot, root} = slotRoot;
267
+ const clockSlot = this.chain.clock.currentSlot;
268
+ const {fork} = message.topic.boundary;
269
+ let earliestPermissableSlot = clockSlot - DEFAULT_EARLIEST_PERMISSIBLE_SLOT_DISTANCE;
270
+ if (ForkSeq[fork] >= ForkSeq.deneb && topicType === GossipType.beacon_attestation) {
271
+ // post deneb, the attestations could be in current or previous epoch
272
+ earliestPermissableSlot = computeStartSlotAtEpoch(this.chain.clock.currentEpoch - 1);
273
+ }
274
+ if (slot < earliestPermissableSlot) {
275
+ // No need to report the dropped job to gossip. It will be eventually pruned from the mcache
276
+ this.metrics?.networkProcessor.gossipValidationError.inc({
277
+ topic: topicType,
278
+ error: GossipErrorCode.PAST_SLOT,
279
+ });
280
+ return;
281
+ }
282
+
283
+ message.msgSlot = slot;
284
+
285
+ // no need to check if root is a descendant of the current finalized block, it will be checked once we validate the message if needed
286
+ if (root && !this.chain.forkChoice.hasBlockHexUnsafe(root)) {
287
+ this.searchUnknownBlock({slot, root}, BlockInputSource.network_processor, message.propagationSource.toString());
288
+
289
+ if (this.unknownBlockGossipsubMessagesCount > MAX_QUEUED_UNKNOWN_BLOCK_GOSSIP_OBJECTS) {
290
+ // No need to report the dropped job to gossip. It will be eventually pruned from the mcache
291
+ this.metrics?.awaitingBlockGossipMessages.reject.inc({
292
+ reason: ReprocessRejectReason.reached_limit,
293
+ topic: topicType,
294
+ });
295
+ return;
290
296
  }
297
+
298
+ this.metrics?.awaitingBlockGossipMessages.queue.inc({topic: topicType});
299
+ const awaitingGossipsubMessages = this.awaitingMessagesByBlockRoot.getOrDefault(root);
300
+ awaitingGossipsubMessages.add(message);
301
+ return;
291
302
  }
292
303
 
293
- // bypass the check for other messages
294
304
  this.pushPendingGossipsubMessageToQueue(message);
295
305
  }
296
306
 
@@ -298,7 +308,7 @@ export class NetworkProcessor {
298
308
  const topicType = message.topic.type;
299
309
  const droppedCount = this.gossipQueues[topicType].add(message);
300
310
  if (droppedCount) {
301
- // TODO: Should report the dropped job to gossip? It will be eventually pruned from the mcache
311
+ // No need to report the dropped job to gossip. It will be eventually pruned from the mcache
302
312
  this.metrics?.gossipValidationQueue.droppedJobs.inc({topic: message.topic.type}, droppedCount);
303
313
  }
304
314
 
@@ -306,58 +316,61 @@ export class NetworkProcessor {
306
316
  this.executeWork();
307
317
  }
308
318
 
309
- private async onBlockProcessed({
310
- slot,
311
- block: rootHex,
312
- }: {
313
- slot: Slot;
314
- block: string;
315
- executionOptimistic: boolean;
316
- }): Promise<void> {
317
- const byRootGossipsubMessages = this.awaitingGossipsubMessagesByRootBySlot.getOrDefault(slot);
318
- const waitingGossipsubMessages = byRootGossipsubMessages.getOrDefault(rootHex);
319
- if (waitingGossipsubMessages.size === 0) {
319
+ private async onBlockProcessed({block: rootHex}: {block: string; executionOptimistic: boolean}): Promise<void> {
320
+ const waitingGossipsubMessages = this.awaitingMessagesByBlockRoot.get(rootHex);
321
+ if (!waitingGossipsubMessages || waitingGossipsubMessages.size === 0) {
320
322
  return;
321
323
  }
322
324
 
323
- this.metrics?.reprocessGossipAttestations.resolve.inc(waitingGossipsubMessages.size);
324
325
  const nowSec = Date.now() / 1000;
325
326
  let count = 0;
326
327
  // TODO: we can group attestations to process in batches but since we have the SeenAttestationDatas
327
328
  // cache, it may not be necessary at this time
328
329
  for (const message of waitingGossipsubMessages) {
329
- this.metrics?.reprocessGossipAttestations.waitSecBeforeResolve.set(nowSec - message.seenTimestampSec);
330
+ const topicType = message.topic.type;
331
+ this.metrics?.awaitingBlockGossipMessages.waitSecBeforeResolve.set(
332
+ {topic: topicType},
333
+ nowSec - message.seenTimestampSec
334
+ );
335
+ this.metrics?.awaitingBlockGossipMessages.resolve.inc({topic: topicType});
330
336
  this.pushPendingGossipsubMessageToQueue(message);
331
337
  count++;
332
338
  // don't want to block the event loop, worse case it'd wait for 16_084 / 1024 * 50ms = 800ms which is not a big deal
333
- if (count === MAX_UNKNOWN_BLOCK_GOSSIP_OBJECTS_PER_TICK) {
339
+ if (count === MAX_AWAITING_GOSSIP_OBJECTS_PER_TICK) {
334
340
  count = 0;
335
- await sleep(PROCESS_UNKNOWN_BLOCK_GOSSIP_OBJECTS_YIELD_EVERY_MS);
341
+ await sleep(AWAITING_GOSSIP_OBJECTS_YIELD_EVERY_MS);
336
342
  }
337
343
  }
338
344
 
339
- byRootGossipsubMessages.delete(rootHex);
345
+ this.awaitingMessagesByBlockRoot.delete(rootHex);
340
346
  }
341
347
 
342
348
  private onClockSlot(clockSlot: Slot): void {
343
349
  const nowSec = Date.now() / 1000;
344
- for (const [slot, gossipMessagesByRoot] of this.awaitingGossipsubMessagesByRootBySlot.entries()) {
345
- if (slot < clockSlot) {
346
- for (const gossipMessages of gossipMessagesByRoot.values()) {
350
+ const minSlot = clockSlot - MAX_UNKNOWN_ROOTS_SLOT_CACHE_SIZE;
351
+
352
+ for (const [slot, roots] of this.unknownBlocksBySlot) {
353
+ if (slot > minSlot) continue;
354
+ for (const rootHex of roots) {
355
+ const gossipMessages = this.awaitingMessagesByBlockRoot.get(rootHex);
356
+ if (gossipMessages !== undefined) {
347
357
  for (const message of gossipMessages) {
348
- this.metrics?.reprocessGossipAttestations.reject.inc({reason: ReprocessRejectReason.expired});
349
- this.metrics?.reprocessGossipAttestations.waitSecBeforeReject.set(
350
- {reason: ReprocessRejectReason.expired},
358
+ const topicType = message.topic.type;
359
+ this.metrics?.awaitingBlockGossipMessages.reject.inc({
360
+ topic: topicType,
361
+ reason: ReprocessRejectReason.expired,
362
+ });
363
+ this.metrics?.awaitingBlockGossipMessages.waitSecBeforeReject.set(
364
+ {topic: topicType, reason: ReprocessRejectReason.expired},
351
365
  nowSec - message.seenTimestampSec
352
366
  );
353
- // TODO: Should report the dropped job to gossip? It will be eventually pruned from the mcache
367
+ // No need to report the dropped job to gossip. It will be eventually pruned from the mcache
354
368
  }
369
+ this.awaitingMessagesByBlockRoot.delete(rootHex);
355
370
  }
356
- this.awaitingGossipsubMessagesByRootBySlot.delete(slot);
357
371
  }
372
+ this.unknownBlocksBySlot.delete(slot);
358
373
  }
359
- pruneSetToMax(this.unknownRootsBySlot, MAX_UNKNOWN_ROOTS_SLOT_CACHE_SIZE);
360
- this.unknownBlockGossipsubMessagesCount = 0;
361
374
  }
362
375
 
363
376
  private executeWork(): void {
@@ -496,4 +509,12 @@ export class NetworkProcessor {
496
509
 
497
510
  return null;
498
511
  }
512
+
513
+ private get unknownBlockGossipsubMessagesCount(): number {
514
+ let count = 0;
515
+ for (const messages of this.awaitingMessagesByBlockRoot.values()) {
516
+ count += messages.size;
517
+ }
518
+ return count;
519
+ }
499
520
  }