@lodestar/beacon-node 1.33.0 → 1.34.0-dev.083b7cce17

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 (305) hide show
  1. package/lib/api/impl/beacon/blocks/index.js +175 -56
  2. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  3. package/lib/api/impl/beacon/pool/index.js +5 -5
  4. package/lib/api/impl/beacon/pool/index.js.map +1 -1
  5. package/lib/api/impl/beacon/state/index.js +24 -17
  6. package/lib/api/impl/beacon/state/index.js.map +1 -1
  7. package/lib/api/impl/debug/index.d.ts +1 -1
  8. package/lib/api/impl/debug/index.js +24 -1
  9. package/lib/api/impl/debug/index.js.map +1 -1
  10. package/lib/api/impl/events/index.js +1 -1
  11. package/lib/api/impl/events/index.js.map +1 -1
  12. package/lib/api/impl/validator/index.js +72 -49
  13. package/lib/api/impl/validator/index.js.map +1 -1
  14. package/lib/api/impl/validator/utils.d.ts +3 -3
  15. package/lib/api/impl/validator/utils.js +2 -2
  16. package/lib/api/impl/validator/utils.js.map +1 -1
  17. package/lib/chain/archiveStore/archiveStore.d.ts +1 -1
  18. package/lib/chain/archiveStore/archiveStore.js +2 -2
  19. package/lib/chain/archiveStore/interface.d.ts +1 -1
  20. package/lib/chain/archiveStore/utils/archiveBlocks.d.ts +1 -1
  21. package/lib/chain/archiveStore/utils/archiveBlocks.js +91 -21
  22. package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
  23. package/lib/chain/beaconProposerCache.d.ts +1 -0
  24. package/lib/chain/beaconProposerCache.js +3 -0
  25. package/lib/chain/beaconProposerCache.js.map +1 -1
  26. package/lib/chain/blocks/importBlock.js +3 -2
  27. package/lib/chain/blocks/importBlock.js.map +1 -1
  28. package/lib/chain/blocks/types.d.ts +66 -23
  29. package/lib/chain/blocks/types.js +39 -5
  30. package/lib/chain/blocks/types.js.map +1 -1
  31. package/lib/chain/blocks/utils/blowfishBanner.js +1 -0
  32. package/lib/chain/blocks/utils/blowfishBanner.js.map +1 -1
  33. package/lib/chain/blocks/utils/giraffeBanner.js +1 -0
  34. package/lib/chain/blocks/utils/giraffeBanner.js.map +1 -1
  35. package/lib/chain/blocks/utils/zebraBanner.d.ts +2 -0
  36. package/lib/chain/blocks/utils/zebraBanner.js +46 -0
  37. package/lib/chain/blocks/utils/zebraBanner.js.map +1 -0
  38. package/lib/chain/blocks/verifyBlock.js +18 -5
  39. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  40. package/lib/chain/blocks/verifyBlocksDataAvailability.js +21 -10
  41. package/lib/chain/blocks/verifyBlocksDataAvailability.js.map +1 -1
  42. package/lib/chain/blocks/writeBlockInputToDb.js +63 -16
  43. package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
  44. package/lib/chain/bls/multithread/index.js +2 -2
  45. package/lib/chain/bls/multithread/index.js.map +1 -1
  46. package/lib/chain/chain.d.ts +18 -101
  47. package/lib/chain/chain.js +111 -78
  48. package/lib/chain/chain.js.map +1 -1
  49. package/lib/chain/emitter.d.ts +18 -2
  50. package/lib/chain/emitter.js +13 -0
  51. package/lib/chain/emitter.js.map +1 -1
  52. package/lib/chain/errors/dataColumnSidecarError.d.ts +69 -0
  53. package/lib/chain/errors/dataColumnSidecarError.js +21 -0
  54. package/lib/chain/errors/dataColumnSidecarError.js.map +1 -0
  55. package/lib/chain/errors/index.d.ts +1 -0
  56. package/lib/chain/errors/index.js +1 -0
  57. package/lib/chain/errors/index.js.map +1 -1
  58. package/lib/chain/forkChoice/index.d.ts +2 -1
  59. package/lib/chain/forkChoice/index.js +2 -2
  60. package/lib/chain/forkChoice/index.js.map +1 -1
  61. package/lib/chain/interface.d.ts +6 -7
  62. package/lib/chain/interface.js.map +1 -1
  63. package/lib/chain/opPools/aggregatedAttestationPool.js +13 -3
  64. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  65. package/lib/chain/opPools/attestationPool.d.ts +1 -1
  66. package/lib/chain/opPools/attestationPool.js +7 -7
  67. package/lib/chain/options.d.ts +4 -1
  68. package/lib/chain/options.js +1 -0
  69. package/lib/chain/options.js.map +1 -1
  70. package/lib/chain/prepareNextSlot.js +4 -2
  71. package/lib/chain/prepareNextSlot.js.map +1 -1
  72. package/lib/chain/produceBlock/produceBlockBody.d.ts +30 -16
  73. package/lib/chain/produceBlock/produceBlockBody.js +28 -28
  74. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  75. package/lib/chain/produceBlock/validateBlobsAndKzgCommitments.d.ts +6 -3
  76. package/lib/chain/produceBlock/validateBlobsAndKzgCommitments.js +28 -4
  77. package/lib/chain/produceBlock/validateBlobsAndKzgCommitments.js.map +1 -1
  78. package/lib/chain/rewards/syncCommitteeRewards.js +4 -4
  79. package/lib/chain/rewards/syncCommitteeRewards.js.map +1 -1
  80. package/lib/chain/seenCache/seenGossipBlockInput.d.ts +64 -18
  81. package/lib/chain/seenCache/seenGossipBlockInput.js +321 -53
  82. package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
  83. package/lib/chain/validation/aggregateAndProof.d.ts +1 -1
  84. package/lib/chain/validation/aggregateAndProof.js +8 -8
  85. package/lib/chain/validation/aggregateAndProof.js.map +1 -1
  86. package/lib/chain/validation/attestation.d.ts +3 -3
  87. package/lib/chain/validation/attestation.js +10 -10
  88. package/lib/chain/validation/attestation.js.map +1 -1
  89. package/lib/chain/validation/dataColumnSidecar.d.ts +29 -0
  90. package/lib/chain/validation/dataColumnSidecar.js +257 -0
  91. package/lib/chain/validation/dataColumnSidecar.js.map +1 -0
  92. package/lib/chain/validation/syncCommitteeContributionAndProof.js +2 -2
  93. package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
  94. package/lib/db/beacon.d.ts +3 -1
  95. package/lib/db/beacon.js +3 -1
  96. package/lib/db/beacon.js.map +1 -1
  97. package/lib/db/buckets.d.ts +3 -1
  98. package/lib/db/buckets.js +2 -0
  99. package/lib/db/buckets.js.map +1 -1
  100. package/lib/db/interface.d.ts +3 -1
  101. package/lib/db/repositories/dataColumnSidecar.d.ts +26 -0
  102. package/lib/db/repositories/dataColumnSidecar.js +39 -0
  103. package/lib/db/repositories/dataColumnSidecar.js.map +1 -0
  104. package/lib/db/repositories/dataColumnSidecarArchive.d.ts +24 -0
  105. package/lib/db/repositories/dataColumnSidecarArchive.js +39 -0
  106. package/lib/db/repositories/dataColumnSidecarArchive.js.map +1 -0
  107. package/lib/db/repositories/index.d.ts +2 -0
  108. package/lib/db/repositories/index.js +2 -0
  109. package/lib/db/repositories/index.js.map +1 -1
  110. package/lib/db/repositories/stateArchive.js +1 -1
  111. package/lib/db/repositories/stateArchive.js.map +1 -1
  112. package/lib/execution/builder/http.d.ts +20 -4
  113. package/lib/execution/builder/http.js +30 -11
  114. package/lib/execution/builder/http.js.map +1 -1
  115. package/lib/execution/builder/interface.d.ts +5 -4
  116. package/lib/execution/engine/http.d.ts +8 -5
  117. package/lib/execution/engine/http.js +65 -46
  118. package/lib/execution/engine/http.js.map +1 -1
  119. package/lib/execution/engine/interface.d.ts +6 -13
  120. package/lib/execution/engine/interface.js +1 -1
  121. package/lib/execution/engine/interface.js.map +1 -1
  122. package/lib/execution/engine/mock.d.ts +5 -1
  123. package/lib/execution/engine/mock.js +58 -15
  124. package/lib/execution/engine/mock.js.map +1 -1
  125. package/lib/execution/engine/types.d.ts +15 -5
  126. package/lib/execution/engine/types.js +8 -2
  127. package/lib/execution/engine/types.js.map +1 -1
  128. package/lib/execution/engine/utils.js +1 -1
  129. package/lib/execution/engine/utils.js.map +1 -1
  130. package/lib/metrics/metrics/beacon.d.ts +16 -28
  131. package/lib/metrics/metrics/beacon.js +66 -75
  132. package/lib/metrics/metrics/beacon.js.map +1 -1
  133. package/lib/metrics/metrics/lodestar.d.ts +31 -1
  134. package/lib/metrics/metrics/lodestar.js +63 -0
  135. package/lib/metrics/metrics/lodestar.js.map +1 -1
  136. package/lib/metrics/metrics.d.ts +2 -1
  137. package/lib/metrics/metrics.js +3 -0
  138. package/lib/metrics/metrics.js.map +1 -1
  139. package/lib/network/core/metrics.d.ts +10 -3
  140. package/lib/network/core/metrics.js +22 -4
  141. package/lib/network/core/metrics.js.map +1 -1
  142. package/lib/network/core/networkCore.d.ts +15 -4
  143. package/lib/network/core/networkCore.js +73 -24
  144. package/lib/network/core/networkCore.js.map +1 -1
  145. package/lib/network/core/networkCoreWorker.js +2 -0
  146. package/lib/network/core/networkCoreWorker.js.map +1 -1
  147. package/lib/network/core/networkCoreWorkerHandler.d.ts +5 -3
  148. package/lib/network/core/networkCoreWorkerHandler.js +7 -2
  149. package/lib/network/core/networkCoreWorkerHandler.js.map +1 -1
  150. package/lib/network/core/types.d.ts +7 -4
  151. package/lib/network/events.d.ts +4 -2
  152. package/lib/network/events.js.map +1 -1
  153. package/lib/network/gossip/gossipsub.d.ts +2 -2
  154. package/lib/network/gossip/gossipsub.js +8 -6
  155. package/lib/network/gossip/gossipsub.js.map +1 -1
  156. package/lib/network/gossip/interface.d.ts +8 -1
  157. package/lib/network/gossip/interface.js +1 -0
  158. package/lib/network/gossip/interface.js.map +1 -1
  159. package/lib/network/gossip/scoringParameters.d.ts +6 -2
  160. package/lib/network/gossip/scoringParameters.js.map +1 -1
  161. package/lib/network/gossip/topic.d.ts +2038 -1489
  162. package/lib/network/gossip/topic.js +29 -1
  163. package/lib/network/gossip/topic.js.map +1 -1
  164. package/lib/network/interface.d.ts +11 -3
  165. package/lib/network/metadata.d.ts +9 -5
  166. package/lib/network/metadata.js +26 -5
  167. package/lib/network/metadata.js.map +1 -1
  168. package/lib/network/network.d.ts +14 -4
  169. package/lib/network/network.js +73 -11
  170. package/lib/network/network.js.map +1 -1
  171. package/lib/network/networkConfig.d.ts +12 -0
  172. package/lib/network/networkConfig.js +2 -0
  173. package/lib/network/networkConfig.js.map +1 -0
  174. package/lib/network/options.d.ts +1 -0
  175. package/lib/network/options.js +7 -2
  176. package/lib/network/options.js.map +1 -1
  177. package/lib/network/peers/discover.d.ts +8 -3
  178. package/lib/network/peers/discover.js +99 -14
  179. package/lib/network/peers/discover.js.map +1 -1
  180. package/lib/network/peers/peerManager.d.ts +10 -4
  181. package/lib/network/peers/peerManager.js +108 -19
  182. package/lib/network/peers/peerManager.js.map +1 -1
  183. package/lib/network/peers/peersData.d.ts +17 -3
  184. package/lib/network/peers/peersData.js.map +1 -1
  185. package/lib/network/peers/score/interface.d.ts +1 -1
  186. package/lib/network/peers/score/score.d.ts +2 -2
  187. package/lib/network/peers/score/score.js +4 -1
  188. package/lib/network/peers/score/score.js.map +1 -1
  189. package/lib/network/peers/score/store.d.ts +3 -1
  190. package/lib/network/peers/score/store.js +6 -2
  191. package/lib/network/peers/score/store.js.map +1 -1
  192. package/lib/network/peers/utils/assertPeerRelevance.d.ts +7 -3
  193. package/lib/network/peers/utils/assertPeerRelevance.js +10 -1
  194. package/lib/network/peers/utils/assertPeerRelevance.js.map +1 -1
  195. package/lib/network/peers/utils/prioritizePeers.d.ts +19 -7
  196. package/lib/network/peers/utils/prioritizePeers.js +42 -6
  197. package/lib/network/peers/utils/prioritizePeers.js.map +1 -1
  198. package/lib/network/processor/extractSlotRootFns.js +8 -1
  199. package/lib/network/processor/extractSlotRootFns.js.map +1 -1
  200. package/lib/network/processor/gossipHandlers.js +172 -23
  201. package/lib/network/processor/gossipHandlers.js.map +1 -1
  202. package/lib/network/processor/gossipQueues/index.js +5 -0
  203. package/lib/network/processor/gossipQueues/index.js.map +1 -1
  204. package/lib/network/processor/index.js +1 -0
  205. package/lib/network/processor/index.js.map +1 -1
  206. package/lib/network/reqresp/ReqRespBeaconNode.d.ts +2 -2
  207. package/lib/network/reqresp/ReqRespBeaconNode.js +36 -14
  208. package/lib/network/reqresp/ReqRespBeaconNode.js.map +1 -1
  209. package/lib/network/reqresp/beaconBlocksMaybeBlobsByRange.d.ts +24 -4
  210. package/lib/network/reqresp/beaconBlocksMaybeBlobsByRange.js +261 -20
  211. package/lib/network/reqresp/beaconBlocksMaybeBlobsByRange.js.map +1 -1
  212. package/lib/network/reqresp/beaconBlocksMaybeBlobsByRoot.d.ts +37 -6
  213. package/lib/network/reqresp/beaconBlocksMaybeBlobsByRoot.js +283 -28
  214. package/lib/network/reqresp/beaconBlocksMaybeBlobsByRoot.js.map +1 -1
  215. package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts +1 -1
  216. package/lib/network/reqresp/handlers/beaconBlocksByRange.js +3 -3
  217. package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
  218. package/lib/network/reqresp/handlers/beaconBlocksByRoot.d.ts +2 -2
  219. package/lib/network/reqresp/handlers/beaconBlocksByRoot.js.map +1 -1
  220. package/lib/network/reqresp/handlers/blobSidecarsByRange.d.ts +2 -2
  221. package/lib/network/reqresp/handlers/blobSidecarsByRange.js +2 -3
  222. package/lib/network/reqresp/handlers/blobSidecarsByRange.js.map +1 -1
  223. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts +8 -0
  224. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +113 -0
  225. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -0
  226. package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.d.ts +6 -0
  227. package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js +64 -0
  228. package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js.map +1 -0
  229. package/lib/network/reqresp/handlers/index.js +13 -2
  230. package/lib/network/reqresp/handlers/index.js.map +1 -1
  231. package/lib/network/reqresp/protocols.d.ts +4 -0
  232. package/lib/network/reqresp/protocols.js +20 -0
  233. package/lib/network/reqresp/protocols.js.map +1 -1
  234. package/lib/network/reqresp/rateLimit.js +19 -3
  235. package/lib/network/reqresp/rateLimit.js.map +1 -1
  236. package/lib/network/reqresp/score.js +3 -0
  237. package/lib/network/reqresp/score.js.map +1 -1
  238. package/lib/network/reqresp/types.d.ts +13 -6
  239. package/lib/network/reqresp/types.js +14 -5
  240. package/lib/network/reqresp/types.js.map +1 -1
  241. package/lib/network/reqresp/utils/dataColumnResponseValidation.d.ts +16 -0
  242. package/lib/network/reqresp/utils/dataColumnResponseValidation.js +59 -0
  243. package/lib/network/reqresp/utils/dataColumnResponseValidation.js.map +1 -0
  244. package/lib/network/statusCache.d.ts +5 -5
  245. package/lib/network/statusCache.js.map +1 -1
  246. package/lib/network/subnets/interface.d.ts +3 -0
  247. package/lib/network/subnets/interface.js +14 -1
  248. package/lib/network/subnets/interface.js.map +1 -1
  249. package/lib/network/subnets/syncnetsService.js +4 -5
  250. package/lib/network/subnets/syncnetsService.js.map +1 -1
  251. package/lib/node/nodejs.js +1 -0
  252. package/lib/node/nodejs.js.map +1 -1
  253. package/lib/sync/backfill/backfill.js +1 -1
  254. package/lib/sync/backfill/backfill.js.map +1 -1
  255. package/lib/sync/constants.d.ts +18 -3
  256. package/lib/sync/constants.js +21 -3
  257. package/lib/sync/constants.js.map +1 -1
  258. package/lib/sync/interface.d.ts +2 -2
  259. package/lib/sync/interface.js +1 -1
  260. package/lib/sync/interface.js.map +1 -1
  261. package/lib/sync/range/batch.d.ts +17 -2
  262. package/lib/sync/range/batch.js +39 -7
  263. package/lib/sync/range/batch.js.map +1 -1
  264. package/lib/sync/range/chain.d.ts +15 -1
  265. package/lib/sync/range/chain.js +124 -33
  266. package/lib/sync/range/chain.js.map +1 -1
  267. package/lib/sync/range/range.d.ts +3 -2
  268. package/lib/sync/range/range.js +9 -3
  269. package/lib/sync/range/range.js.map +1 -1
  270. package/lib/sync/range/utils/chainTarget.d.ts +5 -1
  271. package/lib/sync/range/utils/chainTarget.js +26 -1
  272. package/lib/sync/range/utils/chainTarget.js.map +1 -1
  273. package/lib/sync/range/utils/peerBalancer.d.ts +19 -5
  274. package/lib/sync/range/utils/peerBalancer.js +104 -10
  275. package/lib/sync/range/utils/peerBalancer.js.map +1 -1
  276. package/lib/sync/sync.js +1 -1
  277. package/lib/sync/sync.js.map +1 -1
  278. package/lib/sync/unknownBlock.d.ts +54 -5
  279. package/lib/sync/unknownBlock.js +321 -61
  280. package/lib/sync/unknownBlock.js.map +1 -1
  281. package/lib/sync/utils/remoteSyncType.d.ts +4 -4
  282. package/lib/sync/utils/remoteSyncType.js.map +1 -1
  283. package/lib/util/blobs.d.ts +16 -4
  284. package/lib/util/blobs.js +122 -5
  285. package/lib/util/blobs.js.map +1 -1
  286. package/lib/util/dataColumns.d.ts +137 -0
  287. package/lib/util/dataColumns.js +362 -0
  288. package/lib/util/dataColumns.js.map +1 -0
  289. package/lib/util/metadata.d.ts +5 -0
  290. package/lib/util/metadata.js +10 -0
  291. package/lib/util/metadata.js.map +1 -1
  292. package/lib/util/queue/fnQueue.js +1 -1
  293. package/lib/util/queue/fnQueue.js.map +1 -1
  294. package/lib/util/queue/itemQueue.js +1 -1
  295. package/lib/util/queue/itemQueue.js.map +1 -1
  296. package/lib/util/sszBytes.d.ts +3 -0
  297. package/lib/util/sszBytes.js +40 -0
  298. package/lib/util/sszBytes.js.map +1 -1
  299. package/lib/util/types.d.ts +7 -0
  300. package/lib/util/types.js +3 -0
  301. package/lib/util/types.js.map +1 -1
  302. package/package.json +19 -20
  303. package/lib/network/reqresp/handlers/status.d.ts +0 -4
  304. package/lib/network/reqresp/handlers/status.js +0 -11
  305. package/lib/network/reqresp/handlers/status.js.map +0 -1
