@lodestar/beacon-node 1.41.0-dev.eb7efb2b90 → 1.41.0-dev.f225223000

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 (224) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +121 -3
  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 +5 -24
  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 +5 -2
  12. package/lib/api/impl/debug/index.js.map +1 -1
  13. package/lib/api/impl/lightclient/index.d.ts.map +1 -1
  14. package/lib/api/impl/lightclient/index.js +19 -2
  15. package/lib/api/impl/lightclient/index.js.map +1 -1
  16. package/lib/api/impl/validator/index.d.ts.map +1 -1
  17. package/lib/api/impl/validator/index.js +104 -6
  18. package/lib/api/impl/validator/index.js.map +1 -1
  19. package/lib/chain/archiveStore/archiveStore.d.ts +1 -0
  20. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  21. package/lib/chain/archiveStore/archiveStore.js +9 -0
  22. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  23. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts +5 -6
  24. package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
  25. package/lib/chain/archiveStore/historicalState/getHistoricalState.js +9 -10
  26. package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
  27. package/lib/chain/archiveStore/historicalState/worker.js +3 -3
  28. package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
  29. package/lib/chain/archiveStore/utils/archivePayloads.d.ts +7 -0
  30. package/lib/chain/archiveStore/utils/archivePayloads.d.ts.map +1 -0
  31. package/lib/chain/archiveStore/utils/archivePayloads.js +10 -0
  32. package/lib/chain/archiveStore/utils/archivePayloads.js.map +1 -0
  33. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  34. package/lib/chain/blocks/importBlock.js +0 -2
  35. package/lib/chain/blocks/importBlock.js.map +1 -1
  36. package/lib/chain/blocks/index.d.ts.map +1 -1
  37. package/lib/chain/blocks/index.js +2 -1
  38. package/lib/chain/blocks/index.js.map +1 -1
  39. package/lib/chain/blocks/writeBlockInputToDb.d.ts.map +1 -1
  40. package/lib/chain/blocks/writeBlockInputToDb.js +3 -0
  41. package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
  42. package/lib/chain/bls/multithread/index.d.ts +3 -3
  43. package/lib/chain/bls/multithread/index.d.ts.map +1 -1
  44. package/lib/chain/bls/multithread/index.js +5 -5
  45. package/lib/chain/bls/multithread/index.js.map +1 -1
  46. package/lib/chain/bls/multithread/jobItem.d.ts +2 -2
  47. package/lib/chain/bls/multithread/jobItem.d.ts.map +1 -1
  48. package/lib/chain/bls/multithread/jobItem.js +2 -2
  49. package/lib/chain/bls/multithread/jobItem.js.map +1 -1
  50. package/lib/chain/bls/singleThread.d.ts +4 -4
  51. package/lib/chain/bls/singleThread.d.ts.map +1 -1
  52. package/lib/chain/bls/singleThread.js +4 -4
  53. package/lib/chain/bls/singleThread.js.map +1 -1
  54. package/lib/chain/bls/utils.d.ts +2 -2
  55. package/lib/chain/bls/utils.d.ts.map +1 -1
  56. package/lib/chain/bls/utils.js +7 -4
  57. package/lib/chain/bls/utils.js.map +1 -1
  58. package/lib/chain/chain.d.ts +6 -9
  59. package/lib/chain/chain.d.ts.map +1 -1
  60. package/lib/chain/chain.js +32 -16
  61. package/lib/chain/chain.js.map +1 -1
  62. package/lib/chain/emitter.d.ts +2 -2
  63. package/lib/chain/emitter.d.ts.map +1 -1
  64. package/lib/chain/interface.d.ts +4 -6
  65. package/lib/chain/interface.d.ts.map +1 -1
  66. package/lib/chain/interface.js.map +1 -1
  67. package/lib/chain/lightClient/index.d.ts.map +1 -1
  68. package/lib/chain/lightClient/index.js +1 -1
  69. package/lib/chain/lightClient/index.js.map +1 -1
  70. package/lib/chain/options.d.ts.map +1 -1
  71. package/lib/chain/options.js.map +1 -1
  72. package/lib/chain/prepareNextSlot.js +3 -3
  73. package/lib/chain/prepareNextSlot.js.map +1 -1
  74. package/lib/chain/produceBlock/computeNewStateRoot.d.ts +10 -2
  75. package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
  76. package/lib/chain/produceBlock/computeNewStateRoot.js +24 -2
  77. package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
  78. package/lib/chain/produceBlock/produceBlockBody.d.ts +22 -7
  79. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  80. package/lib/chain/produceBlock/produceBlockBody.js +110 -10
  81. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  82. package/lib/chain/validation/attestation.d.ts.map +1 -1
  83. package/lib/chain/validation/attestation.js +4 -1
  84. package/lib/chain/validation/attestation.js.map +1 -1
  85. package/lib/chain/validation/attesterSlashing.js +1 -1
  86. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  87. package/lib/chain/validation/dataColumnSidecar.d.ts +2 -2
  88. package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
  89. package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
  90. package/lib/chain/validation/payloadAttestationMessage.js +8 -1
  91. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  92. package/lib/chain/validation/proposerSlashing.js +1 -1
  93. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  94. package/lib/chain/validation/syncCommitteeContributionAndProof.js +1 -1
  95. package/lib/db/beacon.d.ts +3 -1
  96. package/lib/db/beacon.d.ts.map +1 -1
  97. package/lib/db/beacon.js +5 -1
  98. package/lib/db/beacon.js.map +1 -1
  99. package/lib/db/buckets.d.ts +3 -1
  100. package/lib/db/buckets.d.ts.map +1 -1
  101. package/lib/db/buckets.js +2 -0
  102. package/lib/db/buckets.js.map +1 -1
  103. package/lib/db/interface.d.ts +3 -1
  104. package/lib/db/interface.d.ts.map +1 -1
  105. package/lib/db/repositories/blockArchiveIndex.d.ts +2 -2
  106. package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
  107. package/lib/db/repositories/dataColumnSidecar.d.ts +5 -3
  108. package/lib/db/repositories/dataColumnSidecar.d.ts.map +1 -1
  109. package/lib/db/repositories/dataColumnSidecar.js +14 -1
  110. package/lib/db/repositories/dataColumnSidecar.js.map +1 -1
  111. package/lib/db/repositories/dataColumnSidecarArchive.d.ts +5 -3
  112. package/lib/db/repositories/dataColumnSidecarArchive.d.ts.map +1 -1
  113. package/lib/db/repositories/dataColumnSidecarArchive.js +14 -1
  114. package/lib/db/repositories/dataColumnSidecarArchive.js.map +1 -1
  115. package/lib/db/repositories/executionPayloadEnvelope.d.ts +19 -0
  116. package/lib/db/repositories/executionPayloadEnvelope.d.ts.map +1 -0
  117. package/lib/db/repositories/executionPayloadEnvelope.js +22 -0
  118. package/lib/db/repositories/executionPayloadEnvelope.js.map +1 -0
  119. package/lib/db/repositories/executionPayloadEnvelopeArchive.d.ts +18 -0
  120. package/lib/db/repositories/executionPayloadEnvelopeArchive.d.ts.map +1 -0
  121. package/lib/db/repositories/executionPayloadEnvelopeArchive.js +28 -0
  122. package/lib/db/repositories/executionPayloadEnvelopeArchive.js.map +1 -0
  123. package/lib/db/repositories/index.d.ts +2 -0
  124. package/lib/db/repositories/index.d.ts.map +1 -1
  125. package/lib/db/repositories/index.js +2 -0
  126. package/lib/db/repositories/index.js.map +1 -1
  127. package/lib/metrics/metrics/beacon.d.ts +1 -0
  128. package/lib/metrics/metrics/beacon.d.ts.map +1 -1
  129. package/lib/metrics/metrics/beacon.js +5 -0
  130. package/lib/metrics/metrics/beacon.js.map +1 -1
  131. package/lib/metrics/metrics/lodestar.d.ts +5 -0
  132. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  133. package/lib/metrics/metrics/lodestar.js +9 -0
  134. package/lib/metrics/metrics/lodestar.js.map +1 -1
  135. package/lib/network/gossip/interface.d.ts +3 -3
  136. package/lib/network/gossip/interface.d.ts.map +1 -1
  137. package/lib/network/gossip/topic.d.ts +113 -63
  138. package/lib/network/gossip/topic.d.ts.map +1 -1
  139. package/lib/network/gossip/topic.js +2 -2
  140. package/lib/network/gossip/topic.js.map +1 -1
  141. package/lib/network/interface.d.ts +3 -2
  142. package/lib/network/interface.d.ts.map +1 -1
  143. package/lib/network/network.d.ts +3 -2
  144. package/lib/network/network.d.ts.map +1 -1
  145. package/lib/network/network.js +10 -1
  146. package/lib/network/network.js.map +1 -1
  147. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  148. package/lib/network/processor/gossipHandlers.js +5 -1
  149. package/lib/network/processor/gossipHandlers.js.map +1 -1
  150. package/lib/network/reqresp/handlers/lightClientUpdatesByRange.d.ts.map +1 -1
  151. package/lib/network/reqresp/handlers/lightClientUpdatesByRange.js +7 -1
  152. package/lib/network/reqresp/handlers/lightClientUpdatesByRange.js.map +1 -1
  153. package/lib/node/nodejs.d.ts +3 -5
  154. package/lib/node/nodejs.d.ts.map +1 -1
  155. package/lib/node/nodejs.js +2 -3
  156. package/lib/node/nodejs.js.map +1 -1
  157. package/lib/util/blobs.d.ts +2 -2
  158. package/lib/util/blobs.d.ts.map +1 -1
  159. package/lib/util/blobs.js.map +1 -1
  160. package/lib/util/dataColumns.d.ts +11 -3
  161. package/lib/util/dataColumns.d.ts.map +1 -1
  162. package/lib/util/dataColumns.js +27 -0
  163. package/lib/util/dataColumns.js.map +1 -1
  164. package/lib/util/multifork.d.ts +8 -0
  165. package/lib/util/multifork.d.ts.map +1 -1
  166. package/lib/util/multifork.js +37 -0
  167. package/lib/util/multifork.js.map +1 -1
  168. package/lib/util/serializedCache.d.ts +5 -0
  169. package/lib/util/serializedCache.d.ts.map +1 -1
  170. package/lib/util/serializedCache.js +5 -0
  171. package/lib/util/serializedCache.js.map +1 -1
  172. package/package.json +15 -15
  173. package/src/api/impl/beacon/blocks/index.ts +145 -2
  174. package/src/api/impl/beacon/state/index.ts +8 -8
  175. package/src/api/impl/beacon/state/utils.ts +15 -29
  176. package/src/api/impl/debug/index.ts +8 -5
  177. package/src/api/impl/lightclient/index.ts +19 -2
  178. package/src/api/impl/validator/index.ts +127 -5
  179. package/src/chain/archiveStore/archiveStore.ts +10 -0
  180. package/src/chain/archiveStore/historicalState/getHistoricalState.ts +10 -11
  181. package/src/chain/archiveStore/historicalState/worker.ts +3 -3
  182. package/src/chain/archiveStore/utils/archivePayloads.ts +15 -0
  183. package/src/chain/blocks/importBlock.ts +0 -3
  184. package/src/chain/blocks/index.ts +2 -1
  185. package/src/chain/blocks/writeBlockInputToDb.ts +3 -0
  186. package/src/chain/bls/multithread/index.ts +7 -7
  187. package/src/chain/bls/multithread/jobItem.ts +3 -3
  188. package/src/chain/bls/singleThread.ts +5 -5
  189. package/src/chain/bls/utils.ts +8 -5
  190. package/src/chain/chain.ts +51 -26
  191. package/src/chain/emitter.ts +2 -2
  192. package/src/chain/interface.ts +4 -11
  193. package/src/chain/lightClient/index.ts +4 -1
  194. package/src/chain/options.ts +1 -0
  195. package/src/chain/prepareNextSlot.ts +5 -5
  196. package/src/chain/produceBlock/computeNewStateRoot.ts +35 -3
  197. package/src/chain/produceBlock/produceBlockBody.ts +163 -13
  198. package/src/chain/validation/attestation.ts +4 -1
  199. package/src/chain/validation/attesterSlashing.ts +1 -1
  200. package/src/chain/validation/dataColumnSidecar.ts +2 -5
  201. package/src/chain/validation/payloadAttestationMessage.ts +9 -1
  202. package/src/chain/validation/proposerSlashing.ts +1 -1
  203. package/src/chain/validation/syncCommitteeContributionAndProof.ts +1 -1
  204. package/src/db/beacon.ts +8 -0
  205. package/src/db/buckets.ts +3 -0
  206. package/src/db/interface.ts +5 -0
  207. package/src/db/repositories/dataColumnSidecar.ts +18 -3
  208. package/src/db/repositories/dataColumnSidecarArchive.ts +18 -3
  209. package/src/db/repositories/executionPayloadEnvelope.ts +26 -0
  210. package/src/db/repositories/executionPayloadEnvelopeArchive.ts +32 -0
  211. package/src/db/repositories/index.ts +2 -0
  212. package/src/metrics/metrics/beacon.ts +5 -0
  213. package/src/metrics/metrics/lodestar.ts +9 -0
  214. package/src/network/gossip/interface.ts +3 -3
  215. package/src/network/gossip/topic.ts +2 -1
  216. package/src/network/interface.ts +4 -1
  217. package/src/network/network.ts +21 -3
  218. package/src/network/processor/gossipHandlers.ts +7 -1
  219. package/src/network/reqresp/handlers/lightClientUpdatesByRange.ts +6 -1
  220. package/src/node/nodejs.ts +4 -8
  221. package/src/util/blobs.ts +3 -3
  222. package/src/util/dataColumns.ts +37 -1
  223. package/src/util/multifork.ts +45 -0
  224. package/src/util/serializedCache.ts +5 -0
