@lodestar/beacon-node 1.50.0-dev.1f38fe79fb → 1.50.0-dev.20062ed60e

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 (382) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +13 -3
  3. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  4. package/lib/api/impl/beacon/index.d.ts.map +1 -1
  5. package/lib/api/impl/beacon/index.js +13 -0
  6. package/lib/api/impl/beacon/index.js.map +1 -1
  7. package/lib/api/impl/beacon/state/index.d.ts.map +1 -1
  8. package/lib/api/impl/beacon/state/index.js +28 -6
  9. package/lib/api/impl/beacon/state/index.js.map +1 -1
  10. package/lib/api/impl/debug/index.d.ts.map +1 -1
  11. package/lib/api/impl/debug/index.js +26 -18
  12. package/lib/api/impl/debug/index.js.map +1 -1
  13. package/lib/api/impl/validator/index.d.ts +1 -0
  14. package/lib/api/impl/validator/index.d.ts.map +1 -1
  15. package/lib/api/impl/validator/index.js +80 -18
  16. package/lib/api/impl/validator/index.js.map +1 -1
  17. package/lib/chain/ColumnReconstructionTracker.d.ts +0 -2
  18. package/lib/chain/ColumnReconstructionTracker.d.ts.map +1 -1
  19. package/lib/chain/ColumnReconstructionTracker.js +4 -5
  20. package/lib/chain/ColumnReconstructionTracker.js.map +1 -1
  21. package/lib/chain/archiveStore/archiveStore.d.ts +5 -0
  22. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  23. package/lib/chain/archiveStore/archiveStore.js +14 -24
  24. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  25. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts +2 -2
  26. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
  27. package/lib/chain/archiveStore/historicalState/getHistoricalState.js +5 -7
  28. package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
  29. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js +1 -1
  30. package/lib/chain/archiveStore/historicalState/historicalStateRegen.js.map +1 -1
  31. package/lib/chain/archiveStore/historicalState/types.d.ts +2 -2
  32. package/lib/chain/archiveStore/historicalState/types.d.ts.map +1 -1
  33. package/lib/chain/archiveStore/historicalState/worker.js +1 -1
  34. package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
  35. package/lib/chain/archiveStore/interface.d.ts +1 -1
  36. package/lib/chain/archiveStore/interface.d.ts.map +1 -1
  37. package/lib/chain/archiveStore/utils/pruneHistory.d.ts +1 -1
  38. package/lib/chain/archiveStore/utils/pruneHistory.d.ts.map +1 -1
  39. package/lib/chain/archiveStore/utils/pruneHistory.js +2 -1
  40. package/lib/chain/archiveStore/utils/pruneHistory.js.map +1 -1
  41. package/lib/chain/beaconProposerCache.d.ts +6 -0
  42. package/lib/chain/beaconProposerCache.d.ts.map +1 -1
  43. package/lib/chain/beaconProposerCache.js +16 -0
  44. package/lib/chain/beaconProposerCache.js.map +1 -1
  45. package/lib/chain/blocks/blockInput/blockInput.d.ts +1 -1
  46. package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
  47. package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
  48. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  49. package/lib/chain/blocks/importBlock.js +24 -11
  50. package/lib/chain/blocks/importBlock.js.map +1 -1
  51. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +2 -1
  52. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
  53. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  54. package/lib/chain/blocks/verifyBlock.js +7 -7
  55. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  56. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts +2 -1
  57. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
  58. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +5 -4
  59. package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
  60. package/lib/chain/chain.d.ts +10 -5
  61. package/lib/chain/chain.d.ts.map +1 -1
  62. package/lib/chain/chain.js +105 -35
  63. package/lib/chain/chain.js.map +1 -1
  64. package/lib/chain/emitter.d.ts +7 -1
  65. package/lib/chain/emitter.d.ts.map +1 -1
  66. package/lib/chain/emitter.js +5 -0
  67. package/lib/chain/emitter.js.map +1 -1
  68. package/lib/chain/errors/envelopeReconstructionError.d.ts +5 -0
  69. package/lib/chain/errors/envelopeReconstructionError.d.ts.map +1 -1
  70. package/lib/chain/errors/envelopeReconstructionError.js +2 -0
  71. package/lib/chain/errors/envelopeReconstructionError.js.map +1 -1
  72. package/lib/chain/errors/gossipValidation.d.ts +3 -1
  73. package/lib/chain/errors/gossipValidation.d.ts.map +1 -1
  74. package/lib/chain/errors/gossipValidation.js +2 -0
  75. package/lib/chain/errors/gossipValidation.js.map +1 -1
  76. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  77. package/lib/chain/forkChoice/index.js +2 -0
  78. package/lib/chain/forkChoice/index.js.map +1 -1
  79. package/lib/chain/interface.d.ts +6 -3
  80. package/lib/chain/interface.d.ts.map +1 -1
  81. package/lib/chain/opPools/aggregatedAttestationPool.d.ts +4 -2
  82. package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
  83. package/lib/chain/opPools/aggregatedAttestationPool.js +30 -8
  84. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  85. package/lib/chain/opPools/opPool.d.ts.map +1 -1
  86. package/lib/chain/opPools/opPool.js +1 -23
  87. package/lib/chain/opPools/opPool.js.map +1 -1
  88. package/lib/chain/opPools/proposerPreferencesPool.d.ts +8 -4
  89. package/lib/chain/opPools/proposerPreferencesPool.d.ts.map +1 -1
  90. package/lib/chain/opPools/proposerPreferencesPool.js +27 -12
  91. package/lib/chain/opPools/proposerPreferencesPool.js.map +1 -1
  92. package/lib/chain/opPools/utils.d.ts +11 -0
  93. package/lib/chain/opPools/utils.d.ts.map +1 -1
  94. package/lib/chain/opPools/utils.js +22 -0
  95. package/lib/chain/opPools/utils.js.map +1 -1
  96. package/lib/chain/options.d.ts +2 -1
  97. package/lib/chain/options.d.ts.map +1 -1
  98. package/lib/chain/options.js +1 -1
  99. package/lib/chain/options.js.map +1 -1
  100. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  101. package/lib/chain/prepareNextSlot.js +20 -8
  102. package/lib/chain/prepareNextSlot.js.map +1 -1
  103. package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
  104. package/lib/chain/produceBlock/computeNewStateRoot.js +1 -1
  105. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  106. package/lib/chain/produceBlock/produceBlockBody.d.ts +11 -1
  107. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  108. package/lib/chain/produceBlock/produceBlockBody.js +54 -36
  109. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  110. package/lib/chain/regen/regen.d.ts +2 -0
  111. package/lib/chain/regen/regen.d.ts.map +1 -1
  112. package/lib/chain/regen/regen.js +10 -4
  113. package/lib/chain/regen/regen.js.map +1 -1
  114. package/lib/chain/reprocess.d.ts +2 -1
  115. package/lib/chain/reprocess.d.ts.map +1 -1
  116. package/lib/chain/reprocess.js +2 -1
  117. package/lib/chain/reprocess.js.map +1 -1
  118. package/lib/chain/seenCache/seenGossipBlockInput.d.ts +7 -0
  119. package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
  120. package/lib/chain/seenCache/seenGossipBlockInput.js +22 -1
  121. package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
  122. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +9 -2
  123. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
  124. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +23 -13
  125. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
  126. package/lib/chain/shufflingCache.d.ts +18 -8
  127. package/lib/chain/shufflingCache.d.ts.map +1 -1
  128. package/lib/chain/shufflingCache.js +72 -18
  129. package/lib/chain/shufflingCache.js.map +1 -1
  130. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  131. package/lib/chain/stateCache/persistentCheckpointsCache.js +1 -1
  132. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  133. package/lib/chain/validatorMonitor.d.ts +5 -1
  134. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  135. package/lib/chain/validatorMonitor.js +70 -58
  136. package/lib/chain/validatorMonitor.js.map +1 -1
  137. package/lib/constants/constants.d.ts +1 -0
  138. package/lib/constants/constants.d.ts.map +1 -1
  139. package/lib/constants/constants.js +1 -0
  140. package/lib/constants/constants.js.map +1 -1
  141. package/lib/db/beacon.d.ts +4 -1
  142. package/lib/db/beacon.d.ts.map +1 -1
  143. package/lib/db/beacon.js +6 -1
  144. package/lib/db/beacon.js.map +1 -1
  145. package/lib/db/buckets.d.ts +3 -1
  146. package/lib/db/buckets.d.ts.map +1 -1
  147. package/lib/db/buckets.js +2 -0
  148. package/lib/db/buckets.js.map +1 -1
  149. package/lib/db/interface.d.ts +4 -1
  150. package/lib/db/interface.d.ts.map +1 -1
  151. package/lib/db/repositories/blockArchive.js +2 -2
  152. package/lib/db/repositories/blockArchive.js.map +1 -1
  153. package/lib/db/repositories/blockArchiveIndex.d.ts +3 -3
  154. package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
  155. package/lib/db/repositories/blockArchiveIndex.js +1 -2
  156. package/lib/db/repositories/blockArchiveIndex.js.map +1 -1
  157. package/lib/db/repositories/earliestAvailableSlot.d.ts +11 -0
  158. package/lib/db/repositories/earliestAvailableSlot.d.ts.map +1 -0
  159. package/lib/db/repositories/earliestAvailableSlot.js +19 -0
  160. package/lib/db/repositories/earliestAvailableSlot.js.map +1 -0
  161. package/lib/db/repositories/index.d.ts +1 -0
  162. package/lib/db/repositories/index.d.ts.map +1 -1
  163. package/lib/db/repositories/index.js +1 -0
  164. package/lib/db/repositories/index.js.map +1 -1
  165. package/lib/db/repositories/proposerPreferences.d.ts +14 -0
  166. package/lib/db/repositories/proposerPreferences.d.ts.map +1 -0
  167. package/lib/db/repositories/proposerPreferences.js +21 -0
  168. package/lib/db/repositories/proposerPreferences.js.map +1 -0
  169. package/lib/execution/engine/blobVersionedHashes.d.ts +9 -0
  170. package/lib/execution/engine/blobVersionedHashes.d.ts.map +1 -0
  171. package/lib/execution/engine/blobVersionedHashes.js +74 -0
  172. package/lib/execution/engine/blobVersionedHashes.js.map +1 -0
  173. package/lib/execution/engine/disabled.d.ts +0 -2
  174. package/lib/execution/engine/disabled.d.ts.map +1 -1
  175. package/lib/execution/engine/disabled.js +0 -6
  176. package/lib/execution/engine/disabled.js.map +1 -1
  177. package/lib/execution/engine/http.d.ts +46 -16
  178. package/lib/execution/engine/http.d.ts.map +1 -1
  179. package/lib/execution/engine/http.js +236 -213
  180. package/lib/execution/engine/http.js.map +1 -1
  181. package/lib/execution/engine/index.d.ts +3 -2
  182. package/lib/execution/engine/index.d.ts.map +1 -1
  183. package/lib/execution/engine/index.js +33 -8
  184. package/lib/execution/engine/index.js.map +1 -1
  185. package/lib/execution/engine/interface.d.ts +2 -4
  186. package/lib/execution/engine/interface.d.ts.map +1 -1
  187. package/lib/execution/engine/jsonRpcTransport.d.ts +25 -0
  188. package/lib/execution/engine/jsonRpcTransport.d.ts.map +1 -0
  189. package/lib/execution/engine/jsonRpcTransport.js +158 -0
  190. package/lib/execution/engine/jsonRpcTransport.js.map +1 -0
  191. package/lib/execution/engine/mock.d.ts +0 -2
  192. package/lib/execution/engine/mock.d.ts.map +1 -1
  193. package/lib/execution/engine/mock.js +0 -8
  194. package/lib/execution/engine/mock.js.map +1 -1
  195. package/lib/execution/engine/restHttpClient.d.ts +71 -0
  196. package/lib/execution/engine/restHttpClient.d.ts.map +1 -0
  197. package/lib/execution/engine/restHttpClient.js +201 -0
  198. package/lib/execution/engine/restHttpClient.js.map +1 -0
  199. package/lib/execution/engine/restTransport.d.ts +46 -0
  200. package/lib/execution/engine/restTransport.d.ts.map +1 -0
  201. package/lib/execution/engine/restTransport.js +399 -0
  202. package/lib/execution/engine/restTransport.js.map +1 -0
  203. package/lib/execution/engine/sszTypes.d.ts +1261 -0
  204. package/lib/execution/engine/sszTypes.d.ts.map +1 -0
  205. package/lib/execution/engine/sszTypes.js +216 -0
  206. package/lib/execution/engine/sszTypes.js.map +1 -0
  207. package/lib/execution/engine/transport.d.ts +39 -0
  208. package/lib/execution/engine/transport.d.ts.map +1 -0
  209. package/lib/execution/engine/transport.js +2 -0
  210. package/lib/execution/engine/transport.js.map +1 -0
  211. package/lib/execution/engine/types.d.ts +2 -8
  212. package/lib/execution/engine/types.d.ts.map +1 -1
  213. package/lib/execution/engine/types.js +24 -57
  214. package/lib/execution/engine/types.js.map +1 -1
  215. package/lib/execution/engine/utils.d.ts.map +1 -1
  216. package/lib/execution/engine/utils.js +9 -2
  217. package/lib/execution/engine/utils.js.map +1 -1
  218. package/lib/metrics/metrics/lodestar.d.ts +10 -0
  219. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  220. package/lib/metrics/metrics/lodestar.js +22 -0
  221. package/lib/metrics/metrics/lodestar.js.map +1 -1
  222. package/lib/metrics/metrics.d.ts +7 -3
  223. package/lib/metrics/metrics.d.ts.map +1 -1
  224. package/lib/metrics/metrics.js +4 -4
  225. package/lib/metrics/metrics.js.map +1 -1
  226. package/lib/network/core/events.d.ts +5 -1
  227. package/lib/network/core/events.d.ts.map +1 -1
  228. package/lib/network/core/events.js +8 -0
  229. package/lib/network/core/events.js.map +1 -1
  230. package/lib/network/gossip/topic.d.ts +0 -14
  231. package/lib/network/gossip/topic.d.ts.map +1 -1
  232. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  233. package/lib/network/processor/gossipHandlers.js +63 -64
  234. package/lib/network/processor/gossipHandlers.js.map +1 -1
  235. package/lib/network/processor/gossipValidatorFn.d.ts +7 -3
  236. package/lib/network/processor/gossipValidatorFn.d.ts.map +1 -1
  237. package/lib/network/processor/gossipValidatorFn.js +7 -3
  238. package/lib/network/processor/gossipValidatorFn.js.map +1 -1
  239. package/lib/network/processor/index.d.ts +9 -0
  240. package/lib/network/processor/index.d.ts.map +1 -1
  241. package/lib/network/processor/index.js +80 -13
  242. package/lib/network/processor/index.js.map +1 -1
  243. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js +1 -1
  244. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js.map +1 -1
  245. package/lib/network/reqresp/rateLimit.js +2 -2
  246. package/lib/network/reqresp/rateLimit.js.map +1 -1
  247. package/lib/network/subnets/attnetsService.d.ts.map +1 -1
  248. package/lib/network/subnets/attnetsService.js +3 -1
  249. package/lib/network/subnets/attnetsService.js.map +1 -1
  250. package/lib/node/nodejs.d.ts +3 -1
  251. package/lib/node/nodejs.d.ts.map +1 -1
  252. package/lib/node/nodejs.js +27 -4
  253. package/lib/node/nodejs.js.map +1 -1
  254. package/lib/node/notifier.d.ts.map +1 -1
  255. package/lib/node/notifier.js +12 -13
  256. package/lib/node/notifier.js.map +1 -1
  257. package/lib/node/options.d.ts +3 -2
  258. package/lib/node/options.d.ts.map +1 -1
  259. package/lib/node/options.js +2 -2
  260. package/lib/node/options.js.map +1 -1
  261. package/lib/sync/range/batch.d.ts +11 -5
  262. package/lib/sync/range/batch.d.ts.map +1 -1
  263. package/lib/sync/range/batch.js +21 -17
  264. package/lib/sync/range/batch.js.map +1 -1
  265. package/lib/sync/range/chain.d.ts +4 -4
  266. package/lib/sync/range/chain.d.ts.map +1 -1
  267. package/lib/sync/range/chain.js +12 -6
  268. package/lib/sync/range/chain.js.map +1 -1
  269. package/lib/sync/range/range.d.ts.map +1 -1
  270. package/lib/sync/range/range.js +75 -29
  271. package/lib/sync/range/range.js.map +1 -1
  272. package/lib/sync/unknownBlock.d.ts +5 -2
  273. package/lib/sync/unknownBlock.d.ts.map +1 -1
  274. package/lib/sync/unknownBlock.js +52 -26
  275. package/lib/sync/unknownBlock.js.map +1 -1
  276. package/lib/sync/utils/downloadByRange.d.ts +38 -14
  277. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  278. package/lib/sync/utils/downloadByRange.js +84 -39
  279. package/lib/sync/utils/downloadByRange.js.map +1 -1
  280. package/lib/util/asyncIterableToEvents.d.ts +10 -2
  281. package/lib/util/asyncIterableToEvents.d.ts.map +1 -1
  282. package/lib/util/asyncIterableToEvents.js +29 -3
  283. package/lib/util/asyncIterableToEvents.js.map +1 -1
  284. package/lib/util/clock.d.ts.map +1 -1
  285. package/lib/util/clock.js +3 -4
  286. package/lib/util/clock.js.map +1 -1
  287. package/lib/util/execution.d.ts +9 -11
  288. package/lib/util/execution.d.ts.map +1 -1
  289. package/lib/util/execution.js +5 -1
  290. package/lib/util/execution.js.map +1 -1
  291. package/lib/util/metadata.d.ts.map +1 -1
  292. package/lib/util/metadata.js +2 -1
  293. package/lib/util/metadata.js.map +1 -1
  294. package/lib/util/sszBytes.d.ts +2 -2
  295. package/lib/util/sszBytes.d.ts.map +1 -1
  296. package/lib/util/sszBytes.js +21 -14
  297. package/lib/util/sszBytes.js.map +1 -1
  298. package/package.json +18 -17
  299. package/src/api/impl/beacon/blocks/index.ts +17 -7
  300. package/src/api/impl/beacon/index.ts +15 -0
  301. package/src/api/impl/beacon/state/index.ts +43 -6
  302. package/src/api/impl/debug/index.ts +28 -19
  303. package/src/api/impl/validator/index.ts +102 -21
  304. package/src/chain/ColumnReconstructionTracker.ts +4 -6
  305. package/src/chain/archiveStore/archiveStore.ts +19 -25
  306. package/src/chain/archiveStore/historicalState/getHistoricalState.ts +5 -7
  307. package/src/chain/archiveStore/historicalState/historicalStateRegen.ts +1 -1
  308. package/src/chain/archiveStore/historicalState/types.ts +2 -2
  309. package/src/chain/archiveStore/historicalState/worker.ts +1 -2
  310. package/src/chain/archiveStore/interface.ts +1 -1
  311. package/src/chain/archiveStore/utils/pruneHistory.ts +4 -1
  312. package/src/chain/beaconProposerCache.ts +19 -1
  313. package/src/chain/blocks/blockInput/blockInput.ts +1 -1
  314. package/src/chain/blocks/importBlock.ts +28 -10
  315. package/src/chain/blocks/payloadEnvelopeInput/types.ts +2 -1
  316. package/src/chain/blocks/verifyBlock.ts +8 -6
  317. package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +6 -3
  318. package/src/chain/chain.ts +135 -37
  319. package/src/chain/emitter.ts +7 -1
  320. package/src/chain/errors/envelopeReconstructionError.ts +3 -0
  321. package/src/chain/errors/gossipValidation.ts +2 -0
  322. package/src/chain/forkChoice/index.ts +2 -0
  323. package/src/chain/interface.ts +7 -3
  324. package/src/chain/opPools/aggregatedAttestationPool.ts +34 -10
  325. package/src/chain/opPools/opPool.ts +1 -31
  326. package/src/chain/opPools/proposerPreferencesPool.ts +34 -11
  327. package/src/chain/opPools/utils.ts +31 -0
  328. package/src/chain/options.ts +3 -3
  329. package/src/chain/prepareNextSlot.ts +28 -9
  330. package/src/chain/produceBlock/computeNewStateRoot.ts +10 -3
  331. package/src/chain/produceBlock/produceBlockBody.ts +86 -40
  332. package/src/chain/regen/regen.ts +12 -4
  333. package/src/chain/reprocess.ts +2 -1
  334. package/src/chain/seenCache/seenGossipBlockInput.ts +25 -1
  335. package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +31 -13
  336. package/src/chain/shufflingCache.ts +84 -22
  337. package/src/chain/stateCache/persistentCheckpointsCache.ts +4 -1
  338. package/src/chain/validatorMonitor.ts +82 -61
  339. package/src/constants/constants.ts +1 -0
  340. package/src/db/beacon.ts +6 -0
  341. package/src/db/buckets.ts +2 -0
  342. package/src/db/interface.ts +4 -0
  343. package/src/db/repositories/blockArchive.ts +2 -2
  344. package/src/db/repositories/blockArchiveIndex.ts +2 -3
  345. package/src/db/repositories/earliestAvailableSlot.ts +19 -0
  346. package/src/db/repositories/index.ts +1 -0
  347. package/src/db/repositories/proposerPreferences.ts +23 -0
  348. package/src/execution/engine/blobVersionedHashes.ts +72 -0
  349. package/src/execution/engine/disabled.ts +0 -8
  350. package/src/execution/engine/http.ts +304 -300
  351. package/src/execution/engine/index.ts +41 -7
  352. package/src/execution/engine/interface.ts +2 -6
  353. package/src/execution/engine/jsonRpcTransport.ts +247 -0
  354. package/src/execution/engine/mock.ts +1 -19
  355. package/src/execution/engine/restHttpClient.ts +269 -0
  356. package/src/execution/engine/restTransport.ts +544 -0
  357. package/src/execution/engine/sszTypes.ts +354 -0
  358. package/src/execution/engine/transport.ts +61 -0
  359. package/src/execution/engine/types.ts +34 -84
  360. package/src/execution/engine/utils.ts +12 -2
  361. package/src/metrics/metrics/lodestar.ts +23 -0
  362. package/src/metrics/metrics.ts +21 -6
  363. package/src/network/core/events.ts +16 -1
  364. package/src/network/processor/gossipHandlers.ts +94 -77
  365. package/src/network/processor/gossipValidatorFn.ts +13 -3
  366. package/src/network/processor/index.ts +92 -13
  367. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRoot.ts +1 -1
  368. package/src/network/reqresp/rateLimit.ts +2 -2
  369. package/src/network/subnets/attnetsService.ts +8 -3
  370. package/src/node/nodejs.ts +35 -3
  371. package/src/node/notifier.ts +14 -13
  372. package/src/node/options.ts +10 -1
  373. package/src/sync/range/batch.ts +25 -19
  374. package/src/sync/range/chain.ts +15 -8
  375. package/src/sync/range/range.ts +76 -30
  376. package/src/sync/unknownBlock.ts +65 -27
  377. package/src/sync/utils/downloadByRange.ts +123 -58
  378. package/src/util/asyncIterableToEvents.ts +44 -5
  379. package/src/util/clock.ts +3 -4
  380. package/src/util/execution.ts +16 -8
  381. package/src/util/metadata.ts +2 -1
  382. package/src/util/sszBytes.ts +25 -12
