@lodestar/beacon-node 1.43.0-dev.bc569affb9 → 1.43.0-dev.be5f70c0c8

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 (317) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +16 -5
  3. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  4. package/lib/api/impl/beacon/pool/index.d.ts.map +1 -1
  5. package/lib/api/impl/beacon/pool/index.js +45 -2
  6. package/lib/api/impl/beacon/pool/index.js.map +1 -1
  7. package/lib/api/impl/debug/index.d.ts.map +1 -1
  8. package/lib/api/impl/debug/index.js +0 -1
  9. package/lib/api/impl/debug/index.js.map +1 -1
  10. package/lib/api/impl/lodestar/index.js +1 -1
  11. package/lib/api/impl/lodestar/index.js.map +1 -1
  12. package/lib/api/impl/validator/index.d.ts.map +1 -1
  13. package/lib/api/impl/validator/index.js +68 -2
  14. package/lib/api/impl/validator/index.js.map +1 -1
  15. package/lib/chain/blocks/blockInput/blockInput.d.ts +3 -0
  16. package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
  17. package/lib/chain/blocks/blockInput/blockInput.js +4 -1
  18. package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
  19. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  20. package/lib/chain/blocks/importBlock.js +16 -28
  21. package/lib/chain/blocks/importBlock.js.map +1 -1
  22. package/lib/chain/blocks/importExecutionPayload.d.ts +23 -6
  23. package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
  24. package/lib/chain/blocks/importExecutionPayload.js +57 -24
  25. package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
  26. package/lib/chain/blocks/index.d.ts +5 -3
  27. package/lib/chain/blocks/index.d.ts.map +1 -1
  28. package/lib/chain/blocks/index.js +58 -25
  29. package/lib/chain/blocks/index.js.map +1 -1
  30. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +12 -1
  31. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
  32. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +28 -2
  33. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
  34. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +17 -0
  35. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
  36. package/lib/chain/blocks/payloadEnvelopeProcessor.js +2 -2
  37. package/lib/chain/blocks/payloadEnvelopeProcessor.js.map +1 -1
  38. package/lib/chain/blocks/types.d.ts +4 -3
  39. package/lib/chain/blocks/types.d.ts.map +1 -1
  40. package/lib/chain/blocks/utils/chainSegment.d.ts +23 -2
  41. package/lib/chain/blocks/utils/chainSegment.d.ts.map +1 -1
  42. package/lib/chain/blocks/utils/chainSegment.js +89 -12
  43. package/lib/chain/blocks/utils/chainSegment.js.map +1 -1
  44. package/lib/chain/blocks/verifyBlock.d.ts +5 -3
  45. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  46. package/lib/chain/blocks/verifyBlock.js +50 -7
  47. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  48. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts +0 -4
  49. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
  50. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +5 -2
  51. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
  52. package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts +2 -1
  53. package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts.map +1 -1
  54. package/lib/chain/blocks/verifyBlocksSanityChecks.js +25 -5
  55. package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
  56. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts +2 -2
  57. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -1
  58. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +12 -8
  59. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -1
  60. package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts.map +1 -1
  61. package/lib/chain/blocks/verifyPayloadsDataAvailability.js +8 -3
  62. package/lib/chain/blocks/verifyPayloadsDataAvailability.js.map +1 -1
  63. package/lib/chain/chain.d.ts +3 -2
  64. package/lib/chain/chain.d.ts.map +1 -1
  65. package/lib/chain/chain.js +35 -12
  66. package/lib/chain/chain.js.map +1 -1
  67. package/lib/chain/emitter.d.ts +0 -11
  68. package/lib/chain/emitter.d.ts.map +1 -1
  69. package/lib/chain/emitter.js +0 -4
  70. package/lib/chain/emitter.js.map +1 -1
  71. package/lib/chain/errors/blockError.d.ts +8 -1
  72. package/lib/chain/errors/blockError.d.ts.map +1 -1
  73. package/lib/chain/errors/blockError.js +2 -0
  74. package/lib/chain/errors/blockError.js.map +1 -1
  75. package/lib/chain/errors/index.d.ts +1 -0
  76. package/lib/chain/errors/index.d.ts.map +1 -1
  77. package/lib/chain/errors/index.js +1 -0
  78. package/lib/chain/errors/index.js.map +1 -1
  79. package/lib/chain/errors/proposerPreferences.d.ts +40 -0
  80. package/lib/chain/errors/proposerPreferences.d.ts.map +1 -0
  81. package/lib/chain/errors/proposerPreferences.js +14 -0
  82. package/lib/chain/errors/proposerPreferences.js.map +1 -0
  83. package/lib/chain/initState.d.ts.map +1 -1
  84. package/lib/chain/initState.js +6 -1
  85. package/lib/chain/initState.js.map +1 -1
  86. package/lib/chain/interface.d.ts +3 -2
  87. package/lib/chain/interface.d.ts.map +1 -1
  88. package/lib/chain/interface.js.map +1 -1
  89. package/lib/chain/opPools/payloadAttestationPool.d.ts +3 -2
  90. package/lib/chain/opPools/payloadAttestationPool.d.ts.map +1 -1
  91. package/lib/chain/opPools/payloadAttestationPool.js +26 -4
  92. package/lib/chain/opPools/payloadAttestationPool.js.map +1 -1
  93. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  94. package/lib/chain/prepareNextSlot.js +16 -18
  95. package/lib/chain/prepareNextSlot.js.map +1 -1
  96. package/lib/chain/produceBlock/produceBlockBody.d.ts +12 -3
  97. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  98. package/lib/chain/produceBlock/produceBlockBody.js +35 -17
  99. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  100. package/lib/chain/regen/interface.d.ts +1 -0
  101. package/lib/chain/regen/interface.d.ts.map +1 -1
  102. package/lib/chain/regen/interface.js +1 -0
  103. package/lib/chain/regen/interface.js.map +1 -1
  104. package/lib/chain/regen/queued.d.ts.map +1 -1
  105. package/lib/chain/regen/queued.js +1 -4
  106. package/lib/chain/regen/queued.js.map +1 -1
  107. package/lib/chain/regen/regen.d.ts.map +1 -1
  108. package/lib/chain/regen/regen.js +1 -4
  109. package/lib/chain/regen/regen.js.map +1 -1
  110. package/lib/chain/seenCache/index.d.ts +1 -0
  111. package/lib/chain/seenCache/index.d.ts.map +1 -1
  112. package/lib/chain/seenCache/index.js +1 -0
  113. package/lib/chain/seenCache/index.js.map +1 -1
  114. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +21 -11
  115. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
  116. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +70 -20
  117. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
  118. package/lib/chain/seenCache/seenProposerPreferences.d.ts +16 -0
  119. package/lib/chain/seenCache/seenProposerPreferences.d.ts.map +1 -0
  120. package/lib/chain/seenCache/seenProposerPreferences.js +26 -0
  121. package/lib/chain/seenCache/seenProposerPreferences.js.map +1 -0
  122. package/lib/chain/validation/block.d.ts.map +1 -1
  123. package/lib/chain/validation/block.js +1 -0
  124. package/lib/chain/validation/block.js.map +1 -1
  125. package/lib/chain/validation/executionPayloadBid.js +11 -8
  126. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  127. package/lib/chain/validation/proposerPreferences.d.ts +8 -0
  128. package/lib/chain/validation/proposerPreferences.d.ts.map +1 -0
  129. package/lib/chain/validation/proposerPreferences.js +91 -0
  130. package/lib/chain/validation/proposerPreferences.js.map +1 -0
  131. package/lib/metrics/metrics/lodestar.d.ts +1 -0
  132. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  133. package/lib/metrics/metrics/lodestar.js +4 -0
  134. package/lib/metrics/metrics/lodestar.js.map +1 -1
  135. package/lib/network/gossip/interface.d.ts +7 -1
  136. package/lib/network/gossip/interface.d.ts.map +1 -1
  137. package/lib/network/gossip/interface.js +1 -0
  138. package/lib/network/gossip/interface.js.map +1 -1
  139. package/lib/network/gossip/scoringParameters.d.ts.map +1 -1
  140. package/lib/network/gossip/scoringParameters.js +12 -1
  141. package/lib/network/gossip/scoringParameters.js.map +1 -1
  142. package/lib/network/gossip/topic.d.ts +29 -766
  143. package/lib/network/gossip/topic.d.ts.map +1 -1
  144. package/lib/network/gossip/topic.js +6 -0
  145. package/lib/network/gossip/topic.js.map +1 -1
  146. package/lib/network/interface.d.ts +2 -0
  147. package/lib/network/interface.d.ts.map +1 -1
  148. package/lib/network/network.d.ts +2 -0
  149. package/lib/network/network.d.ts.map +1 -1
  150. package/lib/network/network.js +8 -0
  151. package/lib/network/network.js.map +1 -1
  152. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  153. package/lib/network/processor/gossipHandlers.js +38 -16
  154. package/lib/network/processor/gossipHandlers.js.map +1 -1
  155. package/lib/network/processor/gossipQueues/index.d.ts.map +1 -1
  156. package/lib/network/processor/gossipQueues/index.js +5 -0
  157. package/lib/network/processor/gossipQueues/index.js.map +1 -1
  158. package/lib/network/processor/index.d.ts.map +1 -1
  159. package/lib/network/processor/index.js +6 -5
  160. package/lib/network/processor/index.js.map +1 -1
  161. package/lib/network/reqresp/ReqRespBeaconNode.d.ts.map +1 -1
  162. package/lib/network/reqresp/ReqRespBeaconNode.js +1 -1
  163. package/lib/network/reqresp/ReqRespBeaconNode.js.map +1 -1
  164. package/lib/network/reqresp/handlers/beaconBlocksByHead.d.ts +9 -0
  165. package/lib/network/reqresp/handlers/beaconBlocksByHead.d.ts.map +1 -0
  166. package/lib/network/reqresp/handlers/beaconBlocksByHead.js +61 -0
  167. package/lib/network/reqresp/handlers/beaconBlocksByHead.js.map +1 -0
  168. package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
  169. package/lib/network/reqresp/handlers/beaconBlocksByRange.js +14 -6
  170. package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
  171. package/lib/network/reqresp/handlers/blobSidecarsByRange.d.ts.map +1 -1
  172. package/lib/network/reqresp/handlers/blobSidecarsByRange.js +11 -5
  173. package/lib/network/reqresp/handlers/blobSidecarsByRange.js.map +1 -1
  174. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
  175. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +17 -5
  176. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
  177. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts.map +1 -1
  178. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +7 -4
  179. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -1
  180. package/lib/network/reqresp/handlers/index.d.ts.map +1 -1
  181. package/lib/network/reqresp/handlers/index.js +5 -0
  182. package/lib/network/reqresp/handlers/index.js.map +1 -1
  183. package/lib/network/reqresp/interface.d.ts +1 -1
  184. package/lib/network/reqresp/interface.js +1 -1
  185. package/lib/network/reqresp/protocols.d.ts +1 -0
  186. package/lib/network/reqresp/protocols.d.ts.map +1 -1
  187. package/lib/network/reqresp/protocols.js +5 -0
  188. package/lib/network/reqresp/protocols.js.map +1 -1
  189. package/lib/network/reqresp/rateLimit.d.ts.map +1 -1
  190. package/lib/network/reqresp/rateLimit.js +4 -0
  191. package/lib/network/reqresp/rateLimit.js.map +1 -1
  192. package/lib/network/reqresp/score.d.ts.map +1 -1
  193. package/lib/network/reqresp/score.js +1 -0
  194. package/lib/network/reqresp/score.js.map +1 -1
  195. package/lib/network/reqresp/types.d.ts +3 -0
  196. package/lib/network/reqresp/types.d.ts.map +1 -1
  197. package/lib/network/reqresp/types.js +3 -0
  198. package/lib/network/reqresp/types.js.map +1 -1
  199. package/lib/node/nodejs.js +2 -2
  200. package/lib/node/nodejs.js.map +1 -1
  201. package/lib/sync/constants.d.ts +7 -1
  202. package/lib/sync/constants.d.ts.map +1 -1
  203. package/lib/sync/constants.js +7 -4
  204. package/lib/sync/constants.js.map +1 -1
  205. package/lib/sync/range/batch.d.ts +35 -5
  206. package/lib/sync/range/batch.d.ts.map +1 -1
  207. package/lib/sync/range/batch.js +240 -59
  208. package/lib/sync/range/batch.js.map +1 -1
  209. package/lib/sync/range/chain.d.ts +22 -4
  210. package/lib/sync/range/chain.d.ts.map +1 -1
  211. package/lib/sync/range/chain.js +100 -10
  212. package/lib/sync/range/chain.js.map +1 -1
  213. package/lib/sync/range/range.d.ts.map +1 -1
  214. package/lib/sync/range/range.js +31 -9
  215. package/lib/sync/range/range.js.map +1 -1
  216. package/lib/sync/sync.d.ts.map +1 -1
  217. package/lib/sync/sync.js +13 -0
  218. package/lib/sync/sync.js.map +1 -1
  219. package/lib/sync/types.d.ts +34 -0
  220. package/lib/sync/types.d.ts.map +1 -1
  221. package/lib/sync/types.js +34 -0
  222. package/lib/sync/types.js.map +1 -1
  223. package/lib/sync/unknownBlock.d.ts +29 -1
  224. package/lib/sync/unknownBlock.d.ts.map +1 -1
  225. package/lib/sync/unknownBlock.js +727 -61
  226. package/lib/sync/unknownBlock.js.map +1 -1
  227. package/lib/sync/utils/downloadByRange.d.ts +67 -10
  228. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  229. package/lib/sync/utils/downloadByRange.js +211 -26
  230. package/lib/sync/utils/downloadByRange.js.map +1 -1
  231. package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
  232. package/lib/sync/utils/downloadByRoot.js +16 -2
  233. package/lib/sync/utils/downloadByRoot.js.map +1 -1
  234. package/lib/sync/utils/pendingBlocksTree.d.ts +0 -1
  235. package/lib/sync/utils/pendingBlocksTree.d.ts.map +1 -1
  236. package/lib/sync/utils/pendingBlocksTree.js +0 -9
  237. package/lib/sync/utils/pendingBlocksTree.js.map +1 -1
  238. package/lib/sync/utils/rateLimit.d.ts +2 -0
  239. package/lib/sync/utils/rateLimit.d.ts.map +1 -0
  240. package/lib/sync/utils/rateLimit.js +15 -0
  241. package/lib/sync/utils/rateLimit.js.map +1 -0
  242. package/lib/util/sszBytes.d.ts.map +1 -1
  243. package/lib/util/sszBytes.js +8 -6
  244. package/lib/util/sszBytes.js.map +1 -1
  245. package/package.json +16 -16
  246. package/src/api/impl/beacon/blocks/index.ts +21 -5
  247. package/src/api/impl/beacon/pool/index.ts +83 -1
  248. package/src/api/impl/debug/index.ts +0 -1
  249. package/src/api/impl/lodestar/index.ts +1 -1
  250. package/src/api/impl/validator/index.ts +82 -1
  251. package/src/chain/blocks/blockInput/blockInput.ts +4 -1
  252. package/src/chain/blocks/importBlock.ts +16 -48
  253. package/src/chain/blocks/importExecutionPayload.ts +76 -30
  254. package/src/chain/blocks/index.ts +71 -22
  255. package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +37 -3
  256. package/src/chain/blocks/payloadEnvelopeInput/types.ts +18 -0
  257. package/src/chain/blocks/payloadEnvelopeProcessor.ts +2 -2
  258. package/src/chain/blocks/types.ts +4 -3
  259. package/src/chain/blocks/utils/chainSegment.ts +114 -17
  260. package/src/chain/blocks/verifyBlock.ts +70 -9
  261. package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +6 -4
  262. package/src/chain/blocks/verifyBlocksSanityChecks.ts +26 -7
  263. package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +16 -8
  264. package/src/chain/blocks/verifyPayloadsDataAvailability.ts +7 -4
  265. package/src/chain/chain.ts +43 -10
  266. package/src/chain/emitter.ts +0 -11
  267. package/src/chain/errors/blockError.ts +4 -1
  268. package/src/chain/errors/index.ts +1 -0
  269. package/src/chain/errors/proposerPreferences.ts +47 -0
  270. package/src/chain/initState.ts +9 -1
  271. package/src/chain/interface.ts +7 -1
  272. package/src/chain/opPools/payloadAttestationPool.ts +29 -8
  273. package/src/chain/prepareNextSlot.ts +21 -29
  274. package/src/chain/produceBlock/produceBlockBody.ts +46 -22
  275. package/src/chain/regen/interface.ts +1 -0
  276. package/src/chain/regen/queued.ts +2 -7
  277. package/src/chain/regen/regen.ts +2 -7
  278. package/src/chain/seenCache/index.ts +1 -0
  279. package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +90 -24
  280. package/src/chain/seenCache/seenProposerPreferences.ts +32 -0
  281. package/src/chain/validation/block.ts +1 -0
  282. package/src/chain/validation/executionPayloadBid.ts +11 -8
  283. package/src/chain/validation/proposerPreferences.ts +110 -0
  284. package/src/metrics/metrics/lodestar.ts +4 -0
  285. package/src/network/gossip/interface.ts +6 -0
  286. package/src/network/gossip/scoringParameters.ts +14 -1
  287. package/src/network/gossip/topic.ts +6 -0
  288. package/src/network/interface.ts +2 -0
  289. package/src/network/network.ts +23 -0
  290. package/src/network/processor/gossipHandlers.ts +53 -17
  291. package/src/network/processor/gossipQueues/index.ts +5 -0
  292. package/src/network/processor/index.ts +6 -5
  293. package/src/network/reqresp/ReqRespBeaconNode.ts +1 -0
  294. package/src/network/reqresp/handlers/beaconBlocksByHead.ts +91 -0
  295. package/src/network/reqresp/handlers/beaconBlocksByRange.ts +14 -6
  296. package/src/network/reqresp/handlers/blobSidecarsByRange.ts +11 -5
  297. package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +17 -5
  298. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +7 -4
  299. package/src/network/reqresp/handlers/index.ts +5 -0
  300. package/src/network/reqresp/interface.ts +1 -1
  301. package/src/network/reqresp/protocols.ts +6 -0
  302. package/src/network/reqresp/rateLimit.ts +4 -0
  303. package/src/network/reqresp/score.ts +1 -0
  304. package/src/network/reqresp/types.ts +5 -0
  305. package/src/node/nodejs.ts +2 -2
  306. package/src/sync/constants.ts +8 -4
  307. package/src/sync/range/batch.ts +320 -67
  308. package/src/sync/range/chain.ts +128 -13
  309. package/src/sync/range/range.ts +34 -9
  310. package/src/sync/sync.ts +13 -1
  311. package/src/sync/types.ts +72 -0
  312. package/src/sync/unknownBlock.ts +915 -65
  313. package/src/sync/utils/downloadByRange.ts +378 -39
  314. package/src/sync/utils/downloadByRoot.ts +24 -2
  315. package/src/sync/utils/pendingBlocksTree.ts +0 -15
  316. package/src/sync/utils/rateLimit.ts +16 -0
  317. package/src/util/sszBytes.ts +8 -6
