@lodestar/beacon-node 1.43.0-dev.38479366cc → 1.43.0-dev.38cd4b01e7

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 (292) 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/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/validator/index.d.ts.map +1 -1
  11. package/lib/api/impl/validator/index.js +68 -2
  12. package/lib/api/impl/validator/index.js.map +1 -1
  13. package/lib/chain/blocks/blockInput/blockInput.d.ts +3 -0
  14. package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
  15. package/lib/chain/blocks/blockInput/blockInput.js +4 -1
  16. package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
  17. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  18. package/lib/chain/blocks/importBlock.js +16 -31
  19. package/lib/chain/blocks/importBlock.js.map +1 -1
  20. package/lib/chain/blocks/importExecutionPayload.d.ts +9 -3
  21. package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
  22. package/lib/chain/blocks/importExecutionPayload.js +37 -15
  23. package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
  24. package/lib/chain/blocks/index.d.ts.map +1 -1
  25. package/lib/chain/blocks/index.js +35 -21
  26. package/lib/chain/blocks/index.js.map +1 -1
  27. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +12 -1
  28. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
  29. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +28 -2
  30. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
  31. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +17 -0
  32. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
  33. package/lib/chain/blocks/types.d.ts +2 -1
  34. package/lib/chain/blocks/types.d.ts.map +1 -1
  35. package/lib/chain/blocks/utils/chainSegment.d.ts +1 -3
  36. package/lib/chain/blocks/utils/chainSegment.d.ts.map +1 -1
  37. package/lib/chain/blocks/utils/chainSegment.js +34 -23
  38. package/lib/chain/blocks/utils/chainSegment.js.map +1 -1
  39. package/lib/chain/blocks/verifyBlock.d.ts +2 -1
  40. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  41. package/lib/chain/blocks/verifyBlock.js +30 -12
  42. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  43. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts +0 -4
  44. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
  45. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +5 -2
  46. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
  47. package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts +2 -1
  48. package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts.map +1 -1
  49. package/lib/chain/blocks/verifyBlocksSanityChecks.js +16 -7
  50. package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
  51. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts +2 -2
  52. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -1
  53. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +10 -6
  54. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -1
  55. package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts.map +1 -1
  56. package/lib/chain/blocks/verifyPayloadsDataAvailability.js +8 -3
  57. package/lib/chain/blocks/verifyPayloadsDataAvailability.js.map +1 -1
  58. package/lib/chain/chain.d.ts +2 -1
  59. package/lib/chain/chain.d.ts.map +1 -1
  60. package/lib/chain/chain.js +28 -9
  61. package/lib/chain/chain.js.map +1 -1
  62. package/lib/chain/emitter.d.ts +0 -11
  63. package/lib/chain/emitter.d.ts.map +1 -1
  64. package/lib/chain/emitter.js +0 -4
  65. package/lib/chain/emitter.js.map +1 -1
  66. package/lib/chain/errors/index.d.ts +1 -0
  67. package/lib/chain/errors/index.d.ts.map +1 -1
  68. package/lib/chain/errors/index.js +1 -0
  69. package/lib/chain/errors/index.js.map +1 -1
  70. package/lib/chain/errors/proposerPreferences.d.ts +40 -0
  71. package/lib/chain/errors/proposerPreferences.d.ts.map +1 -0
  72. package/lib/chain/errors/proposerPreferences.js +14 -0
  73. package/lib/chain/errors/proposerPreferences.js.map +1 -0
  74. package/lib/chain/initState.d.ts.map +1 -1
  75. package/lib/chain/initState.js +6 -1
  76. package/lib/chain/initState.js.map +1 -1
  77. package/lib/chain/interface.d.ts +2 -1
  78. package/lib/chain/interface.d.ts.map +1 -1
  79. package/lib/chain/interface.js.map +1 -1
  80. package/lib/chain/lightClient/index.d.ts.map +1 -1
  81. package/lib/chain/lightClient/index.js +1 -1
  82. package/lib/chain/lightClient/index.js.map +1 -1
  83. package/lib/chain/opPools/payloadAttestationPool.d.ts +4 -3
  84. package/lib/chain/opPools/payloadAttestationPool.d.ts.map +1 -1
  85. package/lib/chain/opPools/payloadAttestationPool.js +56 -14
  86. package/lib/chain/opPools/payloadAttestationPool.js.map +1 -1
  87. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  88. package/lib/chain/prepareNextSlot.js +16 -18
  89. package/lib/chain/prepareNextSlot.js.map +1 -1
  90. package/lib/chain/produceBlock/produceBlockBody.d.ts +12 -3
  91. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  92. package/lib/chain/produceBlock/produceBlockBody.js +34 -22
  93. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  94. package/lib/chain/regen/interface.d.ts +1 -0
  95. package/lib/chain/regen/interface.d.ts.map +1 -1
  96. package/lib/chain/regen/interface.js +1 -0
  97. package/lib/chain/regen/interface.js.map +1 -1
  98. package/lib/chain/regen/queued.d.ts.map +1 -1
  99. package/lib/chain/regen/queued.js +1 -4
  100. package/lib/chain/regen/queued.js.map +1 -1
  101. package/lib/chain/regen/regen.d.ts.map +1 -1
  102. package/lib/chain/regen/regen.js +1 -4
  103. package/lib/chain/regen/regen.js.map +1 -1
  104. package/lib/chain/seenCache/index.d.ts +1 -0
  105. package/lib/chain/seenCache/index.d.ts.map +1 -1
  106. package/lib/chain/seenCache/index.js +1 -0
  107. package/lib/chain/seenCache/index.js.map +1 -1
  108. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +21 -11
  109. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
  110. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +70 -20
  111. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
  112. package/lib/chain/seenCache/seenProposerPreferences.d.ts +16 -0
  113. package/lib/chain/seenCache/seenProposerPreferences.d.ts.map +1 -0
  114. package/lib/chain/seenCache/seenProposerPreferences.js +26 -0
  115. package/lib/chain/seenCache/seenProposerPreferences.js.map +1 -0
  116. package/lib/chain/validation/executionPayloadBid.js +11 -8
  117. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  118. package/lib/chain/validation/payloadAttestationMessage.d.ts +1 -1
  119. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
  120. package/lib/chain/validation/payloadAttestationMessage.js +5 -3
  121. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  122. package/lib/chain/validation/proposerPreferences.d.ts +8 -0
  123. package/lib/chain/validation/proposerPreferences.d.ts.map +1 -0
  124. package/lib/chain/validation/proposerPreferences.js +91 -0
  125. package/lib/chain/validation/proposerPreferences.js.map +1 -0
  126. package/lib/metrics/metrics/lodestar.d.ts +4 -0
  127. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  128. package/lib/metrics/metrics/lodestar.js +5 -0
  129. package/lib/metrics/metrics/lodestar.js.map +1 -1
  130. package/lib/network/gossip/interface.d.ts +7 -1
  131. package/lib/network/gossip/interface.d.ts.map +1 -1
  132. package/lib/network/gossip/interface.js +1 -0
  133. package/lib/network/gossip/interface.js.map +1 -1
  134. package/lib/network/gossip/scoringParameters.d.ts.map +1 -1
  135. package/lib/network/gossip/scoringParameters.js +12 -1
  136. package/lib/network/gossip/scoringParameters.js.map +1 -1
  137. package/lib/network/gossip/topic.d.ts +10 -0
  138. package/lib/network/gossip/topic.d.ts.map +1 -1
  139. package/lib/network/gossip/topic.js +6 -0
  140. package/lib/network/gossip/topic.js.map +1 -1
  141. package/lib/network/interface.d.ts +2 -0
  142. package/lib/network/interface.d.ts.map +1 -1
  143. package/lib/network/network.d.ts +2 -0
  144. package/lib/network/network.d.ts.map +1 -1
  145. package/lib/network/network.js +8 -0
  146. package/lib/network/network.js.map +1 -1
  147. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  148. package/lib/network/processor/gossipHandlers.js +69 -18
  149. package/lib/network/processor/gossipHandlers.js.map +1 -1
  150. package/lib/network/processor/gossipQueues/index.d.ts.map +1 -1
  151. package/lib/network/processor/gossipQueues/index.js +5 -0
  152. package/lib/network/processor/gossipQueues/index.js.map +1 -1
  153. package/lib/network/processor/index.d.ts.map +1 -1
  154. package/lib/network/processor/index.js +6 -5
  155. package/lib/network/processor/index.js.map +1 -1
  156. package/lib/network/reqresp/ReqRespBeaconNode.d.ts.map +1 -1
  157. package/lib/network/reqresp/ReqRespBeaconNode.js +1 -1
  158. package/lib/network/reqresp/ReqRespBeaconNode.js.map +1 -1
  159. package/lib/network/reqresp/handlers/beaconBlocksByHead.d.ts +9 -0
  160. package/lib/network/reqresp/handlers/beaconBlocksByHead.d.ts.map +1 -0
  161. package/lib/network/reqresp/handlers/beaconBlocksByHead.js +61 -0
  162. package/lib/network/reqresp/handlers/beaconBlocksByHead.js.map +1 -0
  163. package/lib/network/reqresp/handlers/index.d.ts.map +1 -1
  164. package/lib/network/reqresp/handlers/index.js +5 -0
  165. package/lib/network/reqresp/handlers/index.js.map +1 -1
  166. package/lib/network/reqresp/interface.d.ts +1 -1
  167. package/lib/network/reqresp/interface.js +1 -1
  168. package/lib/network/reqresp/protocols.d.ts +1 -0
  169. package/lib/network/reqresp/protocols.d.ts.map +1 -1
  170. package/lib/network/reqresp/protocols.js +5 -0
  171. package/lib/network/reqresp/protocols.js.map +1 -1
  172. package/lib/network/reqresp/rateLimit.d.ts.map +1 -1
  173. package/lib/network/reqresp/rateLimit.js +4 -0
  174. package/lib/network/reqresp/rateLimit.js.map +1 -1
  175. package/lib/network/reqresp/score.d.ts.map +1 -1
  176. package/lib/network/reqresp/score.js +1 -0
  177. package/lib/network/reqresp/score.js.map +1 -1
  178. package/lib/network/reqresp/types.d.ts +3 -0
  179. package/lib/network/reqresp/types.d.ts.map +1 -1
  180. package/lib/network/reqresp/types.js +3 -0
  181. package/lib/network/reqresp/types.js.map +1 -1
  182. package/lib/node/nodejs.js +2 -2
  183. package/lib/node/nodejs.js.map +1 -1
  184. package/lib/node/notifier.js +1 -7
  185. package/lib/node/notifier.js.map +1 -1
  186. package/lib/sync/constants.d.ts +7 -1
  187. package/lib/sync/constants.d.ts.map +1 -1
  188. package/lib/sync/constants.js +7 -4
  189. package/lib/sync/constants.js.map +1 -1
  190. package/lib/sync/range/batch.d.ts +43 -6
  191. package/lib/sync/range/batch.d.ts.map +1 -1
  192. package/lib/sync/range/batch.js +243 -44
  193. package/lib/sync/range/batch.js.map +1 -1
  194. package/lib/sync/range/chain.d.ts +16 -2
  195. package/lib/sync/range/chain.d.ts.map +1 -1
  196. package/lib/sync/range/chain.js +100 -9
  197. package/lib/sync/range/chain.js.map +1 -1
  198. package/lib/sync/range/range.d.ts.map +1 -1
  199. package/lib/sync/range/range.js +54 -5
  200. package/lib/sync/range/range.js.map +1 -1
  201. package/lib/sync/range/utils/peerBalancer.d.ts +2 -1
  202. package/lib/sync/range/utils/peerBalancer.d.ts.map +1 -1
  203. package/lib/sync/range/utils/peerBalancer.js +8 -4
  204. package/lib/sync/range/utils/peerBalancer.js.map +1 -1
  205. package/lib/sync/sync.d.ts.map +1 -1
  206. package/lib/sync/sync.js +13 -0
  207. package/lib/sync/sync.js.map +1 -1
  208. package/lib/sync/unknownBlock.d.ts +7 -2
  209. package/lib/sync/unknownBlock.d.ts.map +1 -1
  210. package/lib/sync/unknownBlock.js +127 -57
  211. package/lib/sync/unknownBlock.js.map +1 -1
  212. package/lib/sync/utils/downloadByRange.d.ts +36 -9
  213. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  214. package/lib/sync/utils/downloadByRange.js +106 -42
  215. package/lib/sync/utils/downloadByRange.js.map +1 -1
  216. package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
  217. package/lib/sync/utils/downloadByRoot.js +10 -0
  218. package/lib/sync/utils/downloadByRoot.js.map +1 -1
  219. package/lib/sync/utils/rateLimit.d.ts +2 -0
  220. package/lib/sync/utils/rateLimit.d.ts.map +1 -0
  221. package/lib/sync/utils/rateLimit.js +15 -0
  222. package/lib/sync/utils/rateLimit.js.map +1 -0
  223. package/lib/util/sszBytes.d.ts.map +1 -1
  224. package/lib/util/sszBytes.js +8 -6
  225. package/lib/util/sszBytes.js.map +1 -1
  226. package/package.json +15 -16
  227. package/src/api/impl/beacon/blocks/index.ts +16 -3
  228. package/src/api/impl/beacon/pool/index.ts +83 -1
  229. package/src/api/impl/debug/index.ts +0 -1
  230. package/src/api/impl/validator/index.ts +82 -1
  231. package/src/chain/blocks/blockInput/blockInput.ts +4 -1
  232. package/src/chain/blocks/importBlock.ts +16 -50
  233. package/src/chain/blocks/importExecutionPayload.ts +51 -20
  234. package/src/chain/blocks/index.ts +32 -15
  235. package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +37 -3
  236. package/src/chain/blocks/payloadEnvelopeInput/types.ts +18 -0
  237. package/src/chain/blocks/types.ts +2 -1
  238. package/src/chain/blocks/utils/chainSegment.ts +35 -24
  239. package/src/chain/blocks/verifyBlock.ts +45 -13
  240. package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +6 -4
  241. package/src/chain/blocks/verifyBlocksSanityChecks.ts +16 -6
  242. package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +14 -6
  243. package/src/chain/blocks/verifyPayloadsDataAvailability.ts +7 -4
  244. package/src/chain/chain.ts +32 -7
  245. package/src/chain/emitter.ts +0 -11
  246. package/src/chain/errors/index.ts +1 -0
  247. package/src/chain/errors/proposerPreferences.ts +47 -0
  248. package/src/chain/initState.ts +9 -1
  249. package/src/chain/interface.ts +2 -0
  250. package/src/chain/lightClient/index.ts +6 -6
  251. package/src/chain/opPools/payloadAttestationPool.ts +63 -18
  252. package/src/chain/prepareNextSlot.ts +21 -29
  253. package/src/chain/produceBlock/produceBlockBody.ts +45 -27
  254. package/src/chain/regen/interface.ts +1 -0
  255. package/src/chain/regen/queued.ts +2 -7
  256. package/src/chain/regen/regen.ts +2 -7
  257. package/src/chain/seenCache/index.ts +1 -0
  258. package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +90 -24
  259. package/src/chain/seenCache/seenProposerPreferences.ts +32 -0
  260. package/src/chain/validation/executionPayloadBid.ts +11 -8
  261. package/src/chain/validation/payloadAttestationMessage.ts +6 -4
  262. package/src/chain/validation/proposerPreferences.ts +110 -0
  263. package/src/metrics/metrics/lodestar.ts +6 -0
  264. package/src/network/gossip/interface.ts +6 -0
  265. package/src/network/gossip/scoringParameters.ts +14 -1
  266. package/src/network/gossip/topic.ts +6 -0
  267. package/src/network/interface.ts +2 -0
  268. package/src/network/network.ts +23 -0
  269. package/src/network/processor/gossipHandlers.ts +86 -19
  270. package/src/network/processor/gossipQueues/index.ts +5 -0
  271. package/src/network/processor/index.ts +6 -5
  272. package/src/network/reqresp/ReqRespBeaconNode.ts +1 -0
  273. package/src/network/reqresp/handlers/beaconBlocksByHead.ts +91 -0
  274. package/src/network/reqresp/handlers/index.ts +5 -0
  275. package/src/network/reqresp/interface.ts +1 -1
  276. package/src/network/reqresp/protocols.ts +6 -0
  277. package/src/network/reqresp/rateLimit.ts +4 -0
  278. package/src/network/reqresp/score.ts +1 -0
  279. package/src/network/reqresp/types.ts +5 -0
  280. package/src/node/nodejs.ts +2 -2
  281. package/src/node/notifier.ts +1 -8
  282. package/src/sync/constants.ts +8 -4
  283. package/src/sync/range/batch.ts +309 -51
  284. package/src/sync/range/chain.ts +119 -10
  285. package/src/sync/range/range.ts +68 -5
  286. package/src/sync/range/utils/peerBalancer.ts +9 -3
  287. package/src/sync/sync.ts +13 -1
  288. package/src/sync/unknownBlock.ts +157 -60
  289. package/src/sync/utils/downloadByRange.ts +174 -44
  290. package/src/sync/utils/downloadByRoot.ts +12 -0
  291. package/src/sync/utils/rateLimit.ts +16 -0
  292. package/src/util/sszBytes.ts +8 -6