@@ -144,6 +144,11 @@ export function createBeaconMetrics(register: RegistryMetricCreator) {
144
144
  help: "Time for preparing payload in advance",
145
145
  buckets: [0.1, 1, 3, 5, 10],
146
146
  }),
147
+ executionPayloadEnvelopeProcessingTime: register.histogram({
148
+ name: "beacon_block_payload_envelope_processing_seconds",
149
+ help: "Time to process execution payload envelope during block production",
150
+ buckets: [0.005, 0.01, 0.05, 0.1, 0.2, 0.5, 1],
151
+ }),
147
152
  payloadFetchedTime: register.histogram<{prepType: PayloadPreparationType}>({
148
153
  name: "beacon_block_payload_fetched_time",
149
154
  help: "Time to fetch the payload from EL",
@@ -827,6 +827,15 @@ export function createLodestarMetrics(
827
827
  help: "Total number of blobs retrieved from execution engine and published to gossip",
828
828
  }),
829
829
  },
830
+ // Gossip execution payload envelope
831
+ gossipExecutionPayloadEnvelope: {
832
+ elapsedTimeTillReceived: register.histogram<{source: OpSource}>({
833
+ name: "lodestar_gossip_execution_payload_envelope_elapsed_time_till_received",
834
+ help: "Time elapsed between slot time and the time execution payload envelope received",
835
+ labelNames: ["source"],
836
+ buckets: [0.5, 1, 2, 4, 6, 12],
837
+ }),
838
+ },
830
839
  recoverDataColumnSidecars: {
831
840
  recoverTime: register.histogram({
832
841
  name: "lodestar_recover_data_column_sidecar_recover_time_seconds",
@@ -4,6 +4,7 @@ import {PeerIdStr} from "@chainsafe/libp2p-gossipsub/types";
4
4
  import {BeaconConfig, ForkBoundary} from "@lodestar/config";
5
5
  import {
6
6
  AttesterSlashing,
7
+ DataColumnSidecar,
7
8
  LightClientFinalityUpdate,
8
9
  LightClientOptimisticUpdate,
9
10
  SignedAggregateAndProof,
@@ -14,7 +15,6 @@ import {
14
15
  altair,
15
16
  capella,
16
17
  deneb,
17
- fulu,
18
18
  gloas,
19
19
  phase0,
20
20
  } from "@lodestar/types";
@@ -98,7 +98,7 @@ export type GossipTypeMap = {
98
98
  [GossipType.blob_sidecar]: deneb.BlobSidecar;
99
99
  [GossipType.beacon_aggregate_and_proof]: SignedAggregateAndProof;
100
100
  [GossipType.beacon_attestation]: SingleAttestation;
101
- [GossipType.data_column_sidecar]: fulu.DataColumnSidecar;
101
+ [GossipType.data_column_sidecar]: DataColumnSidecar;
102
102
  [GossipType.voluntary_exit]: phase0.SignedVoluntaryExit;
103
103
  [GossipType.proposer_slashing]: phase0.ProposerSlashing;
104
104
  [GossipType.attester_slashing]: AttesterSlashing;
@@ -117,7 +117,7 @@ export type GossipFnByType = {
117
117
  [GossipType.blob_sidecar]: (blobSidecar: deneb.BlobSidecar) => Promise<void> | void;
118
118
  [GossipType.beacon_aggregate_and_proof]: (aggregateAndProof: SignedAggregateAndProof) => Promise<void> | void;
119
119
  [GossipType.beacon_attestation]: (attestation: SingleAttestation) => Promise<void> | void;
120
- [GossipType.data_column_sidecar]: (dataColumnSidecar: fulu.DataColumnSidecar) => Promise<void> | void;
120
+ [GossipType.data_column_sidecar]: (dataColumnSidecar: DataColumnSidecar) => Promise<void> | void;
121
121
  [GossipType.voluntary_exit]: (voluntaryExit: phase0.SignedVoluntaryExit) => Promise<void> | void;
122
122
  [GossipType.proposer_slashing]: (proposerSlashing: phase0.ProposerSlashing) => Promise<void> | void;
123
123
  [GossipType.attester_slashing]: (attesterSlashing: AttesterSlashing) => Promise<void> | void;
@@ -6,6 +6,7 @@ import {
6
6
  SYNC_COMMITTEE_SUBNET_COUNT,
7
7
  isForkPostAltair,
8
8
  isForkPostElectra,
9
+ isForkPostFulu,
9
10
  } from "@lodestar/params";
10
11
  import {Attestation, SingleAttestation, ssz, sszTypesFor} from "@lodestar/types";
11
12
  import {GossipAction, GossipActionError, GossipErrorCode} from "../../chain/errors/gossipValidation.js";
@@ -92,7 +93,7 @@ export function getGossipSSZType(topic: GossipTopic) {
92
93
  case GossipType.blob_sidecar:
93
94
  return ssz.deneb.BlobSidecar;
94
95
  case GossipType.data_column_sidecar:
95
- return ssz.fulu.DataColumnSidecar;
96
+ return isForkPostFulu(fork) ? sszTypesFor(fork).DataColumnSidecar : ssz.fulu.DataColumnSidecar;
96
97
  case GossipType.beacon_aggregate_and_proof:
97
98
  return sszTypesFor(fork).SignedAggregateAndProof;
98
99
  case GossipType.beacon_attestation:
@@ -19,6 +19,7 @@ import type {Datastore} from "interface-datastore";
19
19
  import {Libp2p as ILibp2p} from "libp2p";
20
20
  import {
21
21
  AttesterSlashing,
22
+ DataColumnSidecar,
22
23
  LightClientFinalityUpdate,
23
24
  LightClientOptimisticUpdate,
24
25
  SignedAggregateAndProof,
@@ -31,6 +32,7 @@ import {
31
32
  capella,
32
33
  deneb,
33
34
  fulu,
35
+ gloas,
34
36
  phase0,
35
37
  } from "@lodestar/types";
36
38
  import {BlockInputSource} from "../chain/blocks/blockInput/types.js";
@@ -86,7 +88,7 @@ export interface INetwork extends INetworkCorePublic {
86
88
  publishBlobSidecar(blobSidecar: deneb.BlobSidecar): Promise<number>;
87
89
  publishBeaconAggregateAndProof(aggregateAndProof: SignedAggregateAndProof): Promise<number>;
88
90
  publishBeaconAttestation(attestation: SingleAttestation, subnet: SubnetID): Promise<number>;
89
- publishDataColumnSidecar(dataColumnSideCar: fulu.DataColumnSidecar): Promise<number>;
91
+ publishDataColumnSidecar(dataColumnSideCar: DataColumnSidecar): Promise<number>;
90
92
  publishVoluntaryExit(voluntaryExit: phase0.SignedVoluntaryExit): Promise<number>;
91
93
  publishBlsToExecutionChange(blsToExecutionChange: capella.SignedBLSToExecutionChange): Promise<number>;
92
94
  publishProposerSlashing(proposerSlashing: phase0.ProposerSlashing): Promise<number>;
@@ -95,6 +97,7 @@ export interface INetwork extends INetworkCorePublic {
95
97
  publishContributionAndProof(contributionAndProof: altair.SignedContributionAndProof): Promise<number>;
96
98
  publishLightClientFinalityUpdate(update: LightClientFinalityUpdate): Promise<number>;
97
99
  publishLightClientOptimisticUpdate(update: LightClientOptimisticUpdate): Promise<number>;
100
+ publishSignedExecutionPayloadEnvelope(signedEnvelope: gloas.SignedExecutionPayloadEnvelope): Promise<number>;
98
101
 
99
102
  // Debug
100
103
  dumpGossipQueue(gossipType: GossipType): Promise<PendingGossipsubMessage[]>;
@@ -10,6 +10,8 @@ import {ResponseIncoming} from "@lodestar/reqresp";
10
10
  import {computeEpochAtSlot} from "@lodestar/state-transition";
11
11
  import {
12
12
  AttesterSlashing,
13
+ DataColumnSidecar,
14
+ DataColumnSidecars,
13
15
  LightClientBootstrap,
14
16
  LightClientFinalityUpdate,
15
17
  LightClientOptimisticUpdate,
@@ -24,6 +26,8 @@ import {
24
26
  capella,
25
27
  deneb,
26
28
  fulu,
29
+ gloas,
30
+ isGloasDataColumnSidecar,
27
31
  phase0,
28
32
  } from "@lodestar/types";
29
33
  import {prettyPrintIndices, sleep} from "@lodestar/utils";
@@ -354,8 +358,11 @@ export class Network implements INetwork {
354
358
  });
355
359
  }
356
360
 
357
- async publishDataColumnSidecar(dataColumnSidecar: fulu.DataColumnSidecar): Promise<number> {
358
- const epoch = computeEpochAtSlot(dataColumnSidecar.signedBlockHeader.message.slot);
361
+ async publishDataColumnSidecar(dataColumnSidecar: DataColumnSidecar): Promise<number> {
362
+ const slot = isGloasDataColumnSidecar(dataColumnSidecar)
363
+ ? dataColumnSidecar.slot
364
+ : dataColumnSidecar.signedBlockHeader.message.slot;
365
+ const epoch = computeEpochAtSlot(slot);
359
366
  const boundary = this.config.getForkBoundaryAtEpoch(epoch);
360
367
 
361
368
  const subnet = computeSubnetForDataColumnSidecar(this.config, dataColumnSidecar);
@@ -489,6 +496,17 @@ export class Network implements INetwork {
489
496
  );
490
497
  }
491
498
 
499
+ async publishSignedExecutionPayloadEnvelope(signedEnvelope: gloas.SignedExecutionPayloadEnvelope): Promise<number> {
500
+ const epoch = computeEpochAtSlot(signedEnvelope.message.slot);
501
+ const boundary = this.config.getForkBoundaryAtEpoch(epoch);
502
+
503
+ return this.publishGossip<GossipType.execution_payload>(
504
+ {type: GossipType.execution_payload, boundary},
505
+ signedEnvelope,
506
+ {ignoreDuplicatePublishError: true}
507
+ );
508
+ }
509
+
492
510
  private async publishGossip<K extends GossipType>(
493
511
  topic: GossipTopicMap[K],
494
512
  object: GossipTypeMap[K],
@@ -765,7 +783,7 @@ export class Network implements INetwork {
765
783
  this.core.setTargetGroupCount(count);
766
784
  };
767
785
 
768
- private onPublishDataColumns = (sidecars: fulu.DataColumnSidecar[]): Promise<number[]> => {
786
+ private onPublishDataColumns = (sidecars: DataColumnSidecars): Promise<number[]> => {
769
787
  return promiseAllMaybeAsync(sidecars.map((sidecar) => () => this.publishDataColumnSidecar(sidecar)));
770
788
  };
771
789
 
@@ -548,7 +548,8 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
548
548
  seenTimestampSec,
549
549
  }: GossipHandlerParamGeneric<GossipType.data_column_sidecar>) => {
550
550
  const {serializedData} = gossipData;
551
- const dataColumnSidecar = sszDeserialize(topic, serializedData);
551
+ // TODO GLOAS: handle gloas.DataColumnSidecar
552
+ const dataColumnSidecar = sszDeserialize(topic, serializedData) as fulu.DataColumnSidecar;
552
553
  const dataColumnSlot = dataColumnSidecar.signedBlockHeader.message.slot;
553
554
  const index = dataColumnSidecar.index;
554
555
 
@@ -821,11 +822,16 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
821
822
  [GossipType.execution_payload]: async ({
822
823
  gossipData,
823
824
  topic,
825
+ seenTimestampSec,
824
826
  }: GossipHandlerParamGeneric<GossipType.execution_payload>) => {
825
827
  const {serializedData} = gossipData;
826
828
  const executionPayloadEnvelope = sszDeserialize(topic, serializedData);
827
829
  await validateGossipExecutionPayloadEnvelope(chain, executionPayloadEnvelope);
828
830
 
831
+ const slot = executionPayloadEnvelope.message.slot;
832
+ const delaySec = seenTimestampSec - computeTimeAtSlot(config, slot, chain.genesisTime);
833
+ metrics?.gossipExecutionPayloadEnvelope.elapsedTimeTillReceived.observe({source: OpSource.gossip}, delaySec);
834
+
829
835
  // TODO GLOAS: Handle valid envelope. Need an import flow that calls `processExecutionPayloadEnvelope` and fork choice
830
836
  },
831
837
  [GossipType.payload_attestation_message]: async ({
@@ -19,6 +19,7 @@ export async function* onLightClientUpdatesByRange(
19
19
  assertLightClientServer(chain.lightClientServer);
20
20
 
21
21
  const count = Math.min(MAX_REQUEST_LIGHT_CLIENT_UPDATES, requestBody.count);
22
+ let started = false;
22
23
  for (let period = requestBody.startPeriod; period < requestBody.startPeriod + count; period++) {
23
24
  try {
24
25
  const update = await chain.lightClientServer.getUpdate(period);
@@ -29,9 +30,13 @@ export async function* onLightClientUpdatesByRange(
29
30
  data: type.serialize(update),
30
31
  boundary,
31
32
  };
33
+ started = true;
32
34
  } catch (e) {
33
35
  if ((e as LightClientServerError).type?.code === LightClientServerErrorCode.RESOURCE_UNAVAILABLE) {
34
- throw new ResponseError(RespStatus.RESOURCE_UNAVAILABLE, (e as Error).message);
36
+ // Period not available, if we already started yielding, stop to
37
+ // preserve consecutive order. Otherwise skip leading gaps.
38
+ if (started) return;
39
+ continue;
35
40
  }
36
41
  throw new ResponseError(RespStatus.SERVER_ERROR, (e as Error).message);
37
42
  }
@@ -2,12 +2,11 @@ import {setMaxListeners} from "node:events";
2
2
  import {PrivateKey} from "@libp2p/interface";
3
3
  import {Registry} from "prom-client";
4
4
  import {hasher} from "@chainsafe/persistent-merkle-tree";
5
- import {PubkeyIndexMap} from "@chainsafe/pubkey-index-map";
6
5
  import {BeaconApiMethods} from "@lodestar/api/beacon/server";
7
6
  import {BeaconConfig} from "@lodestar/config";
8
7
  import type {LoggerNode} from "@lodestar/logger/node";
9
8
  import {ZERO_HASH_HEX} from "@lodestar/params";
10
- import {CachedBeaconStateAllForks, Index2PubkeyCache, isExecutionCachedStateType} from "@lodestar/state-transition";
9
+ import {CachedBeaconStateAllForks, PubkeyCache, isExecutionCachedStateType} from "@lodestar/state-transition";
11
10
  import {phase0} from "@lodestar/types";
12
11
  import {sleep, toRootHex} from "@lodestar/utils";
13
12
  import {ProcessShutdownCallback} from "@lodestar/validator";
@@ -47,8 +46,7 @@ export type BeaconNodeModules = {
47
46
  export type BeaconNodeInitModules = {
48
47
  opts: IBeaconNodeOptions;
49
48
  config: BeaconConfig;
50
- pubkey2index: PubkeyIndexMap;
51
- index2pubkey: Index2PubkeyCache;
49
+ pubkeyCache: PubkeyCache;
52
50
  db: IBeaconDb;
53
51
  logger: LoggerNode;
54
52
  processShutdownCallback: ProcessShutdownCallback;
@@ -150,8 +148,7 @@ export class BeaconNode {
150
148
  static async init<T extends BeaconNode = BeaconNode>({
151
149
  opts,
152
150
  config,
153
- pubkey2index,
154
- index2pubkey,
151
+ pubkeyCache,
155
152
  db,
156
153
  logger,
157
154
  processShutdownCallback,
@@ -240,8 +237,7 @@ export class BeaconNode {
240
237
  privateKey,
241
238
  config,
242
239
  clock,
243
- pubkey2index,
244
- index2pubkey,
240
+ pubkeyCache,
245
241
  dataDir,
246
242
  db,
247
243
  dbName: opts.db.name,
package/src/util/blobs.ts CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  VERSIONED_HASH_VERSION_KZG,
14
14
  } from "@lodestar/params";
15
15
  import {signedBlockToSignedHeader} from "@lodestar/state-transition";
16
- import {BeaconBlockBody, SSZTypesFor, SignedBeaconBlock, deneb, fulu, ssz} from "@lodestar/types";
16
+ import {BeaconBlockBody, DataColumnSidecars, SSZTypesFor, SignedBeaconBlock, deneb, fulu, ssz} from "@lodestar/types";
17
17
  import {kzg} from "./kzg.js";
18
18
 
19
19
  type VersionHash = Uint8Array;
@@ -149,7 +149,7 @@ export async function dataColumnMatrixRecovery(
149
149
  * Reconstruct blobs from a set of data columns, at least 50%+ of all the columns
150
150
  * must be provided to allow to reconstruct the full data matrix
151
151
  */
152
- export async function reconstructBlobs(sidecars: fulu.DataColumnSidecars, indices?: number[]): Promise<deneb.Blobs> {
152
+ export async function reconstructBlobs(sidecars: DataColumnSidecars, indices?: number[]): Promise<deneb.Blobs> {
153
153
  if (sidecars.length < NUMBER_OF_COLUMNS / 2) {
154
154
  throw Error(
155
155
  `Expected at least ${NUMBER_OF_COLUMNS / 2} data columns to reconstruct blobs, received ${sidecars.length}`
@@ -188,7 +188,7 @@ export async function reconstructBlobs(sidecars: fulu.DataColumnSidecars, indice
188
188
  * Recover cells for specific blob indices from a set of data columns
189
189
  */
190
190
  async function recoverBlobCells(
191
- partialSidecars: fulu.DataColumnSidecar[],
191
+ partialSidecars: DataColumnSidecars,
192
192
  blobIndices: number[]
193
193
  ): Promise<Map<number, fulu.Cell[]> | null> {
194
194
  const columnCount = partialSidecars.length;
@@ -4,6 +4,7 @@ import {ChainForkConfig} from "@lodestar/config";
4
4
  import {
5
5
  ForkAll,
6
6
  ForkName,
7
+ ForkPostDeneb,
7
8
  ForkPostFulu,
8
9
  ForkPreGloas,
9
10
  KZG_COMMITMENTS_GINDEX,
@@ -15,9 +16,11 @@ import {
15
16
  BeaconBlockBody,
16
17
  ColumnIndex,
17
18
  CustodyIndex,
19
+ Root,
18
20
  SSZTypesFor,
19
21
  SignedBeaconBlock,
20
22
  SignedBeaconBlockHeader,
23
+ Slot,
21
24
  deneb,
22
25
  fulu,
23
26
  gloas,
@@ -269,7 +272,7 @@ export async function getCellsAndProofs(
269
272
  */
270
273
  export function getBlobKzgCommitments(
271
274
  fork: ForkName,
272
- signedBlock: SignedBeaconBlock<ForkPostFulu>
275
+ signedBlock: SignedBeaconBlock<ForkPostDeneb>
273
276
  ): deneb.KZGCommitment[] {
274
277
  if (isForkPostGloas(fork)) {
275
278
  return (signedBlock as gloas.SignedBeaconBlock).message.body.signedExecutionPayloadBid.message.blobKzgCommitments;
@@ -359,6 +362,39 @@ export function getDataColumnSidecarsFromColumnSidecar(
359
362
  );
360
363
  }
361
364
 
365
+ /**
366
+ * In Gloas, data column sidecars have a simplified structure with `slot` and `beaconBlockRoot`
367
+ * instead of `signedBlockHeader`, `kzgCommitments`, and `kzgCommitmentsInclusionProof`.
368
+ */
369
+ export function getDataColumnSidecarsForGloas(
370
+ slot: Slot,
371
+ beaconBlockRoot: Root,
372
+ cellsAndKzgProofs: {cells: Uint8Array[]; proofs: Uint8Array[]}[]
373
+ ): gloas.DataColumnSidecars {
374
+ // No need to create data column sidecars if there are no blobs
375
+ if (cellsAndKzgProofs.length === 0) {
376
+ return [];
377
+ }
378
+
379
+ const sidecars: gloas.DataColumnSidecars = [];
380
+ for (let columnIndex = 0; columnIndex < NUMBER_OF_COLUMNS; columnIndex++) {
381
+ const column: Uint8Array[] = [];
382
+ const kzgProofs: Uint8Array[] = [];
383
+ for (const {cells, proofs} of cellsAndKzgProofs) {
384
+ column.push(cells[columnIndex]);
385
+ kzgProofs.push(proofs[columnIndex]);
386
+ }
387
+ sidecars.push({
388
+ index: columnIndex,
389
+ column,
390
+ kzgProofs,
391
+ slot,
392
+ beaconBlockRoot,
393
+ });
394
+ }
395
+ return sidecars;
396
+ }
397
+
362
398
  /**
363
399
  * If we receive more than half of NUMBER_OF_COLUMNS (64) we should recover all remaining columns
364
400
  */
@@ -9,6 +9,11 @@ import {getSlotFromSignedBeaconBlockSerialized} from "./sszBytes.js";
9
9
  */
10
10
  const SLOT_BYTE_COUNT = 8;
11
11
 
12
+ /**
13
+ * SSZ offset uint32
14
+ */
15
+ const OFFSET_BYTE_COUNT = 4;
16
+
12
17
  /**
13
18
  * 8 + 32 = 40
14
19
  * ```
@@ -67,3 +72,43 @@ export function getLightClientHeaderTypeFromBytes(
67
72
  );
68
73
  return config.getPostAltairForkTypes(slot).LightClientHeader;
69
74
  }
75
+
76
+ /**
77
+ * Position of first offset in DataColumnSidecar (after index field)
78
+ *
79
+ * Fulu DataColumnSidecar (6 fields):
80
+ * index: uint64 [fixed - 8 bytes]
81
+ * column: List [variable - 4-byte offset]
82
+ * kzgCommitments: List [variable - 4-byte offset]
83
+ * kzgProofs: List [variable - 4-byte offset]
84
+ * signedBlockHeader: Container [fixed - 208 bytes]
85
+ * kzgCommitmentsInclusionProof: Vector[Bytes32, 4] [fixed - 128 bytes]
86
+ * => First offset value = 8 + 4 + 4 + 4 + 208 + 128 = 356
87
+ *
88
+ * Gloas DataColumnSidecar (5 fields):
89
+ * index: uint64 [fixed - 8 bytes]
90
+ * column: List [variable - 4-byte offset]
91
+ * kzgProofs: List [variable - 4-byte offset]
92
+ * slot: uint64 [fixed - 8 bytes]
93
+ * beaconBlockRoot: Bytes32 [fixed - 32 bytes]
94
+ * => First offset value = 8 + 4 + 4 + 8 + 32 = 56
95
+ */
96
+ const FIRST_OFFSET_POSITION_IN_DATA_COLUMN_SIDECAR = 8;
97
+ const GLOAS_DATA_COLUMN_SIDECAR_FIRST_OFFSET = 56;
98
+
99
+ /**
100
+ * Determines if DataColumnSidecar bytes are from Gloas fork by checking the SSZ offset structure.
101
+ *
102
+ * The first offset (bytes 8-12) indicates where variable-size data begins:
103
+ * - Gloas: 56 (small fixed section)
104
+ * - Fulu: 356
105
+ */
106
+ export function isGloasDataColumnSidecarBytes(bytes: Uint8Array): boolean {
107
+ const firstOffset = bytesToInt(
108
+ bytes.subarray(
109
+ FIRST_OFFSET_POSITION_IN_DATA_COLUMN_SIDECAR,
110
+ FIRST_OFFSET_POSITION_IN_DATA_COLUMN_SIDECAR + OFFSET_BYTE_COUNT
111
+ )
112
+ );
113
+ return firstOffset === GLOAS_DATA_COLUMN_SIDECAR_FIRST_OFFSET;
114
+ }
@@ -14,6 +14,11 @@ export class SerializedCache {
14
14
  this.map.set(obj, serialized);
15
15
  }
16
16
 
17
+ /**
18
+ * Replace the internal WeakMap to force GC of all cached entries.
19
+ * Must only be called after all DB writes that may read from this cache have completed,
20
+ * otherwise cached serialized bytes will be unavailable and data will be re-serialized unnecessarily.
21
+ */
17
22
  clear(): void {
18
23
  this.map = new WeakMap();
19
24
  }