@lodestar/beacon-node 1.41.0-dev.aeb5a213ee → 1.41.0-dev.bb273175f2

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 (294) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +3 -2
  3. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  4. package/lib/api/impl/beacon/state/index.js +8 -8
  5. package/lib/api/impl/beacon/state/index.js.map +1 -1
  6. package/lib/api/impl/beacon/state/utils.d.ts +3 -4
  7. package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
  8. package/lib/api/impl/beacon/state/utils.js +4 -4
  9. package/lib/api/impl/beacon/state/utils.js.map +1 -1
  10. package/lib/api/impl/debug/index.d.ts.map +1 -1
  11. package/lib/api/impl/debug/index.js +1 -0
  12. package/lib/api/impl/debug/index.js.map +1 -1
  13. package/lib/api/impl/node/utils.d.ts +1 -1
  14. package/lib/api/impl/node/utils.d.ts.map +1 -1
  15. package/lib/api/impl/node/utils.js.map +1 -1
  16. package/lib/api/impl/validator/index.d.ts.map +1 -1
  17. package/lib/api/impl/validator/index.js +29 -15
  18. package/lib/api/impl/validator/index.js.map +1 -1
  19. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  20. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  21. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts +5 -6
  22. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
  23. package/lib/chain/archiveStore/historicalState/getHistoricalState.js +9 -10
  24. package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
  25. package/lib/chain/archiveStore/historicalState/worker.js +3 -3
  26. package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
  27. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts +3 -8
  28. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
  29. package/lib/chain/archiveStore/utils/archiveBlocks.js +1 -1
  30. package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
  31. package/lib/chain/archiveStore/utils/updateBackfillRange.js +1 -1
  32. package/lib/chain/archiveStore/utils/updateBackfillRange.js.map +1 -1
  33. package/lib/chain/blocks/blockInput/blockInput.d.ts +20 -2
  34. package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
  35. package/lib/chain/blocks/blockInput/blockInput.js +47 -0
  36. package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
  37. package/lib/chain/blocks/blockInput/types.d.ts +13 -1
  38. package/lib/chain/blocks/blockInput/types.d.ts.map +1 -1
  39. package/lib/chain/blocks/blockInput/types.js +1 -0
  40. package/lib/chain/blocks/blockInput/types.js.map +1 -1
  41. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  42. package/lib/chain/blocks/importBlock.js +27 -4
  43. package/lib/chain/blocks/importBlock.js.map +1 -1
  44. package/lib/chain/blocks/verifyBlocksDataAvailability.d.ts.map +1 -1
  45. package/lib/chain/blocks/verifyBlocksDataAvailability.js +3 -0
  46. package/lib/chain/blocks/verifyBlocksDataAvailability.js.map +1 -1
  47. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts +4 -0
  48. package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
  49. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +5 -1
  50. package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
  51. package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts.map +1 -1
  52. package/lib/chain/blocks/verifyBlocksSanityChecks.js +4 -1
  53. package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
  54. package/lib/chain/blocks/writeBlockInputToDb.d.ts +12 -3
  55. package/lib/chain/blocks/writeBlockInputToDb.d.ts.map +1 -1
  56. package/lib/chain/blocks/writeBlockInputToDb.js +101 -96
  57. package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
  58. package/lib/chain/bls/multithread/index.d.ts +3 -3
  59. package/lib/chain/bls/multithread/index.d.ts.map +1 -1
  60. package/lib/chain/bls/multithread/index.js +5 -5
  61. package/lib/chain/bls/multithread/index.js.map +1 -1
  62. package/lib/chain/bls/multithread/jobItem.d.ts +2 -2
  63. package/lib/chain/bls/multithread/jobItem.d.ts.map +1 -1
  64. package/lib/chain/bls/multithread/jobItem.js +2 -2
  65. package/lib/chain/bls/multithread/jobItem.js.map +1 -1
  66. package/lib/chain/bls/singleThread.d.ts +4 -4
  67. package/lib/chain/bls/singleThread.d.ts.map +1 -1
  68. package/lib/chain/bls/singleThread.js +4 -4
  69. package/lib/chain/bls/singleThread.js.map +1 -1
  70. package/lib/chain/bls/utils.d.ts +2 -2
  71. package/lib/chain/bls/utils.d.ts.map +1 -1
  72. package/lib/chain/bls/utils.js +7 -4
  73. package/lib/chain/bls/utils.js.map +1 -1
  74. package/lib/chain/chain.d.ts +5 -8
  75. package/lib/chain/chain.d.ts.map +1 -1
  76. package/lib/chain/chain.js +19 -21
  77. package/lib/chain/chain.js.map +1 -1
  78. package/lib/chain/emitter.d.ts +3 -3
  79. package/lib/chain/emitter.d.ts.map +1 -1
  80. package/lib/chain/errors/executionPayloadEnvelope.d.ts +2 -2
  81. package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
  82. package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
  83. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  84. package/lib/chain/forkChoice/index.js +30 -24
  85. package/lib/chain/forkChoice/index.js.map +1 -1
  86. package/lib/chain/interface.d.ts +2 -4
  87. package/lib/chain/interface.d.ts.map +1 -1
  88. package/lib/chain/interface.js.map +1 -1
  89. package/lib/chain/opPools/aggregatedAttestationPool.js +1 -1
  90. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  91. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  92. package/lib/chain/produceBlock/produceBlockBody.js +1 -2
  93. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  94. package/lib/chain/regen/queued.d.ts.map +1 -1
  95. package/lib/chain/regen/queued.js +4 -1
  96. package/lib/chain/regen/queued.js.map +1 -1
  97. package/lib/chain/regen/regen.d.ts.map +1 -1
  98. package/lib/chain/regen/regen.js +6 -2
  99. package/lib/chain/regen/regen.js.map +1 -1
  100. package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
  101. package/lib/chain/seenCache/seenGossipBlockInput.js +15 -7
  102. package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
  103. package/lib/chain/validation/aggregateAndProof.js +1 -1
  104. package/lib/chain/validation/aggregateAndProof.js.map +1 -1
  105. package/lib/chain/validation/attestation.d.ts.map +1 -1
  106. package/lib/chain/validation/attestation.js +7 -4
  107. package/lib/chain/validation/attestation.js.map +1 -1
  108. package/lib/chain/validation/attesterSlashing.d.ts.map +1 -1
  109. package/lib/chain/validation/attesterSlashing.js +9 -2
  110. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  111. package/lib/chain/validation/blobSidecar.js +2 -2
  112. package/lib/chain/validation/blobSidecar.js.map +1 -1
  113. package/lib/chain/validation/block.d.ts.map +1 -1
  114. package/lib/chain/validation/block.js +6 -3
  115. package/lib/chain/validation/block.js.map +1 -1
  116. package/lib/chain/validation/dataColumnSidecar.js +1 -1
  117. package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
  118. package/lib/chain/validation/executionPayloadBid.js +1 -2
  119. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  120. package/lib/chain/validation/executionPayloadEnvelope.js +4 -4
  121. package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
  122. package/lib/chain/validation/payloadAttestationMessage.js +9 -3
  123. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  124. package/lib/chain/validation/proposerSlashing.js +1 -1
  125. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  126. package/lib/chain/validation/syncCommitteeContributionAndProof.js +1 -1
  127. package/lib/db/repositories/blockArchive.d.ts.map +1 -1
  128. package/lib/db/repositories/blockArchive.js +1 -2
  129. package/lib/db/repositories/blockArchive.js.map +1 -1
  130. package/lib/execution/engine/http.d.ts +1 -0
  131. package/lib/execution/engine/http.d.ts.map +1 -1
  132. package/lib/execution/engine/http.js +3 -0
  133. package/lib/execution/engine/http.js.map +1 -1
  134. package/lib/metrics/metrics/lodestar.d.ts +3 -0
  135. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  136. package/lib/metrics/metrics/lodestar.js +5 -0
  137. package/lib/metrics/metrics/lodestar.js.map +1 -1
  138. package/lib/monitoring/service.d.ts +2 -2
  139. package/lib/monitoring/service.d.ts.map +1 -1
  140. package/lib/monitoring/service.js +3 -2
  141. package/lib/monitoring/service.js.map +1 -1
  142. package/lib/network/core/networkCore.d.ts +3 -3
  143. package/lib/network/core/networkCore.d.ts.map +1 -1
  144. package/lib/network/core/networkCore.js.map +1 -1
  145. package/lib/network/core/networkCoreWorkerHandler.d.ts +3 -3
  146. package/lib/network/core/networkCoreWorkerHandler.d.ts.map +1 -1
  147. package/lib/network/core/types.d.ts +2 -2
  148. package/lib/network/core/types.d.ts.map +1 -1
  149. package/lib/network/events.d.ts +2 -1
  150. package/lib/network/events.d.ts.map +1 -1
  151. package/lib/network/events.js.map +1 -1
  152. package/lib/network/gossip/encoding.d.ts +3 -3
  153. package/lib/network/gossip/encoding.d.ts.map +1 -1
  154. package/lib/network/gossip/encoding.js.map +1 -1
  155. package/lib/network/gossip/gossipsub.d.ts +13 -4
  156. package/lib/network/gossip/gossipsub.d.ts.map +1 -1
  157. package/lib/network/gossip/gossipsub.js +47 -20
  158. package/lib/network/gossip/gossipsub.js.map +1 -1
  159. package/lib/network/gossip/interface.d.ts +3 -3
  160. package/lib/network/gossip/interface.d.ts.map +1 -1
  161. package/lib/network/gossip/scoringParameters.d.ts +1 -1
  162. package/lib/network/gossip/scoringParameters.d.ts.map +1 -1
  163. package/lib/network/gossip/scoringParameters.js +1 -1
  164. package/lib/network/gossip/scoringParameters.js.map +1 -1
  165. package/lib/network/interface.d.ts +3 -3
  166. package/lib/network/interface.d.ts.map +1 -1
  167. package/lib/network/libp2p/index.d.ts +1 -1
  168. package/lib/network/libp2p/index.d.ts.map +1 -1
  169. package/lib/network/libp2p/index.js +7 -2
  170. package/lib/network/libp2p/index.js.map +1 -1
  171. package/lib/network/network.d.ts +2 -2
  172. package/lib/network/network.d.ts.map +1 -1
  173. package/lib/network/network.js.map +1 -1
  174. package/lib/network/options.d.ts.map +1 -1
  175. package/lib/network/options.js +3 -0
  176. package/lib/network/options.js.map +1 -1
  177. package/lib/network/peers/datastore.d.ts +7 -5
  178. package/lib/network/peers/datastore.d.ts.map +1 -1
  179. package/lib/network/peers/datastore.js +10 -10
  180. package/lib/network/peers/datastore.js.map +1 -1
  181. package/lib/network/peers/peerManager.d.ts +3 -0
  182. package/lib/network/peers/peerManager.d.ts.map +1 -1
  183. package/lib/network/peers/peerManager.js +103 -53
  184. package/lib/network/peers/peerManager.js.map +1 -1
  185. package/lib/network/peers/utils/prioritizePeers.d.ts +3 -3
  186. package/lib/network/peers/utils/prioritizePeers.d.ts.map +1 -1
  187. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  188. package/lib/network/processor/gossipHandlers.js +4 -1
  189. package/lib/network/processor/gossipHandlers.js.map +1 -1
  190. package/lib/network/processor/gossipValidatorFn.js +1 -1
  191. package/lib/network/processor/types.d.ts +1 -1
  192. package/lib/network/processor/types.d.ts.map +1 -1
  193. package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
  194. package/lib/network/reqresp/handlers/beaconBlocksByRange.js +3 -2
  195. package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
  196. package/lib/network/reqresp/handlers/blobSidecarsByRange.d.ts.map +1 -1
  197. package/lib/network/reqresp/handlers/blobSidecarsByRange.js +3 -2
  198. package/lib/network/reqresp/handlers/blobSidecarsByRange.js.map +1 -1
  199. package/lib/network/reqresp/handlers/blobSidecarsByRoot.js +1 -1
  200. package/lib/network/reqresp/handlers/blobSidecarsByRoot.js.map +1 -1
  201. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
  202. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +3 -2
  203. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
  204. package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js +1 -1
  205. package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js.map +1 -1
  206. package/lib/network/reqresp/score.d.ts.map +1 -1
  207. package/lib/network/reqresp/score.js +0 -1
  208. package/lib/network/reqresp/score.js.map +1 -1
  209. package/lib/network/util.js +2 -2
  210. package/lib/network/util.js.map +1 -1
  211. package/lib/node/nodejs.d.ts +3 -5
  212. package/lib/node/nodejs.d.ts.map +1 -1
  213. package/lib/node/nodejs.js +6 -4
  214. package/lib/node/nodejs.js.map +1 -1
  215. package/lib/util/clock.d.ts +6 -0
  216. package/lib/util/clock.d.ts.map +1 -1
  217. package/lib/util/clock.js +9 -3
  218. package/lib/util/clock.js.map +1 -1
  219. package/package.json +39 -42
  220. package/src/api/impl/beacon/blocks/index.ts +3 -2
  221. package/src/api/impl/beacon/state/index.ts +8 -8
  222. package/src/api/impl/beacon/state/utils.ts +5 -6
  223. package/src/api/impl/debug/index.ts +1 -0
  224. package/src/api/impl/node/utils.ts +3 -3
  225. package/src/api/impl/validator/index.ts +29 -16
  226. package/src/chain/archiveStore/archiveStore.ts +5 -5
  227. package/src/chain/archiveStore/historicalState/getHistoricalState.ts +10 -11
  228. package/src/chain/archiveStore/historicalState/worker.ts +3 -3
  229. package/src/chain/archiveStore/utils/archiveBlocks.ts +4 -5
  230. package/src/chain/archiveStore/utils/updateBackfillRange.ts +1 -1
  231. package/src/chain/blocks/blockInput/blockInput.ts +68 -3
  232. package/src/chain/blocks/blockInput/types.ts +13 -0
  233. package/src/chain/blocks/importBlock.ts +35 -4
  234. package/src/chain/blocks/verifyBlocksDataAvailability.ts +3 -0
  235. package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +9 -2
  236. package/src/chain/blocks/verifyBlocksSanityChecks.ts +7 -2
  237. package/src/chain/blocks/writeBlockInputToDb.ts +119 -101
  238. package/src/chain/bls/multithread/index.ts +7 -7
  239. package/src/chain/bls/multithread/jobItem.ts +3 -3
  240. package/src/chain/bls/singleThread.ts +5 -5
  241. package/src/chain/bls/utils.ts +8 -5
  242. package/src/chain/chain.ts +36 -29
  243. package/src/chain/emitter.ts +3 -3
  244. package/src/chain/errors/executionPayloadEnvelope.ts +6 -2
  245. package/src/chain/forkChoice/index.ts +39 -21
  246. package/src/chain/interface.ts +2 -9
  247. package/src/chain/opPools/aggregatedAttestationPool.ts +1 -1
  248. package/src/chain/produceBlock/produceBlockBody.ts +1 -2
  249. package/src/chain/regen/queued.ts +7 -2
  250. package/src/chain/regen/regen.ts +9 -3
  251. package/src/chain/seenCache/seenGossipBlockInput.ts +16 -7
  252. package/src/chain/validation/aggregateAndProof.ts +1 -1
  253. package/src/chain/validation/attestation.ts +7 -4
  254. package/src/chain/validation/attesterSlashing.ts +10 -1
  255. package/src/chain/validation/blobSidecar.ts +2 -2
  256. package/src/chain/validation/block.ts +9 -4
  257. package/src/chain/validation/dataColumnSidecar.ts +1 -1
  258. package/src/chain/validation/executionPayloadBid.ts +1 -2
  259. package/src/chain/validation/executionPayloadEnvelope.ts +4 -4
  260. package/src/chain/validation/payloadAttestationMessage.ts +10 -3
  261. package/src/chain/validation/proposerSlashing.ts +1 -1
  262. package/src/chain/validation/syncCommitteeContributionAndProof.ts +1 -1
  263. package/src/db/repositories/blockArchive.ts +1 -2
  264. package/src/execution/engine/http.ts +3 -0
  265. package/src/metrics/metrics/lodestar.ts +5 -0
  266. package/src/monitoring/service.ts +3 -2
  267. package/src/network/core/networkCore.ts +3 -3
  268. package/src/network/core/networkCoreWorkerHandler.ts +3 -3
  269. package/src/network/core/types.ts +2 -2
  270. package/src/network/events.ts +2 -1
  271. package/src/network/gossip/encoding.ts +3 -3
  272. package/src/network/gossip/gossipsub.ts +86 -25
  273. package/src/network/gossip/interface.ts +3 -3
  274. package/src/network/gossip/scoringParameters.ts +4 -4
  275. package/src/network/interface.ts +3 -3
  276. package/src/network/libp2p/index.ts +8 -3
  277. package/src/network/network.ts +3 -3
  278. package/src/network/options.ts +3 -0
  279. package/src/network/peers/datastore.ts +13 -10
  280. package/src/network/peers/peerManager.ts +118 -54
  281. package/src/network/peers/utils/prioritizePeers.ts +3 -3
  282. package/src/network/processor/gossipHandlers.ts +12 -3
  283. package/src/network/processor/gossipValidatorFn.ts +1 -1
  284. package/src/network/processor/types.ts +1 -1
  285. package/src/network/reqresp/handlers/beaconBlocksByRange.ts +3 -2
  286. package/src/network/reqresp/handlers/blobSidecarsByRange.ts +3 -2
  287. package/src/network/reqresp/handlers/blobSidecarsByRoot.ts +1 -1
  288. package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +3 -2
  289. package/src/network/reqresp/handlers/dataColumnSidecarsByRoot.ts +1 -1
  290. package/src/network/reqresp/score.ts +0 -1
  291. package/src/network/util.ts +2 -2
  292. package/src/node/nodejs.ts +8 -9
  293. package/src/util/clock.ts +9 -4
  294. package/src/util/workerEvents.ts +1 -1