@@ -20,7 +20,7 @@ export type VerifyExecutionPayloadEnvelopeOpts = {
20
20
  * performed outside this function, see `verifyExecutionPayloadEnvelopeSignature` and
21
21
  * `importExecutionPayload` which run both in parallel with this check.
22
22
  *
23
- * Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.5/specs/gloas/fork-choice.md#new-verify_execution_payload_envelope
23
+ * Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.6/specs/gloas/fork-choice.md#new-verify_execution_payload_envelope
24
24
  */
25
25
  export function verifyExecutionPayloadEnvelope(
26
26
  config: BeaconConfig,
@@ -43,6 +43,11 @@ export function verifyExecutionPayloadEnvelope(
43
43
  `Envelope's block is not the latest block header envelope=${toRootHex(envelope.beaconBlockRoot)} latestBlockHeader=${toRootHex(headerRoot)}`
44
44
  );
45
45
  }
46
+ if (!byteArrayEquals(envelope.parentBeaconBlockRoot, state.latestBlockHeader.parentRoot)) {
47
+ throw new Error(
48
+ `Envelope's parent_beacon_block_root mismatch envelope=${toRootHex(envelope.parentBeaconBlockRoot)} state=${toRootHex(state.latestBlockHeader.parentRoot)}`
49
+ );
50
+ }
46
51
 
47
52
  // Verify consistency with the committed bid
48
53
  const bid = state.latestExecutionPayloadBid;
@@ -77,16 +82,19 @@ export function verifyExecutionPayloadEnvelope(
77
82
  }
78
83
  }