@@ -3,15 +3,17 @@ import { CompositeTypeAny, TreeView, Type } from "@chainsafe/ssz";
3
3
  import { BeaconConfig } from "@lodestar/config";
4
4
  import { CheckpointWithHex, IForkChoice, ProtoBlock } from "@lodestar/fork-choice";
5
5
  import { BeaconStateAllForks, CachedBeaconStateAllForks, EpochShuffling, Index2PubkeyCache } from "@lodestar/state-transition";
6
- import { BeaconBlock, BlindedBeaconBlock, Epoch, Root, RootHex, SignedBeaconBlock, Slot, UintNum64, ValidatorIndex, Wei, deneb, phase0 } from "@lodestar/types";
6
+ import { BeaconBlock, BlindedBeaconBlock, Epoch, Root, RootHex, SignedBeaconBlock, Slot, Status, UintNum64, ValidatorIndex, Wei } from "@lodestar/types";
7
7
  import { Logger } from "@lodestar/utils";
8
8
  import { ProcessShutdownCallback } from "@lodestar/validator";
9
+ import { PrivateKey } from "@libp2p/interface";
9
10
  import { IBeaconDb } from "../db/index.js";
10
11
  import { IEth1ForBlockProduction } from "../eth1/index.js";
11
12
  import { IExecutionBuilder, IExecutionEngine } from "../execution/index.js";