@@ -1,7 +1,15 @@
1
- import {fulu} from "@lodestar/types";
2
- import {prettyPrintIndices, toRootHex} from "@lodestar/utils";
1
+ import {ForkPostDeneb, isForkPostDeneb} from "@lodestar/params";
2
+ import {SignedBeaconBlock} from "@lodestar/types";
3
+ import {fromHex, toRootHex} from "@lodestar/utils";
4
+ import {getBlobKzgCommitments} from "../../util/dataColumns.js";
3
5
  import {BeaconChain} from "../chain.js";
4
- import {IBlockInput, isBlockInputBlobs, isBlockInputColumns} from "./blockInput/index.js";
6
+ import {
7
+ IBlockInput,
8
+ IDataColumnsInput,
9
+ isBlockInputBlobs,
10
+ isBlockInputColumns,
11
+ isBlockInputNoData,
12
+ } from "./blockInput/index.js";
5
13
  import {BLOB_AVAILABILITY_TIMEOUT} from "./verifyBlocksDataAvailability.js";
6
14
 
7
15
  /**
@@ -10,129 +18,139 @@ import {BLOB_AVAILABILITY_TIMEOUT} from "./verifyBlocksDataAvailability.js";
10
18
  *
11
19
  * This operation may be performed before, during or after importing to the fork-choice. As long as errors
12
20
  * are handled properly for eventual consistency.
21
+ *
22
+ * Block+blobs (pre-fulu) and data columns (fulu+) are written in parallel.
13
23
  */