@@ -2,9 +2,10 @@ import {EventEmitter} from "node:events";
2
2
  import {StrictEventEmitter} from "strict-event-emitter-types";
3
3
  import {BeaconConfig} from "@lodestar/config";
4
4
  import {IBeaconStateViewGloas, computeStartSlotAtEpoch, isStatePostGloas} from "@lodestar/state-transition";
5
- import {Epoch, Status, fulu} from "@lodestar/types";
6
- import {Logger, prettyPrintIndices, toRootHex} from "@lodestar/utils";
5
+ import {Epoch, Status, fulu, ssz} from "@lodestar/types";
6
+ import {Logger, byteArrayEquals, prettyPrintIndices, toRootHex} from "@lodestar/utils";
7
7
  import {IBlockInput} from "../../chain/blocks/blockInput/types.js";
8
+ import {PayloadError, PayloadErrorCode} from "../../chain/blocks/importExecutionPayload.js";
8
9
  import {AttestationImportOpt, ImportBlockOpts} from "../../chain/blocks/index.js";
9
10
  import {assertLinearChainSegment} from "../../chain/blocks/utils/chainSegment.js";
10
11
  import {BlockError} from "../../chain/errors/index.js";
@@ -15,6 +16,7 @@ import {PeerIdStr} from "../../util/peerId.js";
15
16
  import {
16
17
  DownloadByRangeError,
17
18
  DownloadByRangeErrorCode,
19
+ ParentPayload,
18
20
  cacheByRangeResponses,
19
21
  downloadByRange,
20
22
  } from "../utils/downloadByRange.js";