12
13
  import { Metrics } from "../metrics/index.js";
13
14
  import { BufferPool } from "../util/bufferPool.js";
14
15
  import { IClock } from "../util/clock.js";
16
+ import { CustodyConfig } from "../util/dataColumns.js";
15
17
  import { SerializedCache } from "../util/serializedCache.js";
16
18
  import { ArchiveStore } from "./archiveStore/archiveStore.js";
17
19
  import { CheckpointBalancesCache } from "./balancesCache.js";
@@ -25,7 +27,7 @@ import { CommonBlockBody, IBeaconChain, ProposerPreparationData, StateGetOpts }
25
27
  import { LightClientServer } from "./lightClient/index.js";
26
28
  import { AggregatedAttestationPool, AttestationPool, OpPool, SyncCommitteeMessagePool, SyncContributionAndProofPool } from "./opPools/index.js";
27
29
  import { IChainOptions } from "./options.js";
28
- import { AssembledBlockType, BlockType } from "./produceBlock/index.js";
30
+ import { AssembledBlockType, BlockType, ProduceResult } from "./produceBlock/index.js";
29
31
  import { BlockAttributes } from "./produceBlock/produceBlockBody.js";
30
32
  import { QueuedStateRegenerator, RegenCaller } from "./regen/index.js";
