@lodestar/beacon-node 1.51.0-dev.c6e566f915 → 1.51.0-dev.cda05d18f1

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 (598) hide show
  1. package/lib/api/impl/api.js +1 -1
  2. package/lib/api/impl/api.js.map +1 -1
  3. package/lib/api/impl/beacon/blocks/index.d.ts +2 -1
  4. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  5. package/lib/api/impl/beacon/blocks/index.js +48 -95
  6. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  7. package/lib/api/impl/beacon/index.d.ts +2 -1
  8. package/lib/api/impl/beacon/index.d.ts.map +1 -1
  9. package/lib/api/impl/beacon/index.js +2 -2
  10. package/lib/api/impl/beacon/index.js.map +1 -1
  11. package/lib/api/impl/beacon/pool/index.d.ts.map +1 -1
  12. package/lib/api/impl/beacon/pool/index.js +22 -2
  13. package/lib/api/impl/beacon/pool/index.js.map +1 -1
  14. package/lib/api/impl/beacon/state/utils.d.ts +1 -1
  15. package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
  16. package/lib/api/impl/validator/index.d.ts +6 -0
  17. package/lib/api/impl/validator/index.d.ts.map +1 -1
  18. package/lib/api/impl/validator/index.js +49 -31
  19. package/lib/api/impl/validator/index.js.map +1 -1
  20. package/lib/api/options.d.ts +2 -0
  21. package/lib/api/options.d.ts.map +1 -1
  22. package/lib/api/options.js +1 -0
  23. package/lib/api/options.js.map +1 -1
  24. package/lib/chain/GetBlobsTracker.d.ts +13 -2
  25. package/lib/chain/GetBlobsTracker.d.ts.map +1 -1
  26. package/lib/chain/GetBlobsTracker.js +69 -35
  27. package/lib/chain/GetBlobsTracker.js.map +1 -1
  28. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  29. package/lib/chain/archiveStore/archiveStore.js +1 -0
  30. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  31. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts +4 -0
  32. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
  33. package/lib/chain/archiveStore/utils/archiveBlocks.js +61 -97
  34. package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
  35. package/lib/chain/blocks/blockInput/blockInput.d.ts +11 -56
  36. package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
  37. package/lib/chain/blocks/blockInput/blockInput.js +5 -241
  38. package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
  39. package/lib/chain/blocks/blockInput/errors.d.ts +2 -4
  40. package/lib/chain/blocks/blockInput/errors.d.ts.map +1 -1
  41. package/lib/chain/blocks/blockInput/errors.js.map +1 -1
  42. package/lib/chain/blocks/blockInput/types.d.ts +2 -18
  43. package/lib/chain/blocks/blockInput/types.d.ts.map +1 -1
  44. package/lib/chain/blocks/blockInput/types.js +0 -1
  45. package/lib/chain/blocks/blockInput/types.js.map +1 -1
  46. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  47. package/lib/chain/blocks/importBlock.js +40 -56
  48. package/lib/chain/blocks/importBlock.js.map +1 -1
  49. package/lib/chain/blocks/importExecutionPayload.d.ts +10 -11
  50. package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
  51. package/lib/chain/blocks/importExecutionPayload.js +34 -19
  52. package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
  53. package/lib/chain/blocks/index.d.ts.map +1 -1
  54. package/lib/chain/blocks/index.js +4 -4
  55. package/lib/chain/blocks/index.js.map +1 -1
  56. package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts +12 -9
  57. package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts.map +1 -1
  58. package/lib/chain/blocks/payloadEnvelopeProcessor.js +24 -19
  59. package/lib/chain/blocks/payloadEnvelopeProcessor.js.map +1 -1
  60. package/lib/chain/blocks/types.d.ts +4 -20
  61. package/lib/chain/blocks/types.d.ts.map +1 -1
  62. package/lib/chain/blocks/types.js +0 -24
  63. package/lib/chain/blocks/types.js.map +1 -1
  64. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  65. package/lib/chain/blocks/verifyBlock.js +18 -7
  66. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  67. package/lib/chain/blocks/verifyBlocksDataAvailability.d.ts.map +1 -1
  68. package/lib/chain/blocks/verifyBlocksDataAvailability.js +14 -2
  69. package/lib/chain/blocks/verifyBlocksDataAvailability.js.map +1 -1
  70. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts +1 -1
  71. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
  72. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +7 -3
  73. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
  74. package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts.map +1 -1
  75. package/lib/chain/blocks/verifyBlocksSanityChecks.js +4 -0
  76. package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
  77. package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
  78. package/lib/chain/blocks/verifyBlocksSignatures.js +10 -5
  79. package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
  80. package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts +3 -3
  81. package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts.map +1 -1
  82. package/lib/chain/blocks/verifyPayloadsDataAvailability.js +11 -6
  83. package/lib/chain/blocks/verifyPayloadsDataAvailability.js.map +1 -1
  84. package/lib/chain/blocks/writeBlockInputToDb.d.ts +0 -2
  85. package/lib/chain/blocks/writeBlockInputToDb.d.ts.map +1 -1
  86. package/lib/chain/blocks/writeBlockInputToDb.js +6 -24
  87. package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
  88. package/lib/chain/bls/interface.d.ts +2 -0
  89. package/lib/chain/bls/interface.d.ts.map +1 -1
  90. package/lib/chain/bls/multithread/index.d.ts +1 -1
  91. package/lib/chain/bls/multithread/index.d.ts.map +1 -1
  92. package/lib/chain/bls/multithread/index.js +50 -22
  93. package/lib/chain/bls/multithread/index.js.map +1 -1
  94. package/lib/chain/bls/multithread/types.d.ts +1 -1
  95. package/lib/chain/bls/multithread/types.d.ts.map +1 -1
  96. package/lib/chain/bls/multithread/worker.js +1 -1
  97. package/lib/chain/bls/multithread/worker.js.map +1 -1
  98. package/lib/chain/bls/singleThread.js +1 -1
  99. package/lib/chain/bls/singleThread.js.map +1 -1
  100. package/lib/chain/bls/utils.js +1 -1
  101. package/lib/chain/bls/utils.js.map +1 -1
  102. package/lib/chain/chain.d.ts +25 -4
  103. package/lib/chain/chain.d.ts.map +1 -1
  104. package/lib/chain/chain.js +124 -43
  105. package/lib/chain/chain.js.map +1 -1
  106. package/lib/chain/emitter.d.ts +7 -7
  107. package/lib/chain/emitter.d.ts.map +1 -1
  108. package/lib/chain/emitter.js +5 -5
  109. package/lib/chain/emitter.js.map +1 -1
  110. package/lib/chain/errors/blockError.d.ts +1 -1
  111. package/lib/chain/errors/blockError.d.ts.map +1 -1
  112. package/lib/chain/errors/blockError.js +1 -1
  113. package/lib/chain/errors/blockError.js.map +1 -1
  114. package/lib/chain/errors/executionPayloadEnvelope.d.ts +7 -0
  115. package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
  116. package/lib/chain/errors/executionPayloadEnvelope.js +1 -0
  117. package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
  118. package/lib/chain/errors/index.d.ts +0 -1
  119. package/lib/chain/errors/index.d.ts.map +1 -1
  120. package/lib/chain/errors/index.js +0 -1
  121. package/lib/chain/errors/index.js.map +1 -1
  122. package/lib/chain/forkChoice/index.d.ts +11 -1
  123. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  124. package/lib/chain/forkChoice/index.js +11 -0
  125. package/lib/chain/forkChoice/index.js.map +1 -1
  126. package/lib/chain/forkChoiceExecutionEngine.d.ts +51 -0
  127. package/lib/chain/forkChoiceExecutionEngine.d.ts.map +1 -0
  128. package/lib/chain/forkChoiceExecutionEngine.js +117 -0
  129. package/lib/chain/forkChoiceExecutionEngine.js.map +1 -0
  130. package/lib/chain/interface.d.ts +9 -7
  131. package/lib/chain/interface.d.ts.map +1 -1
  132. package/lib/chain/interface.js.map +1 -1
  133. package/lib/chain/opPools/aggregatedAttestationPool.d.ts +17 -4
  134. package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
  135. package/lib/chain/opPools/aggregatedAttestationPool.js +199 -46
  136. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  137. package/lib/chain/opPools/attestationPool.d.ts +1 -1
  138. package/lib/chain/opPools/attestationPool.d.ts.map +1 -1
  139. package/lib/chain/opPools/attestationPool.js +15 -4
  140. package/lib/chain/opPools/attestationPool.js.map +1 -1
  141. package/lib/chain/opPools/inclusionListStore.d.ts.map +1 -1
  142. package/lib/chain/opPools/inclusionListStore.js +2 -2
  143. package/lib/chain/opPools/inclusionListStore.js.map +1 -1
  144. package/lib/chain/opPools/index.d.ts +1 -0
  145. package/lib/chain/opPools/index.d.ts.map +1 -1
  146. package/lib/chain/opPools/index.js +1 -0
  147. package/lib/chain/opPools/index.js.map +1 -1
  148. package/lib/chain/opPools/payloadAttestationPool.d.ts.map +1 -1
  149. package/lib/chain/opPools/payloadAttestationPool.js +17 -7
  150. package/lib/chain/opPools/payloadAttestationPool.js.map +1 -1
  151. package/lib/chain/opPools/singleAttestationPool.d.ts +77 -0
  152. package/lib/chain/opPools/singleAttestationPool.d.ts.map +1 -0
  153. package/lib/chain/opPools/singleAttestationPool.js +209 -0
  154. package/lib/chain/opPools/singleAttestationPool.js.map +1 -0
  155. package/lib/chain/opPools/syncCommitteeMessagePool.d.ts.map +1 -1
  156. package/lib/chain/opPools/syncCommitteeMessagePool.js +9 -3
  157. package/lib/chain/opPools/syncCommitteeMessagePool.js.map +1 -1
  158. package/lib/chain/opPools/syncContributionAndProofPool.d.ts.map +1 -1
  159. package/lib/chain/opPools/syncContributionAndProofPool.js +11 -3
  160. package/lib/chain/opPools/syncContributionAndProofPool.js.map +1 -1
  161. package/lib/chain/opPools/utils.d.ts +1 -1
  162. package/lib/chain/opPools/utils.d.ts.map +1 -1
  163. package/lib/chain/opPools/utils.js +1 -1
  164. package/lib/chain/opPools/utils.js.map +1 -1
  165. package/lib/chain/options.d.ts +5 -3
  166. package/lib/chain/options.d.ts.map +1 -1
  167. package/lib/chain/options.js +0 -1
  168. package/lib/chain/options.js.map +1 -1
  169. package/lib/chain/produceBlock/produceBlockBody.d.ts +3 -2
  170. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  171. package/lib/chain/produceBlock/produceBlockBody.js +3 -3
  172. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  173. package/lib/chain/proposerTracker.d.ts +31 -0
  174. package/lib/chain/proposerTracker.d.ts.map +1 -0
  175. package/lib/chain/proposerTracker.js +75 -0
  176. package/lib/chain/proposerTracker.js.map +1 -0
  177. package/lib/chain/regen/interface.d.ts +1 -2
  178. package/lib/chain/regen/interface.d.ts.map +1 -1
  179. package/lib/chain/regen/interface.js +0 -1
  180. package/lib/chain/regen/interface.js.map +1 -1
  181. package/lib/chain/regen/queued.d.ts +1 -1
  182. package/lib/chain/regen/queued.d.ts.map +1 -1
  183. package/lib/chain/regen/queued.js +5 -3
  184. package/lib/chain/regen/queued.js.map +1 -1
  185. package/lib/chain/seenCache/seenGossipBlockInput.d.ts +7 -14
  186. package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
  187. package/lib/chain/seenCache/seenGossipBlockInput.js +6 -65
  188. package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
  189. package/lib/chain/validation/executionPayloadBid.d.ts +0 -15
  190. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
  191. package/lib/chain/validation/executionPayloadBid.js +13 -166
  192. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  193. package/lib/chain/validation/executionPayloadEnvelope.d.ts +6 -0
  194. package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
  195. package/lib/chain/validation/executionPayloadEnvelope.js +53 -0
  196. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
  197. package/lib/chain/validation/inclusionList.d.ts.map +1 -1
  198. package/lib/chain/validation/inclusionList.js +11 -2
  199. package/lib/chain/validation/inclusionList.js.map +1 -1
  200. package/lib/chain/validation/syncCommittee.d.ts.map +1 -1
  201. package/lib/chain/validation/syncCommittee.js +16 -10
  202. package/lib/chain/validation/syncCommittee.js.map +1 -1
  203. package/lib/chain/validation/syncCommitteeContributionAndProof.d.ts.map +1 -1
  204. package/lib/chain/validation/syncCommitteeContributionAndProof.js +11 -0
  205. package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
  206. package/lib/chain/validatorMonitor.d.ts +1 -2
  207. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  208. package/lib/chain/validatorMonitor.js +0 -3
  209. package/lib/chain/validatorMonitor.js.map +1 -1
  210. package/lib/db/beacon.d.ts +7 -0
  211. package/lib/db/beacon.d.ts.map +1 -1
  212. package/lib/db/beacon.js +34 -0
  213. package/lib/db/beacon.js.map +1 -1
  214. package/lib/db/dataColumnStore.d.ts +1 -1
  215. package/lib/db/dataColumnStore.d.ts.map +1 -1
  216. package/lib/db/dataColumnStore.js +1 -4
  217. package/lib/db/dataColumnStore.js.map +1 -1
  218. package/lib/db/flatFileStore/flatFileStore.js +5 -5
  219. package/lib/db/flatFileStore/flatFileStore.js.map +1 -1
  220. package/lib/db/flatFileStore/slotIndex.d.ts.map +1 -1
  221. package/lib/db/flatFileStore/slotIndex.js +2 -2
  222. package/lib/db/flatFileStore/slotIndex.js.map +1 -1
  223. package/lib/db/interface.d.ts +1 -0
  224. package/lib/db/interface.d.ts.map +1 -1
  225. package/lib/db/repositories/blobSidecars.d.ts +0 -1
  226. package/lib/db/repositories/blobSidecars.d.ts.map +1 -1
  227. package/lib/db/repositories/blobSidecars.js +0 -1
  228. package/lib/db/repositories/blobSidecars.js.map +1 -1
  229. package/lib/db/repositories/dataColumnSidecarArchive.d.ts +6 -0
  230. package/lib/db/repositories/dataColumnSidecarArchive.d.ts.map +1 -1
  231. package/lib/db/repositories/dataColumnSidecarArchive.js +19 -0
  232. package/lib/db/repositories/dataColumnSidecarArchive.js.map +1 -1
  233. package/lib/execution/builder/apiClient.d.ts +14 -8
  234. package/lib/execution/builder/apiClient.d.ts.map +1 -1
  235. package/lib/execution/builder/apiClient.js +12 -10
  236. package/lib/execution/builder/apiClient.js.map +1 -1
  237. package/lib/execution/builder/http.d.ts +2 -0
  238. package/lib/execution/builder/http.d.ts.map +1 -1
  239. package/lib/execution/builder/http.js +2 -0
  240. package/lib/execution/builder/http.js.map +1 -1
  241. package/lib/execution/engine/blobVersionedHashes.d.ts +1 -1
  242. package/lib/execution/engine/blobVersionedHashes.d.ts.map +1 -1
  243. package/lib/execution/engine/blobVersionedHashes.js.map +1 -1
  244. package/lib/execution/engine/http.d.ts +4 -6
  245. package/lib/execution/engine/http.d.ts.map +1 -1
  246. package/lib/execution/engine/http.js +8 -11
  247. package/lib/execution/engine/http.js.map +1 -1
  248. package/lib/execution/engine/index.d.ts +1 -1
  249. package/lib/execution/engine/index.d.ts.map +1 -1
  250. package/lib/execution/engine/index.js +1 -1
  251. package/lib/execution/engine/index.js.map +1 -1
  252. package/lib/execution/engine/interface.d.ts +18 -6
  253. package/lib/execution/engine/interface.d.ts.map +1 -1
  254. package/lib/execution/engine/interface.js.map +1 -1
  255. package/lib/execution/engine/jsonRpcTransport.d.ts +2 -4
  256. package/lib/execution/engine/jsonRpcTransport.d.ts.map +1 -1
  257. package/lib/execution/engine/jsonRpcTransport.js +2 -12
  258. package/lib/execution/engine/jsonRpcTransport.js.map +1 -1
  259. package/lib/execution/engine/mock.d.ts +0 -1
  260. package/lib/execution/engine/mock.d.ts.map +1 -1
  261. package/lib/execution/engine/mock.js +6 -8
  262. package/lib/execution/engine/mock.js.map +1 -1
  263. package/lib/execution/engine/payloadIdCache.d.ts +1 -2
  264. package/lib/execution/engine/payloadIdCache.d.ts.map +1 -1
  265. package/lib/execution/engine/payloadIdCache.js +3 -3
  266. package/lib/execution/engine/payloadIdCache.js.map +1 -1
  267. package/lib/execution/engine/restTransport.d.ts +2 -4
  268. package/lib/execution/engine/restTransport.d.ts.map +1 -1
  269. package/lib/execution/engine/restTransport.js +1 -15
  270. package/lib/execution/engine/restTransport.js.map +1 -1
  271. package/lib/execution/engine/sszTypes.d.ts +38 -47
  272. package/lib/execution/engine/sszTypes.d.ts.map +1 -1
  273. package/lib/execution/engine/sszTypes.js +0 -5
  274. package/lib/execution/engine/sszTypes.js.map +1 -1
  275. package/lib/execution/engine/transport.d.ts +1 -14
  276. package/lib/execution/engine/transport.d.ts.map +1 -1
  277. package/lib/execution/engine/types.d.ts +1 -9
  278. package/lib/execution/engine/types.d.ts.map +1 -1
  279. package/lib/execution/engine/types.js +9 -16
  280. package/lib/execution/engine/types.js.map +1 -1
  281. package/lib/execution/engine/utils.d.ts.map +1 -1
  282. package/lib/execution/engine/utils.js +3 -2
  283. package/lib/execution/engine/utils.js.map +1 -1
  284. package/lib/index.d.ts +1 -0
  285. package/lib/index.d.ts.map +1 -1
  286. package/lib/index.js +2 -0
  287. package/lib/index.js.map +1 -1
  288. package/lib/metrics/metrics/beacon.d.ts +0 -9
  289. package/lib/metrics/metrics/beacon.d.ts.map +1 -1
  290. package/lib/metrics/metrics/beacon.js +0 -30
  291. package/lib/metrics/metrics/beacon.js.map +1 -1
  292. package/lib/metrics/metrics/lodestar.d.ts +33 -8
  293. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  294. package/lib/metrics/metrics/lodestar.js +84 -18
  295. package/lib/metrics/metrics/lodestar.js.map +1 -1
  296. package/lib/metrics/server/http.js +5 -5
  297. package/lib/metrics/server/http.js.map +1 -1
  298. package/lib/monitoring/service.js +1 -1
  299. package/lib/monitoring/service.js.map +1 -1
  300. package/lib/network/core/networkCore.d.ts +4 -1
  301. package/lib/network/core/networkCore.d.ts.map +1 -1
  302. package/lib/network/core/networkCore.js +7 -0
  303. package/lib/network/core/networkCore.js.map +1 -1
  304. package/lib/network/core/networkCoreWorker.js +2 -0
  305. package/lib/network/core/networkCoreWorker.js.map +1 -1
  306. package/lib/network/core/networkCoreWorkerHandler.d.ts +4 -1
  307. package/lib/network/core/networkCoreWorkerHandler.d.ts.map +1 -1
  308. package/lib/network/core/networkCoreWorkerHandler.js +6 -0
  309. package/lib/network/core/networkCoreWorkerHandler.js.map +1 -1
  310. package/lib/network/core/types.d.ts +6 -1
  311. package/lib/network/core/types.d.ts.map +1 -1
  312. package/lib/network/gossip/gossipsub.d.ts +1 -0
  313. package/lib/network/gossip/gossipsub.d.ts.map +1 -1
  314. package/lib/network/gossip/gossipsub.js +10 -0
  315. package/lib/network/gossip/gossipsub.js.map +1 -1
  316. package/lib/network/gossip/interface.d.ts +1 -8
  317. package/lib/network/gossip/interface.d.ts.map +1 -1
  318. package/lib/network/gossip/interface.js +0 -1
  319. package/lib/network/gossip/interface.js.map +1 -1
  320. package/lib/network/gossip/topic.d.ts +6 -22
  321. package/lib/network/gossip/topic.d.ts.map +1 -1
  322. package/lib/network/gossip/topic.js +0 -23
  323. package/lib/network/gossip/topic.js.map +1 -1
  324. package/lib/network/interface.d.ts +4 -5
  325. package/lib/network/interface.d.ts.map +1 -1
  326. package/lib/network/libp2p/index.d.ts.map +1 -1
  327. package/lib/network/libp2p/index.js +5 -1
  328. package/lib/network/libp2p/index.js.map +1 -1
  329. package/lib/network/network.d.ts +8 -7
  330. package/lib/network/network.d.ts.map +1 -1
  331. package/lib/network/network.js +53 -35
  332. package/lib/network/network.js.map +1 -1
  333. package/lib/network/options.d.ts +2 -0
  334. package/lib/network/options.d.ts.map +1 -1
  335. package/lib/network/options.js +2 -0
  336. package/lib/network/options.js.map +1 -1
  337. package/lib/network/peers/peerManager.d.ts +2 -1
  338. package/lib/network/peers/peerManager.d.ts.map +1 -1
  339. package/lib/network/peers/peerManager.js +28 -1
  340. package/lib/network/peers/peerManager.js.map +1 -1
  341. package/lib/network/peers/utils/assertPeerRelevance.d.ts +9 -1
  342. package/lib/network/peers/utils/assertPeerRelevance.d.ts.map +1 -1
  343. package/lib/network/peers/utils/assertPeerRelevance.js +32 -21
  344. package/lib/network/peers/utils/assertPeerRelevance.js.map +1 -1
  345. package/lib/network/peers/utils/prioritizePeers.d.ts +4 -1
  346. package/lib/network/peers/utils/prioritizePeers.d.ts.map +1 -1
  347. package/lib/network/peers/utils/prioritizePeers.js +8 -16
  348. package/lib/network/peers/utils/prioritizePeers.js.map +1 -1
  349. package/lib/network/peers/utils/subnetMap.d.ts +5 -2
  350. package/lib/network/peers/utils/subnetMap.d.ts.map +1 -1
  351. package/lib/network/peers/utils/subnetMap.js +6 -3
  352. package/lib/network/peers/utils/subnetMap.js.map +1 -1
  353. package/lib/network/processor/extractSlotRootFns.d.ts.map +1 -1
  354. package/lib/network/processor/extractSlotRootFns.js +1 -8
  355. package/lib/network/processor/extractSlotRootFns.js.map +1 -1
  356. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  357. package/lib/network/processor/gossipHandlers.js +79 -149
  358. package/lib/network/processor/gossipHandlers.js.map +1 -1
  359. package/lib/network/processor/gossipQueues/index.d.ts.map +1 -1
  360. package/lib/network/processor/gossipQueues/index.js +0 -6
  361. package/lib/network/processor/gossipQueues/index.js.map +1 -1
  362. package/lib/network/processor/gossipValidatorFn.d.ts.map +1 -1
  363. package/lib/network/processor/gossipValidatorFn.js +1 -5
  364. package/lib/network/processor/gossipValidatorFn.js.map +1 -1
  365. package/lib/network/processor/index.d.ts +6 -0
  366. package/lib/network/processor/index.d.ts.map +1 -1
  367. package/lib/network/processor/index.js +55 -29
  368. package/lib/network/processor/index.js.map +1 -1
  369. package/lib/network/reqresp/ReqRespBeaconNode.d.ts.map +1 -1
  370. package/lib/network/reqresp/ReqRespBeaconNode.js +0 -3
  371. package/lib/network/reqresp/ReqRespBeaconNode.js.map +1 -1
  372. package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts +2 -2
  373. package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
  374. package/lib/network/reqresp/handlers/index.d.ts.map +1 -1
  375. package/lib/network/reqresp/handlers/index.js +1 -12
  376. package/lib/network/reqresp/handlers/index.js.map +1 -1
  377. package/lib/network/reqresp/protocols.d.ts +0 -2
  378. package/lib/network/reqresp/protocols.d.ts.map +1 -1
  379. package/lib/network/reqresp/protocols.js +0 -10
  380. package/lib/network/reqresp/protocols.js.map +1 -1
  381. package/lib/network/reqresp/rateLimit.d.ts.map +1 -1
  382. package/lib/network/reqresp/rateLimit.js +1 -17
  383. package/lib/network/reqresp/rateLimit.js.map +1 -1
  384. package/lib/network/reqresp/types.d.ts +2 -8
  385. package/lib/network/reqresp/types.d.ts.map +1 -1
  386. package/lib/network/reqresp/types.js +1 -7
  387. package/lib/network/reqresp/types.js.map +1 -1
  388. package/lib/network/subnets/attnetsService.d.ts +35 -5
  389. package/lib/network/subnets/attnetsService.d.ts.map +1 -1
  390. package/lib/network/subnets/attnetsService.js +84 -6
  391. package/lib/network/subnets/attnetsService.js.map +1 -1
  392. package/lib/network/subnets/interface.d.ts +7 -0
  393. package/lib/network/subnets/interface.d.ts.map +1 -1
  394. package/lib/network/subnets/interface.js.map +1 -1
  395. package/lib/node/nodejs.d.ts +3 -1
  396. package/lib/node/nodejs.d.ts.map +1 -1
  397. package/lib/node/nodejs.js +47 -21
  398. package/lib/node/nodejs.js.map +1 -1
  399. package/lib/node/options.d.ts +3 -1
  400. package/lib/node/options.d.ts.map +1 -1
  401. package/lib/node/options.js +4 -2
  402. package/lib/node/options.js.map +1 -1
  403. package/lib/sync/interface.d.ts.map +1 -1
  404. package/lib/sync/interface.js.map +1 -1
  405. package/lib/sync/range/batch.d.ts +2 -3
  406. package/lib/sync/range/batch.d.ts.map +1 -1
  407. package/lib/sync/range/batch.js +9 -22
  408. package/lib/sync/range/batch.js.map +1 -1
  409. package/lib/sync/range/chain.d.ts.map +1 -1
  410. package/lib/sync/range/chain.js +2 -15
  411. package/lib/sync/range/chain.js.map +1 -1
  412. package/lib/sync/sync.d.ts +15 -0
  413. package/lib/sync/sync.d.ts.map +1 -1
  414. package/lib/sync/sync.js +103 -25
  415. package/lib/sync/sync.js.map +1 -1
  416. package/lib/sync/unknownBlock.d.ts.map +1 -1
  417. package/lib/sync/unknownBlock.js +43 -25
  418. package/lib/sync/unknownBlock.js.map +1 -1
  419. package/lib/sync/utils/downloadByRange.d.ts +6 -34
  420. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  421. package/lib/sync/utils/downloadByRange.js +24 -128
  422. package/lib/sync/utils/downloadByRange.js.map +1 -1
  423. package/lib/sync/utils/downloadByRoot.d.ts +2 -18
  424. package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
  425. package/lib/sync/utils/downloadByRoot.js +14 -99
  426. package/lib/sync/utils/downloadByRoot.js.map +1 -1
  427. package/lib/util/blobs.d.ts +1 -7
  428. package/lib/util/blobs.d.ts.map +1 -1
  429. package/lib/util/blobs.js +0 -19
  430. package/lib/util/blobs.js.map +1 -1
  431. package/lib/util/execution.d.ts +3 -4
  432. package/lib/util/execution.d.ts.map +1 -1
  433. package/lib/util/execution.js +1 -73
  434. package/lib/util/execution.js.map +1 -1
  435. package/lib/util/file.d.ts.map +1 -1
  436. package/lib/util/file.js +8 -9
  437. package/lib/util/file.js.map +1 -1
  438. package/lib/util/queue/itemQueue.js +1 -1
  439. package/lib/util/queue/itemQueue.js.map +1 -1
  440. package/lib/util/sszBytes.d.ts +5 -1
  441. package/lib/util/sszBytes.d.ts.map +1 -1
  442. package/lib/util/sszBytes.js +36 -19
  443. package/lib/util/sszBytes.js.map +1 -1
  444. package/lib/util/types.d.ts +0 -5
  445. package/lib/util/types.d.ts.map +1 -1
  446. package/lib/util/types.js +1 -2
  447. package/lib/util/types.js.map +1 -1
  448. package/package.json +31 -32
  449. package/src/api/impl/api.ts +1 -1
  450. package/src/api/impl/beacon/blocks/index.ts +81 -126
  451. package/src/api/impl/beacon/index.ts +3 -1
  452. package/src/api/impl/beacon/pool/index.ts +31 -1
  453. package/src/api/impl/beacon/state/utils.ts +1 -1
  454. package/src/api/impl/validator/index.ts +54 -37
  455. package/src/api/options.ts +3 -0
  456. package/src/chain/GetBlobsTracker.ts +82 -52
  457. package/src/chain/archiveStore/archiveStore.ts +1 -0
  458. package/src/chain/archiveStore/utils/archiveBlocks.ts +76 -130
  459. package/src/chain/blocks/blockInput/blockInput.ts +11 -343
  460. package/src/chain/blocks/blockInput/errors.ts +1 -2
  461. package/src/chain/blocks/blockInput/types.ts +2 -20
  462. package/src/chain/blocks/importBlock.ts +61 -76
  463. package/src/chain/blocks/importExecutionPayload.ts +57 -35
  464. package/src/chain/blocks/index.ts +11 -4
  465. package/src/chain/blocks/payloadEnvelopeProcessor.ts +35 -24
  466. package/src/chain/blocks/types.ts +5 -31
  467. package/src/chain/blocks/verifyBlock.ts +31 -16
  468. package/src/chain/blocks/verifyBlocksDataAvailability.ts +16 -2
  469. package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +9 -6
  470. package/src/chain/blocks/verifyBlocksSanityChecks.ts +4 -1
  471. package/src/chain/blocks/verifyBlocksSignatures.ts +10 -5
  472. package/src/chain/blocks/verifyPayloadsDataAvailability.ts +14 -6
  473. package/src/chain/blocks/writeBlockInputToDb.ts +6 -29
  474. package/src/chain/bls/interface.ts +2 -0
  475. package/src/chain/bls/multithread/index.ts +48 -24
  476. package/src/chain/bls/multithread/types.ts +1 -1
  477. package/src/chain/bls/multithread/worker.ts +1 -5
  478. package/src/chain/bls/singleThread.ts +1 -1
  479. package/src/chain/bls/utils.ts +1 -1
  480. package/src/chain/chain.ts +140 -42
  481. package/src/chain/emitter.ts +8 -8
  482. package/src/chain/errors/blockError.ts +1 -1
  483. package/src/chain/errors/executionPayloadEnvelope.ts +8 -0
  484. package/src/chain/errors/index.ts +0 -1
  485. package/src/chain/forkChoice/index.ts +11 -0
  486. package/src/chain/forkChoiceExecutionEngine.ts +183 -0
  487. package/src/chain/interface.ts +9 -6
  488. package/src/chain/opPools/aggregatedAttestationPool.ts +246 -43
  489. package/src/chain/opPools/attestationPool.ts +16 -4
  490. package/src/chain/opPools/inclusionListStore.ts +3 -3
  491. package/src/chain/opPools/index.ts +1 -0
  492. package/src/chain/opPools/payloadAttestationPool.ts +18 -7
  493. package/src/chain/opPools/singleAttestationPool.ts +287 -0
  494. package/src/chain/opPools/syncCommitteeMessagePool.ts +10 -3
  495. package/src/chain/opPools/syncContributionAndProofPool.ts +13 -3
  496. package/src/chain/opPools/utils.ts +1 -1
  497. package/src/chain/options.ts +5 -4
  498. package/src/chain/produceBlock/produceBlockBody.ts +7 -4
  499. package/src/chain/proposerTracker.ts +94 -0
  500. package/src/chain/regen/interface.ts +1 -2
  501. package/src/chain/regen/queued.ts +6 -4
  502. package/src/chain/seenCache/seenGossipBlockInput.ts +9 -93
  503. package/src/chain/validation/executionPayloadBid.ts +14 -193
  504. package/src/chain/validation/executionPayloadEnvelope.ts +68 -1
  505. package/src/chain/validation/inclusionList.ts +11 -2
  506. package/src/chain/validation/syncCommittee.ts +31 -15
  507. package/src/chain/validation/syncCommitteeContributionAndProof.ts +13 -0
  508. package/src/chain/validatorMonitor.ts +0 -6
  509. package/src/db/beacon.ts +44 -0
  510. package/src/db/dataColumnStore.ts +2 -4
  511. package/src/db/flatFileStore/flatFileStore.ts +7 -7
  512. package/src/db/flatFileStore/slotIndex.ts +4 -3
  513. package/src/db/interface.ts +2 -0
  514. package/src/db/repositories/blobSidecars.ts +0 -1
  515. package/src/db/repositories/dataColumnSidecarArchive.ts +20 -0
  516. package/src/execution/builder/apiClient.ts +16 -13
  517. package/src/execution/builder/http.ts +4 -0
  518. package/src/execution/engine/blobVersionedHashes.ts +1 -1
  519. package/src/execution/engine/http.ts +19 -43
  520. package/src/execution/engine/index.ts +1 -1
  521. package/src/execution/engine/interface.ts +19 -10
  522. package/src/execution/engine/jsonRpcTransport.ts +10 -22
  523. package/src/execution/engine/mock.ts +6 -11
  524. package/src/execution/engine/payloadIdCache.ts +6 -7
  525. package/src/execution/engine/restTransport.ts +3 -22
  526. package/src/execution/engine/sszTypes.ts +0 -9
  527. package/src/execution/engine/transport.ts +8 -17
  528. package/src/execution/engine/types.ts +11 -26
  529. package/src/execution/engine/utils.ts +4 -2
  530. package/src/index.ts +2 -0
  531. package/src/metrics/metrics/beacon.ts +0 -30
  532. package/src/metrics/metrics/lodestar.ts +85 -18
  533. package/src/metrics/server/http.ts +5 -5
  534. package/src/monitoring/service.ts +1 -1
  535. package/src/network/core/networkCore.ts +11 -1
  536. package/src/network/core/networkCoreWorker.ts +2 -0
  537. package/src/network/core/networkCoreWorkerHandler.ts +8 -1
  538. package/src/network/core/types.ts +6 -1
  539. package/src/network/gossip/gossipsub.ts +11 -0
  540. package/src/network/gossip/interface.ts +0 -5
  541. package/src/network/gossip/topic.ts +0 -25
  542. package/src/network/interface.ts +2 -5
  543. package/src/network/libp2p/index.ts +5 -1
  544. package/src/network/network.ts +55 -58
  545. package/src/network/options.ts +4 -0
  546. package/src/network/peers/peerManager.ts +28 -3
  547. package/src/network/peers/utils/assertPeerRelevance.ts +39 -23
  548. package/src/network/peers/utils/prioritizePeers.ts +14 -22
  549. package/src/network/peers/utils/subnetMap.ts +6 -3
  550. package/src/network/processor/extractSlotRootFns.ts +0 -9
  551. package/src/network/processor/gossipHandlers.ts +99 -183
  552. package/src/network/processor/gossipQueues/index.ts +0 -6
  553. package/src/network/processor/gossipValidatorFn.ts +0 -5
  554. package/src/network/processor/index.ts +47 -27
  555. package/src/network/processor/types.ts +1 -1
  556. package/src/network/reqresp/ReqRespBeaconNode.ts +0 -7
  557. package/src/network/reqresp/handlers/beaconBlocksByRange.ts +2 -2
  558. package/src/network/reqresp/handlers/index.ts +0 -17
  559. package/src/network/reqresp/protocols.ts +0 -12
  560. package/src/network/reqresp/rateLimit.ts +1 -17
  561. package/src/network/reqresp/types.ts +0 -13
  562. package/src/network/subnets/attnetsService.ts +94 -6
  563. package/src/network/subnets/interface.ts +7 -0
  564. package/src/node/nodejs.ts +58 -22
  565. package/src/node/options.ts +9 -6
  566. package/src/sync/interface.ts +1 -0
  567. package/src/sync/range/batch.ts +9 -21
  568. package/src/sync/range/chain.ts +2 -14
  569. package/src/sync/sync.ts +108 -26
  570. package/src/sync/unknownBlock.ts +48 -36
  571. package/src/sync/utils/downloadByRange.ts +31 -230
  572. package/src/sync/utils/downloadByRoot.ts +15 -142
  573. package/src/util/blobs.ts +0 -34
  574. package/src/util/execution.ts +8 -102
  575. package/src/util/file.ts +8 -9
  576. package/src/util/queue/itemQueue.ts +1 -1
  577. package/src/util/sszBytes.ts +42 -24
  578. package/src/util/types.ts +1 -8
  579. package/lib/chain/errors/blobSidecarError.d.ts +0 -108
  580. package/lib/chain/errors/blobSidecarError.d.ts.map +0 -1
  581. package/lib/chain/errors/blobSidecarError.js +0 -38
  582. package/lib/chain/errors/blobSidecarError.js.map +0 -1
  583. package/lib/chain/validation/blobSidecar.d.ts +0 -16
  584. package/lib/chain/validation/blobSidecar.d.ts.map +0 -1
  585. package/lib/chain/validation/blobSidecar.js +0 -276
  586. package/lib/chain/validation/blobSidecar.js.map +0 -1
  587. package/lib/network/reqresp/handlers/blobSidecarsByRange.d.ts +0 -9
  588. package/lib/network/reqresp/handlers/blobSidecarsByRange.d.ts.map +0 -1
  589. package/lib/network/reqresp/handlers/blobSidecarsByRange.js +0 -91
  590. package/lib/network/reqresp/handlers/blobSidecarsByRange.js.map +0 -1
  591. package/lib/network/reqresp/handlers/blobSidecarsByRoot.d.ts +0 -5
  592. package/lib/network/reqresp/handlers/blobSidecarsByRoot.d.ts.map +0 -1
  593. package/lib/network/reqresp/handlers/blobSidecarsByRoot.js +0 -46
  594. package/lib/network/reqresp/handlers/blobSidecarsByRoot.js.map +0 -1
  595. package/src/chain/errors/blobSidecarError.ts +0 -70
  596. package/src/chain/validation/blobSidecar.ts +0 -357
  597. package/src/network/reqresp/handlers/blobSidecarsByRange.ts +0 -133
  598. package/src/network/reqresp/handlers/blobSidecarsByRoot.ts +0 -69