79
84
 
80
- // Verify the execution payload is valid
81
- if (payload.slotNumber !== state.slot) {
82
- throw new Error(`Slot mismatch between payload and state payload=${payload.slotNumber} state=${state.slot}`);
85
+ // should not use state.slot, it does not work for skipped slot checkpoint sync
86
+ const blockSlot = state.latestBlockHeader.slot;
87
+ if (payload.slotNumber !== blockSlot) {
88
+ throw new Error(
89
+ `Slot mismatch between payload and latest block header payload=${payload.slotNumber} latestBlockHeader=${blockSlot}`
90
+ );
83
91
  }
84
92
  if (!byteArrayEquals(payload.parentHash, state.latestBlockHash)) {
85
93
  throw new Error(
86
94
  `Parent hash mismatch between payload and state payload=${toRootHex(payload.parentHash)} state=${toRootHex(state.latestBlockHash)}`
87
95
  );
88
96
  }
89
- const expectedTimestamp = computeTimeAtSlot(config, state.slot, state.genesisTime);
97
+ const expectedTimestamp = computeTimeAtSlot(config, blockSlot, state.genesisTime);
90
98
  if (payload.timestamp !== expectedTimestamp) {
91
99
  throw new Error(
92
100
  `Timestamp mismatch between payload and state payload=${payload.timestamp} state=${expectedTimestamp}`
@@ -108,7 +116,7 @@ export function verifyExecutionPayloadEnvelope(
108
116
  /**
109
117
  * Verify the BLS signature of an execution payload envelope.
110
118
  *
111
- * Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.5/specs/gloas/fork-choice.md#new-verify_execution_payload_envelope_signature
119
+ * Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.6/specs/gloas/fork-choice.md#new-verify_execution_payload_envelope_signature
112
120
  */
113
121
  export async function verifyExecutionPayloadEnvelopeSignature(
114
122
  config: BeaconConfig,
@@ -28,11 +28,14 @@ export async function verifyPayloadsDataAvailability(
28
28
  await Promise.all(promises);
29
29
 
30
30
  const availableTime = Math.max(0, Math.max(...payloadInputs.map((payloadInput) => payloadInput.getTimeComplete())));
31
- const dataAvailabilityStatuses: DataAvailabilityStatus[] = payloadInputs.map((payloadInput) =>
32
- payloadInput.getBlobKzgCommitments().length === 0
31
+ const dataAvailabilityStatuses: DataAvailabilityStatus[] = payloadInputs.map((payloadInput) => {
32
+ if (payloadInput.daOutOfRange) {
33
+ return DataAvailabilityStatus.OutOfRange;
34
+ }
35
+ return payloadInput.getBlobKzgCommitments().length === 0
33
36
  ? DataAvailabilityStatus.NotRequired
34
- : DataAvailabilityStatus.Available
35
- );
37
+ : DataAvailabilityStatus.Available;
38
+ });
36
39
 
37
40
  return {dataAvailabilityStatuses, availableTime};
38
41
  }
@@ -23,6 +23,7 @@ import {
23
23
  getEffectiveBalancesFromStateBytes,
24
24
  isStatePostAltair,
25
25
  isStatePostElectra,
26
+ isStatePostGloas,
26
27
  } from "@lodestar/state-transition";
27
28
  import {
28
29
  BeaconBlock,
@@ -106,6 +107,7 @@ import {
106
107
  SeenExecutionPayloadBids,
107
108
  SeenPayloadAttesters,
108
109
  SeenPayloadEnvelopeInput,
110
+ SeenProposerPreferences,
109
111
  SeenSyncCommitteeMessages,
110
112
  } from "./seenCache/index.js";
111
113
  import {SeenAggregatedAttestations} from "./seenCache/seenAggregateAndProof.js";
@@ -186,6 +188,7 @@ export class BeaconChain implements IBeaconChain {
186
188
  readonly seenPayloadAttesters = new SeenPayloadAttesters();
187
189
  readonly seenAggregatedAttestations: SeenAggregatedAttestations;
188
190
  readonly seenExecutionPayloadBids = new SeenExecutionPayloadBids();
191
+ readonly seenProposerPreferences = new SeenProposerPreferences();
189
192
  readonly seenBlockProposers = new SeenBlockProposers();
190
193
  readonly seenSyncCommitteeMessages = new SeenSyncCommitteeMessages();
191
194
  readonly seenContributionAndProof: SeenContributionAndProof;
@@ -333,13 +336,6 @@ export class BeaconChain implements IBeaconChain {
333
336
  metrics,
334
337
  logger,
335
338
  });
336
- this.seenPayloadEnvelopeInputCache = new SeenPayloadEnvelopeInput({
337
- chainEvents: emitter,
338
- signal,
339
- serializedCache: this.serializedCache,
340
- metrics,
341
- logger,
342
- });
343
339
 
344
340
  this._earliestAvailableSlot = anchorState.slot;
345
341
 
@@ -395,6 +391,7 @@ export class BeaconChain implements IBeaconChain {
395
391
  metrics,
396
392
  logger
397
393
  );
394
+
398
395
  const regen = new QueuedStateRegenerator({
399
396
  config,
400
397
  forkChoice,
@@ -419,6 +416,33 @@ export class BeaconChain implements IBeaconChain {
419
416
  this.payloadEnvelopeProcessor = new PayloadEnvelopeProcessor(this, metrics, signal);
420
417
 
421
418
  this.forkChoice = forkChoice;
419
+
420
+ this.seenPayloadEnvelopeInputCache = new SeenPayloadEnvelopeInput({
421
+ config,
422
+ clock,
423
+ forkChoice,
424
+ chainEvents: emitter,
425
+ signal,
426
+ serializedCache: this.serializedCache,
427
+ metrics,
428
+ logger,
429
+ });
430
+
431
+ const anchorBlockSlot = anchorState.latestBlockHeader.slot;
432
+ if (isStatePostGloas(anchorState) && anchorBlockSlot > 0) {
433
+ const anchorBid = anchorState.latestExecutionPayloadBid;
434
+ this.seenPayloadEnvelopeInputCache.addFromBid({
435
+ blockRootHex: toRootHex(checkpoint.root),
436
+ slot: anchorBlockSlot,
437
+ forkName: anchorState.forkName,
438
+ proposerIndex: anchorState.latestBlockHeader.proposerIndex,
439
+ bid: anchorBid,
440
+ sampledColumns: this.custodyConfig.sampledColumns,
441
+ custodyColumns: this.custodyConfig.custodyColumns,
442
+ timeCreatedSec: Math.floor(Date.now() / 1000),
443
+ });
444
+ }
445
+
422
446
  this.clock = clock;
423
447
  this.regen = regen;
424
448
  this.bls = bls;
@@ -1437,6 +1461,7 @@ export class BeaconChain implements IBeaconChain {
1437
1461
  this.payloadAttestationPool.prune(slot);
1438
1462
  this.executionPayloadBidPool.prune(slot);
1439
1463
  this.seenExecutionPayloadBids.prune(slot);
1464
+ this.seenProposerPreferences.prune(slot);
1440
1465
  this.seenAttestationDatas.onSlot(slot);
1441
1466
  this.reprocessController.onSlot(slot);
1442
1467
 
@@ -4,7 +4,6 @@ import {routes} from "@lodestar/api";
4
4
  import {CheckpointWithHex} from "@lodestar/fork-choice";
5
5
  import {IBeaconStateView} from "@lodestar/state-transition";
6
6
  import {DataColumnSidecar, RootHex, deneb, phase0} from "@lodestar/types";
7
- import {SignedExecutionPayloadEnvelope} from "@lodestar/types/gloas";
8
7
  import {PeerIdStr} from "../util/peerId.js";
9
8
  import {BlockInputSource, IBlockInput} from "./blocks/blockInput/types.js";
10
9
  import {PayloadEnvelopeInput} from "./blocks/payloadEnvelopeInput/payloadEnvelopeInput.js";
@@ -60,10 +59,6 @@ export enum ChainEvent {
60
59
  * Post-gloas, missing parent could be a SignedBeaconBlock and/or a SignedExecutionPayloadEnvelope
61
60
  */
62
61
  blockUnknownParent = "blockUnknownParent",
63
- /**
64
- * Trigger BlockInputSync to find a SignedBeaconBlock given a SignedExecutionPayloadEnvelop received
65
- */
66
- envelopeUnknownBlock = "envelopeUnknownBlock",
67
62
  /**
68
63
  * Trigger BlockInputSync to find a SignedBeaconBlock with specified block root.
69
64
  */
@@ -92,11 +87,6 @@ type ApiEvents = {[K in routes.events.EventType]: (data: routes.events.EventData
92
87
 
93
88
  export type ChainEventData = {
94
89
  [ChainEvent.blockUnknownParent]: {blockInput: IBlockInput; peer: PeerIdStr; source: BlockInputSource};
95
- [ChainEvent.envelopeUnknownBlock]: {
96
- envelope: SignedExecutionPayloadEnvelope;
97
- peer?: PeerIdStr;
98
- source: BlockInputSource;
99
- };
100
90
  [ChainEvent.unknownBlockRoot]: {rootHex: RootHex; peer?: PeerIdStr; source: BlockInputSource};
101
91
  [ChainEvent.incompleteBlockInput]: {blockInput: IBlockInput; peer: PeerIdStr; source: BlockInputSource};
102
92
  [ChainEvent.incompletePayloadEnvelope]: {
@@ -124,7 +114,6 @@ export type IChainEvents = ApiEvents & {
124
114
  // Sync events that are chain->chain. Initiated from network requests but do not cross the network
125
115
  // barrier so are considered ChainEvent(s).
126
116
  [ChainEvent.blockUnknownParent]: (data: ChainEventData[ChainEvent.blockUnknownParent]) => void;
127
- [ChainEvent.envelopeUnknownBlock]: (data: ChainEventData[ChainEvent.envelopeUnknownBlock]) => void;
128
117
  [ChainEvent.unknownBlockRoot]: (data: ChainEventData[ChainEvent.unknownBlockRoot]) => void;
129
118
  [ChainEvent.incompleteBlockInput]: (data: ChainEventData[ChainEvent.incompleteBlockInput]) => void;
130
119
  [ChainEvent.incompletePayloadEnvelope]: (data: ChainEventData[ChainEvent.incompletePayloadEnvelope]) => void;
@@ -8,6 +8,7 @@ export * from "./executionPayloadBid.js";
8
8
  export * from "./executionPayloadEnvelope.js";
9
9
  export * from "./gossipValidation.js";
10
10
  export * from "./payloadAttestation.js";
11
+ export * from "./proposerPreferences.js";
11
12
  export * from "./proposerSlashingError.js";
12
13
  export * from "./syncCommitteeError.js";
13
14
  export * from "./voluntaryExitError.js";
@@ -0,0 +1,47 @@
1
+ import {RootHex, Slot, ValidatorIndex} from "@lodestar/types";
2
+ import {GossipActionError} from "./gossipValidation.js";
3
+
4
+ export enum ProposerPreferencesErrorCode {
5
+ INVALID_EPOCH = "PROPOSER_PREFERENCES_ERROR_INVALID_EPOCH",
6
+ PROPOSAL_SLOT_PASSED = "PROPOSER_PREFERENCES_ERROR_PROPOSAL_SLOT_PASSED",
7
+ UNKNOWN_DEPENDENT_ROOT = "PROPOSER_PREFERENCES_ERROR_UNKNOWN_DEPENDENT_ROOT",
8
+ INVALID_PROPOSER = "PROPOSER_PREFERENCES_ERROR_INVALID_PROPOSER",
9
+ ALREADY_KNOWN = "PROPOSER_PREFERENCES_ERROR_ALREADY_KNOWN",
10
+ INVALID_SIGNATURE = "PROPOSER_PREFERENCES_ERROR_INVALID_SIGNATURE",
11
+ }
12
+
13
+ export type ProposerPreferencesErrorType =
14
+ | {
15
+ code: ProposerPreferencesErrorCode.INVALID_EPOCH;
16
+ proposalSlot: Slot;
17
+ currentEpoch: number;
18
+ }
19
+ | {
20
+ code: ProposerPreferencesErrorCode.PROPOSAL_SLOT_PASSED;
21
+ proposalSlot: Slot;
22
+ currentSlot: Slot;
23
+ }
24
+ | {
25
+ code: ProposerPreferencesErrorCode.UNKNOWN_DEPENDENT_ROOT;
26
+ proposalSlot: Slot;
27
+ dependentRoot: RootHex;
28
+ }
29
+ | {
30
+ code: ProposerPreferencesErrorCode.INVALID_PROPOSER;
31
+ proposalSlot: Slot;
32
+ validatorIndex: ValidatorIndex;
33
+ dependentRoot: RootHex;
34
+ }
35
+ | {
36
+ code: ProposerPreferencesErrorCode.ALREADY_KNOWN;
37
+ proposalSlot: Slot;
38
+ validatorIndex: ValidatorIndex;
39
+ dependentRoot: RootHex;
40
+ }
41
+ | {
42
+ code: ProposerPreferencesErrorCode.INVALID_SIGNATURE;
43
+ proposalSlot: Slot;
44
+ validatorIndex: ValidatorIndex;
45
+ };
46
+
47
+ export class ProposerPreferencesError extends GossipActionError<ProposerPreferencesErrorType> {}
@@ -1,7 +1,8 @@
1
1
  import {ChainForkConfig} from "@lodestar/config";
2
- import {ZERO_HASH} from "@lodestar/params";
2
+ import {ForkPostGloas, ForkSeq, ZERO_HASH} from "@lodestar/params";
3
3
  import {
4
4
  BeaconStateAllForks,
5
+ BeaconStateGloas,
5
6
  IBeaconStateView,
6
7
  computeEpochAtSlot,
7
8
  computeStartSlotAtEpoch,
@@ -52,6 +53,13 @@ export function createGenesisBlock(config: ChainForkConfig, genesisState: Beacon
52
53
  const genesisBlock = types.SignedBeaconBlock.defaultValue();
53
54
  const stateRoot = genesisState.hashTreeRoot();
54
55
  genesisBlock.message.stateRoot = stateRoot;
56
+
57
+ if (config.getForkSeq(GENESIS_SLOT) >= ForkSeq.gloas) {
58
+ const gloasBlock = genesisBlock as SignedBeaconBlock<ForkPostGloas>;
59
+ const gloasState = genesisState as BeaconStateGloas;
60
+ gloasBlock.message.body.signedExecutionPayloadBid.message = gloasState.latestExecutionPayloadBid.toValue();
61
+ }
62
+
55
63
  return genesisBlock;
56
64
  }
57
65
 
@@ -61,6 +61,7 @@ import {
61
61
  SeenContributionAndProof,
62
62
  SeenExecutionPayloadBids,
63
63
  SeenPayloadAttesters,
64
+ SeenProposerPreferences,
64
65
  SeenSyncCommitteeMessages,
65
66
  } from "./seenCache/index.js";
66
67
  import {SeenAggregatedAttestations} from "./seenCache/seenAggregateAndProof.js";
@@ -131,6 +132,7 @@ export interface IBeaconChain {
131
132
  readonly seenPayloadAttesters: SeenPayloadAttesters;
132
133
  readonly seenAggregatedAttestations: SeenAggregatedAttestations;
133
134
  readonly seenExecutionPayloadBids: SeenExecutionPayloadBids;
135
+ readonly seenProposerPreferences: SeenProposerPreferences;
134
136
  readonly seenBlockProposers: SeenBlockProposers;
135
137
  readonly seenSyncCommitteeMessages: SeenSyncCommitteeMessages;
136
138
  readonly seenContributionAndProof: SeenContributionAndProof;
@@ -1,12 +1,6 @@
1
1
  import {BitArray} from "@chainsafe/ssz";
2
2
  import {routes} from "@lodestar/api";
3
3
  import {ChainForkConfig} from "@lodestar/config";
4
- import {
5
- LightClientUpdateSummary,
6
- isBetterUpdate,
7
- toLightClientUpdateSummary,
8
- upgradeLightClientHeader,
9
- } from "@lodestar/light-client/spec";
10
4
  import {
11
5
  ForkName,
12
6
  ForkPostAltair,
@@ -27,6 +21,12 @@ import {
27
21
  computeSyncPeriodAtSlot,
28
22
  executionPayloadToPayloadHeader,
29
23
  } from "@lodestar/state-transition";
24
+ import {
25
+ LightClientUpdateSummary,
26
+ isBetterUpdate,
27
+ toLightClientUpdateSummary,
28
+ upgradeLightClientHeader,
29
+ } from "@lodestar/state-transition/light-client";
30
30
  import {
31
31
  BeaconBlock,
32
32
  BeaconBlockBody,
@@ -1,7 +1,7 @@
1
1
  import {Signature, aggregateSignatures} from "@chainsafe/blst";
2
2
  import {BitArray} from "@chainsafe/ssz";
3
3
  import {ChainForkConfig} from "@lodestar/config";
4
- import {MAX_COMMITTEES_PER_SLOT, PTC_SIZE} from "@lodestar/params";
4
+ import {MAX_COMMITTEES_PER_SLOT, MAX_PAYLOAD_ATTESTATIONS, PTC_SIZE} from "@lodestar/params";
5
5
  import {RootHex, Slot, gloas} from "@lodestar/types";
6
6
  import {MapDef, toRootHex} from "@lodestar/utils";
7
7
  import {Metrics} from "../../metrics/metrics.js";
@@ -57,7 +57,7 @@ export class PayloadAttestationPool {
57
57
  add(
58
58
  message: gloas.PayloadAttestationMessage,
59
59
  payloadAttDataRootHex: RootHex,
60
- validatorCommitteeIndex: number
60
+ validatorCommitteeIndices: number[]
61
61
  ): InsertOutcome {
62
62
  const slot = message.data.slot;
63
63
  const lowestPermissibleSlot = this.lowestPermissibleSlot;
@@ -85,23 +85,19 @@ export class PayloadAttestationPool {
85
85
  const aggregate = aggregateByDataRoot.get(payloadAttDataRootHex);
86
86
  if (aggregate) {
87
87
  // Aggregate msg into aggregate
88
- return aggregateMessageInto(message, validatorCommitteeIndex, aggregate);
88
+ return aggregateMessageInto(message, validatorCommitteeIndices, aggregate);
89
89
  }
90
90
  // Create a new aggregate with data
91
- aggregateByDataRoot.set(payloadAttDataRootHex, messageToAggregate(message, validatorCommitteeIndex));
91
+ aggregateByDataRoot.set(payloadAttDataRootHex, messageToAggregate(message, validatorCommitteeIndices));
92
92
 
93
93
  return InsertOutcome.NewData;
94
94
  }
95
95
 
96
96
  /**
97
97
  * Get payload attestations to be included in a block.
98
- * Pick the top `maxAttestation` number of attestations with the most votes
98
+ * Pick the top `MAX_PAYLOAD_ATTESTATIONS` aggregates with the most votes.
99
99
  */
100
- getPayloadAttestationsForBlock(
101
- beaconBlockRoot: BlockRootHex,
102
- slot: Slot,
103
- maxAttestation: number
104
- ): gloas.PayloadAttestation[] {
100
+ getPayloadAttestationsForBlock(beaconBlockRoot: BlockRootHex, slot: Slot): gloas.PayloadAttestation[] {
105
101
  const aggregateByDataRootByBlockRoot = this.aggregateByDataRootByBlockRootBySlot.get(slot);
106
102
 
107
103
  if (!aggregateByDataRootByBlockRoot) {
@@ -119,7 +115,32 @@ export class PayloadAttestationPool {
119
115
  return Array.from(aggregateByDataRoot.values())
120
116
  .slice()
121
117
  .sort((a, b) => b.aggregationBits.getTrueBitIndexes().length - a.aggregationBits.getTrueBitIndexes().length)
122
- .slice(0, maxAttestation)
118
+ .slice(0, MAX_PAYLOAD_ATTESTATIONS)
119
+ .map(fastToPayloadAttestation);
120
+ }
121
+
122
+ getAll(slot?: Slot): gloas.PayloadAttestation[] {
123
+ const aggregates: AggregateFast[] = [];
124
+
125
+ const addAggregates = (aggregateByDataRootByBlockRoot: Map<BlockRootHex, Map<DataRootHex, AggregateFast>>) => {
126
+ for (const aggregateByDataRoot of aggregateByDataRootByBlockRoot.values()) {
127
+ aggregates.push(...aggregateByDataRoot.values());
128
+ }
129
+ };
130
+
131
+ if (slot !== undefined) {
132
+ const aggregateByDataRootByBlockRoot = this.aggregateByDataRootByBlockRootBySlot.get(slot);
133
+ if (aggregateByDataRootByBlockRoot) {
134
+ addAggregates(aggregateByDataRootByBlockRoot);
135
+ }
136
+ } else {
137
+ for (const aggregateByDataRootByBlockRoot of this.aggregateByDataRootByBlockRootBySlot.values()) {
138
+ addAggregates(aggregateByDataRootByBlockRoot);
139
+ }
140
+ }
141
+
142
+ return aggregates
143
+ .sort((a, b) => b.aggregationBits.getTrueBitIndexes().length - a.aggregationBits.getTrueBitIndexes().length)
123
144
  .map(fastToPayloadAttestation);
124
145
  }
125
146
 
@@ -129,25 +150,49 @@ export class PayloadAttestationPool {
129
150
  }
130
151
  }
131
152
 
132
- function messageToAggregate(message: gloas.PayloadAttestationMessage, validatorCommitteeIndex: number): AggregateFast {
153
+ function messageToAggregate(
154
+ message: gloas.PayloadAttestationMessage,
155
+ validatorCommitteeIndices: number[]
156
+ ): AggregateFast {
157
+ const aggregationBits = BitArray.fromBitLen(PTC_SIZE);
158
+ for (const index of validatorCommitteeIndices) {
159
+ aggregationBits.set(index, true);
160
+ }
161
+ const sig = signatureFromBytesNoCheck(message.signature);
162
+ // The validator signed once but occupies `validatorCommitteeIndices.length` PTC positions.
163
+ // Verification aggregates the pubkey once per set bit, so the signature must be aggregated
164
+ // the same number of times for the BLS check to balance — same pattern as sync committee.
165
+ const signature =
166
+ validatorCommitteeIndices.length === 1
167
+ ? sig
168
+ : aggregateSignatures(new Array(validatorCommitteeIndices.length).fill(sig));
133
169
  return {
134
- aggregationBits: BitArray.fromSingleBit(PTC_SIZE, validatorCommitteeIndex),
170
+ aggregationBits,
135
171
  data: message.data,
136
- signature: signatureFromBytesNoCheck(message.signature),
172
+ signature,
137
173
  };
138
174
  }
139
175
 
140
176
  function aggregateMessageInto(
141
177
  message: gloas.PayloadAttestationMessage,
142
- validatorCommitteeIndex: number,
178
+ validatorCommitteeIndices: number[],
143
179
  aggregate: AggregateFast
144
180
  ): InsertOutcome {
145
- if (aggregate.aggregationBits.get(validatorCommitteeIndex) === true) {
181
+ // Gossip dedup via `seenPayloadAttesters` is keyed by (epoch, validatorIndex), so the same
182
+ // validator's message is never processed twice — all of its bits are set together or none.
183
+ // Checking the first index is sufficient.
184
+ if (aggregate.aggregationBits.get(validatorCommitteeIndices[0]) === true) {
146
185
  return InsertOutcome.AlreadyKnown;
147
186
  }
148
187
 
149
- aggregate.aggregationBits.set(validatorCommitteeIndex, true);
150
- aggregate.signature = aggregateSignatures([aggregate.signature, signatureFromBytesNoCheck(message.signature)]);
188
+ for (const index of validatorCommitteeIndices) {
189
+ aggregate.aggregationBits.set(index, true);
190
+ }
191
+ const sig = signatureFromBytesNoCheck(message.signature);
192
+ aggregate.signature = aggregateSignatures([
193
+ aggregate.signature,
194
+ ...new Array(validatorCommitteeIndices.length).fill(sig),
195
+ ]);
151
196
 
152
197
  return InsertOutcome.Aggregated;
153
198
  }
@@ -4,13 +4,14 @@ import {getSafeExecutionBlockHash} from "@lodestar/fork-choice";
4
4
  import {ForkPostBellatrix, ForkSeq, SLOTS_PER_EPOCH, isForkPostBellatrix} from "@lodestar/params";
5
5
  import {
6
6
  IBeaconStateView,
7
+ IBeaconStateViewBellatrix,
7
8
  StateHashTreeRootSource,
8
9
  computeEpochAtSlot,
9
10
  computeTimeAtSlot,
10
11
  isStatePostBellatrix,
11
12
  isStatePostGloas,
12
13
  } from "@lodestar/state-transition";
13
- import {Bytes32, Slot, electra} from "@lodestar/types";
14
+ import {Bytes32, Slot} from "@lodestar/types";
14
15
  import {Logger, fromHex, isErrorAborted, sleep} from "@lodestar/utils";
15
16
  import {GENESIS_SLOT, ZERO_HASH_HEX} from "../constants/constants.js";
16
17
  import {BuilderStatus} from "../execution/builder/http.js";
@@ -165,19 +166,26 @@ export class PrepareNextSlotScheduler {
165
166
  }
166
167
 
167
168
  let parentBlockHash: Bytes32;
168
- let isExtendingPayload = false;
169
+ // Apply parent payload once here as it's reused by EL prep and SSE emit below
170
+ let stateAfterParentPayload: IBeaconStateViewBellatrix = updatedPrepareState;
169
171
  if (isStatePostGloas(updatedPrepareState)) {
170
- isExtendingPayload = this.chain.forkChoice.shouldExtendPayload(updatedHead.blockRoot);
171
- parentBlockHash = isExtendingPayload
172
- ? updatedPrepareState.latestExecutionPayloadBid.blockHash
173
- : updatedPrepareState.latestExecutionPayloadBid.parentBlockHash;
172
+ if (this.chain.forkChoice.shouldExtendPayload(updatedHead.blockRoot)) {
173
+ parentBlockHash = updatedPrepareState.latestExecutionPayloadBid.blockHash;
174
+ // Skip applying parent payload unless we're proposing the next slot or have to emit payload_attributes events
175
+ if (feeRecipient !== undefined || this.chain.opts.emitPayloadAttributes === true) {
176
+ const parentExecutionRequests = await this.chain.getParentExecutionRequests(
177
+ updatedHead.slot,
178
+ updatedHead.blockRoot
179
+ );
180
+ stateAfterParentPayload = updatedPrepareState.withParentPayloadApplied(parentExecutionRequests);
181
+ }
182
+ } else {
183
+ parentBlockHash = updatedPrepareState.latestExecutionPayloadBid.parentBlockHash;
184
+ }
174
185
  } else {
175
186
  parentBlockHash = updatedPrepareState.latestExecutionPayloadHeader.blockHash;
176
187
  }
177
188
 
178
- // Reused by the SSE emit below to avoid a second DB lookup on cache miss
179
- let parentExecutionRequests: electra.ExecutionRequests | undefined;
180
-
181
189
  if (feeRecipient) {
182
190
  const preparationTime =
183
191
  computeTimeAtSlot(this.config, prepareSlot, this.chain.genesisTime) - Date.now() / 1000;
@@ -187,13 +195,6 @@ export class PrepareNextSlotScheduler {
187
195
  const finalizedBlockHash =
188
196
  this.chain.forkChoice.getFinalizedBlock().executionPayloadBlockHash ?? ZERO_HASH_HEX;
189
197
 
190
- if (isExtendingPayload) {
191
- parentExecutionRequests = await this.chain.getParentExecutionRequests(
192
- updatedHead.slot,
193
- updatedHead.blockRoot
194
- );
195
- }
196
-
197
198
  // awaiting here instead of throwing an async call because there is no other task
198
199
  // left for scheduler and this gives nice semantics to catch and log errors in the
199
200
  // try/catch wrapper here.
@@ -205,9 +206,8 @@ export class PrepareNextSlotScheduler {
205
206
  parentBlockHash,
206
207
  safeBlockHash,
207
208
  finalizedBlockHash,
208
- updatedPrepareState,
209
- feeRecipient,
210
- parentExecutionRequests
209
+ stateAfterParentPayload,
210
+ feeRecipient
211
211
  );
212
212
  this.logger.verbose("PrepareNextSlotScheduler prepared new payload", {
213
213
  prepareSlot,
@@ -222,7 +222,7 @@ export class PrepareNextSlotScheduler {
222
222
  // and head.parent (proposer-boost-reorg fallback). Anything older is evicted.
223
223
  const updatedHeadParent = this.chain.forkChoice.getBlockHexDefaultStatus(updatedHead.parentRoot);
224
224
  if (updatedHeadParent) {
225
- this.chain.seenPayloadEnvelopeInputCache.pruneBelow(updatedHeadParent.slot);
225
+ this.chain.seenPayloadEnvelopeInputCache.pruneBelowParent(updatedHeadParent);
226
226
  }
227
227
  }
228
228
 
@@ -234,20 +234,12 @@ export class PrepareNextSlotScheduler {
234
234
  (feeRecipient || this.chain.opts.emitPayloadAttributes === true) &&
235
235
  this.chain.emitter.listenerCount(routes.events.EventType.payloadAttributes)
236
236
  ) {
237
- // if we didn't fetch above (not proposing), SSE still needs it here
238
- if (!parentExecutionRequests && isExtendingPayload) {
239
- parentExecutionRequests = await this.chain.getParentExecutionRequests(
240
- updatedHead.slot,
241
- updatedHead.blockRoot
242
- );
243
- }
244
237
  const data = getPayloadAttributesForSSE(fork as ForkPostBellatrix, this.chain, {
245
- prepareState: updatedPrepareState,
238
+ prepareState: stateAfterParentPayload,
246
239
  prepareSlot,
247
240
  parentBlockRoot: fromHex(updatedHead.blockRoot),
248
241
  parentBlockHash,
249
242
  feeRecipient: feeRecipient ?? "0x0000000000000000000000000000000000000000",
250
- parentExecutionRequests,
251
243
  });
252
244
  this.chain.emitter.emit(routes.events.EventType.payloadAttributes, {data, version: fork});
253
245
  }