31
33
  import { ReprocessController } from "./reprocess.js";
@@ -47,6 +49,7 @@ export declare class BeaconChain implements IBeaconChain {
47
49
  readonly executionEngine: IExecutionEngine;
48
50
  readonly executionBuilder?: IExecutionBuilder;
49
51
  readonly config: BeaconConfig;
52
+ readonly custodyConfig: CustodyConfig;
50
53
  readonly logger: Logger;
51
54
  readonly metrics: Metrics | null;
52
55
  readonly validatorMonitor: ValidatorMonitor | null;
@@ -80,92 +83,12 @@ export declare class BeaconChain implements IBeaconChain {
80
83
  readonly beaconProposerCache: BeaconProposerCache;
81
84
  readonly checkpointBalancesCache: CheckpointBalancesCache;
82
85
  readonly shufflingCache: ShufflingCache;
83
- /** Map keyed by executionPayload.blockHash of the block for those blobs */
84
- readonly producedContentsCache: Map<string, deneb.Contents>;
85
- readonly producedBlockRoot: Map<string, import("@chainsafe/ssz").ValueOfFields<{
86
- transactions: import("@chainsafe/ssz").ListCompositeType<import("@chainsafe/ssz").ByteListType>;
87
- parentHash: import("@chainsafe/ssz").ByteVectorType;
88
- feeRecipient: import("@lodestar/types/lib/utils/executionAddress.js").ExecutionAddressType;
89
- stateRoot: import("@chainsafe/ssz").ByteVectorType;
90
- receiptsRoot: import("@chainsafe/ssz").ByteVectorType;
91
- logsBloom: import("@chainsafe/ssz").ByteVectorType;
92
- prevRandao: import("@chainsafe/ssz").ByteVectorType;
93
- blockNumber: import("@chainsafe/ssz").UintNumberType;
94
- gasLimit: import("@chainsafe/ssz").UintNumberType;
95
- gasUsed: import("@chainsafe/ssz").UintNumberType;
96
- timestamp: import("@chainsafe/ssz").UintNumberType;
97
- extraData: import("@chainsafe/ssz").ByteListType;
98
- baseFeePerGas: import("@chainsafe/ssz").UintBigintType;
99
- blockHash: import("@chainsafe/ssz").ByteVectorType;
100
- }> | import("@chainsafe/ssz").ValueOfFields<{
101
- withdrawals: import("@chainsafe/ssz").ListCompositeType<import("@chainsafe/ssz").ContainerType<{
102
- index: import("@chainsafe/ssz").UintNumberType;
103
- validatorIndex: import("@chainsafe/ssz").UintNumberType;
104
- address: import("@lodestar/types/lib/utils/executionAddress.js").ExecutionAddressType;
105
- amount: import("@chainsafe/ssz").UintBigintType;
106
- }>>;
107
- transactions: import("@chainsafe/ssz").ListCompositeType<import("@chainsafe/ssz").ByteListType>;
108
- parentHash: import("@chainsafe/ssz").ByteVectorType;
109
- feeRecipient: import("@lodestar/types/lib/utils/executionAddress.js").ExecutionAddressType;
110
- stateRoot: import("@chainsafe/ssz").ByteVectorType;
111
- receiptsRoot: import("@chainsafe/ssz").ByteVectorType;
112
- logsBloom: import("@chainsafe/ssz").ByteVectorType;
113
- prevRandao: import("@chainsafe/ssz").ByteVectorType;
114
- blockNumber: import("@chainsafe/ssz").UintNumberType;
115
- gasLimit: import("@chainsafe/ssz").UintNumberType;
116
- gasUsed: import("@chainsafe/ssz").UintNumberType;
117
- timestamp: import("@chainsafe/ssz").UintNumberType;
118
- extraData: import("@chainsafe/ssz").ByteListType;
119
- baseFeePerGas: import("@chainsafe/ssz").UintBigintType;
120
- blockHash: import("@chainsafe/ssz").ByteVectorType;
121
- }> | import("@chainsafe/ssz").ValueOfFields<{
122
- blobGasUsed: import("@chainsafe/ssz").UintBigintType;
123
- excessBlobGas: import("@chainsafe/ssz").UintBigintType;
124
- withdrawals: import("@chainsafe/ssz").ListCompositeType<import("@chainsafe/ssz").ContainerType<{
125
- index: import("@chainsafe/ssz").UintNumberType;
126
- validatorIndex: import("@chainsafe/ssz").UintNumberType;
127
- address: import("@lodestar/types/lib/utils/executionAddress.js").ExecutionAddressType;
128
- amount: import("@chainsafe/ssz").UintBigintType;
129
- }>>;
130
- transactions: import("@chainsafe/ssz").ListCompositeType<import("@chainsafe/ssz").ByteListType>;
131
- parentHash: import("@chainsafe/ssz").ByteVectorType;
132
- feeRecipient: import("@lodestar/types/lib/utils/executionAddress.js").ExecutionAddressType;
133
- stateRoot: import("@chainsafe/ssz").ByteVectorType;
134
- receiptsRoot: import("@chainsafe/ssz").ByteVectorType;
135
- logsBloom: import("@chainsafe/ssz").ByteVectorType;
136
- prevRandao: import("@chainsafe/ssz").ByteVectorType;
137
- blockNumber: import("@chainsafe/ssz").UintNumberType;
138
- gasLimit: import("@chainsafe/ssz").UintNumberType;
139
- gasUsed: import("@chainsafe/ssz").UintNumberType;
140
- timestamp: import("@chainsafe/ssz").UintNumberType;
141
- extraData: import("@chainsafe/ssz").ByteListType;
142
- baseFeePerGas: import("@chainsafe/ssz").UintBigintType;
143
- blockHash: import("@chainsafe/ssz").ByteVectorType;
144
- }> | import("@chainsafe/ssz").ValueOfFields<{
145
- blobGasUsed: import("@chainsafe/ssz").UintBigintType;
146
- excessBlobGas: import("@chainsafe/ssz").UintBigintType;
147
- withdrawals: import("@chainsafe/ssz").ListCompositeType<import("@chainsafe/ssz").ContainerType<{
148
- index: import("@chainsafe/ssz").UintNumberType;
149
- validatorIndex: import("@chainsafe/ssz").UintNumberType;
150
- address: import("@lodestar/types/lib/utils/executionAddress.js").ExecutionAddressType;
151
- amount: import("@chainsafe/ssz").UintBigintType;
152
- }>>;
153
- transactions: import("@chainsafe/ssz").ListCompositeType<import("@chainsafe/ssz").ByteListType>;
154
- parentHash: import("@chainsafe/ssz").ByteVectorType;
155
- feeRecipient: import("@lodestar/types/lib/utils/executionAddress.js").ExecutionAddressType;
156
- stateRoot: import("@chainsafe/ssz").ByteVectorType;
157
- receiptsRoot: import("@chainsafe/ssz").ByteVectorType;
158
- logsBloom: import("@chainsafe/ssz").ByteVectorType;
159
- prevRandao: import("@chainsafe/ssz").ByteVectorType;
160
- blockNumber: import("@chainsafe/ssz").UintNumberType;
161
- gasLimit: import("@chainsafe/ssz").UintNumberType;
162
- gasUsed: import("@chainsafe/ssz").UintNumberType;
163
- timestamp: import("@chainsafe/ssz").UintNumberType;
164
- extraData: import("@chainsafe/ssz").ByteListType;
165
- baseFeePerGas: import("@chainsafe/ssz").UintBigintType;
166
- blockHash: import("@chainsafe/ssz").ByteVectorType;
167
- }> | null>;
168
- readonly producedBlindedBlockRoot: Set<string>;
86
+ /**
87
+ * Cache produced results (ExecutionPayload, DA Data) from the local execution so that we can send
88
+ * and get signed/published blinded versions which beacon node can
89
+ * assemble into full blocks before publishing to the network.
90
+ */
91
+ readonly blockProductionCache: Map<string, ProduceResult>;
169
92
  readonly blacklistedBlocks: Map<RootHex, Slot | null>;
170
93
  readonly serializedCache: SerializedCache;
171
94
  readonly opts: IChainOptions;
@@ -173,7 +96,11 @@ export declare class BeaconChain implements IBeaconChain {
173
96
  protected readonly db: IBeaconDb;
174
97
  private abortController;
175
98
  private processShutdownCallback;
176
- constructor(opts: IChainOptions, { config, db, dbName, dataDir, logger, processShutdownCallback, clock, metrics, validatorMonitor, anchorState, eth1, executionEngine, executionBuilder, }: {
99
+ private _earliestAvailableSlot;
100
+ get earliestAvailableSlot(): Slot;
101
+ set earliestAvailableSlot(slot: Slot);
102
+ constructor(opts: IChainOptions, { privateKey, config, db, dbName, dataDir, logger, processShutdownCallback, clock, metrics, validatorMonitor, anchorState, eth1, executionEngine, executionBuilder, }: {
103
+ privateKey: PrivateKey;
177
104
  config: BeaconConfig;
178
105
  db: IBeaconDb;
179
106
  dbName: string;
@@ -261,20 +188,9 @@ export declare class BeaconChain implements IBeaconChain {
261
188
  consensusBlockValue: Wei;
262
189
  shouldOverrideBuilder?: boolean;
263
190
  }>;
264
- /**
265
- * https://github.com/ethereum/consensus-specs/blob/dev/specs/eip4844/validator.md#sidecar
266
- * def get_blobs_sidecar(block: BeaconBlock, blobs: Sequence[Blob]) -> BlobSidecars:
267
- * return BlobSidecars(
268
- * beacon_block_root=hash_tree_root(block),
269
- * beacon_block_slot=block.slot,
270
- * blobs=blobs,
271
- * kzg_aggregated_proof=compute_proof_from_blobs(blobs),
272
- * )
273
- */
274
- getContents(beaconBlock: deneb.BeaconBlock): deneb.Contents;
275
191
  processBlock(block: BlockInput, opts?: ImportBlockOpts): Promise<void>;
276
192
  processChainSegment(blocks: BlockInput[], opts?: ImportBlockOpts): Promise<void>;
277
- getStatus(): phase0.Status;
193
+ getStatus(): Status;
278
194
  recomputeForkChoiceHead(caller: ForkchoiceCaller): ProtoBlock;
279
195
  predictProposerHead(slot: Slot): ProtoBlock;
280
196
  getProposerHead(slot: Slot): ProtoBlock;
@@ -322,6 +238,7 @@ export declare class BeaconChain implements IBeaconChain {
322
238
  private onForkChoiceJustified;
323
239
  private onForkChoiceFinalized;
324
240
  updateBeaconProposerData(epoch: Epoch, proposers: ProposerPreparationData[]): Promise<void>;
241
+ private updateValidatorsCustodyRequirement;
325
242
  updateBuilderStatus(clockSlot: Slot): void;
326
243
  getBlockRewards(block: BeaconBlock | BlindedBeaconBlock): Promise<BlockRewards>;
327
244
  getAttestationsRewards(epoch: Epoch, validatorIds?: (ValidatorIndex | string)[]): Promise<{
@@ -1,13 +1,16 @@
1
1
  import path from "node:path";
2
2
  import { PubkeyIndexMap } from "@chainsafe/pubkey-index-map";
3
3
  import { ExecutionStatus, UpdateHeadOpt } from "@lodestar/fork-choice";
4
- import { ForkSeq, GENESIS_SLOT, SLOTS_PER_EPOCH, isForkPostElectra } from "@lodestar/params";
5
- import { computeAnchorCheckpoint, computeEndSlotAtEpoch, computeEpochAtSlot, computeStartSlotAtEpoch, createCachedBeaconState, getEffectiveBalanceIncrementsZeroInactive, isCachedBeaconState, processSlots, } from "@lodestar/state-transition";
4
+ import { EFFECTIVE_BALANCE_INCREMENT, GENESIS_SLOT, SLOTS_PER_EPOCH, isForkPostElectra } from "@lodestar/params";
5
+ import { computeAnchorCheckpoint, computeEndSlotAtEpoch, computeEpochAtSlot, computeStartSlotAtEpoch, createCachedBeaconState, getEffectiveBalanceIncrementsZeroInactive, getEffectiveBalancesFromStateBytes, isCachedBeaconState, processSlots, } from "@lodestar/state-transition";
6
6
  import { isBlindedBeaconBlock, } from "@lodestar/types";
7
7
  import { fromHex, gweiToWei, isErrorAborted, pruneSetToMax, sleep, toRootHex } from "@lodestar/utils";
8
8
  import { GENESIS_EPOCH, ZERO_HASH } from "../constants/index.js";
9
+ import { BuilderStatus } from "../execution/builder/http.js";
10
+ import { computeNodeIdFromPrivateKey } from "../network/subnets/interface.js";
9
11
  import { BufferPool } from "../util/bufferPool.js";
10
12
  import { Clock, ClockEvent } from "../util/clock.js";
13
+ import { CustodyConfig, getValidatorsCustodyRequirement } from "../util/dataColumns.js";
11
14
  import { ensureDir, writeIfNotExist } from "../util/file.js";
12
15
  import { isOptimisticBlock } from "../util/forkChoice.js";
13
16
  import { SerializedCache } from "../util/serializedCache.js";
@@ -18,12 +21,12 @@ import { BlockProcessor } from "./blocks/index.js";
18
21
  import { BlsMultiThreadWorkerPool, BlsSingleThreadVerifier } from "./bls/index.js";
19
22
  import { ChainEvent, ChainEventEmitter } from "./emitter.js";
20
23
  import { initializeForkChoice } from "./forkChoice/index.js";
21
- import { FindHeadFnName, } from "./interface.js";
24
+ import { FindHeadFnName } from "./interface.js";
22
25
  import { LightClientServer } from "./lightClient/index.js";
23
26
  import { AggregatedAttestationPool, AttestationPool, OpPool, SyncCommitteeMessagePool, SyncContributionAndProofPool, } from "./opPools/index.js";
24
27
  import { PrepareNextSlotScheduler } from "./prepareNextSlot.js";
25
28
  import { computeNewStateRoot } from "./produceBlock/computeNewStateRoot.js";
26
- import { BlobsResultType, BlockType } from "./produceBlock/index.js";
29
+ import { BlockType } from "./produceBlock/index.js";
27
30
  import { produceBlockBody, produceCommonBlockBody } from "./produceBlock/produceBlockBody.js";
28
31
  import { QueuedStateRegenerator, RegenCaller } from "./regen/index.js";
29
32
  import { ReprocessController } from "./reprocess.js";
@@ -44,29 +47,38 @@ import { FIFOBlockStateCache } from "./stateCache/fifoBlockStateCache.js";
44
47
  import { InMemoryCheckpointStateCache } from "./stateCache/inMemoryCheckpointsCache.js";
45
48
  import { PersistentCheckpointStateCache } from "./stateCache/persistentCheckpointsCache.js";
46
49
  /**
47
- * Arbitrary constants, blobs and payloads should be consumed immediately in the same slot
50
+ * The maximum number of cached produced results to keep in memory.
51
+ *
52
+ * Arbitrary constant. Blobs and payloads should be consumed immediately in the same slot
48
53
  * they are produced. A value of 1 would probably be sufficient. However it's sensible to
49
54
  * allow some margin if the node overloads.
50
55
  */
51
- const DEFAULT_MAX_CACHED_PRODUCED_ROOTS = 4;
56
+ const DEFAULT_MAX_CACHED_PRODUCED_RESULTS = 4;
52
57
  export class BeaconChain {
53
- constructor(opts, { config, db, dbName, dataDir, logger, processShutdownCallback, clock, metrics, validatorMonitor, anchorState, eth1, executionEngine, executionBuilder, }) {
58
+ get earliestAvailableSlot() {
59
+ return this._earliestAvailableSlot;
60
+ }
61
+ set earliestAvailableSlot(slot) {
62
+ if (this._earliestAvailableSlot !== slot) {
63
+ this._earliestAvailableSlot = slot;
64
+ this.emitter.emit(ChainEvent.updateStatus);
65
+ }
66
+ }
67
+ constructor(opts, { privateKey, config, db, dbName, dataDir, logger, processShutdownCallback, clock, metrics, validatorMonitor, anchorState, eth1, executionEngine, executionBuilder, }) {
54
68
  this.opPool = new OpPool();
55
69
  // Gossip seen cache
56
70
  this.seenAttesters = new SeenAttesters();
57
71
  this.seenAggregators = new SeenAggregators();
58
72
  this.seenBlockProposers = new SeenBlockProposers();
59
73
  this.seenSyncCommitteeMessages = new SeenSyncCommitteeMessages();
60
- this.seenGossipBlockInput = new SeenGossipBlockInput();
61
74
  // Seen cache for liveness checks
62
75
  this.seenBlockAttesters = new SeenBlockAttesters();
63
- /** Map keyed by executionPayload.blockHash of the block for those blobs */
64
- this.producedContentsCache = new Map();
65
- // Cache payloads from the local execution so that we can send
66
- // and get signed/published blinded versions which beacon node can
67
- // assemble into full blocks before publishing to the network.
68
- this.producedBlockRoot = new Map();
69
- this.producedBlindedBlockRoot = new Set();
76
+ /**
77
+ * Cache produced results (ExecutionPayload, DA Data) from the local execution so that we can send
78
+ * and get signed/published blinded versions which beacon node can
79
+ * assemble into full blocks before publishing to the network.
80
+ */
81
+ this.blockProductionCache = new Map();
70
82
  this.abortController = new AbortController();
71
83
  this.opts = opts;
72
84
  this.config = config;
@@ -98,6 +110,15 @@ export class BeaconChain {
98
110
  this.seenAggregatedAttestations = new SeenAggregatedAttestations(metrics);
99
111
  this.seenContributionAndProof = new SeenContributionAndProof(metrics);
100
112
  this.seenAttestationDatas = new SeenAttestationDatas(metrics, this.opts?.attDataCacheSlotDistance);
113
+ const nodeId = computeNodeIdFromPrivateKey(privateKey);
114
+ const initialCustodyGroupCount = opts.initialCustodyGroupCount ?? (opts.supernode ? config.NUMBER_OF_CUSTODY_GROUPS : config.CUSTODY_REQUIREMENT);
115
+ this.metrics?.peerDas.targetCustodyGroupCount.set(initialCustodyGroupCount);
116
+ this.custodyConfig = new CustodyConfig({
117
+ nodeId,
118
+ config,
119
+ initialCustodyGroupCount,
120
+ });
121
+ this.seenGossipBlockInput = new SeenGossipBlockInput(this.custodyConfig, this.executionEngine, emitter, clock, logger);
101
122
  this.beaconProposerCache = new BeaconProposerCache(opts);
102
123
  this.checkpointBalancesCache = new CheckpointBalancesCache();
103
124
  this.seenBlockInputCache = new SeenBlockInputCache({
@@ -120,6 +141,7 @@ export class BeaconChain {
120
141
  pubkey2index: new PubkeyIndexMap(),
121
142
  index2pubkey: [],
122
143
  });
144
+ this._earliestAvailableSlot = cachedState.slot;
123
145
  this.shufflingCache = cachedState.epochCtx.shufflingCache = new ShufflingCache(metrics, logger, this.opts, [
124
146
  {
125
147
  shuffling: cachedState.epochCtx.previousShuffling,
@@ -162,7 +184,7 @@ export class BeaconChain {
162
184
  blockStateCache.add(cachedState);
163
185
  blockStateCache.setHeadState(cachedState);
164
186
  checkpointStateCache.add(checkpoint, cachedState);
165
- const forkChoice = initializeForkChoice(config, emitter, clock.currentSlot, cachedState, opts, this.justifiedBalancesGetter.bind(this), logger);
187
+ const forkChoice = initializeForkChoice(config, emitter, clock.currentSlot, cachedState, opts, this.justifiedBalancesGetter.bind(this), metrics, logger);
166
188
  const regen = new QueuedStateRegenerator({
167
189
  config,
168
190
  forkChoice,
@@ -416,7 +438,7 @@ export class BeaconChain {
416
438
  const state = await this.regen.getBlockSlotState(toRootHex(parentBlockRoot), slot, { dontTransferCache: true }, RegenCaller.produceBlock);
417
439
  const proposerIndex = state.epochCtx.getBeaconProposer(slot);
418
440
  const proposerPubKey = state.epochCtx.index2pubkey[proposerIndex].toBytes();
419
- const { body, blobs, executionPayloadValue, shouldOverrideBuilder } = await produceBlockBody.call(this, blockType, state, {
441
+ const { body, produceResult, executionPayloadValue, shouldOverrideBuilder } = await produceBlockBody.call(this, blockType, state, {
420
442
  randaoReveal,
421
443
  graffiti,
422
444
  slot,
@@ -428,7 +450,7 @@ export class BeaconChain {
428
450
  commonBlockBodyPromise,
429
451
  });
430
452
  // The hashtree root computed here for debug log will get cached and hence won't introduce additional delays
431
- const bodyRoot = blockType === BlockType.Full
453
+ const bodyRoot = produceResult.type === BlockType.Full
432
454
  ? this.config.getForkTypes(slot).BeaconBlockBody.hashTreeRoot(body)
433
455
  : this.config
434
456
  .getPostBellatrixForkTypes(slot)
@@ -447,51 +469,15 @@ export class BeaconChain {
447
469
  };
448
470
  const { newStateRoot, proposerReward } = computeNewStateRoot(this.metrics, state, block);
449
471
  block.stateRoot = newStateRoot;
450
- const blockRoot = blockType === BlockType.Full
472
+ const blockRoot = produceResult.type === BlockType.Full
451
473
  ? this.config.getForkTypes(slot).BeaconBlock.hashTreeRoot(block)
452
474
  : this.config.getPostBellatrixForkTypes(slot).BlindedBeaconBlock.hashTreeRoot(block);
453
475
  const blockRootHex = toRootHex(blockRoot);
454
- // track the produced block for consensus broadcast validations
455
- if (blockType === BlockType.Full) {
456
- this.logger.debug("Setting executionPayload cache for produced block", { blockRootHex, slot, blockType });
457
- this.producedBlockRoot.set(blockRootHex, block.body.executionPayload ?? null);
458
- this.metrics?.blockProductionCaches.producedBlockRoot.set(this.producedBlockRoot.size);
459
- }
460
- else {
461
- this.logger.debug("Tracking the produced blinded block", { blockRootHex, slot, blockType });
462
- this.producedBlindedBlockRoot.add(blockRootHex);
463
- this.metrics?.blockProductionCaches.producedBlindedBlockRoot.set(this.producedBlindedBlockRoot.size);
464
- }
465
- // Cache for latter broadcasting
466
- //
467
- // blinded blobs will be fetched and added to this cache later before finally
468
- // publishing the blinded block's full version
469
- if (blobs.type === BlobsResultType.produced) {
470
- // body is of full type here
471
- const { blockHash, contents } = blobs;
472
- this.producedContentsCache.set(blockHash, contents);
473
- this.metrics?.blockProductionCaches.producedContentsCache.set(this.producedContentsCache.size);
474
- }
476
+ // Track the produced block for consensus broadcast validations, later validation, etc.
477
+ this.blockProductionCache.set(blockRootHex, produceResult);
478
+ this.metrics?.blockProductionCacheSize.set(this.blockProductionCache.size);
475
479
  return { block, executionPayloadValue, consensusBlockValue: gweiToWei(proposerReward), shouldOverrideBuilder };
476
480
  }
477
- /**
478
- * https://github.com/ethereum/consensus-specs/blob/dev/specs/eip4844/validator.md#sidecar
479
- * def get_blobs_sidecar(block: BeaconBlock, blobs: Sequence[Blob]) -> BlobSidecars:
480
- * return BlobSidecars(
481
- * beacon_block_root=hash_tree_root(block),
482
- * beacon_block_slot=block.slot,
483
- * blobs=blobs,
484
- * kzg_aggregated_proof=compute_proof_from_blobs(blobs),
485
- * )
486
- */
487
- getContents(beaconBlock) {
488
- const blockHash = toRootHex(beaconBlock.body.executionPayload.blockHash);
489
- const contents = this.producedContentsCache.get(blockHash);
490
- if (!contents) {
491
- throw Error(`No contents for executionPayload.blockHash ${blockHash}`);
492
- }
493
- return contents;
494
- }
495
481
  async processBlock(block, opts) {
496
482
  return this.blockProcessor.processBlocksJob([block], opts);
497
483
  }
@@ -514,6 +500,7 @@ export class BeaconChain {
514
500
  // TODO: PERFORMANCE: Memoize to prevent re-computing every time
515
501
  headRoot: fromHex(head.blockRoot),
516
502
  headSlot: head.slot,
503
+ earliestAvailableSlot: this._earliestAvailableSlot,
517
504
  };
518
505
  }
519
506
  recomputeForkChoiceHead(caller) {
@@ -744,16 +731,10 @@ export class BeaconChain {
744
731
  // syncContributionAndProofPool tracks metrics on its own
745
732
  metrics.opPool.blsToExecutionChangePoolSize.set(this.opPool.blsToExecutionChangeSize);
746
733
  metrics.chain.blacklistedBlocks.set(this.blacklistedBlocks.size);
747
- const forkChoiceMetrics = this.forkChoice.getMetrics();
748
- metrics.forkChoice.votes.set(forkChoiceMetrics.votes);
749
- metrics.forkChoice.queuedAttestations.set(forkChoiceMetrics.queuedAttestations);
750
- metrics.forkChoice.validatedAttestationDatas.set(forkChoiceMetrics.validatedAttestationDatas);
751
- metrics.forkChoice.balancesLength.set(forkChoiceMetrics.balancesLength);
752
- metrics.forkChoice.nodes.set(forkChoiceMetrics.nodes);
753
- metrics.forkChoice.indices.set(forkChoiceMetrics.indices);
754
- const fork = this.config.getForkName(this.clock.currentSlot);
734
+ const headState = this.getHeadState();
735
+ const fork = this.config.getForkName(headState.slot);
755
736
  if (isForkPostElectra(fork)) {
756
- const headStateElectra = this.getHeadState();
737
+ const headStateElectra = headState;
757
738
  metrics.pendingDeposits.set(headStateElectra.pendingDeposits.length);
758
739
  metrics.pendingPartialWithdrawals.set(headStateElectra.pendingPartialWithdrawals.length);
759
740
  metrics.pendingConsolidations.set(headStateElectra.pendingConsolidations.length);
@@ -774,14 +755,8 @@ export class BeaconChain {
774
755
  this.seenAttestationDatas.onSlot(slot);
775
756
  this.reprocessController.onSlot(slot);
776
757
  // Prune old cached block production artifacts, those are only useful on their slot
777
- pruneSetToMax(this.producedBlockRoot, this.opts.maxCachedProducedRoots ?? DEFAULT_MAX_CACHED_PRODUCED_ROOTS);
778
- this.metrics?.blockProductionCaches.producedBlockRoot.set(this.producedBlockRoot.size);
779
- pruneSetToMax(this.producedBlindedBlockRoot, this.opts.maxCachedProducedRoots ?? DEFAULT_MAX_CACHED_PRODUCED_ROOTS);
780
- this.metrics?.blockProductionCaches.producedBlindedBlockRoot.set(this.producedBlindedBlockRoot.size);
781
- if (this.config.getForkSeq(slot) >= ForkSeq.deneb) {
782
- pruneSetToMax(this.producedContentsCache, this.opts.maxCachedProducedRoots ?? DEFAULT_MAX_CACHED_PRODUCED_ROOTS);
783
- this.metrics?.blockProductionCaches.producedContentsCache.set(this.producedContentsCache.size);
784
- }
758
+ pruneSetToMax(this.blockProductionCache, this.opts.maxCachedProducedRoots ?? DEFAULT_MAX_CACHED_PRODUCED_RESULTS);
759
+ this.metrics?.blockProductionCacheSize.set(this.blockProductionCache.size);
785
760
  const metrics = this.metrics;
786
761
  if (metrics && (slot + 1) % SLOTS_PER_EPOCH === 0) {
787
762
  // On the last slot of the epoch
@@ -821,6 +796,8 @@ export class BeaconChain {
821
796
  async onForkChoiceFinalized(cp) {
822
797
  this.logger.verbose("Fork choice finalized", { epoch: cp.epoch, root: cp.rootHex });
823
798
  this.seenBlockProposers.prune(computeStartSlotAtEpoch(cp.epoch));
799
+ // Update validator custody to account for effective balance changes
800
+ await this.updateValidatorsCustodyRequirement(cp);
824
801
  // TODO: Improve using regen here
825
802
  const { blockRoot, stateRoot, slot } = this.forkChoice.getHead();
826
803
  const headState = this.regen.getStateSync(stateRoot);
@@ -836,9 +813,65 @@ export class BeaconChain {
836
813
  }
837
814
  }
838
815
  async updateBeaconProposerData(epoch, proposers) {
816
+ const previousValidatorCount = this.beaconProposerCache.getValidatorIndices().length;
839
817
  for (const proposer of proposers) {
840
818
  this.beaconProposerCache.add(epoch, proposer);
841
819
  }
820
+ const newValidatorCount = this.beaconProposerCache.getValidatorIndices().length;
821
+ // Only update validator custody if we discovered new validators
822
+ if (newValidatorCount > previousValidatorCount) {
823
+ const finalizedCheckpoint = this.forkChoice.getFinalizedCheckpoint();
824
+ await this.updateValidatorsCustodyRequirement(finalizedCheckpoint);
825
+ }
826
+ }
827
+ async updateValidatorsCustodyRequirement(finalizedCheckpoint) {
828
+ if (this.opts.supernode) {
829
+ // Disable dynamic custody updates for supernodes since they must maintain custody
830
+ // of all custody groups regardless of validator effective balances
831
+ return;
832
+ }
833
+ // Validators attached to the node
834
+ const validatorIndices = this.beaconProposerCache.getValidatorIndices();
835
+ // Update custody requirement based on finalized state
836
+ let effectiveBalances;
837
+ const effectiveBalanceIncrements = this.checkpointBalancesCache.get(finalizedCheckpoint);
838
+ if (effectiveBalanceIncrements) {
839
+ effectiveBalances = validatorIndices.map((index) => (effectiveBalanceIncrements[index] ?? 0) * EFFECTIVE_BALANCE_INCREMENT);
840
+ }
841
+ else {
842
+ // If there's no cached effective balances, get the state from disk and parse them out
843
+ this.logger.debug("No cached finalized effective balances to update target custody group count", {
844
+ finalizedEpoch: finalizedCheckpoint.epoch,
845
+ finalizedRoot: finalizedCheckpoint.rootHex,
846
+ });
847
+ const stateOrBytes = (await this.getStateOrBytesByCheckpoint(finalizedCheckpoint))?.state;
848
+ if (!stateOrBytes) {
849
+ // If even the state is not available, we cannot update the custody group count
850
+ this.logger.debug("No finalized state or bytes available to update target custody group count", {
851
+ finalizedEpoch: finalizedCheckpoint.epoch,
852
+ finalizedRoot: finalizedCheckpoint.rootHex,
853
+ });
854
+ return;
855
+ }
856
+ if (stateOrBytes instanceof Uint8Array) {
857
+ effectiveBalances = getEffectiveBalancesFromStateBytes(this.config, stateOrBytes, validatorIndices);
858
+ }
859
+ else {
860
+ effectiveBalances = validatorIndices.map((index) => stateOrBytes.validators.get(index).effectiveBalance ?? 0);
861
+ }
862
+ }
863
+ const targetCustodyGroupCount = getValidatorsCustodyRequirement(this.config, effectiveBalances);
864
+ // Only update if target is increased
865
+ if (targetCustodyGroupCount > this.custodyConfig.targetCustodyGroupCount) {
866
+ this.custodyConfig.updateTargetCustodyGroupCount(targetCustodyGroupCount);
867
+ this.metrics?.peerDas.targetCustodyGroupCount.set(targetCustodyGroupCount);
868
+ this.logger.verbose("Updated target custody group count", {
869
+ finalizedEpoch: finalizedCheckpoint.epoch,
870
+ validatorCount: validatorIndices.length,
871
+ targetCustodyGroupCount,
872
+ });
873
+ this.emitter.emit(ChainEvent.updateTargetCustodyGroupCount, targetCustodyGroupCount);
874
+ }
842
875
  }
843
876
  updateBuilderStatus(clockSlot) {
844
877
  const executionBuilder = this.executionBuilder;
@@ -847,7 +880,7 @@ export class BeaconChain {
847
880
  const slotsPresent = this.forkChoice.getSlotsPresent(clockSlot - faultInspectionWindow);
848
881
  const previousStatus = executionBuilder.status;
849
882
  const shouldEnable = slotsPresent >= Math.min(faultInspectionWindow - allowedFaults, clockSlot);
850
- executionBuilder.updateStatus(shouldEnable);
883
+ executionBuilder.updateStatus(shouldEnable ? BuilderStatus.enabled : BuilderStatus.circuitBreaker);
851
884
  // The status changed we should log
852
885
  const status = executionBuilder.status;
853
886
  const builderLog = {
@@ -857,10 +890,10 @@ export class BeaconChain {
857
890
  allowedFaults,
858
891
  };
859
892
  if (status !== previousStatus) {
860
- this.logger.info("Execution builder status updated", builderLog);
893
+ this.logger.info("External builder status updated", builderLog);
861
894
  }
862
895
  else {
863
- this.logger.verbose("Execution builder status", builderLog);
896
+ this.logger.verbose("External builder status", builderLog);
864
897
  }
865
898
  }
866
899
  }