@@ -25,12 +25,6 @@ const linearGossipQueueOpts: {
25
25
  } = {
26
26
  // validation gossip block asap
27
27
  [GossipType.beacon_block]: {maxLength: 1024, type: QueueType.FIFO, dropOpts: {type: DropType.count, count: 1}},
28
- // gossip length for blob is beacon block length * max blobs per block = 4096
29
- [GossipType.blob_sidecar]: {
30
- maxLength: 4096,
31
- type: QueueType.FIFO,
32
- dropOpts: {type: DropType.count, count: 1},
33
- },
34
28
  [GossipType.data_column_sidecar]: {
35
29
  maxLength: 4096,
36
30
  type: QueueType.FIFO,
@@ -5,7 +5,6 @@ import {
5
5
  AttestationError,
6
6
  AttestationErrorCode,
7
7
  AttesterSlashingErrorCode,
8
- BlobSidecarErrorCode,
9
8
  BlockErrorCode,
10
9
  BlsToExecutionChangeErrorCode,
11
10
  DataColumnSidecarErrorCode,
@@ -55,10 +54,6 @@ const gossipRejectPeerAction: Record<GossipType, RejectPeerActionRule> = {
55
54
  default: PeerAction.LowToleranceError,
56
55
  byCode: {[BlockErrorCode.PROPOSAL_SIGNATURE_INVALID]: PeerAction.Fatal},
57
56
  },
58
- [GossipType.blob_sidecar]: {
59
- default: PeerAction.LowToleranceError,
60
- byCode: {[BlobSidecarErrorCode.PROPOSAL_SIGNATURE_INVALID]: PeerAction.Fatal},
61
- },
62
57
  [GossipType.data_column_sidecar]: {
63
58
  default: PeerAction.LowToleranceError,
64
59
  byCode: {[DataColumnSidecarErrorCode.PROPOSAL_SIGNATURE_INVALID]: PeerAction.Fatal},
@@ -125,7 +125,6 @@ type WorkOpts = {
125
125
  const executeGossipWorkOrderObj: Record<GossipType, WorkOpts> = {
126
126
  [GossipType.beacon_block]: {bypassQueue: true},
127
127
  [GossipType.execution_payload]: {bypassQueue: true},
128
- [GossipType.blob_sidecar]: {bypassQueue: true},
129
128
  [GossipType.data_column_sidecar]: {bypassQueue: true},
130
129
  [GossipType.beacon_aggregate_and_proof]: {},
131
130
  [GossipType.voluntary_exit]: {},
@@ -244,6 +243,12 @@ type SearchUnknownRootTarget =
244
243
  * Such that enough work is processed to fill either one of the queue.
245
244
  */
246
245
  export class NetworkProcessor {
246
+ private stopped = false;
247
+ /**
248
+ * Replaced by dropAllJobs(). Loops that yield while re-queueing awaiting messages compare it after each yield
249
+ * and stop, so no message is queued after a drop.
250
+ */
251
+ private jobGeneration = Symbol();
247
252
  private readonly chain: IBeaconChain;
248
253
  private readonly core: INetworkCore;
249
254
  private readonly events: NetworkEventBus;
@@ -335,16 +340,27 @@ export class NetworkProcessor {
335
340
  }
336
341
 
337
342
  async stop(): Promise<void> {
343
+ if (this.stopped) return;
344
+ this.stopped = true;
338
345
  this.events.off(NetworkEvent.pendingGossipsubMessage, this.onPendingGossipsubMessage);
339
346
  this.chain.emitter.off(routes.events.EventType.block, this.onBlockProcessed);
340
347
  this.chain.emitter.off(routes.events.EventType.executionPayload, this.onPayloadEnvelopeProcessed);
341
- this.chain.emitter.off(ClockEvent.slot, this.onClockSlot);
348
+ this.chain.clock.off(ClockEvent.slot, this.onClockSlot);
349
+ this.dropAllJobs();
342
350
  }
343
351
 
344
352
  dropAllJobs(): void {
353
+ this.jobGeneration = Symbol();
345
354
  for (const topic of executeGossipWorkOrder) {
346
355
  this.gossipQueues[topic].clear();
347
356
  }
357
+ this.awaitingMessagesByBlockRoot.clear();
358
+ this.awaitingBlockMessageCount = 0;
359
+ this.awaitingMessagesByPayloadBlockRoot.clear();
360
+ this.awaitingPayloadMessageCount = 0;
361
+ this.searchedRootsBySlot.clear();
362
+ this.bufferedRootsBySlot.clear();
363
+ this.fatalPeers.clear();
348
364
  }
349
365
 
350
366
  dumpGossipQueue(topic: GossipType): PendingGossipsubMessage[] {
@@ -364,7 +380,7 @@ export class NetworkProcessor {
364
380
  * prefer them as by-root download candidates.
365
381
  */
366
382
  searchUnknownBlock({slot, root}: SlotRootHex, source: BlockInputSource, peer?: PeerIdStr): void {
367
- if (this.chain.seenBlock(root)) {
383
+ if (this.stopped || this.chain.seenBlock(root)) {
368
384
  return;
369
385
  }
370
386
  const entry = this.searchedRootsBySlot.getOrDefault(slot).getOrDefault(root);
@@ -398,7 +414,7 @@ export class NetworkProcessor {
398
414
  peer?: PeerIdStr,
399
415
  slotIsPayloadSlot = false
400
416
  ): void {
401
- if (this.chain.seenPayloadEnvelope(root)) {
417
+ if (this.stopped || this.chain.seenPayloadEnvelope(root)) {
402
418
  return;
403
419
  }
404
420
  const entry = this.searchedRootsBySlot.getOrDefault(slot).getOrDefault(root);
@@ -801,6 +817,7 @@ export class NetworkProcessor {
801
817
  this.awaitingBlockMessageCount -= total;
802
818
  }
803
819
 
820
+ const generation = this.jobGeneration;
804
821
  const nowSec = Date.now() / 1000;
805
822
  let count = 0;
806
823
  // TODO: we can group attestations to process in batches but since we have the SeenAttestationDatas
@@ -819,6 +836,7 @@ export class NetworkProcessor {
819
836
  if (count === MAX_AWAITING_GOSSIP_OBJECTS_PER_TICK) {
820
837
  count = 0;
821
838
  await sleep(AWAITING_GOSSIP_OBJECTS_YIELD_EVERY_MS);
839
+ if (generation !== this.jobGeneration) return;
822
840
  }
823
841
  }
824
842
  }
@@ -843,6 +861,7 @@ export class NetworkProcessor {
843
861
  this.awaitingPayloadMessageCount -= total;
844
862
  }
845
863
 
864
+ const generation = this.jobGeneration;
846
865
  const nowSec = Date.now() / 1000;
847
866
  let count = 0;
848
867
  for (const messages of messagesByTopic.values()) {
@@ -858,6 +877,7 @@ export class NetworkProcessor {
858
877
  if (count === MAX_AWAITING_GOSSIP_OBJECTS_PER_TICK) {
859
878
  count = 0;
860
879
  await sleep(AWAITING_GOSSIP_OBJECTS_YIELD_EVERY_MS);
880
+ if (generation !== this.jobGeneration) return;
861
881
  }
862
882
  }
863
883
  }
@@ -867,19 +887,20 @@ export class NetworkProcessor {
867
887
  const nowSec = Date.now() / 1000;
868
888
  const minSlot = clockSlot - MAX_UNKNOWN_ROOTS_SLOT_CACHE_SIZE;
869
889
 
870
- for (const [slot, searchedRoots] of this.searchedRootsBySlot) {
890
+ for (const [slot, bufferedRoots] of this.bufferedRootsBySlot) {
871
891
  if (slot > minSlot) continue;
872
892
 
873
- // expire messages awaiting an unknown block for these roots. Only roots this slot did a BLOCK search
874
- // for (blockPeerIds set) have block waits keyed here; skipping the rest avoids deleting a payload wait
875
- // that a newer slot created for the same root (block/envelope searches share searchedRootsBySlot).
876
- for (const [rootHex, entry] of searchedRoots) {
877
- if (entry.blockPeerIds === undefined) continue;
893
+ for (const rootHex of bufferedRoots) {
878
894
  const messagesByTopic = this.awaitingMessagesByBlockRoot.get(rootHex);
879
895
  if (messagesByTopic === undefined) continue;
880
- let removed = 0;
896
+ let remaining = 0;
881
897
  for (const messages of messagesByTopic.values()) {
882
898
  for (const message of messages) {
899
+ // the same root may be buffered again from a newer slot, keep those messages.
900
+ // msgSlot is always set before buffering, a missing one expires rather than leaks
901
+ if ((message.msgSlot ?? minSlot) > minSlot) continue;
902
+ messages.delete(message);
903
+ this.awaitingBlockMessageCount--;
883
904
  const topicType = message.topic.type;
884
905
  this.metrics?.awaitingBlockGossipMessages.reject.inc({
885
906
  topic: topicType,
@@ -891,22 +912,22 @@ export class NetworkProcessor {
891
912
  );
892
913
  // No need to report the dropped job to gossip. It will be eventually pruned from the mcache
893
914
  }
894
- removed += messages.size;
895
- }
896
- if (this.awaitingMessagesByBlockRoot.delete(rootHex)) {
897
- this.awaitingBlockMessageCount -= removed;
915
+ remaining += messages.size;
898
916
  }
917
+ if (remaining === 0) this.awaitingMessagesByBlockRoot.delete(rootHex);
899
918
  }
900
919
 
901
- // expire messages awaiting an unknown payload envelope for these roots. Symmetric to the block pass:
902
- // only roots this slot did an ENVELOPE search for (envelopePeerIds set) have payload waits keyed here.
903
- for (const [rootHex, entry] of searchedRoots) {
904
- if (entry.envelopePeerIds === undefined) continue;
920
+ for (const rootHex of bufferedRoots) {
905
921
  const messagesByTopic = this.awaitingMessagesByPayloadBlockRoot.get(rootHex);
906
922
  if (messagesByTopic === undefined) continue;
907
- let removed = 0;
923
+ let remaining = 0;
908
924
  for (const messages of messagesByTopic.values()) {
909
925
  for (const message of messages) {
926
+ // the same root may be buffered again from a newer slot, keep those messages.
927
+ // msgSlot is always set before buffering, a missing one expires rather than leaks
928
+ if ((message.msgSlot ?? minSlot) > minSlot) continue;
929
+ messages.delete(message);
930
+ this.awaitingPayloadMessageCount--;
910
931
  const topicType = message.topic.type;
911
932
  this.metrics?.awaitingPayloadGossipMessages.reject.inc({
912
933
  topic: topicType,
@@ -918,18 +939,16 @@ export class NetworkProcessor {
918
939
  );
919
940
  // No need to report the dropped job to gossip. It will be eventually pruned from the mcache
920
941
  }
921
- removed += messages.size;
922
- }
923
- if (this.awaitingMessagesByPayloadBlockRoot.delete(rootHex)) {
924
- this.awaitingPayloadMessageCount -= removed;
942
+ remaining += messages.size;
925
943
  }
944
+ if (remaining === 0) this.awaitingMessagesByPayloadBlockRoot.delete(rootHex);
926
945
  }
927
946
 
928
- this.searchedRootsBySlot.delete(slot);
947
+ this.bufferedRootsBySlot.delete(slot);
929
948
  }
930
949
 
931
- for (const slot of this.bufferedRootsBySlot.keys()) {
932
- if (slot <= minSlot) this.bufferedRootsBySlot.delete(slot);
950
+ for (const slot of this.searchedRootsBySlot.keys()) {
951
+ if (slot <= minSlot) this.searchedRootsBySlot.delete(slot);
933
952
  }
934
953
 
935
954
  for (const [peer, slot] of this.fatalPeers) {
@@ -938,6 +957,7 @@ export class NetworkProcessor {
938
957
  };
939
958
 
940
959
  private executeWork(): void {
960
+ if (this.stopped) return;
941
961
  // TODO: Maybe de-bounce by timing the last time executeWork was run
942
962
 
943
963
  this.metrics?.networkProcessor.executeWorkCalls.inc();
@@ -11,7 +11,7 @@ export type GossipAttestationsWork = {
11
11
  export type PendingGossipsubMessage = {
12
12
  topic: GossipTopic;
13
13
  msg: Message;
14
- // only available for beacon_attestation and aggregate_and_proof
14
+ // set for every topic with a slot, held messages expire by it
15
15
  msgSlot?: Slot;
16
16
  msgId: string;
17
17
  propagationSource: PeerIdStr;
@@ -267,13 +267,6 @@ export class ReqRespBeaconNode extends ReqResp {
267
267
  );
268
268
  }
269
269
 
270
- if (ForkSeq[fork] >= ForkSeq.deneb) {
271
- protocolsAtFork.push(
272
- [protocols.BlobSidecarsByRoot(fork, this.config), this.getHandler(ReqRespMethod.BlobSidecarsByRoot)],
273
- [protocols.BlobSidecarsByRange(fork, this.config), this.getHandler(ReqRespMethod.BlobSidecarsByRange)]
274
- );
275
- }
276
-
277
270
  if (ForkSeq[fork] < ForkSeq.fulu) {
278
271
  // Unregister StatusV1, MetadataV2 at the fork boundary, so only declare for pre-fulu
279
272
  protocolsAtFork.push(
@@ -3,7 +3,7 @@ import {BeaconConfig} from "@lodestar/config";
3
3
  import {GENESIS_SLOT, isForkPostDeneb} from "@lodestar/params";
4
4
  import {RespStatus, ResponseError, ResponseOutgoing} from "@lodestar/reqresp";
5
5
  import {computeEpochAtSlot} from "@lodestar/state-transition";
6
- import {deneb, phase0} from "@lodestar/types";
6
+ import {phase0} from "@lodestar/types";
7
7
  import {IBeaconChain} from "../../../chain/index.js";
8
8
  import {IBeaconDb} from "../../../db/index.js";
9
9
  import {prettyPrintPeerId} from "../../util.js";
@@ -104,7 +104,7 @@ export async function* onBeaconBlocksByRange(
104
104
  export function validateBeaconBlocksByRangeRequest(
105
105
  config: BeaconConfig,
106
106
  request: phase0.BeaconBlocksByRangeRequest
107
- ): deneb.BlobSidecarsByRangeRequest {
107
+ ): Pick<phase0.BeaconBlocksByRangeRequest, "startSlot" | "count"> {
108
108
  const {startSlot} = request;
109
109
  let {count} = request;
110
110
 
@@ -5,7 +5,6 @@ import {IBeaconChain} from "../../../chain/index.js";
5
5
  import {IBeaconDb} from "../../../db/index.js";
6
6
  import {
7
7
  BeaconBlocksByRootRequestType,
8
- BlobSidecarsByRootRequestType,
9
8
  DataColumnSidecarsByRootRequestType,
10
9
  ExecutionPayloadEnvelopesByRootRequestType,
11
10
  } from "../../../util/types.js";
@@ -13,8 +12,6 @@ import {GetReqRespHandlerFn, ReqRespMethod} from "../types.js";
13
12
  import {onBeaconBlocksByHead} from "./beaconBlocksByHead.js";
14
13
  import {onBeaconBlocksByRange} from "./beaconBlocksByRange.js";
15
14
  import {onBeaconBlocksByRoot} from "./beaconBlocksByRoot.js";
16
- import {onBlobSidecarsByRange} from "./blobSidecarsByRange.js";
17
- import {onBlobSidecarsByRoot} from "./blobSidecarsByRoot.js";
18
15
  import {onDataColumnSidecarsByRange} from "./dataColumnSidecarsByRange.js";
19
16
  import {onDataColumnSidecarsByRoot} from "./dataColumnSidecarsByRoot.js";
20
17
  import {onExecutionPayloadEnvelopesByRange} from "./executionPayloadEnvelopesByRange.js";
@@ -90,20 +87,6 @@ export function getReqRespHandlers({db, chain}: {db: IBeaconDb; chain: IBeaconCh
90
87
  const body = deserializeRequestBody(ssz.fulu.BeaconBlocksByHeadRequest, req.data);
91
88
  return onBeaconBlocksByHead(body, chain, peerId, peerClient);
92
89
  },
93
- [ReqRespMethod.BlobSidecarsByRoot]: (req) => {
94
- const fork = chain.config.getForkName(chain.clock.currentSlot);
95
- const body = deserializeRequestBody(BlobSidecarsByRootRequestType(fork, chain.config), req.data);
96
- return onBlobSidecarsByRoot(body, chain);
97
- },
98
- [ReqRespMethod.BlobSidecarsByRange]: (req) => {
99
- const body = deserializeRequestBody(ssz.deneb.BlobSidecarsByRangeRequest, req.data);
100
- return trackByRangeResponse(
101
- chain,
102
- ReqRespMethod.BlobSidecarsByRange,
103
- body.count,
104
- onBlobSidecarsByRange(body, chain, db)
105
- );
106
- },
107
90
  [ReqRespMethod.DataColumnSidecarsByRange]: (req, peerId, peerClient) => {
108
91
  const body = deserializeRequestBody(ssz.fulu.DataColumnSidecarsByRangeRequest, req.data);
109
92
  return trackByRangeResponse(
@@ -77,18 +77,6 @@ export const BeaconBlocksByHead = toProtocol({
77
77
  contextBytesType: ContextBytesType.ForkDigest,
78
78
  });
79
79
 
80
- export const BlobSidecarsByRange = toProtocol({
81
- method: ReqRespMethod.BlobSidecarsByRange,
82
- version: Version.V1,
83
- contextBytesType: ContextBytesType.ForkDigest,
84
- });
85
-
86
- export const BlobSidecarsByRoot = toProtocol({
87
- method: ReqRespMethod.BlobSidecarsByRoot,
88
- version: Version.V1,
89
- contextBytesType: ContextBytesType.ForkDigest,
90
- });
91
-
92
80
  export const DataColumnSidecarsByRange = toProtocol({
93
81
  method: ReqRespMethod.DataColumnSidecarsByRange,
94
82
  version: Version.V1,
@@ -1,5 +1,5 @@
1
1
  import {BeaconConfig} from "@lodestar/config";
2
- import {ForkName, MAX_REQUEST_LIGHT_CLIENT_UPDATES, isForkPostDeneb, isForkPostElectra} from "@lodestar/params";
2
+ import {ForkName, MAX_REQUEST_LIGHT_CLIENT_UPDATES, isForkPostDeneb} from "@lodestar/params";
3
3
  import {InboundRateLimitQuota} from "@lodestar/reqresp";
4
4
  import {ReqRespMethod, RequestBodyByMethod, requestSszTypeByMethod} from "./types.js";
5
5
 
@@ -44,22 +44,6 @@ export const rateLimitQuotas: (fork: ForkName, config: BeaconConfig) => Record<R
44
44
  byPeer: {quota: config.MAX_REQUEST_BLOCKS_DENEB, quotaTimeMs: 10_000},
45
45
  getRequestCount: getRequestCountFn(fork, config, ReqRespMethod.BeaconBlocksByHead, (req) => req.count),
46
46
  },
47
- [ReqRespMethod.BlobSidecarsByRange]: {
48
- // Rationale: MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK
49
- byPeer: {
50
- quota: isForkPostElectra(fork) ? config.MAX_REQUEST_BLOB_SIDECARS_ELECTRA : config.MAX_REQUEST_BLOB_SIDECARS,
51
- quotaTimeMs: 10_000,
52
- },
53
- getRequestCount: getRequestCountFn(fork, config, ReqRespMethod.BlobSidecarsByRange, (req) => req.count),
54
- },
55
- [ReqRespMethod.BlobSidecarsByRoot]: {
56
- // Rationale: quota of BeaconBlocksByRoot * MAX_BLOBS_PER_BLOCK
57
- byPeer: {
58
- quota: isForkPostElectra(fork) ? config.MAX_REQUEST_BLOB_SIDECARS_ELECTRA : config.MAX_REQUEST_BLOB_SIDECARS,
59
- quotaTimeMs: 10_000,
60
- },
61
- getRequestCount: getRequestCountFn(fork, config, ReqRespMethod.BlobSidecarsByRoot, (req) => req.length),
62
- },
63
47
  [ReqRespMethod.DataColumnSidecarsByRange]: {
64
48
  // Rationale: MAX_REQUEST_BLOCKS_DENEB * NUMBER_OF_COLUMNS
65
49
  byPeer: {quota: config.MAX_REQUEST_DATA_COLUMN_SIDECARS, quotaTimeMs: 10_000},
@@ -13,7 +13,6 @@ import {
13
13
  SignedBeaconBlock,
14
14
  Status,
15
15
  altair,
16
- deneb,
17
16
  fulu,
18
17
  gloas,
19
18
  heze,
@@ -24,8 +23,6 @@ import {
24
23
  import {
25
24
  BeaconBlocksByRootRequest,
26
25
  BeaconBlocksByRootRequestType,
27
- BlobSidecarsByRootRequest,
28
- BlobSidecarsByRootRequestType,
29
26
  DataColumnSidecarsByRootRequest,
30
27
  DataColumnSidecarsByRootRequestType,
31
28
  ExecutionPayloadEnvelopesByRootRequest,
@@ -44,8 +41,6 @@ export enum ReqRespMethod {
44
41
  BeaconBlocksByRange = "beacon_blocks_by_range",
45
42
  BeaconBlocksByRoot = "beacon_blocks_by_root",
46
43
  BeaconBlocksByHead = "beacon_blocks_by_head",
47
- BlobSidecarsByRange = "blob_sidecars_by_range",
48
- BlobSidecarsByRoot = "blob_sidecars_by_root",
49
44
  DataColumnSidecarsByRange = "data_column_sidecars_by_range",
50
45
  DataColumnSidecarsByRoot = "data_column_sidecars_by_root",
51
46
  ExecutionPayloadEnvelopesByRoot = "execution_payload_envelopes_by_root",
@@ -66,8 +61,6 @@ export type RequestBodyByMethod = {
66
61
  [ReqRespMethod.BeaconBlocksByRange]: phase0.BeaconBlocksByRangeRequest;
67
62
  [ReqRespMethod.BeaconBlocksByRoot]: BeaconBlocksByRootRequest;
68
63
  [ReqRespMethod.BeaconBlocksByHead]: fulu.BeaconBlocksByHeadRequest;
69
- [ReqRespMethod.BlobSidecarsByRange]: deneb.BlobSidecarsByRangeRequest;
70
- [ReqRespMethod.BlobSidecarsByRoot]: BlobSidecarsByRootRequest;
71
64
  [ReqRespMethod.DataColumnSidecarsByRange]: fulu.DataColumnSidecarsByRangeRequest;
72
65
  [ReqRespMethod.DataColumnSidecarsByRoot]: DataColumnSidecarsByRootRequest;
73
66
  [ReqRespMethod.ExecutionPayloadEnvelopesByRoot]: ExecutionPayloadEnvelopesByRootRequest;
@@ -88,8 +81,6 @@ type ResponseBodyByMethod = {
88
81
  [ReqRespMethod.BeaconBlocksByRange]: SignedBeaconBlock;
89
82
  [ReqRespMethod.BeaconBlocksByRoot]: SignedBeaconBlock;
90
83
  [ReqRespMethod.BeaconBlocksByHead]: SignedBeaconBlock;
91
- [ReqRespMethod.BlobSidecarsByRange]: deneb.BlobSidecar;
92
- [ReqRespMethod.BlobSidecarsByRoot]: deneb.BlobSidecar;
93
84
  [ReqRespMethod.DataColumnSidecarsByRange]: DataColumnSidecar;
94
85
  [ReqRespMethod.DataColumnSidecarsByRoot]: DataColumnSidecar;
95
86
  [ReqRespMethod.ExecutionPayloadEnvelopesByRoot]: gloas.SignedExecutionPayloadEnvelope;
@@ -119,8 +110,6 @@ export const requestSszTypeByMethod: (
119
110
  [ReqRespMethod.BeaconBlocksByRange]: ssz.phase0.BeaconBlocksByRangeRequest,
120
111
  [ReqRespMethod.BeaconBlocksByRoot]: BeaconBlocksByRootRequestType(fork, config),
121
112
  [ReqRespMethod.BeaconBlocksByHead]: ssz.fulu.BeaconBlocksByHeadRequest,
122
- [ReqRespMethod.BlobSidecarsByRange]: ssz.deneb.BlobSidecarsByRangeRequest,
123
- [ReqRespMethod.BlobSidecarsByRoot]: BlobSidecarsByRootRequestType(fork, config),
124
113
  [ReqRespMethod.DataColumnSidecarsByRange]: ssz.fulu.DataColumnSidecarsByRangeRequest,
125
114
  [ReqRespMethod.DataColumnSidecarsByRoot]: DataColumnSidecarsByRootRequestType(config),
126
115
  [ReqRespMethod.ExecutionPayloadEnvelopesByRoot]: ExecutionPayloadEnvelopesByRootRequestType(config),
@@ -152,8 +141,6 @@ export const responseSszTypeByMethod: {[K in ReqRespMethod]: ResponseTypeGetter<
152
141
  [ReqRespMethod.BeaconBlocksByRange]: blocksResponseType,
153
142
  [ReqRespMethod.BeaconBlocksByRoot]: blocksResponseType,
154
143
  [ReqRespMethod.BeaconBlocksByHead]: (fork) => ssz[fork].SignedBeaconBlock,
155
- [ReqRespMethod.BlobSidecarsByRange]: () => ssz.deneb.BlobSidecar,
156
- [ReqRespMethod.BlobSidecarsByRoot]: () => ssz.deneb.BlobSidecar,
157
144
  [ReqRespMethod.LightClientBootstrap]: (fork) => sszTypesFor(onlyPostAltairFork(fork)).LightClientBootstrap,
158
145
  [ReqRespMethod.LightClientUpdatesByRange]: (fork) => sszTypesFor(onlyPostAltairFork(fork)).LightClientUpdate,
159
146
  [ReqRespMethod.LightClientFinalityUpdate]: (fork) => sszTypesFor(onlyPostAltairFork(fork)).LightClientFinalityUpdate,
@@ -20,6 +20,7 @@ const gossipType = GossipType.beacon_attestation;
20
20
  export enum SubnetSource {
21
21
  committee = "committee",
22
22
  longLived = "long_lived",
23
+ beforeProposal = "before_proposal",
23
24
  }
24
25
 
25
26
  // map of subnet to time to form stable mesh as seconds, null if not yet formed
@@ -40,7 +41,7 @@ export class AttnetsService implements IAttnetsService {
40
41
  /** Committee subnets - PeerManager must find peers for those */
41
42
  private committeeSubnets = new SubnetMap();
42
43
  /**
43
- * All currently subscribed short-lived subnets, for attestation aggregation
44
+ * All currently subscribed short-lived subnets, for attestation aggregation and before local block proposals
44
45
  * This class will tell gossip to subscribe and un-subscribe
45
46
  * If a value exists for `SubscriptionId` it means that gossip subscription is active in network.gossip
46
47
  */
@@ -52,6 +53,11 @@ export class AttnetsService implements IAttnetsService {
52
53
  * Used to determine if we should process an attestation.
53
54
  */
54
55
  private aggregatorSlotSubnet = new MapDef<Slot, AggregatorDutyInfo>(() => new Map());
56
+ /**
57
+ * Block proposal slots of validators connected to this node.
58
+ * Used to subscribe to all subnets `slotsToSubscribeBeforeProposalDuty` slots before, see onSlot
59
+ */
60
+ private localProposalSlots = new Set<Slot>();
55
61
 
56
62
  constructor(
57
63
  private readonly config: BeaconConfig,
@@ -119,6 +125,22 @@ export class AttnetsService implements IAttnetsService {
119
125
  }
120
126
  }
121
127
 
128
+ /**
129
+ * Called from the main thread with upcoming block proposal slots of connected validators.
130
+ * Tracked here, the subscription happens in onSlot like aggregator duties, or right away for a proposal learned
131
+ * after its subscription slot (node restart, newly connected validator)
132
+ */
133
+ addLocalProposalSlots(slots: Slot[]): void {
134
+ const clockSlot = this.clock.currentSlot;
135
+ for (const proposalSlot of slots) {
136
+ this.localProposalSlots.add(proposalSlot);
137
+ // not from the slot before the proposal, its votes are published before a mesh could form
138
+ if (proposalSlot - this.opts.slotsToSubscribeBeforeProposalDuty <= clockSlot && clockSlot < proposalSlot - 1) {
139
+ this.subscribeAllSubnetsUntilProposal(proposalSlot);
140
+ }
141
+ }
142
+ }
143
+
122
144
  /**
123
145
  * Check if a subscription is still active before handling a gossip object
124
146
  */
@@ -158,7 +180,8 @@ export class AttnetsService implements IAttnetsService {
158
180
 
159
181
  /**
160
182
  * Run per slot.
161
- * - Subscribe to gossip subnets 2 slots in advance
183
+ * - Subscribe to gossip subnets 2 slots in advance of aggregator duties
184
+ * - Subscribe to all subnets `slotsToSubscribeBeforeProposalDuty` slots in advance of local block proposals
162
185
  * - Unsubscribe from expired subnets
163
186
  * - Track time to stable mesh if not yet formed
164
187
  */
@@ -186,19 +209,76 @@ export class AttnetsService implements IAttnetsService {
186
209
  this.trackTimeToStableMesh(clockSlot, dutiedSlot, dutiedInfo);
187
210
  }
188
211
 
212
+ // Must run before unsubscribeExpiredCommitteeSubnets so that a subnet whose subscription expires in this slot
213
+ // gets its ttl extended instead of being unsubscribed and subscribed again
214
+ this.subscribeAllSubnetsBeforeProposal(clockSlot);
215
+
189
216
  this.unsubscribeExpiredCommitteeSubnets(clockSlot);
190
217
  this.pruneExpiredAggregator(clockSlot);
218
+ this.pruneExpiredLocalProposals(clockSlot);
191
219
  } catch (e) {
192
220
  this.logger.error("Error on AttnetsService.onSlot", {slot: clockSlot}, e as Error);
193
221
  }
194
222
  };
195
223
 
196
224
  private onHalfSlot = (clockSlot: Slot): void => {
197
- for (const [dutiedSlot, dutiedInfo] of this.aggregatorSlotSubnet.entries()) {
198
- this.trackTimeToStableMesh(clockSlot, dutiedSlot, dutiedInfo);
225
+ try {
226
+ for (const [dutiedSlot, dutiedInfo] of this.aggregatorSlotSubnet.entries()) {
227
+ this.trackTimeToStableMesh(clockSlot, dutiedSlot, dutiedInfo);
228
+ }
229
+
230
+ this.unsubscribeAllSubnetsBeforeProposal(clockSlot);
231
+ } catch (e) {
232
+ this.logger.error("Error on AttnetsService.onHalfSlot", {slot: clockSlot}, e as Error);
199
233
  }
200
234
  };
201
235
 
236
+ /**
237
+ * Subscribe to all subnets `slotsToSubscribeBeforeProposalDuty` slots before a block proposal of a connected
238
+ * validator, so that single attestations of those slots can be packed into the block. The subscription expires in
239
+ * the slot before the proposal, see unsubscribeAllSubnetsBeforeProposal
240
+ */
241
+ private subscribeAllSubnetsBeforeProposal(clockSlot: Slot): void {
242
+ for (const proposalSlot of this.localProposalSlots) {
243
+ if (proposalSlot === clockSlot + this.opts.slotsToSubscribeBeforeProposalDuty) {
244
+ this.subscribeAllSubnetsUntilProposal(proposalSlot);
245
+ }
246
+ }
247
+ }
248
+
249
+ private subscribeAllSubnetsUntilProposal(proposalSlot: Slot): void {
250
+ if (this.opts.slotsToSubscribeBeforeProposalDuty === 0 || this.opts.subscribeAllSubnets) {
251
+ return;
252
+ }
253
+
254
+ const subnets = Array.from({length: ATTESTATION_SUBNET_COUNT}, (_, subnet) => subnet);
255
+ // Same as aggregator duties: trigger gossip subscription first, then register the subscriptions.
256
+ // Do not add to committeeSubnets: it drives peer discovery, we only use the peers we already have
257
+ this.subscribeToSubnets(subnets, SubnetSource.beforeProposal);
258
+ for (const subnet of subnets) {
259
+ this.shortLivedSubscriptions.request({subnet, toSlot: proposalSlot - 1});
260
+ }
261
+ }
262
+
263
+ /**
264
+ * Unsubscribe from subnets of subscribeAllSubnetsBeforeProposal at half of the slot before the proposal instead of
265
+ * the proposal slot start, so the proposal slot does not carry their traffic. Single attestations are published at
266
+ * 1/3 of the slot so they have arrived by then.
267
+ * Short-lived subscriptions are either aggregator duties or these, an aggregator duty ends in its dutied slot and is
268
+ * kept here (aggregates are due later), it expires at the next slot start in onSlot as before. So only subnets of
269
+ * subscribeAllSubnetsBeforeProposal are unsubscribed here.
270
+ */
271
+ private unsubscribeAllSubnetsBeforeProposal(clockSlot: Slot): void {
272
+ const aggregatorSubnets = this.aggregatorSlotSubnet.get(clockSlot);
273
+ const expiring = this.shortLivedSubscriptions.getExpired(
274
+ clockSlot + 1,
275
+ (subnet) => aggregatorSubnets?.has(subnet) === true
276
+ );
277
+ if (expiring.length > 0) {
278
+ this.unsubscribeSubnets(expiring, clockSlot + 1, SubnetSource.beforeProposal);
279
+ }
280
+ }
281
+
202
282
  /**
203
283
  * Track time to form stable mesh if not yet formed
204
284
  */
@@ -291,8 +371,8 @@ export class AttnetsService implements IAttnetsService {
291
371
  }
292
372
 
293
373
  /**
294
- * Unsubscribe to a committee subnet from subscribedCommitteeSubnets.
295
- * If a random subnet is present, we do not unsubscribe from it.
374
+ * Unsubscribe from short-lived subnets whose subscription expired.
375
+ * If a long-lived subnet is present, we do not unsubscribe from it.
296
376
  */
297
377
  private unsubscribeExpiredCommitteeSubnets(slot: Slot): void {
298
378
  const expired = this.shortLivedSubscriptions.getExpired(slot);
@@ -313,6 +393,14 @@ export class AttnetsService implements IAttnetsService {
313
393
  }
314
394
  }
315
395
 
396
+ private pruneExpiredLocalProposals(currentSlot: Slot): void {
397
+ for (const proposalSlot of this.localProposalSlots) {
398
+ if (currentSlot > proposalSlot) {
399
+ this.localProposalSlots.delete(proposalSlot);
400
+ }
401
+ }
402
+ }
403
+
316
404
  /** Update ENR */
317
405
  private updateMetadata(): void {
318
406
  const subnets = ssz.phase0.AttestationSubnets.defaultValue();
@@ -25,6 +25,8 @@ export type SubnetsService = {
25
25
 
26
26
  export interface IAttnetsService extends SubnetsService {
27
27
  shouldProcess(subnet: SubnetID, slot: Slot): boolean;
28
+ /** Block proposal slots of validators connected to this node, see `slotsToSubscribeBeforeProposalDuty` */
29
+ addLocalProposalSlots(slots: Slot[]): void;
28
30
  }
29
31
 
30
32
  export type RandBetweenFn = (min: number, max: number) => number;
@@ -33,6 +35,11 @@ export type ShuffleFn = <T>(arr: T[]) => T[];
33
35
  export type SubnetsServiceOpts = {
34
36
  subscribeAllSubnets?: boolean;
35
37
  slotsToSubscribeBeforeAggregatorDuty: number;
38
+ /**
39
+ * Subscribe to all attestation subnets this many slots before a block proposal of a connected validator, so that
40
+ * its single attestations can be packed into the block. In `[0, SLOTS_PER_EPOCH]`, 0 disables
41
+ */
42
+ slotsToSubscribeBeforeProposalDuty: number;
36
43
  };
37
44
 
38
45
  export type SubnetsServiceTestOpts = {