@@ -1,9 +1,10 @@
1
1
  import {ChainForkConfig} from "@lodestar/config";
2
- import {Epoch, Root, Slot} from "@lodestar/types";
3
- import {ErrorAborted, LodestarError, Logger, toRootHex} from "@lodestar/utils";
2
+ import {Epoch, Root, Slot, gloas} from "@lodestar/types";
3
+ import {ErrorAborted, LodestarError, Logger, prettyPrintIndices, toRootHex} from "@lodestar/utils";
4
4
  import {isBlockInputBlobs, isBlockInputColumns} from "../../chain/blocks/blockInput/blockInput.js";
5
5
  import {BlockInputErrorCode} from "../../chain/blocks/blockInput/errors.js";
6
6
  import {IBlockInput} from "../../chain/blocks/blockInput/types.js";
7
+ import {PayloadEnvelopeInput} from "../../chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js";
7
8
  import {BlobSidecarErrorCode} from "../../chain/errors/blobSidecarError.js";
8
9
  import {DataColumnSidecarErrorCode} from "../../chain/errors/dataColumnSidecarError.js";
9
10
  import {Metrics} from "../../metrics/metrics.js";
@@ -16,6 +17,7 @@ import {PeerIdStr} from "../../util/peerId.js";
16
17
  import {WarnResult, wrapError} from "../../util/wrapError.js";