@@ -207,22 +209,50 @@ export class RangeSync extends (EventEmitter as {new (): RangeSyncEmitter}) {
207
209
  blsVerifyOnMainThread: false,
208
210
  };
209
211
 
210
- if (this.opts?.disableProcessAsChainSegment) {
211
- // Should only be used for debugging or testing
212
- for (const block of blocks) {
213
- await this.chain.processBlock(block, flags);
214
- const payloadEnvelope = payloadEnvelopes?.get(block.slot);
215
- if (payloadEnvelope?.hasPayloadEnvelope()) {
216
- await this.chain.processExecutionPayload(payloadEnvelope);
212
+ try {
213
+ if (this.opts?.disableProcessAsChainSegment) {
214
+ // Should only be used for debugging or testing
215
+ for (const block of blocks) {
216
+ await this.chain.processBlock(block, flags);
217
+ const payloadEnvelope = payloadEnvelopes?.get(block.slot);
218
+ if (payloadEnvelope?.hasPayloadEnvelope()) {
219
+ await this.chain.processExecutionPayload(payloadEnvelope);
220
+ }
221
+ }
222
+ } else {
223
+ const {orphaned, skipped} = await this.chain.processChainSegment(blocks, payloadEnvelopes, flags);
224
+ // We log orphaned payloads to work with different clients
225
+ // in the future, consider applying penalties in certain conditions
226
+ // make sure the payload source was from range sync in that case
227
+ for (const {slot, payloadEnvelopeInput} of orphaned) {
228
+ const {peerIdStr, source} = payloadEnvelopeInput.getPayloadEnvelopeSource();
229
+ let client = "unknown";
230
+ if (peerIdStr !== undefined) {
231
+ try {
232
+ client = this.getConnectedPeerSyncMeta(peerIdStr).client;
233
+ } catch {
234
+ // peer disconnected since serving the envelope, keep "unknown"
235
+ }
236
+ }
237
+ this.logger.debug("Orphaned payload envelope in range sync batch", {
238
+ slot,
239
+ root: payloadEnvelopeInput.blockRootHex,
240
+ peer: peerIdStr ?? "unknown",
241
+ source,
242
+ client,
243
+ skipped,
244
+ });
217
245
  }
218
246
  }
219
- } else {
220
- const {orphaned, skipped} = await this.chain.processChainSegment(blocks, payloadEnvelopes, flags);
221
- // We log orphaned payloads to work with different clients
222
- // in the future, consider applying penalties in certain conditions
223
- // make sure the payload source was from range sync in that case
224
- for (const {slot, payloadEnvelopeInput} of orphaned) {
225
- const {peerIdStr, source} = payloadEnvelopeInput.getPayloadEnvelopeSource();
247
+ } catch (e) {
248
+ if (
249
+ e instanceof PayloadError &&
250
+ (e.type.code === PayloadErrorCode.INVALID_SIGNATURE ||
251
+ e.type.code === PayloadErrorCode.ENVELOPE_VERIFICATION_ERROR ||
252
+ e.type.code === PayloadErrorCode.EXECUTION_ENGINE_INVALID)
253
+ ) {
254
+ const {payloadInput} = e;
255
+ const {peerIdStr, source} = payloadInput.getPayloadEnvelopeSource();
226
256
  let client = "unknown";
227
257
  if (peerIdStr !== undefined) {
228
258
  try {
@@ -231,30 +261,32 @@ export class RangeSync extends (EventEmitter as {new (): RangeSyncEmitter}) {
231
261
  // peer disconnected since serving the envelope, keep "unknown"
232
262
  }
233
263
  }
234
- this.logger.debug("Orphaned payload envelope in range sync batch", {
235
- slot,
236
- root: payloadEnvelopeInput.blockRootHex,
264
+ this.logger.debug("Removing invalid payload envelope in range sync batch", {
265
+ slot: payloadInput.slot,
266
+ root: payloadInput.blockRootHex,
237
267
  peer: peerIdStr ?? "unknown",
238
268
  source,
239
269
  client,
240
- skipped,
270
+ code: e.type.code,
241
271
  });
272
+ // The batch is downloaded again, it would otherwise reuse the cached envelope and fail the same way
273
+ this.chain.seenPayloadEnvelopeInputCache.removeInvalid(payloadInput);
242
274
  }
275
+ throw e;
243
276
  }
244
277
  };
245
278
 
246
279
  private downloadByRange: SyncChainFns["downloadByRange"] = async (peer, batch) => {
247
280
  const batchBlocks = batch.getBlocks();
248
281
  const requests = batch.getRequestsForPeer(peer);
249
- const parentRoot = requests.parentPayloadRequest?.envelopeBlockRoot ?? requests.parentPayloadRequest?.blockRoot;
250
- const parentPayloadCommitments = parentRoot ? batch.getParentPayloadCommitments(parentRoot) : undefined;
282
+ const parentPayload = requests.parentPayloadRequest ? batch.getParentPayload() : undefined;
251
283
  const {result, warnings} = await downloadByRange({
252
284
  config: this.config,
253
285
  network: this.network,
254
286
  logger: this.logger,
255
287
  peerIdStr: peer.peerId,
256
288
  batchBlocks,
257
- parentPayloadCommitments,
289
+ parentPayload,
258
290
  peerDasMetrics: this.chain.metrics?.peerDas,
259
291
  ...requests,
260
292
  });
@@ -267,6 +299,7 @@ export class RangeSync extends (EventEmitter as {new (): RangeSyncEmitter}) {
267
299
  batchBlocks,
268
300
  downloadedPayloadEnvelopes,
269
301
  existingPayloadEnvelopes: batch.getPayloadEnvelopes(),
302
+ parentPayload,
270
303
  custodyConfig: this.chain.custodyConfig,
271
304
  seenTimestampSec: Date.now() / 1000,
272
305
  });
@@ -344,13 +377,26 @@ export class RangeSync extends (EventEmitter as {new (): RangeSyncEmitter}) {
344
377
  private addPeerOrCreateChain(startEpoch: Epoch, target: ChainTarget, peer: PeerIdStr, syncType: RangeSyncType): void {
345
378
  let syncChain = this.chains.get(syncType);
346
379
  if (!syncChain) {
347
- // The first batch of a new sync chain may need to detect whether the parent block was an
348
- // gloas "empty" block (no envelope produced). It does so by comparing the first
349
- // downloaded block's `bid.parentBlockHash` against the head state's `latestExecutionPayloadBid.blockHash`.
380
+ // The first block of the first batch may build on the head's FULL variant before its payload is imported,
381
+ // the batch then downloads the head's payload as dangling parent and validates it against the bid
350
382
  const headState = this.chain.getHeadState();
351
- const latestBid = isStatePostGloas(headState)
352
- ? (headState as IBeaconStateViewGloas).latestExecutionPayloadBid
353
- : undefined;
383
+ let parentPayload: ParentPayload | undefined;
384
+ if (isStatePostGloas(headState) && headState.latestBlockHeader.slot > 0) {
385
+ const header = ssz.phase0.BeaconBlockHeader.clone(headState.latestBlockHeader);
386
+ if (byteArrayEquals(header.stateRoot, ssz.Root.defaultValue())) {
387
+ header.stateRoot = headState.hashTreeRoot();
388
+ }
389
+ const headRoot = ssz.phase0.BeaconBlockHeader.hashTreeRoot(header);
390
+ const headSlot = headState.latestBlockHeader.slot;
391
+ parentPayload = {
392
+ blockRoot: headRoot,
393
+ blockRootHex: toRootHex(headRoot),
394
+ slot: headSlot,
395
+ proposerIndex: headState.latestBlockHeader.proposerIndex,
396
+ forkName: this.config.getForkName(headSlot),
397
+ bid: (headState as IBeaconStateViewGloas).latestExecutionPayloadBid,
398
+ };
399
+ }
354
400
 
355
401
  syncChain = new SyncChain(
356
402
  startEpoch,
@@ -371,7 +417,7 @@ export class RangeSync extends (EventEmitter as {new (): RangeSyncEmitter}) {
371
417
  custodyConfig: this.chain.custodyConfig,
372
418
  metrics: this.metrics,
373
419
  },
374
- latestBid
420
+ parentPayload
375
421
  );
376
422
  this.chains.set(syncType, syncChain);
377
423
 
@@ -73,7 +73,11 @@ type AdvancePendingBlockResult =
73
73
  | "removed";
74
74
 
75
75
  class UnknownBlockRateLimitedError extends Error {
76
- constructor(message: string) {
76
+ constructor(
77
+ message: string,
78
+ /** Earliest backoff expiry seen when the download was deferred, it is retried once that has passed */
79
+ readonly retryAt: number
80
+ ) {
77
81
  super(message);
78
82
  this.name = "UnknownBlockRateLimitedError";
79
83
  }
@@ -849,17 +853,20 @@ export class BlockInputSync {
849
853
  }
850
854
  };
851
855
 
852
- private scheduleRateLimitBackoffRetry(): void {
856
+ /**
857
+ * Returns false if there is no backoff left to wait for, in which case no retry is scheduled.
858
+ */
859
+ private scheduleRateLimitBackoffRetry(): boolean {
853
860
  this.clearRateLimitBackoffTimer();
854
861
 
855
862
  if (!this.subscribedToNetworkEvents || (this.pendingBlocks.size === 0 && this.pendingPayloads.size === 0)) {
856
- return;
863
+ return false;
857
864
  }
858
865
 
859
866
  const now = Date.now();
860
867
  const retryAt = this.peerBalancer.getNextRateLimitRetryAt();
861
868
  if (retryAt === null) {
862
- return;
869
+ return false;
863
870
  }
864
871
 
865
872
  this.rateLimitBackoffTimeout = setTimeout(
@@ -870,6 +877,7 @@ export class BlockInputSync {
870
877
  },
871
878
  Math.max(0, retryAt - now)
872
879
  );
880
+ return true;
873
881
  }
874
882
 
875
883
  private clearRateLimitBackoffTimer(): void {
@@ -910,16 +918,17 @@ export class BlockInputSync {
910
918
  * Poll unknown payloads of the current slot.
911
919
  */
912
920
  private async pollPayloadsAtSlot(slot: Slot, signal: AbortSignal): Promise<void> {
921
+ const fork = this.config.getForkName(slot);
913
922
  // fixed tick count so the loop cannot outlive its slot: for mainnet, it's 6 ticks
914
923
  const tickCount = Math.floor(
915
- (this.config.SLOT_DURATION_MS - this.config.getPayloadDueMs()) / PAYLOAD_POLL_INTERVAL_MS
924
+ (this.config.getSlotDurationMs(fork) - this.config.getPayloadDueMs(fork)) / PAYLOAD_POLL_INTERVAL_MS
916
925
  );
917
926
  // a root still missing on several ticks is searched on each of them, recorded once
918
927
  const searchedRoots = new Set<RootHex>();
919
928
  let polls = 0;
920
929
 
921
930
  try {
922
- await sleep(Math.max(0, this.config.getPayloadDueMs() - this.chain.clock.msFromSlot(slot)), signal);
931
+ await sleep(Math.max(0, this.config.getPayloadDueMs(fork) - this.chain.clock.msFromSlot(slot)), signal);
923
932
 
924
933
  for (polls = 0; polls < tickCount; polls++) {
925
934
  let importedCount = 0;
@@ -1081,7 +1090,11 @@ export class BlockInputSync {
1081
1090
  pendingBlock.status = PendingBlockInputStatus.pending;
1082
1091
  }
1083
1092
  this.logger.debug("Deferring unknown block download due to peer rate limit", logCtx, res.err);
1084
- this.scheduleRateLimitBackoffRetry();
1093
+ if (!this.scheduleRateLimitBackoffRetry() || res.err.retryAt <= Date.now()) {
1094
+ // The backoff this download waited for expired in the meantime, a timer is only armed if another
1095
+ // peer is still in backoff and would retry it later than needed
1096
+ this.triggerUnknownBlockSearch();
1097
+ }
1085
1098
  return;
1086
1099
  }
1087
1100
 
@@ -1364,6 +1377,14 @@ export class BlockInputSync {
1364
1377
  if (!isPendingPayloadEnvelope(payload)) {
1365
1378
  payload.status = PendingPayloadInputStatus.pending;
1366
1379
  }
1380
+ if (
1381
+ res.err instanceof UnknownBlockRateLimitedError &&
1382
+ (!this.scheduleRateLimitBackoffRetry() || res.err.retryAt <= Date.now())
1383
+ ) {
1384
+ // The backoff this download waited for expired in the meantime, a timer is only armed if another
1385
+ // peer is still in backoff and would retry it later than needed
1386
+ this.triggerUnknownBlockSearch();
1387
+ }
1367
1388
  }
1368
1389
 
1369
1390
  private async processPayload(pendingPayload: PendingPayloadInput): Promise<void> {
@@ -1426,20 +1447,23 @@ export class BlockInputSync {
1426
1447
  pendingPayload.status = PendingPayloadInputStatus.downloaded;
1427
1448
  break;
1428
1449
 
1450
+ // The invalid envelope is evicted from the seen cache in the cases below, otherwise the next
1451
+ // attempt would reuse it instead of fetching another envelope from peers
1429
1452
  case PayloadErrorCode.EXECUTION_ENGINE_INVALID:
1430
1453
  this.logger.debug("Error processing payload from unknown sync", logCtx, res.err);
1454
+ this.chain.seenPayloadEnvelopeInputCache.removeInvalid(pendingPayload.payloadInput);
1431
1455
  this.removePendingPayloadAndDescendants(rootHex, DroppedItemReason.elInvalid);
1432
1456
  break;
1433
1457
 
1434
1458
  case PayloadErrorCode.ENVELOPE_VERIFICATION_ERROR:
1435
1459
  this.logger.debug("Error processing payload from unknown sync", logCtx, res.err);
1460
+ this.chain.seenPayloadEnvelopeInputCache.removeInvalid(pendingPayload.payloadInput);
1436
1461
  this.removePendingPayloadAndDescendants(rootHex, DroppedItemReason.invalidEnvelope);
1437
1462
  break;
1438
1463
 
1439
1464
  case PayloadErrorCode.INVALID_SIGNATURE:
1440
- // TODO GLOAS: Decide how invalid payload inputs should eventually leave memory without
1441
- // reintroducing envelope replacement / recreation flows.
1442
1465
  this.logger.debug("Error processing payload from unknown sync", logCtx, res.err);
1466
+ this.chain.seenPayloadEnvelopeInputCache.removeInvalid(pendingPayload.payloadInput);
1443
1467
  this.removePendingPayloadAndDescendants(rootHex, DroppedItemReason.invalidSignature);
1444
1468
  break;
1445
1469
 
@@ -1485,16 +1509,21 @@ export class BlockInputSync {
1485
1509
  const pendingColumns = payloadInput?.hasAllData()
1486
1510
  ? new Set<number>()
1487
1511
  : new Set(payloadInput?.getMissingSampledColumnMeta().missing ?? []);
1512
+ // Same `now` for both calls, a backoff expiring in between would be reported as no peer available
1513
+ const now = Date.now();
1488
1514
  // prefer peers that gossiped this payload root to us (#9923)
1489
1515
  const peerMeta = this.peerBalancer.bestPeerForPendingColumns(
1490
1516
  pendingColumns,
1491
1517
  excludedPeers,
1492
- cacheItem.peerIdStrings
1518
+ cacheItem.peerIdStrings,
1519
+ now
1493
1520
  );
1494
1521
  if (peerMeta === null) {
1495
- if (this.peerBalancer.getNextRateLimitRetryAt(pendingColumns, excludedPeers) !== null) {
1522
+ const retryAt = this.peerBalancer.getNextRateLimitRetryAt(pendingColumns, excludedPeers, now);
1523
+ if (retryAt !== null) {
1496
1524
  throw new UnknownBlockRateLimitedError(
1497
- `Error fetching payload by root slot=${slot} root=${rootHex} after ${i}: peers with needed columns are rate-limited`
1525
+ `Error fetching payload by root slot=${slot} root=${rootHex} after ${i}: peers with needed columns are rate-limited`,
1526
+ retryAt
1498
1527
  );
1499
1528
  }
1500
1529
 
@@ -1633,9 +1662,11 @@ export class BlockInputSync {
1633
1662
  );
1634
1663
  this.metrics?.blockInputSync.payloadFetchPeers.set({result: FetchResult.FailureMaxAttempts}, i - 1);
1635
1664
 
1636
- if (deferredByRateLimit && this.peerBalancer.getNextRateLimitRetryAt() !== null) {
1665
+ const retryAt = deferredByRateLimit ? this.peerBalancer.getNextRateLimitRetryAt() : null;
1666
+ if (retryAt !== null) {
1637
1667
  throw new UnknownBlockRateLimitedError(
1638
- `Error fetching payload with slot=${slot} root=${rootHex} after ${i - 1} attempts: peers are rate-limited`
1668
+ `Error fetching payload with slot=${slot} root=${rootHex} after ${i - 1} attempts: peers are rate-limited`,
1669
+ retryAt
1639
1670
  );
1640
1671
  }
1641
1672
  throw Error(`Error fetching payload with slot=${slot} root=${rootHex} after ${i - 1} attempts.`);
@@ -1727,16 +1758,21 @@ export class BlockInputSync {
1727
1758
  isPendingBlockInput(cacheItem) && isBlockInputColumns(cacheItem.blockInput)
1728
1759
  ? new Set(cacheItem.blockInput.getMissingSampledColumnMeta().missing)
1729
1760
  : defaultPendingColumns;
1761
+ // Same `now` for both calls, a backoff expiring in between would be reported as no peer available
1762
+ const now = Date.now();
1730
1763
  // prefer peers that gossiped this block root to us (#9923)
1731
1764
  const peerMeta = this.peerBalancer.bestPeerForPendingColumns(
1732
1765
  pendingColumns,
1733
1766
  excludedPeers,
1734
- cacheItem.peerIdStrings
1767
+ cacheItem.peerIdStrings,
1768
+ now
1735
1769
  );
1736
1770
  if (peerMeta === null) {
1737
- if (this.peerBalancer.getNextRateLimitRetryAt(pendingColumns, excludedPeers) !== null) {
1771
+ const retryAt = this.peerBalancer.getNextRateLimitRetryAt(pendingColumns, excludedPeers, now);
1772
+ if (retryAt !== null) {
1738
1773
  throw new UnknownBlockRateLimitedError(
1739
- `Error fetching UnknownBlockRoot slot=${slot} root=${rootHex} after ${i}: peers with needed columns are rate-limited`
1774
+ `Error fetching UnknownBlockRoot slot=${slot} root=${rootHex} after ${i}: peers with needed columns are rate-limited`,
1775
+ retryAt
1740
1776
  );
1741
1777
  }
1742
1778
 
@@ -1842,8 +1878,9 @@ export class BlockInputSync {
1842
1878
 
1843
1879
  const message = `Error fetching BlockInput with slot=${slot} root=${rootHex} after ${i - 1} attempts.`;
1844
1880
 
1845
- if (deferredByRateLimit && this.peerBalancer.getNextRateLimitRetryAt() !== null) {
1846
- throw new UnknownBlockRateLimitedError(`${message} Peers are rate-limited.`);
1881
+ const retryAt = deferredByRateLimit ? this.peerBalancer.getNextRateLimitRetryAt() : null;
1882
+ if (retryAt !== null) {
1883
+ throw new UnknownBlockRateLimitedError(`${message} Peers are rate-limited.`, retryAt);
1847
1884
  }
1848
1885
 
1849
1886
  if (!isPendingBlockInput(cacheItem)) {
@@ -1879,8 +1916,6 @@ export class BlockInputSync {
1879
1916
 
1880
1917
  // Once a parent payload is invalid, every descendant waiting on that payload lineage becomes unrecoverable too.
1881
1918
  private removePendingPayloadAndDescendants(rootHex: RootHex, headReason: DroppedItemReason): void {
1882
- // Keep PayloadEnvelopeInput resident in the seen cache. importBlock() owns that object and
1883
- // later validation/finalization logic decides when it can leave memory.
1884
1919
  if (this.pendingPayloads.delete(rootHex)) {
1885
1920
  this.metrics?.blockInputSync.removedPayloads.inc({reason: headReason}, 1);
1886
1921
  }
@@ -2036,8 +2071,11 @@ export class UnknownBlockPeerBalancer {
2036
2071
  this.rateLimitedUntilByPeer.set(peerId, rateLimitedUntilMs);
2037
2072
  }
2038
2073
 
2039
- getNextRateLimitRetryAt(pendingColumns?: Set<number>, excludedPeers?: Set<PeerIdStr>): number | null {
2040
- const now = Date.now();
2074
+ getNextRateLimitRetryAt(
2075
+ pendingColumns?: Set<number>,
2076
+ excludedPeers?: Set<PeerIdStr>,
2077
+ now = Date.now()
2078
+ ): number | null {
2041
2079
  let retryAt: number | null = null;
2042
2080
 
2043
2081
  for (const [peerId, rateLimitedUntil] of this.rateLimitedUntilByPeer.entries()) {
@@ -2076,9 +2114,10 @@ export class UnknownBlockPeerBalancer {
2076
2114
  bestPeerForPendingColumns(
2077
2115
  pendingColumns: Set<number>,
2078
2116
  excludedPeers: Set<PeerIdStr>,
2079
- preferredPeers?: Set<PeerIdStr>
2117
+ preferredPeers?: Set<PeerIdStr>,
2118
+ now = Date.now()
2080
2119
  ): PeerSyncMeta | null {
2081
- const eligiblePeers = this.filterPeers(pendingColumns, excludedPeers);
2120
+ const eligiblePeers = this.filterPeers(pendingColumns, excludedPeers, now);
2082
2121
  if (eligiblePeers.length === 0) {
2083
2122
  return null;
2084
2123
  }
@@ -2119,8 +2158,7 @@ export class UnknownBlockPeerBalancer {
2119
2158
  return totalActiveRequests;
2120
2159
  }
2121
2160
 
2122
- private filterPeers(pendingDataColumns: Set<number>, excludedPeers: Set<PeerIdStr>): PeerIdStr[] {
2123
- const now = Date.now();
2161
+ private filterPeers(pendingDataColumns: Set<number>, excludedPeers: Set<PeerIdStr>, now: number): PeerIdStr[] {
2124
2162
  let maxColumnCount = 0;
2125
2163
  const considerPeers: {peerId: PeerIdStr; columnCount: number}[] = [];
2126
2164
  for (const [peerId, syncMeta] of this.peersMeta.entries()) {