14
- export async function writeBlockInputToDb(this: BeaconChain, blocksInputs: IBlockInput[]): Promise<void> {
15
- const fnPromises: Promise<void>[] = [];
16
- // track slots for logging
17
- const slots: number[] = [];
18
-
19
- for (const blockInput of blocksInputs) {
20
- const block = blockInput.getBlock();
21
- const slot = block.message.slot;
22
- slots.push(slot);
23
- const blockRoot = this.config.getForkTypes(block.message.slot).BeaconBlock.hashTreeRoot(block.message);
24
- const blockRootHex = toRootHex(blockRoot);
25
- const blockBytes = this.serializedCache.get(block);
26
- if (blockBytes) {
27
- // skip serializing data if we already have it
28
- this.metrics?.importBlock.persistBlockWithSerializedDataCount.inc();
29
- fnPromises.push(this.db.block.putBinary(this.db.block.getId(block), blockBytes));
30
- } else {
31
- this.metrics?.importBlock.persistBlockNoSerializedDataCount.inc();
32
- fnPromises.push(this.db.block.add(block));
33
- }
24
+ export async function writeBlockInputToDb(this: BeaconChain, blockInput: IBlockInput): Promise<void> {
25
+ const promises: Promise<void>[] = [writeBlockAndBlobsToDb.call(this, blockInput)];
34
26
 
35
- this.logger.debug("Persist block to hot DB", {
36
- slot: block.message.slot,
37
- root: blockRootHex,
38
- inputType: blockInput.type,
39
- });
27
+ if (isBlockInputColumns(blockInput)) {
28
+ promises.push(writeDataColumnsToDb.call(this, blockInput));
29
+ }
40
30
 
41
- if (!blockInput.hasAllData()) {
42
- await blockInput.waitForAllData(BLOB_AVAILABILITY_TIMEOUT);
43
- }
31
+ await Promise.all(promises);
32
+ this.logger.debug("Persisted blockInput to db", {slot: blockInput.slot, root: blockInput.blockRootHex});
33
+ }
44
34
 
45
- // NOTE: Old data is pruned on archive
46
- if (isBlockInputColumns(blockInput)) {
47
- if (!blockInput.hasComputedAllData()) {
48
- // Supernodes may only have a subset of the data columns by the time the block begins to be imported
49
- // because full data availability can be assumed after NUMBER_OF_COLUMNS / 2 columns are available.
50
- // Here, however, all data columns must be fully available/reconstructed before persisting to the DB.
51
- await blockInput.waitForComputedAllData(BLOB_AVAILABILITY_TIMEOUT).catch(() => {
52
- this.logger.debug("Failed to wait for computed all data", {slot, blockRoot: blockRootHex});
53
- });
54
- }
35
+ async function writeBlockAndBlobsToDb(this: BeaconChain, blockInput: IBlockInput): Promise<void> {
36
+ const block = blockInput.getBlock();
37
+ const slot = block.message.slot;
38
+ const blockRoot = this.config.getForkTypes(slot).BeaconBlock.hashTreeRoot(block.message);
39
+ const blockRootHex = toRootHex(blockRoot);
40
+ const numBlobs = isForkPostDeneb(blockInput.forkName)
41
+ ? getBlobKzgCommitments(blockInput.forkName, block as SignedBeaconBlock<ForkPostDeneb>).length
42
+ : undefined;
43
+ const fnPromises: Promise<void>[] = [];
55
44
 
56
- const {custodyColumns} = this.custodyConfig;
57
- const blobsLen = (block.message as fulu.BeaconBlock).body.blobKzgCommitments.length;
58
- let dataColumnsLen: number;
59
- if (blobsLen === 0) {
60
- dataColumnsLen = 0;
61
- } else {
62
- dataColumnsLen = custodyColumns.length;
63
- }
45
+ const blockBytes = this.serializedCache.get(block);
46
+ if (blockBytes) {
47
+ // skip serializing data if we already have it
48
+ this.metrics?.importBlock.persistBlockWithSerializedDataCount.inc();
49
+ fnPromises.push(this.db.block.putBinary(this.db.block.getId(block), blockBytes));
50
+ } else {
51
+ this.metrics?.importBlock.persistBlockNoSerializedDataCount.inc();
52
+ fnPromises.push(this.db.block.add(block));
53
+ }
64
54
 
65
- const dataColumnSidecars = blockInput.getCustodyColumns();
66
- if (dataColumnSidecars.length !== dataColumnsLen) {
67
- this.logger.debug(
68
- `Invalid dataColumnSidecars=${dataColumnSidecars.length} for custody expected custodyColumnsLen=${dataColumnsLen}`
69
- );
70
- }
55
+ this.logger.debug("Persist block to hot DB", {slot, root: blockRootHex, inputType: blockInput.type, numBlobs});
71
56
 
72
- const binaryPuts = [];
73
- const nonbinaryPuts = [];
74
- for (const dataColumnSidecar of dataColumnSidecars) {
75
- // skip reserializing column if we already have it
76
- const serialized = this.serializedCache.get(dataColumnSidecar);
77
- if (serialized) {
78
- binaryPuts.push({key: dataColumnSidecar.index, value: serialized});
79
- } else {
80
- nonbinaryPuts.push(dataColumnSidecar);
57
+ if (isBlockInputBlobs(blockInput)) {
58
+ fnPromises.push(
59
+ (async () => {
60
+ if (!blockInput.hasAllData()) {
61
+ await blockInput.waitForAllData(BLOB_AVAILABILITY_TIMEOUT);
81
62
  }
82
- }
83
- fnPromises.push(this.db.dataColumnSidecar.putManyBinary(blockRoot, binaryPuts));
84
- fnPromises.push(this.db.dataColumnSidecar.putMany(blockRoot, nonbinaryPuts));
85
- this.logger.debug("Persisted dataColumnSidecars to hot DB", {
86
- slot: block.message.slot,
87
- root: blockRootHex,
88
- dataColumnSidecars: dataColumnSidecars.length,
89
- numBlobs: blobsLen,
90
- custodyColumns: custodyColumns.length,
91
- });
92
- } else if (isBlockInputBlobs(blockInput)) {
93
- const blobSidecars = blockInput.getBlobs();
94
- fnPromises.push(this.db.blobSidecars.add({blockRoot, slot: block.message.slot, blobSidecars}));
95
- this.logger.debug("Persisted blobSidecars to hot DB", {
96
- blobsLen: blobSidecars.length,
97
- slot: block.message.slot,
98
- root: blockRootHex,
99
- });
100
- }
63
+ const blobSidecars = blockInput.getBlobs();
64
+ await this.db.blobSidecars.add({blockRoot, slot, blobSidecars});
65
+ this.logger.debug("Persisted blobSidecars to hot DB", {
66
+ slot,
67
+ root: blockRootHex,
68
+ numBlobs: blobSidecars.length,
69
+ });
70
+ })()
71
+ );
72
+ }
101
73
 
102
- await Promise.all(fnPromises);
103
- this.logger.debug("Persisted blocksInput to db", {
104
- blocksInput: blocksInputs.length,
105
- slots: prettyPrintIndices(slots),
74
+ await Promise.all(fnPromises);
75
+ }
76
+
77
+ /**
78
+ * Persists data columns to DB for a given block. Accepts a narrow sub-interface of IBlockInput
79
+ * so it can be reused across forks (e.g. Fulu, Gloas).
80
+ *
81
+ * NOTE: Old data is pruned on archive.
82
+ */
83
+ export async function writeDataColumnsToDb(this: BeaconChain, blockInput: IDataColumnsInput): Promise<void> {
84
+ const {slot, blockRootHex} = blockInput;
85
+ const blockRoot = fromHex(blockRootHex);
86
+
87
+ if (!blockInput.hasComputedAllData()) {
88
+ // Supernodes may only have a subset of the data columns by the time the block begins to be imported
89
+ // because full data availability can be assumed after NUMBER_OF_COLUMNS / 2 columns are available.
90
+ // Here, however, all data columns must be fully available/reconstructed before persisting to the DB.
91
+ await blockInput.waitForComputedAllData(BLOB_AVAILABILITY_TIMEOUT).catch(() => {
92
+ this.logger.debug("Failed to wait for computed all data", {slot, blockRoot: blockRootHex});
106
93
  });
107
94
  }
95
+
96
+ const {custodyColumns} = this.custodyConfig;
97
+ const dataColumnSidecars = blockInput.getCustodyColumns();
98
+
99
+ const binaryPuts: {key: number; value: Uint8Array}[] = [];
100
+ const nonbinaryPuts = [];
101
+ for (const dataColumnSidecar of dataColumnSidecars) {
102
+ // skip reserializing column if we already have it
103
+ const serialized = this.serializedCache.get(dataColumnSidecar);
104
+ if (serialized) {
105
+ binaryPuts.push({key: dataColumnSidecar.index, value: serialized});
106
+ } else {
107
+ nonbinaryPuts.push(dataColumnSidecar);
108
+ }
109
+ }
110
+
111
+ await Promise.all([
112
+ this.db.dataColumnSidecar.putManyBinary(blockRoot, binaryPuts),
113
+ this.db.dataColumnSidecar.putMany(blockRoot, nonbinaryPuts),
114
+ ]);
115
+
116
+ this.logger.debug("Persisted dataColumnSidecars to hot DB", {
117
+ slot,
118
+ root: blockRootHex,
119
+ dataColumnSidecars: dataColumnSidecars.length,
120
+ custodyColumns: custodyColumns.length,
121
+ numBlobs: dataColumnSidecars[0]?.column.length,
122
+ });
108
123
  }
109
124
 
110
- export async function persistBlockInputs(this: BeaconChain, blockInputs: IBlockInput[]): Promise<void> {
125
+ export async function persistBlockInput(this: BeaconChain, blockInput: IBlockInput): Promise<void> {
111
126
  await writeBlockInputToDb
112
- .call(this, blockInputs)
127
+ .call(this, blockInput)
113
128
  .catch((e) => {
114
129
  this.logger.debug(
115
130
  "Error persisting block input in hot db",
116
131
  {
117
- count: blockInputs.length,
118
- slot: blockInputs[0].slot,
119
- root: blockInputs[0].blockRootHex,
132
+ slot: blockInput.slot,
133
+ root: blockInput.blockRootHex,
120
134
  },
121
135
  e
122
136
  );
123
137
  })
124
138
  .finally(() => {
125
- for (const blockInput of blockInputs) {
126
- this.seenBlockInputCache.prune(blockInput.blockRootHex);
127
- }
139
+ this.seenBlockInputCache.prune(blockInput.blockRootHex);
128
140
  // Without forcefully clearing this cache, we would rely on WeakMap to evict memory which is not reliable.
129
141
  // Clear here (after the DB write) so that writeBlockInputToDb can still use the cached serialized bytes.
130
- this.serializedCache.clear();
131
- if (blockInputs.length === 1) {
132
- this.logger.debug("Pruned block input", {
133
- slot: blockInputs[0].slot,
134
- root: blockInputs[0].blockRootHex,
135
- });
142
+ //
143
+ // For Gloas (BlockInputNoData), the execution payload and columns arrive separately after the beacon block.
144
+ // Do NOT clear the cache here — it must remain available for writeDataColumnsToDb when the payload arrives.
145
+ // The cache is cleared in the Gloas payload persistence path instead.
146
+ if (!isBlockInputNoData(blockInput)) {
147
+ // TODO: enhance this SerializedCache for Gloas because payload may not come
148
+ // see https://github.com/ChainSafe/lodestar/pull/8974#discussion_r2885598229
149
+ this.serializedCache.clear();
136
150
  }
151
+ this.logger.debug("Pruned block input", {
152
+ slot: blockInput.slot,
153
+ root: blockInput.blockRootHex,
154
+ });
137
155
  });
138
156
  }
@@ -7,7 +7,7 @@ import {Worker, spawn} from "@chainsafe/threads";
7
7
  self = undefined;
8
8
 
9
9
  import {PublicKey} from "@chainsafe/blst";
10
- import {ISignatureSet, Index2PubkeyCache} from "@lodestar/state-transition";
10
+ import {ISignatureSet, PubkeyCache} from "@lodestar/state-transition";
11
11
  import {Logger} from "@lodestar/utils";
12
12
  import {Metrics} from "../../../metrics/index.js";
13
13
  import {LinkedList} from "../../../util/array.js";
@@ -34,7 +34,7 @@ const workerDir = process.env.NODE_ENV === "test" ? "../../../../lib/chain/bls/m
34
34
  export type BlsMultiThreadWorkerPoolModules = {
35
35
  logger: Logger;
36
36
  metrics: Metrics | null;
37
- index2pubkey: Index2PubkeyCache;
37
+ pubkeyCache: PubkeyCache;
38
38
  };
39
39
 
40
40
  export type BlsMultiThreadWorkerPoolOptions = {
@@ -114,7 +114,7 @@ type WorkerDescriptor = {
114
114
  export class BlsMultiThreadWorkerPool implements IBlsVerifier {
115
115
  private readonly logger: Logger;
116
116
  private readonly metrics: Metrics | null;
117
- private readonly index2pubkey: Index2PubkeyCache;
117
+ private readonly pubkeyCache: PubkeyCache;
118
118
 
119
119
  private readonly workers: WorkerDescriptor[];
120
120
  private readonly jobs = new LinkedList<JobQueueItem>();
@@ -130,10 +130,10 @@ export class BlsMultiThreadWorkerPool implements IBlsVerifier {
130
130
  private workersBusy = 0;
131
131
 
132
132
  constructor(options: BlsMultiThreadWorkerPoolOptions, modules: BlsMultiThreadWorkerPoolModules) {
133
- const {logger, metrics, index2pubkey} = modules;
133
+ const {logger, metrics, pubkeyCache} = modules;
134
134
  this.logger = logger;
135
135
  this.metrics = metrics;
136
- this.index2pubkey = index2pubkey;
136
+ this.pubkeyCache = pubkeyCache;
137
137
  this.blsVerifyAllMultiThread = options.blsVerifyAllMultiThread ?? false;
138
138
 
139
139
  // Use compressed for herumi for now.
@@ -173,7 +173,7 @@ export class BlsMultiThreadWorkerPool implements IBlsVerifier {
173
173
  try {
174
174
  return verifySignatureSetsMaybeBatch(
175
175
  sets.map((set) => ({
176
- publicKey: getAggregatedPubkey(set, this.index2pubkey),
176
+ publicKey: getAggregatedPubkey(set, this.pubkeyCache),
177
177
  message: set.signingRoot.valueOf(),
178
178
  signature: set.signature,
179
179
  }))
@@ -398,7 +398,7 @@ export class BlsMultiThreadWorkerPool implements IBlsVerifier {
398
398
  try {
399
399
  // Note: This can throw, must be handled per-job.
400
400
  // Pubkey and signature aggregation is defered here
401
- workReq = await jobItemWorkReq(job, this.index2pubkey, this.metrics);
401
+ workReq = await jobItemWorkReq(job, this.pubkeyCache, this.metrics);
402
402
  } catch (e) {
403
403
  this.metrics?.blsThreadPool.errorAggregateSignatureSetsCount.inc({type: job.type});
404
404
 
@@ -1,5 +1,5 @@
1
1
  import {PublicKey, asyncAggregateWithRandomness} from "@chainsafe/blst";
2
- import {ISignatureSet, Index2PubkeyCache, SignatureSetType} from "@lodestar/state-transition";
2
+ import {ISignatureSet, PubkeyCache, SignatureSetType} from "@lodestar/state-transition";
3
3
  import {Metrics} from "../../../metrics/metrics.js";
4
4
  import {LinkedList} from "../../../util/array.js";
5
5
  import {VerifySignatureOpts} from "../interface.js";
@@ -50,7 +50,7 @@ export function jobItemSigSets(job: JobQueueItem): number {
50
50
  */
51
51
  export async function jobItemWorkReq(
52
52
  job: JobQueueItem,
53
- index2pubkey: Index2PubkeyCache,
53
+ pubkeyCache: PubkeyCache,
54
54
  metrics: Metrics | null
55
55
  ): Promise<BlsWorkReq> {
56
56
  switch (job.type) {
@@ -59,7 +59,7 @@ export async function jobItemWorkReq(
59
59
  opts: job.opts,
60
60
  sets: job.sets.map((set) => ({
61
61
  // this can throw, handled in the consumer code
62
- publicKey: getAggregatedPubkey(set, index2pubkey, metrics).toBytes(),
62
+ publicKey: getAggregatedPubkey(set, pubkeyCache, metrics).toBytes(),
63
63
  signature: set.signature,
64
64
  message: set.signingRoot,
65
65
  })),
@@ -1,5 +1,5 @@
1
1
  import {PublicKey, Signature, aggregatePublicKeys, aggregateSignatures, verify} from "@chainsafe/blst";
2
- import {ISignatureSet, Index2PubkeyCache} from "@lodestar/state-transition";
2
+ import {ISignatureSet, PubkeyCache} from "@lodestar/state-transition";
3
3
  import {Metrics} from "../../metrics/index.js";
4
4
  import {IBlsVerifier} from "./interface.js";
5
5
  import {verifySignatureSetsMaybeBatch} from "./maybeBatch.js";
@@ -7,18 +7,18 @@ import {getAggregatedPubkey, getAggregatedPubkeysCount} from "./utils.js";
7
7
 
8
8
  export class BlsSingleThreadVerifier implements IBlsVerifier {
9
9
  private readonly metrics: Metrics | null;
10
- private readonly index2pubkey: Index2PubkeyCache;
10
+ private readonly pubkeyCache: PubkeyCache;
11
11
 
12
- constructor({metrics = null, index2pubkey}: {metrics: Metrics | null; index2pubkey: Index2PubkeyCache}) {
12
+ constructor({metrics = null, pubkeyCache}: {metrics: Metrics | null; pubkeyCache: PubkeyCache}) {
13
13
  this.metrics = metrics;
14
- this.index2pubkey = index2pubkey;
14
+ this.pubkeyCache = pubkeyCache;
15
15
  }
16
16
 
17
17
  async verifySignatureSets(sets: ISignatureSet[]): Promise<boolean> {
18
18
  this.metrics?.bls.aggregatedPubkeys.inc(getAggregatedPubkeysCount(sets));
19
19
 
20
20
  const setsAggregated = sets.map((set) => ({
21
- publicKey: getAggregatedPubkey(set, this.index2pubkey, this.metrics),
21
+ publicKey: getAggregatedPubkey(set, this.pubkeyCache, this.metrics),
22
22
  message: set.signingRoot,
23
23
  signature: set.signature,
24
24
  }));
@@ -1,22 +1,25 @@
1
1
  import {PublicKey, aggregatePublicKeys} from "@chainsafe/blst";
2
- import {ISignatureSet, Index2PubkeyCache, SignatureSetType} from "@lodestar/state-transition";
2
+ import {ISignatureSet, PubkeyCache, SignatureSetType} from "@lodestar/state-transition";
3
3
  import {Metrics} from "../../metrics/metrics.js";
4
4
 
5
5
  export function getAggregatedPubkey(
6
6
  signatureSet: ISignatureSet,
7
- index2pubkey: Index2PubkeyCache,
7
+ pubkeyCache: PubkeyCache,
8
8
  metrics: Metrics | null = null
9
9
  ): PublicKey {
10
10
  switch (signatureSet.type) {
11
11
  case SignatureSetType.single:
12
12
  return signatureSet.pubkey;
13
13
 
14
- case SignatureSetType.indexed:
15
- return index2pubkey[signatureSet.index];
14
+ case SignatureSetType.indexed: {
15
+ return pubkeyCache.getOrThrow(signatureSet.index);
16
+ }
16
17
 
17
18
  case SignatureSetType.aggregate: {
18
19
  const timer = metrics?.blsThreadPool.pubkeysAggregationMainThreadDuration.startTimer();
19
- const pubkeys = signatureSet.indices.map((i) => index2pubkey[i]);
20
+ const pubkeys = signatureSet.indices.map((i) => {
21
+ return pubkeyCache.getOrThrow(i);
22
+ });
20
23
  const aggregated = aggregatePublicKeys(pubkeys);
21
24
  timer?.();
22
25
  return aggregated;
@@ -1,9 +1,14 @@
1
1
  import path from "node:path";
2
2
  import {PrivateKey} from "@libp2p/interface";
3
- import {PubkeyIndexMap} from "@chainsafe/pubkey-index-map";
4
3
  import {CompositeTypeAny, TreeView, Type} from "@chainsafe/ssz";
5
4
  import {BeaconConfig} from "@lodestar/config";
6
- import {CheckpointWithHex, IForkChoice, ProtoBlock, UpdateHeadOpt} from "@lodestar/fork-choice";
5
+ import {
6
+ CheckpointWithHex,
7
+ CheckpointWithPayloadStatus,
8
+ IForkChoice,
9
+ ProtoBlock,
10
+ UpdateHeadOpt,
11
+ } from "@lodestar/fork-choice";
7
12
  import {LoggerNode} from "@lodestar/logger/node";
8
13
  import {
9
14
  BUILDER_INDEX_SELF_BUILD,
@@ -21,7 +26,7 @@ import {
21
26
  CachedBeaconStateGloas,
22
27
  EffectiveBalanceIncrements,
23
28
  EpochShuffling,
24
- Index2PubkeyCache,
29
+ PubkeyCache,
25
30
  computeAnchorCheckpoint,
26
31
  computeAttestationsRewards,
27
32
  computeBlockRewards,
@@ -78,7 +83,7 @@ import {CheckpointBalancesCache} from "./balancesCache.js";
78
83
  import {BeaconProposerCache} from "./beaconProposerCache.js";
79
84
  import {IBlockInput, isBlockInputBlobs, isBlockInputColumns} from "./blocks/blockInput/index.js";
80
85
  import {BlockProcessor, ImportBlockOpts} from "./blocks/index.js";
81
- import {persistBlockInputs} from "./blocks/writeBlockInputToDb.ts";
86
+ import {persistBlockInput} from "./blocks/writeBlockInputToDb.ts";
82
87
  import {BlsMultiThreadWorkerPool, BlsSingleThreadVerifier, IBlsVerifier} from "./bls/index.js";
83
88
  import {ColumnReconstructionTracker} from "./ColumnReconstructionTracker.js";
84
89
  import {ChainEvent, ChainEventEmitter} from "./emitter.js";
@@ -165,7 +170,7 @@ export class BeaconChain implements IBeaconChain {
165
170
  readonly lightClientServer?: LightClientServer;
166
171
  readonly reprocessController: ReprocessController;
167
172
  readonly archiveStore: ArchiveStore;
168
- readonly unfinalizedBlockWrites: JobItemQueue<[IBlockInput[]], void>;
173
+ readonly unfinalizedBlockWrites: JobItemQueue<[IBlockInput], void>;
169
174
 
170
175
  // Ops pool
171
176
  readonly attestationPool: AttestationPool;
@@ -192,8 +197,7 @@ export class BeaconChain implements IBeaconChain {
192
197
  readonly seenBlockAttesters = new SeenBlockAttesters();
193
198
 
194
199
  // Global state caches
195
- readonly pubkey2index: PubkeyIndexMap;
196
- readonly index2pubkey: Index2PubkeyCache;
200
+ readonly pubkeyCache: PubkeyCache;
197
201
 
198
202
  readonly beaconProposerCache: BeaconProposerCache;
199
203
  readonly checkpointBalancesCache: CheckpointBalancesCache;
@@ -239,8 +243,7 @@ export class BeaconChain implements IBeaconChain {
239
243
  {
240
244
  privateKey,
241
245
  config,
242
- pubkey2index,
243
- index2pubkey,
246
+ pubkeyCache,
244
247
  db,
245
248
  dbName,
246
249
  dataDir,
@@ -256,8 +259,7 @@ export class BeaconChain implements IBeaconChain {
256
259
  }: {
257
260
  privateKey: PrivateKey;
258
261
  config: BeaconConfig;
259
- pubkey2index: PubkeyIndexMap;
260
- index2pubkey: Index2PubkeyCache;
262
+ pubkeyCache: PubkeyCache;
261
263
  db: IBeaconDb;
262
264
  dbName: string;
263
265
  dataDir: string;
@@ -289,8 +291,8 @@ export class BeaconChain implements IBeaconChain {
289
291
  const emitter = new ChainEventEmitter();
290
292
  // by default, verify signatures on both main threads and worker threads
291
293
  const bls = opts.blsVerifyAllMainThread
292
- ? new BlsSingleThreadVerifier({metrics, index2pubkey})
293
- : new BlsMultiThreadWorkerPool(opts, {logger, metrics, index2pubkey});
294
+ ? new BlsSingleThreadVerifier({metrics, pubkeyCache})
295
+ : new BlsMultiThreadWorkerPool(opts, {logger, metrics, pubkeyCache});
294
296
 
295
297
  if (!clock) clock = new Clock({config, genesisTime: this.genesisTime, signal});
296
298
 
@@ -346,8 +348,7 @@ export class BeaconChain implements IBeaconChain {
346
348
  ]);
347
349
 
348
350
  // Global cache of validators pubkey/index mapping
349
- this.pubkey2index = pubkey2index;
350
- this.index2pubkey = index2pubkey;
351
+ this.pubkeyCache = pubkeyCache;
351
352
 
352
353
  const fileDataStore = opts.nHistoricalStatesFileDataStore ?? true;
353
354
  const blockStateCache = new FIFOBlockStateCache(this.opts, {metrics});
@@ -434,7 +435,7 @@ export class BeaconChain implements IBeaconChain {
434
435
  );
435
436
 
436
437
  this.unfinalizedBlockWrites = new JobItemQueue(
437
- persistBlockInputs.bind(this),
438
+ persistBlockInput.bind(this),
438
439
  {
439
440
  maxLength: DEFAULT_MAX_PENDING_UNFINALIZED_BLOCK_WRITES,
440
441
  signal,
@@ -605,7 +606,7 @@ export class BeaconChain implements IBeaconChain {
605
606
  ): Promise<{state: CachedBeaconStateAllForks | Uint8Array; executionOptimistic: boolean; finalized: boolean} | null> {
606
607
  if (opts?.allowRegen) {
607
608
  const state = await this.regen.getState(stateRoot, RegenCaller.restApi);
608
- const block = this.forkChoice.getBlock(state.latestBlockHeader.hashTreeRoot());
609
+ const block = this.forkChoice.getBlockDefaultStatus(state.latestBlockHeader.hashTreeRoot());
609
610
  const finalizedEpoch = this.forkChoice.getFinalizedCheckpoint().epoch;
610
611
  return {
611
612
  state,
@@ -621,7 +622,7 @@ export class BeaconChain implements IBeaconChain {
621
622
  // TODO: This is very inneficient for debug requests of serialized content, since it deserializes to serialize again
622
623
  const cachedStateCtx = this.regen.getStateSync(stateRoot);
623
624
  if (cachedStateCtx) {
624
- const block = this.forkChoice.getBlock(cachedStateCtx.latestBlockHeader.hashTreeRoot());
625
+ const block = this.forkChoice.getBlockDefaultStatus(cachedStateCtx.latestBlockHeader.hashTreeRoot());
625
626
  const finalizedEpoch = this.forkChoice.getFinalizedCheckpoint().epoch;
626
627
  return {
627
628
  state: cachedStateCtx,
@@ -655,7 +656,7 @@ export class BeaconChain implements IBeaconChain {
655
656
  // finalized or justified checkpoint states maynot be available with PersistentCheckpointStateCache, use getCheckpointStateOrBytes() api to get Uint8Array
656
657
  const cachedStateCtx = this.regen.getCheckpointStateSync(checkpoint);
657
658
  if (cachedStateCtx) {
658
- const block = this.forkChoice.getBlock(cachedStateCtx.latestBlockHeader.hashTreeRoot());
659
+ const block = this.forkChoice.getBlockDefaultStatus(cachedStateCtx.latestBlockHeader.hashTreeRoot());
659
660
  const finalizedEpoch = this.forkChoice.getFinalizedCheckpoint().epoch;
660
661
  return {
661
662
  state: cachedStateCtx,
@@ -672,7 +673,7 @@ export class BeaconChain implements IBeaconChain {
672
673
  ): Promise<{state: CachedBeaconStateAllForks | Uint8Array; executionOptimistic: boolean; finalized: boolean} | null> {
673
674
  const cachedStateCtx = await this.regen.getCheckpointStateOrBytes(checkpoint);
674
675
  if (cachedStateCtx) {
675
- const block = this.forkChoice.getBlock(checkpoint.root);
676
+ const block = this.forkChoice.getBlockDefaultStatus(checkpoint.root);
676
677
  const finalizedEpoch = this.forkChoice.getFinalizedCheckpoint().epoch;
677
678
  return {
678
679
  state: cachedStateCtx,
@@ -716,7 +717,7 @@ export class BeaconChain implements IBeaconChain {
716
717
  async getBlockByRoot(
717
718
  root: string
718
719
  ): Promise<{block: SignedBeaconBlock; executionOptimistic: boolean; finalized: boolean} | null> {
719
- const block = this.forkChoice.getBlockHex(root);
720
+ const block = this.forkChoice.getBlockHexDefaultStatus(root);
720
721
  if (block) {
721
722
  // Block found in fork-choice.
722
723
  // It may be in the block input cache, awaiting full DA reconstruction, check there first
@@ -740,7 +741,7 @@ export class BeaconChain implements IBeaconChain {
740
741
  async getSerializedBlockByRoot(
741
742
  root: string
742
743
  ): Promise<{block: Uint8Array; executionOptimistic: boolean; finalized: boolean; slot: Slot} | null> {
743
- const block = this.forkChoice.getBlockHex(root);
744
+ const block = this.forkChoice.getBlockHexDefaultStatus(root);
744
745
  if (block) {
745
746
  // Block found in fork-choice.
746
747
  // It may be in the block input cache, awaiting full DA reconstruction, check there first
@@ -920,7 +921,7 @@ export class BeaconChain implements IBeaconChain {
920
921
  RegenCaller.produceBlock
921
922
  );
922
923
  const proposerIndex = state.epochCtx.getBeaconProposer(slot);
923
- const proposerPubKey = this.index2pubkey[proposerIndex].toBytes();
924
+ const proposerPubKey = this.pubkeyCache.getOrThrow(proposerIndex).toBytes();
924
925
 
925
926
  const {body, produceResult, executionPayloadValue, shouldOverrideBuilder} = await produceBlockBody.call(
926
927
  this,
@@ -1191,7 +1192,7 @@ export class BeaconChain implements IBeaconChain {
1191
1192
  * @param blockState state that declares justified checkpoint `checkpoint`
1192
1193
  */
1193
1194
  private justifiedBalancesGetter(
1194
- checkpoint: CheckpointWithHex,
1195
+ checkpoint: CheckpointWithPayloadStatus,
1195
1196
  blockState: CachedBeaconStateAllForks
1196
1197
  ): EffectiveBalanceIncrements {
1197
1198
  this.metrics?.balancesCache.requests.inc();
@@ -1230,7 +1231,7 @@ export class BeaconChain implements IBeaconChain {
1230
1231
  * @param blockState state that declares justified checkpoint `checkpoint`
1231
1232
  */
1232
1233
  private closestJustifiedBalancesStateToCheckpoint(
1233
- checkpoint: CheckpointWithHex,
1234
+ checkpoint: CheckpointWithPayloadStatus,
1234
1235
  blockState: CachedBeaconStateAllForks
1235
1236
  ): {state: CachedBeaconStateAllForks; stateId: string; shouldWarn: boolean} {
1236
1237
  const state = this.regen.getCheckpointStateSync(checkpoint);
@@ -1244,7 +1245,10 @@ export class BeaconChain implements IBeaconChain {
1244
1245
  }
1245
1246
 
1246
1247
  // Find a state in the same branch of checkpoint at same epoch. Balances should exactly the same
1247
- for (const descendantBlock of this.forkChoice.forwardIterateDescendants(checkpoint.rootHex)) {
1248
+ for (const descendantBlock of this.forkChoice.forwardIterateDescendants(
1249
+ checkpoint.rootHex,
1250
+ checkpoint.payloadStatus
1251
+ )) {
1248
1252
  if (computeEpochAtSlot(descendantBlock.slot) === checkpoint.epoch) {
1249
1253
  const descendantBlockState = this.regen.getStateSync(descendantBlock.stateRoot);
1250
1254
  if (descendantBlockState) {
@@ -1260,7 +1264,10 @@ export class BeaconChain implements IBeaconChain {
1260
1264
 
1261
1265
  // Find a state in the same branch of checkpoint at a latter epoch. Balances are not the same, but should be close
1262
1266
  // Note: must call .forwardIterateDescendants() again since nodes are not sorted
1263
- for (const descendantBlock of this.forkChoice.forwardIterateDescendants(checkpoint.rootHex)) {
1267
+ for (const descendantBlock of this.forkChoice.forwardIterateDescendants(
1268
+ checkpoint.rootHex,
1269
+ checkpoint.payloadStatus
1270
+ )) {
1264
1271
  if (computeEpochAtSlot(descendantBlock.slot) > checkpoint.epoch) {
1265
1272
  const descendantBlockState = this.regen.getStateSync(descendantBlock.stateRoot);
1266
1273
  if (descendantBlockState) {
@@ -1536,7 +1543,7 @@ export class BeaconChain implements IBeaconChain {
1536
1543
  throw Error(`State is not in cache for slot ${slot}`);
1537
1544
  }
1538
1545
 
1539
- const rewards = await computeAttestationsRewards(this.config, this.pubkey2index, cachedState, validatorIds);
1546
+ const rewards = await computeAttestationsRewards(this.config, this.pubkeyCache, cachedState, validatorIds);
1540
1547
 
1541
1548
  return {rewards, executionOptimistic, finalized};
1542
1549
  }
@@ -1553,6 +1560,6 @@ export class BeaconChain implements IBeaconChain {
1553
1560
 
1554
1561
  preState = processSlots(preState, block.slot); // Dial preState's slot to block.slot
1555
1562
 
1556
- return computeSyncCommitteeRewards(this.config, this.index2pubkey, block, preState, validatorIds);
1563
+ return computeSyncCommitteeRewards(this.config, this.pubkeyCache, block, preState, validatorIds);
1557
1564
  }
1558
1565
  }
@@ -1,7 +1,7 @@
1
1
  import {EventEmitter} from "node:events";
2
2
  import {StrictEventEmitter} from "strict-event-emitter-types";
3
3
  import {routes} from "@lodestar/api";
4
- import {CheckpointWithHex} from "@lodestar/fork-choice";
4
+ import {CheckpointWithPayloadStatus} from "@lodestar/fork-choice";
5
5
  import {CachedBeaconStateAllForks} from "@lodestar/state-transition";
6
6
  import {DataColumnSidecars, RootHex, deneb, phase0} from "@lodestar/types";
7
7
  import {PeerIdStr} from "../util/peerId.js";
@@ -83,8 +83,8 @@ export type ChainEventData = {
83
83
  export type IChainEvents = ApiEvents & {
84
84
  [ChainEvent.checkpoint]: (checkpoint: phase0.Checkpoint, state: CachedBeaconStateAllForks) => void;
85
85
 
86
- [ChainEvent.forkChoiceJustified]: (checkpoint: CheckpointWithHex) => void;
87
- [ChainEvent.forkChoiceFinalized]: (checkpoint: CheckpointWithHex) => void;
86
+ [ChainEvent.forkChoiceJustified]: (checkpoint: CheckpointWithPayloadStatus) => void;
87
+ [ChainEvent.forkChoiceFinalized]: (checkpoint: CheckpointWithPayloadStatus) => void;
88
88
 
89
89
  [ChainEvent.updateTargetCustodyGroupCount]: (targetGroupCount: number) => void;
90
90
 
@@ -25,9 +25,13 @@ export type ExecutionPayloadEnvelopeErrorType =
25
25
  | {
26
26
  code: ExecutionPayloadEnvelopeErrorCode.BUILDER_INDEX_MISMATCH;
27
27
  envelopeBuilderIndex: BuilderIndex;
28
- bidBuilderIndex: BuilderIndex;
28
+ bidBuilderIndex: BuilderIndex | null;
29
+ }
30
+ | {
31
+ code: ExecutionPayloadEnvelopeErrorCode.BLOCK_HASH_MISMATCH;
32
+ envelopeBlockHash: RootHex;
33
+ bidBlockHash: RootHex | null;
29
34
  }
30
- | {code: ExecutionPayloadEnvelopeErrorCode.BLOCK_HASH_MISMATCH; envelopeBlockHash: RootHex; bidBlockHash: RootHex}
31
35
  | {code: ExecutionPayloadEnvelopeErrorCode.INVALID_SIGNATURE}
32
36
  | {code: ExecutionPayloadEnvelopeErrorCode.CACHE_FAIL; blockRoot: RootHex};
33
37