17
18
  import {BATCH_BUFFER_SIZE, EPOCHS_PER_BATCH, MAX_LOOK_AHEAD_EPOCHS} from "../constants.js";
18
19
  import {DownloadByRangeError, DownloadByRangeErrorCode} from "../utils/downloadByRange.js";
20
+ import {getRateLimitedUntilMs} from "../utils/rateLimit.js";
19
21
  import {RangeSyncType} from "../utils/remoteSyncType.js";
20
22
  import {Batch, BatchError, BatchErrorCode, BatchMetadata, BatchStatus} from "./batch.js";
21
23
  import {
@@ -44,13 +46,19 @@ export type SyncChainFns = {
44
46
  * Must return if ALL blocks are processed successfully
45
47
  * If SOME blocks are processed must throw BlockProcessorError()
46
48
  */
47
- processChainSegment: (blocks: IBlockInput[], syncType: RangeSyncType) => Promise<void>;
49
+ processChainSegment: (
50
+ blocks: IBlockInput[],
51
+ payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null,
52
+ syncType: RangeSyncType
53
+ ) => Promise<void>;
48
54
  /** Must download blocks, and validate their range */
49
55
  downloadByRange: (
50
56
  peer: PeerSyncMeta,
51
57
  batch: Batch,
52
58
  syncType: RangeSyncType
53
- ) => Promise<WarnResult<IBlockInput[], DownloadByRangeError>>;
59
+ ) => Promise<
60
+ WarnResult<{blocks: IBlockInput[]; payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null}, DownloadByRangeError>
61
+ >;
54
62
  /** Report peer for negative actions. Decouples from the full network instance */
55
63
  reportPeer: (peer: PeerIdStr, action: PeerAction, actionName: string) => void;
56
64
  /** Gets current peer custodyColumns and earliestAvailableSlot */
@@ -132,20 +140,33 @@ export class SyncChain {
132
140
  private readonly batchProcessor = new ItTrigger();
133
141
  /** Sorted map of batches undergoing some kind of processing. */
134
142
  private readonly batches = new Map<Epoch, Batch>();
143
+ /**
144
+ * `true` until the first `Batch` is constructed via `includeNextBatch`
145
+ */
146
+ private isFirstBatch = true;
135
147
  private readonly peerset = new Map<PeerIdStr, ChainTarget>();
148
+ /**
149
+ * Tracks peers that have rate-limited us, mapped to the timestamp (ms) until which we should avoid them.
150
+ * This is a sync-layer optimization to avoid assigning batches to backed-off peers.
151
+ * The reqresp SelfRateLimiter independently enforces backoff at the protocol level as a safety net.
152
+ */
153
+ private readonly rateLimitedPeers = new Map<PeerIdStr, number>();
154
+ private rateLimitBackoffTimeout: NodeJS.Timeout | undefined;
136
155
 
137
156
  private readonly logger: Logger;
138
157
  private readonly config: ChainForkConfig;
139
158
  private readonly clock: IClock;
140
159
  private readonly metrics: Metrics | null;
141
160
  private readonly custodyConfig: CustodyConfig;
161
+ private readonly latestBid: gloas.ExecutionPayloadBid | undefined;
142
162
 
143
163
  constructor(
144
164
  initialBatchEpoch: Epoch,
145
165
  initialTarget: ChainTarget,
146
166
  syncType: RangeSyncType,
147
167
  fns: SyncChainFns,
148
- modules: SyncChainModules
168
+ modules: SyncChainModules,
169
+ latestBid: gloas.ExecutionPayloadBid | undefined
149
170
  ) {
150
171
  const {config, clock, custodyConfig, logger, metrics} = modules;
151
172
  this.firstBatchEpoch = initialBatchEpoch;
@@ -161,6 +182,7 @@ export class SyncChain {
161
182
  this.clock = clock;
162
183
  this.metrics = metrics;
163
184
  this.custodyConfig = custodyConfig;
185
+ this.latestBid = latestBid;
164
186
  this.logger = logger;
165
187
  this.logId = `${syncType}-${nextChainId++}`;
166
188
 
@@ -215,12 +237,16 @@ export class SyncChain {
215
237
  */
216
238
  stopSyncing(): void {
217
239
  this.status = SyncChainStatus.Stopped;
240
+ this.clearRateLimitBackoffTimer();
241
+ this.logger.debug("SyncChain stopSyncing", {id: this.logId});
218
242
  }
219
243
 
220
244
  /**
221
245
  * Permanently remove this chain. Throws the main AsyncIterable
222
246
  */
223
247
  remove(): void {
248
+ this.logger.debug("SyncChain remove", {id: this.logId});
249
+ this.clearRateLimitBackoffTimer();
224
250
  this.batchProcessor.end(new ErrorAborted("SyncChain"));
225
251
  }
226
252
 
@@ -239,6 +265,7 @@ export class SyncChain {
239
265
  */
240
266
  removePeer(peerId: PeerIdStr): boolean {
241
267
  const deleted = this.peerset.delete(peerId);
268
+ this.rateLimitedPeers.delete(peerId);
242
269
  this.computeTarget();
243
270
  return deleted;
244
271
  }
@@ -342,6 +369,8 @@ export class SyncChain {
342
369
  }
343
370
 
344
371
  throw e;
372
+ } finally {
373
+ this.clearRateLimitBackoffTimer();
345
374
  }
346
375
  }
347
376
 
@@ -365,6 +394,44 @@ export class SyncChain {
365
394
  }
366
395
  }
367
396
 
397
+ private scheduleRateLimitBackoffRetry(): void {
398
+ this.clearRateLimitBackoffTimer();
399
+
400
+ if (this.status !== SyncChainStatus.Syncing || this.rateLimitedPeers.size === 0) {
401
+ return;
402
+ }
403
+
404
+ const now = Date.now();
405
+ let retryAt: number | null = null;
406
+ for (const [peerId, rateLimitedUntil] of this.rateLimitedPeers.entries()) {
407
+ if (rateLimitedUntil <= now) {
408
+ this.rateLimitedPeers.delete(peerId);
409
+ continue;
410
+ }
411
+ retryAt = Math.min(retryAt ?? rateLimitedUntil, rateLimitedUntil);
412
+ }
413
+
414
+ if (retryAt === null) {
415
+ return;
416
+ }
417
+
418
+ this.rateLimitBackoffTimeout = setTimeout(
419
+ () => {
420
+ this.rateLimitBackoffTimeout = undefined;
421
+ this.triggerBatchDownloader();
422
+ this.scheduleRateLimitBackoffRetry();
423
+ },
424
+ Math.max(0, retryAt - now)
425
+ );
426
+ }
427
+
428
+ private clearRateLimitBackoffTimer(): void {
429
+ if (this.rateLimitBackoffTimeout !== undefined) {
430
+ clearTimeout(this.rateLimitBackoffTimeout);
431
+ this.rateLimitBackoffTimeout = undefined;
432
+ }
433
+ }
434
+
368
435
  /**
369
436
  * Attempts to request the next required batches from the peer pool if the chain is syncing.
370
437
  * It will exhaust the peer pool and left over batches until the batch buffer is reached.
@@ -374,8 +441,18 @@ export class SyncChain {
374
441
  return;
375
442
  }
376
443
 
444
+ const now = Date.now();
377
445
  const peersSyncInfo: PeerSyncInfo[] = [];
378
446
  for (const [peerId, target] of this.peerset.entries()) {
447
+ // Skip peers that are currently in rate-limit backoff
448
+ const rateLimitedUntil = this.rateLimitedPeers.get(peerId);
449
+ if (rateLimitedUntil !== undefined) {
450
+ if (now < rateLimitedUntil) {
451
+ continue;
452
+ }
453
+ this.rateLimitedPeers.delete(peerId);
454
+ }
455
+
379
456
  try {
380
457
  peersSyncInfo.push({...this.getConnectedPeerSyncMeta(peerId), target});
381
458
  } catch (e) {
@@ -449,7 +526,17 @@ export class SyncChain {
449
526
  return null;
450
527
  }
451
528
 
452
- const batch = new Batch(startEpoch, this.config, this.clock, this.custodyConfig);
529
+ const batch = new Batch(
530
+ startEpoch,
531
+ this.config,
532
+ this.clock,
533
+ this.custodyConfig,
534
+ this.isFirstBatch,
535
+ // `latestBid` is only meaningful for the first batch's parent-payload check
536
+ this.isFirstBatch ? this.latestBid : undefined,
537
+ this.target.slot
538
+ );
539
+ this.isFirstBatch = false;
453
540
  this.batches.set(startEpoch, batch);
454
541
  return batch;
455
542
  }
@@ -507,7 +594,16 @@ export class SyncChain {
507
594
  {id: this.logId, ...batch.getMetadata(), peer: prettyPrintPeerIdStr(peer.peerId)},
508
595
  res.err
509
596
  );
510
- batch.downloadingError(peer.peerId); // Throws after MAX_DOWNLOAD_ATTEMPTS
597
+ const rateLimitedUntilMs = getRateLimitedUntilMs(res.err);
598
+ if (rateLimitedUntilMs !== null) {
599
+ // Peer rate-limited us — don't count as a failed download attempt and mark peer for backoff
600
+ this.rateLimitedPeers.set(peer.peerId, rateLimitedUntilMs);
601
+ this.scheduleRateLimitBackoffRetry();
602
+ batch.downloadingRateLimited();
603
+ this.triggerBatchDownloader();
604
+ } else {
605
+ batch.downloadingError(peer.peerId); // Throws after MAX_DOWNLOAD_ATTEMPTS
606
+ }
511
607
  } else {
512
608
  this.logger.verbose("Batch download success", {
513
609
  id: this.logId,
@@ -516,7 +612,8 @@ export class SyncChain {
516
612
  });
517
613
  this.metrics?.syncRange.downloadByRange.success.inc();
518
614
  const {warnings, result} = res.result;
519
- const downloadSuccessOutput = batch.downloadingSuccess(peer.peerId, result);
615
+ const {blocks: downloadedBlocks, payloadEnvelopes} = result;
616
+ const downloadSuccessOutput = batch.downloadingSuccess(peer.peerId, downloadedBlocks, payloadEnvelopes);
520
617
  const logMeta: Record<string, number> = {
521
618
  blockCount: downloadSuccessOutput.blocks.length,
522
619
  };
@@ -526,7 +623,7 @@ export class SyncChain {
526
623
  this.metrics?.syncRange.downloadByRange.warn.inc({client: peer.client, code: warning.type.code});
527
624
  this.logger.debug(
528
625
  "Batch downloaded with warning",
529
- {id: this.logId, epoch: batch.startEpoch, ...logMeta, peer: prettyPrintPeerIdStr(peer.peerId)},
626
+ {id: this.logId, ...batch.getMetadata(), ...logMeta, peer: prettyPrintPeerIdStr(peer.peerId)},
530
627
  warning
531
628
  );
532
629
  }
@@ -552,10 +649,17 @@ export class SyncChain {
552
649
  // the flow will continue to call triggerBatchDownloader() below
553
650
  }
554
651
 
652
+ const blockSlots = downloadSuccessOutput.blocks.map((b) => b.slot);
653
+ const envelopeSlots = downloadSuccessOutput.payloadEnvelopes
654
+ ? Array.from(downloadSuccessOutput.payloadEnvelopes.keys())
655
+ : null;
656
+
555
657
  this.logger.debug(logMessage, {
556
658
  id: this.logId,
557
- epoch: batch.startEpoch,
659
+ ...batch.getMetadata(),
558
660
  ...logMeta,
661
+ blockSlots: prettyPrintIndices(blockSlots),
662
+ ...(envelopeSlots ? {envelopeSlots: prettyPrintIndices(envelopeSlots)} : {}),
559
663
  peer: prettyPrintPeerIdStr(peer.peerId),
560
664
  });
561
665
  }
@@ -578,13 +682,24 @@ export class SyncChain {
578
682
  * Sends `batch` to the processor. Note: batch may be empty
579
683
  */
580
684
  private async processBatch(batch: Batch): Promise<void> {
581
- const blocks = batch.startProcessing();
685
+ const {blocks, payloadEnvelopes, peers} = batch.startProcessing();
686
+
687
+ const logCtx = {
688
+ id: this.logId,
689
+ ...batch.getMetadata(),
690
+ blockCount: blocks.length,
691
+ blockSlots: prettyPrintIndices(blocks.map((b) => b.slot)),
692
+ ...(payloadEnvelopes ? {envelopeSlots: prettyPrintIndices(Array.from(payloadEnvelopes.keys()))} : {}),
693
+ peers: peers.map(prettyPrintPeerIdStr).join(","),
694
+ };
695
+ this.logger.verbose("Processing batch", logCtx);
582
696
 
583
697
  // wrapError ensures to never call both batch success() and batch error()
584
- const res = await wrapError(this.processChainSegment(blocks, this.syncType));
698
+ const res = await wrapError(this.processChainSegment(blocks, payloadEnvelopes, this.syncType));
585
699
 
586
700
  if (!res.err) {
587
701
  batch.processingSuccess();
702
+ this.logger.verbose("Processed batch", {...logCtx, ...batch.getMetadata()});
588
703
 
589
704
  // If the processed batch is not empty, validate previous AwaitingValidation blocks.
590
705
  if (blocks.length > 0) {
@@ -594,7 +709,7 @@ export class SyncChain {
594
709
  // Potentially process next AwaitingProcessing batch
595
710
  this.triggerBatchProcessor();
596
711
  } else {
597
- this.logger.verbose("Batch process error", {id: this.logId, ...batch.getMetadata()}, res.err);
712
+ this.logger.verbose("Batch process error", logCtx, res.err);
598
713
  batch.processingError(res.err); // Throws after MAX_BATCH_PROCESSING_ATTEMPTS
599
714
 
600
715
  // At least one block was successfully verified and imported, so we can be sure all
@@ -1,7 +1,7 @@
1
1
  import {EventEmitter} from "node:events";
2
2
  import {StrictEventEmitter} from "strict-event-emitter-types";
3
3
  import {BeaconConfig} from "@lodestar/config";
4
- import {computeStartSlotAtEpoch} from "@lodestar/state-transition";
4
+ import {IBeaconStateViewGloas, computeStartSlotAtEpoch, isStatePostGloas} from "@lodestar/state-transition";
5
5
  import {Epoch, Status, fulu} from "@lodestar/types";
6
6
  import {Logger, toRootHex} from "@lodestar/utils";
7
7
  import {IBlockInput} from "../../chain/blocks/blockInput/types.js";
@@ -172,7 +172,7 @@ export class RangeSync extends (EventEmitter as {new (): RangeSyncEmitter}) {
172
172
  }
173
173
 
174
174
  /** Convenience method for `SyncChain` */
175
- private processChainSegment: SyncChainFns["processChainSegment"] = async (blocks, syncType) => {
175
+ private processChainSegment: SyncChainFns["processChainSegment"] = async (blocks, payloadEnvelopes, syncType) => {
176
176
  // Not trusted, verify signatures
177
177
  const flags: ImportBlockOpts = {
178
178
  // Only skip importing attestations for finalized sync. For head sync attestation are valuable.
@@ -192,30 +192,46 @@ export class RangeSync extends (EventEmitter as {new (): RangeSyncEmitter}) {
192
192
 
193
193
  if (this.opts?.disableProcessAsChainSegment) {
194
194
  // Should only be used for debugging or testing
195
- for (const block of blocks) await this.chain.processBlock(block, flags);
195
+ for (const block of blocks) {
196
+ await this.chain.processBlock(block, flags);
197
+ const payloadEnvelope = payloadEnvelopes?.get(block.slot);
198
+ if (payloadEnvelope) {
199
+ await this.chain.processExecutionPayload(payloadEnvelope);
200
+ }
201
+ }
196
202
  } else {
197
- await this.chain.processChainSegment(blocks, flags);
203
+ await this.chain.processChainSegment(blocks, payloadEnvelopes, flags);
198
204
  }
199
205
  };
200
206
 
201
207
  private downloadByRange: SyncChainFns["downloadByRange"] = async (peer, batch) => {
202
208
  const batchBlocks = batch.getBlocks();
209
+ const requests = batch.getRequestsForPeer(peer);
210
+ const parentRoot = requests.parentPayloadRequest?.envelopeBlockRoot ?? requests.parentPayloadRequest?.blockRoot;
211
+ const parentPayloadCommitments = parentRoot ? batch.getParentPayloadCommitments(parentRoot) : undefined;
203
212
  const {result, warnings} = await downloadByRange({
204
213
  config: this.config,
205
214
  network: this.network,
206
215
  logger: this.logger,
207
216
  peerIdStr: peer.peerId,
208
217
  batchBlocks,
218
+ parentPayloadCommitments,
209
219
  peerDasMetrics: this.chain.metrics?.peerDas,
210
- ...batch.getRequestsForPeer(peer),
220
+ ...requests,
211
221
  });
212
- const cached = cacheByRangeResponses({
222
+ const {responses, payloadEnvelopes: downloadedPayloadEnvelopes} = result;
223
+ const {blocks, payloadEnvelopes} = cacheByRangeResponses({
213
224
  cache: this.chain.seenBlockInputCache,
225
+ seenPayloadEnvelopeInputCache: this.chain.seenPayloadEnvelopeInputCache,
214
226
  peerIdStr: peer.peerId,
215
- responses: result,
227
+ responses,
216
228
  batchBlocks,
229
+ downloadedPayloadEnvelopes,
230
+ existingPayloadEnvelopes: batch.getPayloadEnvelopes(),
231
+ custodyConfig: this.chain.custodyConfig,
232
+ seenTimestampSec: Date.now() / 1000,
217
233
  });
218
- return {result: cached, warnings};
234
+ return {result: {blocks, payloadEnvelopes}, warnings};
219
235
  };
220
236
 
221
237
  private pruneBlockInputs: SyncChainFns["pruneBlockInputs"] = (blocks: IBlockInput[]) => {
@@ -246,6 +262,14 @@ export class RangeSync extends (EventEmitter as {new (): RangeSyncEmitter}) {
246
262
  private addPeerOrCreateChain(startEpoch: Epoch, target: ChainTarget, peer: PeerIdStr, syncType: RangeSyncType): void {
247
263
  let syncChain = this.chains.get(syncType);
248
264
  if (!syncChain) {
265
+ // The first batch of a new sync chain may need to detect whether the parent block was an
266
+ // gloas "empty" block (no envelope produced). It does so by comparing the first
267
+ // downloaded block's `bid.parentBlockHash` against the head state's `latestExecutionPayloadBid.blockHash`.
268
+ const headState = this.chain.getHeadState();
269
+ const latestBid = isStatePostGloas(headState)
270
+ ? (headState as IBeaconStateViewGloas).latestExecutionPayloadBid
271
+ : undefined;
272
+
249
273
  syncChain = new SyncChain(
250
274
  startEpoch,
251
275
  target,
@@ -264,7 +288,8 @@ export class RangeSync extends (EventEmitter as {new (): RangeSyncEmitter}) {
264
288
  logger: this.logger,
265
289
  custodyConfig: this.chain.custodyConfig,
266
290
  metrics: this.metrics,
267
- }
291
+ },
292
+ latestBid
268
293
  );
269
294
  this.chains.set(syncType, syncChain);
270
295
 
package/src/sync/sync.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import {SLOTS_PER_EPOCH} from "@lodestar/params";
2
2
  import {Slot} from "@lodestar/types";
3
- import {Logger} from "@lodestar/utils";
3
+ import {Logger, toRootHex} from "@lodestar/utils";
4
4
  import {IBeaconChain} from "../chain/index.js";
5
5
  import {GENESIS_SLOT} from "../constants/constants.js";
6
6
  import {ExecutionEngineState} from "../execution/index.js";
@@ -188,6 +188,18 @@ export class BeaconSync implements IBeaconSync {
188
188
  private addPeer = (data: NetworkEventData[NetworkEvent.peerConnected]): void => {
189
189
  const localStatus = this.chain.getStatus();
190
190
  const syncType = getPeerSyncType(localStatus, data.status, this.chain.forkChoice, this.slotImportTolerance);
191
+ this.logger.verbose("Peer sync type classified", {
192
+ peer: data.peer,
193
+ syncType,
194
+ localFinalizedEpoch: localStatus.finalizedEpoch,
195
+ localFinalizedRoot: toRootHex(localStatus.finalizedRoot),
196
+ localHeadSlot: localStatus.headSlot,
197
+ localHeadRoot: toRootHex(localStatus.headRoot),
198
+ remoteFinalizedEpoch: data.status.finalizedEpoch,
199
+ remoteFinalizedRoot: toRootHex(data.status.finalizedRoot),
200
+ remoteHeadSlot: data.status.headSlot,
201
+ remoteHeadRoot: toRootHex(data.status.headRoot),
202
+ });
191
203
 
192
204
  // For metrics only
193
205
  this.peerSyncType.set(data.peer, syncType);
package/src/sync/types.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  import {RootHex, Slot} from "@lodestar/types";
2
+ import {SignedExecutionPayloadEnvelope} from "@lodestar/types/gloas";
3
+ import {toRootHex} from "@lodestar/utils";
2
4
  import {IBlockInput} from "../chain/blocks/blockInput/index.js";
5
+ import {PayloadEnvelopeInput} from "../chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js";
3
6
 
4
7
  export enum PendingBlockType {
5
8
  /**
@@ -26,6 +29,14 @@ export enum PendingBlockInputStatus {
26
29
  processing = "processing",
27
30
  }
28
31
 
32
+ export enum PendingPayloadInputStatus {
33
+ pending = "pending",
34
+ fetching = "fetching",
35
+ waitingForBlock = "waiting_for_block",
36
+ downloaded = "downloaded",
37
+ processing = "processing",
38
+ }
39
+
29
40
  export type PendingBlockInput = {
30
41
  status: PendingBlockInputStatus;
31
42
  blockInput: IBlockInput;
@@ -44,10 +55,47 @@ export type PendingRootHex = {
44
55
 
45
56
  export type BlockInputSyncCacheItem = PendingBlockInput | PendingRootHex;
46
57
 
58
+ export type PendingPayloadInput = {
59
+ status:
60
+ | PendingPayloadInputStatus.pending
61
+ | PendingPayloadInputStatus.fetching
62
+ | PendingPayloadInputStatus.downloaded
63
+ | PendingPayloadInputStatus.processing;
64
+ payloadInput: PayloadEnvelopeInput;
65
+ timeAddedSec: number;
66
+ timeSyncedSec?: number;
67
+ peerIdStrings: Set<string>;
68
+ };
69
+
70
+ export type PendingPayloadRootHex = {
71
+ status: PendingPayloadInputStatus.pending | PendingPayloadInputStatus.fetching;
72
+ rootHex: RootHex;
73
+ timeAddedSec: number;
74
+ timeSyncedSec?: number;
75
+ peerIdStrings: Set<string>;
76
+ };
77
+
78
+ export type PendingPayloadEnvelope = {
79
+ status: PendingPayloadInputStatus.waitingForBlock;
80
+ envelope: SignedExecutionPayloadEnvelope;
81
+ timeAddedSec: number;
82
+ peerIdStrings: Set<string>;
83
+ };
84
+
85
+ export type PayloadSyncCacheItem = PendingPayloadInput | PendingPayloadRootHex | PendingPayloadEnvelope;
86
+
47
87
  export function isPendingBlockInput(pending: BlockInputSyncCacheItem): pending is PendingBlockInput {
48
88
  return "blockInput" in pending;
49
89
  }
50
90
 
91
+ export function isPendingPayloadInput(pending: PayloadSyncCacheItem): pending is PendingPayloadInput {
92
+ return "payloadInput" in pending;
93
+ }
94
+
95
+ export function isPendingPayloadEnvelope(pending: PayloadSyncCacheItem): pending is PendingPayloadEnvelope {
96
+ return "envelope" in pending;
97
+ }
98
+
51
99
  export function getBlockInputSyncCacheItemRootHex(block: BlockInputSyncCacheItem): RootHex {
52
100
  return isPendingBlockInput(block) ? block.blockInput.blockRootHex : block.rootHex;
53
101
  }
@@ -55,3 +103,27 @@ export function getBlockInputSyncCacheItemRootHex(block: BlockInputSyncCacheItem
55
103
  export function getBlockInputSyncCacheItemSlot(block: BlockInputSyncCacheItem): Slot | string {
56
104
  return isPendingBlockInput(block) ? block.blockInput.slot : "unknown";
57
105
  }
106
+
107
+ export function getPayloadSyncCacheItemRootHex(payload: PayloadSyncCacheItem): RootHex {
108
+ if (isPendingPayloadInput(payload)) {
109
+ return payload.payloadInput.blockRootHex;
110
+ }
111
+
112
+ if (isPendingPayloadEnvelope(payload)) {
113
+ return toRootHex(payload.envelope.message.beaconBlockRoot);
114
+ }
115
+
116
+ return payload.rootHex;
117
+ }
118
+
119
+ export function getPayloadSyncCacheItemSlot(payload: PayloadSyncCacheItem): Slot | string {
120
+ if (isPendingPayloadInput(payload)) {
121
+ return payload.payloadInput.slot;
122
+ }
123
+
124
+ if (isPendingPayloadEnvelope(payload)) {
125
+ return payload.envelope.message.payload.slotNumber;
126
+ }
127
+
128
+ return "unknown";
129
+ }