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

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 (93) hide show
  1. package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/state/utils.js +1 -20
  3. package/lib/api/impl/beacon/state/utils.js.map +1 -1
  4. package/lib/api/impl/debug/index.d.ts.map +1 -1
  5. package/lib/api/impl/debug/index.js +5 -2
  6. package/lib/api/impl/debug/index.js.map +1 -1
  7. package/lib/chain/archiveStore/archiveStore.d.ts +1 -0
  8. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  9. package/lib/chain/archiveStore/archiveStore.js +9 -0
  10. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  11. package/lib/chain/archiveStore/utils/archivePayloads.d.ts +7 -0
  12. package/lib/chain/archiveStore/utils/archivePayloads.d.ts.map +1 -0
  13. package/lib/chain/archiveStore/utils/archivePayloads.js +10 -0
  14. package/lib/chain/archiveStore/utils/archivePayloads.js.map +1 -0
  15. package/lib/chain/chain.d.ts +2 -2
  16. package/lib/chain/chain.d.ts.map +1 -1
  17. package/lib/chain/chain.js +1 -1
  18. package/lib/chain/chain.js.map +1 -1
  19. package/lib/chain/emitter.d.ts +2 -2
  20. package/lib/chain/emitter.d.ts.map +1 -1
  21. package/lib/chain/interface.d.ts +2 -2
  22. package/lib/chain/interface.d.ts.map +1 -1
  23. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  24. package/lib/chain/produceBlock/produceBlockBody.js +8 -1
  25. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  26. package/lib/db/beacon.d.ts +3 -1
  27. package/lib/db/beacon.d.ts.map +1 -1
  28. package/lib/db/beacon.js +5 -1
  29. package/lib/db/beacon.js.map +1 -1
  30. package/lib/db/buckets.d.ts +3 -1
  31. package/lib/db/buckets.d.ts.map +1 -1
  32. package/lib/db/buckets.js +2 -0
  33. package/lib/db/buckets.js.map +1 -1
  34. package/lib/db/interface.d.ts +3 -1
  35. package/lib/db/interface.d.ts.map +1 -1
  36. package/lib/db/repositories/blockArchiveIndex.d.ts +2 -2
  37. package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
  38. package/lib/db/repositories/dataColumnSidecar.d.ts +5 -3
  39. package/lib/db/repositories/dataColumnSidecar.d.ts.map +1 -1
  40. package/lib/db/repositories/dataColumnSidecar.js +14 -1
  41. package/lib/db/repositories/dataColumnSidecar.js.map +1 -1
  42. package/lib/db/repositories/dataColumnSidecarArchive.d.ts +5 -3
  43. package/lib/db/repositories/dataColumnSidecarArchive.d.ts.map +1 -1
  44. package/lib/db/repositories/dataColumnSidecarArchive.js +14 -1
  45. package/lib/db/repositories/dataColumnSidecarArchive.js.map +1 -1
  46. package/lib/db/repositories/executionPayloadEnvelope.d.ts +19 -0
  47. package/lib/db/repositories/executionPayloadEnvelope.d.ts.map +1 -0
  48. package/lib/db/repositories/executionPayloadEnvelope.js +22 -0
  49. package/lib/db/repositories/executionPayloadEnvelope.js.map +1 -0
  50. package/lib/db/repositories/executionPayloadEnvelopeArchive.d.ts +18 -0
  51. package/lib/db/repositories/executionPayloadEnvelopeArchive.d.ts.map +1 -0
  52. package/lib/db/repositories/executionPayloadEnvelopeArchive.js +28 -0
  53. package/lib/db/repositories/executionPayloadEnvelopeArchive.js.map +1 -0
  54. package/lib/db/repositories/index.d.ts +2 -0
  55. package/lib/db/repositories/index.d.ts.map +1 -1
  56. package/lib/db/repositories/index.js +2 -0
  57. package/lib/db/repositories/index.js.map +1 -1
  58. package/lib/network/gossip/topic.d.ts +51 -51
  59. package/lib/network/network.d.ts.map +1 -1
  60. package/lib/network/network.js +1 -1
  61. package/lib/network/network.js.map +1 -1
  62. package/lib/util/blobs.d.ts +2 -2
  63. package/lib/util/blobs.d.ts.map +1 -1
  64. package/lib/util/blobs.js.map +1 -1
  65. package/lib/util/dataColumns.d.ts +3 -5
  66. package/lib/util/dataColumns.d.ts.map +1 -1
  67. package/lib/util/dataColumns.js +0 -4
  68. package/lib/util/dataColumns.js.map +1 -1
  69. package/lib/util/multifork.d.ts +8 -0
  70. package/lib/util/multifork.d.ts.map +1 -1
  71. package/lib/util/multifork.js +37 -0
  72. package/lib/util/multifork.js.map +1 -1
  73. package/package.json +15 -15
  74. package/src/api/impl/beacon/state/utils.ts +10 -23
  75. package/src/api/impl/debug/index.ts +8 -5
  76. package/src/chain/archiveStore/archiveStore.ts +10 -0
  77. package/src/chain/archiveStore/utils/archivePayloads.ts +15 -0
  78. package/src/chain/chain.ts +6 -5
  79. package/src/chain/emitter.ts +2 -2
  80. package/src/chain/interface.ts +2 -2
  81. package/src/chain/produceBlock/produceBlockBody.ts +9 -2
  82. package/src/db/beacon.ts +8 -0
  83. package/src/db/buckets.ts +3 -0
  84. package/src/db/interface.ts +5 -0
  85. package/src/db/repositories/dataColumnSidecar.ts +18 -3
  86. package/src/db/repositories/dataColumnSidecarArchive.ts +18 -3
  87. package/src/db/repositories/executionPayloadEnvelope.ts +26 -0
  88. package/src/db/repositories/executionPayloadEnvelopeArchive.ts +32 -0
  89. package/src/db/repositories/index.ts +2 -0
  90. package/src/network/network.ts +4 -2
  91. package/src/util/blobs.ts +3 -3
  92. package/src/util/dataColumns.ts +2 -7
  93. package/src/util/multifork.ts +45 -0
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "bugs": {
12
12
  "url": "https://github.com/ChainSafe/lodestar/issues"
13
13
  },
14
- "version": "1.41.0-dev.a35cbde8b3",
14
+ "version": "1.41.0-dev.aeb5a213ee",
15
15
  "type": "module",
16
16
  "exports": {
17
17
  ".": {
@@ -134,18 +134,18 @@
134
134
  "@libp2p/peer-id": "^5.1.0",
135
135
  "@libp2p/prometheus-metrics": "^4.3.15",
136
136
  "@libp2p/tcp": "^10.1.8",
137
- "@lodestar/api": "^1.41.0-dev.a35cbde8b3",
138
- "@lodestar/config": "^1.41.0-dev.a35cbde8b3",
139
- "@lodestar/db": "^1.41.0-dev.a35cbde8b3",
140
- "@lodestar/fork-choice": "^1.41.0-dev.a35cbde8b3",
141
- "@lodestar/light-client": "^1.41.0-dev.a35cbde8b3",
142
- "@lodestar/logger": "^1.41.0-dev.a35cbde8b3",
143
- "@lodestar/params": "^1.41.0-dev.a35cbde8b3",
144
- "@lodestar/reqresp": "^1.41.0-dev.a35cbde8b3",
145
- "@lodestar/state-transition": "^1.41.0-dev.a35cbde8b3",
146
- "@lodestar/types": "^1.41.0-dev.a35cbde8b3",
147
- "@lodestar/utils": "^1.41.0-dev.a35cbde8b3",
148
- "@lodestar/validator": "^1.41.0-dev.a35cbde8b3",
137
+ "@lodestar/api": "^1.41.0-dev.aeb5a213ee",
138
+ "@lodestar/config": "^1.41.0-dev.aeb5a213ee",
139
+ "@lodestar/db": "^1.41.0-dev.aeb5a213ee",
140
+ "@lodestar/fork-choice": "^1.41.0-dev.aeb5a213ee",
141
+ "@lodestar/light-client": "^1.41.0-dev.aeb5a213ee",
142
+ "@lodestar/logger": "^1.41.0-dev.aeb5a213ee",
143
+ "@lodestar/params": "^1.41.0-dev.aeb5a213ee",
144
+ "@lodestar/reqresp": "^1.41.0-dev.aeb5a213ee",
145
+ "@lodestar/state-transition": "^1.41.0-dev.aeb5a213ee",
146
+ "@lodestar/types": "^1.41.0-dev.aeb5a213ee",
147
+ "@lodestar/utils": "^1.41.0-dev.aeb5a213ee",
148
+ "@lodestar/validator": "^1.41.0-dev.aeb5a213ee",
149
149
  "@multiformats/multiaddr": "^12.1.3",
150
150
  "datastore-core": "^10.0.2",
151
151
  "datastore-fs": "^10.0.6",
@@ -169,7 +169,7 @@
169
169
  "@chainsafe/swap-or-not-shuffle": "^1.2.1",
170
170
  "@libp2p/interface-internal": "^2.3.18",
171
171
  "@libp2p/logger": "^5.1.21",
172
- "@lodestar/spec-test-util": "^1.41.0-dev.a35cbde8b3",
172
+ "@lodestar/spec-test-util": "^1.41.0-dev.aeb5a213ee",
173
173
  "@types/js-yaml": "^4.0.5",
174
174
  "@types/qs": "^6.9.7",
175
175
  "@types/tmp": "^0.2.3",
@@ -188,5 +188,5 @@
188
188
  "beacon",
189
189
  "blockchain"
190
190
  ],
191
- "gitHead": "090cdf258f4c067ebe6b5f0bdba221c2c23b9962"
191
+ "gitHead": "43590e813190f5db12afb15c9ee4d878989d837e"
192
192
  }
@@ -3,7 +3,16 @@ import {routes} from "@lodestar/api";
3
3
  import {CheckpointWithHex, IForkChoice} from "@lodestar/fork-choice";
4
4
  import {GENESIS_SLOT} from "@lodestar/params";
5
5
  import {BeaconStateAllForks, CachedBeaconStateAllForks} from "@lodestar/state-transition";
6
- import {BLSPubkey, Epoch, RootHex, Slot, ValidatorIndex, getValidatorStatus, phase0} from "@lodestar/types";
6
+ import {
7
+ BLSPubkey,
8
+ Epoch,
9
+ RootHex,
10
+ Slot,
11
+ ValidatorIndex,
12
+ getValidatorStatus,
13
+ mapToGeneralStatus,
14
+ phase0,
15
+ } from "@lodestar/types";
7
16
  import {fromHex} from "@lodestar/utils";
8
17
  import {IBeaconChain} from "../../../../chain/index.js";
9
18
  import {ApiError, ValidationError} from "../../errors.js";
@@ -65,28 +74,6 @@ export async function getStateResponseWithRegen(
65
74
  return res;
66
75
  }
67
76
 
68
- type GeneralValidatorStatus = "active" | "pending" | "exited" | "withdrawal";
69
-
70
- function mapToGeneralStatus(subStatus: routes.beacon.ValidatorStatus): GeneralValidatorStatus {
71
- switch (subStatus) {
72
- case "active_ongoing":
73
- case "active_exiting":
74
- case "active_slashed":
75
- return "active";
76
- case "pending_initialized":
77
- case "pending_queued":
78
- return "pending";
79
- case "exited_slashed":
80
- case "exited_unslashed":
81
- return "exited";
82
- case "withdrawal_possible":
83
- case "withdrawal_done":
84
- return "withdrawal";
85
- default:
86
- throw new Error(`Unknown substatus: ${subStatus}`);
87
- }
88
- }
89
-
90
77
  export function toValidatorResponse(
91
78
  index: ValidatorIndex,
92
79
  validator: phase0.Validator,
@@ -1,9 +1,10 @@
1
1
  import {routes} from "@lodestar/api";
2
2
  import {ApplicationMethods} from "@lodestar/api/server";
3
3
  import {ExecutionStatus} from "@lodestar/fork-choice";
4
- import {ZERO_HASH_HEX, isForkPostDeneb, isForkPostFulu} from "@lodestar/params";
5
- import {BeaconState, deneb, fulu, sszTypesFor} from "@lodestar/types";
4
+ import {ForkPostDeneb, ZERO_HASH_HEX, isForkPostDeneb, isForkPostFulu} from "@lodestar/params";
5
+ import {BeaconState, DataColumnSidecars, type SignedBeaconBlock, sszTypesFor} from "@lodestar/types";
6
6
  import {toRootHex} from "@lodestar/utils";
7
+ import {getBlobKzgCommitments} from "../../../util/dataColumns.js";
7
8
  import {isOptimisticBlock} from "../../../util/forkChoice.js";
8
9
  import {getStateSlotFromBytes} from "../../../util/multifork.js";
9
10
  import {getBlockResponse} from "../beacon/blocks/utils.js";
@@ -96,10 +97,10 @@ export function getDebugApi({
96
97
  const fork = config.getForkName(block.message.slot);
97
98
  const blockRoot = sszTypesFor(fork).BeaconBlock.hashTreeRoot(block.message);
98
99
 
99
- let dataColumnSidecars: fulu.DataColumnSidecars;
100
+ let dataColumnSidecars: DataColumnSidecars;
100
101
 
101
102
  const blobCount = isForkPostDeneb(fork)
102
- ? (block.message.body as deneb.BeaconBlockBody).blobKzgCommitments.length
103
+ ? getBlobKzgCommitments(fork, block as SignedBeaconBlock<ForkPostDeneb>).length
103
104
  : 0;
104
105
 
105
106
  if (isForkPostFulu(fork) && blobCount > 0) {
@@ -115,7 +116,9 @@ export function getDebugApi({
115
116
  }
116
117
 
117
118
  return {
118
- data: indices ? dataColumnSidecars.filter(({index}) => indices.includes(index)) : dataColumnSidecars,
119
+ data: (indices
120
+ ? dataColumnSidecars.filter(({index}) => indices.includes(index))
121
+ : dataColumnSidecars) as DataColumnSidecars,
119
122
  meta: {
120
123
  executionOptimistic,
121
124
  finalized,
@@ -1,5 +1,6 @@
1
1
  import {CheckpointWithHex} from "@lodestar/fork-choice";
2
2
  import {LoggerNode} from "@lodestar/logger/node";
3
+ import {ForkSeq} from "@lodestar/params";
3
4
  import {Checkpoint} from "@lodestar/types/phase0";
4
5
  import {callFnWhenAwait} from "@lodestar/utils";
5
6
  import {IBeaconDb} from "../../db/index.js";
@@ -13,6 +14,7 @@ import {HistoricalStateRegen} from "./historicalState/historicalStateRegen.js";
13
14
  import {ArchiveMode, ArchiveStoreOpts, StateArchiveStrategy} from "./interface.js";
14
15
  import {FrequencyStateArchiveStrategy} from "./strategies/frequencyStateArchiveStrategy.js";
15
16
  import {archiveBlocks} from "./utils/archiveBlocks.js";
17
+ import {archiveExecutionPayloadEnvelopes} from "./utils/archivePayloads.js";
16
18
  import {pruneHistory} from "./utils/pruneHistory.js";
17
19
  import {updateBackfillRange} from "./utils/updateBackfillRange.js";
18
20
 
@@ -27,6 +29,7 @@ type ArchiveStoreInitOpts = ArchiveStoreOpts & {dbName: string; anchorState: {fi
27
29
 
28
30
  export enum ArchiveStoreTask {
29
31
  ArchiveBlocks = "archive_blocks",
32
+ ArchivePayloads = "archive_payloads",
30
33
  PruneHistory = "prune_history",
31
34
  OnFinalizedCheckpoint = "on_finalized_checkpoint",
32
35
  MaybeArchiveState = "maybe_archive_state",
@@ -189,6 +192,7 @@ export class ArchiveStore {
189
192
  private processFinalizedCheckpoint = async (finalized: CheckpointWithHex): Promise<void> => {
190
193
  try {
191
194
  const finalizedEpoch = finalized.epoch;
195
+ const finalizedFork = this.chain.config.getForkSeqAtEpoch(finalizedEpoch);
192
196
  this.logger.verbose("Start processing finalized checkpoint", {epoch: finalizedEpoch, rootHex: finalized.rootHex});
193
197
 
194
198
  let timer = this.metrics?.processFinalizedCheckpoint.durationByTask.startTimer();
@@ -206,6 +210,12 @@ export class ArchiveStore {
206
210
  );
207
211
  timer?.({source: ArchiveStoreTask.ArchiveBlocks});
208
212
 
213
+ if (finalizedFork >= ForkSeq.gloas) {
214
+ timer = this.metrics?.processFinalizedCheckpoint.durationByTask.startTimer();
215
+ await archiveExecutionPayloadEnvelopes(this.chain, finalized);
216
+ timer?.({source: ArchiveStoreTask.ArchivePayloads});
217
+ }
218
+
209
219
  if (this.opts.pruneHistory) {
210
220
  timer = this.metrics?.processFinalizedCheckpoint.durationByTask.startTimer();
211
221
  await pruneHistory(
@@ -0,0 +1,15 @@
1
+ import {CheckpointWithHex} from "@lodestar/fork-choice";
2
+ import {IBeaconChain} from "../../interface.js";
3
+
4
+ /**
5
+ * Archives execution payload envelopes from hot DB to archive DB after finalization.
6
+ */
7
+ export async function archiveExecutionPayloadEnvelopes(
8
+ chain: IBeaconChain,
9
+ _finalized: CheckpointWithHex
10
+ ): Promise<void> {
11
+ const finalizedBlock = chain.forkChoice.getFinalizedBlock();
12
+ if (!finalizedBlock) return;
13
+
14
+ // TODO GLOAS: Implement payload envelope archival after epbs fork choice changes are merged
15
+ }
@@ -8,6 +8,7 @@ import {LoggerNode} from "@lodestar/logger/node";
8
8
  import {
9
9
  BUILDER_INDEX_SELF_BUILD,
10
10
  EFFECTIVE_BALANCE_INCREMENT,
11
+ ForkPostFulu,
11
12
  GENESIS_SLOT,
12
13
  SLOTS_PER_EPOCH,
13
14
  isForkPostElectra,
@@ -36,6 +37,7 @@ import {
36
37
  BeaconBlock,
37
38
  BlindedBeaconBlock,
38
39
  BlindedBeaconBlockBody,
40
+ DataColumnSidecars,
39
41
  Epoch,
40
42
  Root,
41
43
  RootHex,
@@ -46,7 +48,6 @@ import {
46
48
  ValidatorIndex,
47
49
  Wei,
48
50
  deneb,
49
- fulu,
50
51
  gloas,
51
52
  isBlindedBeaconBlock,
52
53
  phase0,
@@ -817,7 +818,7 @@ export class BeaconChain implements IBeaconChain {
817
818
  return null;
818
819
  }
819
820
 
820
- async getDataColumnSidecars(blockSlot: Slot, blockRootHex: string): Promise<fulu.DataColumnSidecars> {
821
+ async getDataColumnSidecars(blockSlot: Slot, blockRootHex: string): Promise<DataColumnSidecars> {
821
822
  const blockInput = this.seenBlockInputCache.get(blockRootHex);
822
823
  if (blockInput) {
823
824
  if (!isBlockInputColumns(blockInput)) {
@@ -827,10 +828,10 @@ export class BeaconChain implements IBeaconChain {
827
828
  }
828
829
  const sidecarsUnfinalized = await this.db.dataColumnSidecar.values(fromHex(blockRootHex));
829
830
  if (sidecarsUnfinalized.length > 0) {
830
- return sidecarsUnfinalized;
831
+ return sidecarsUnfinalized as DataColumnSidecars;
831
832
  }
832
833
  const sidecarsFinalized = await this.db.dataColumnSidecarArchive.values(blockSlot);
833
- return sidecarsFinalized;
834
+ return sidecarsFinalized as DataColumnSidecars;
834
835
  }
835
836
 
836
837
  async getSerializedDataColumnSidecars(
@@ -852,7 +853,7 @@ export class BeaconChain implements IBeaconChain {
852
853
  if (serialized) {
853
854
  return serialized;
854
855
  }
855
- return ssz.fulu.DataColumnSidecar.serialize(sidecar);
856
+ return sszTypesFor(blockInput.forkName as ForkPostFulu).DataColumnSidecar.serialize(sidecar);
856
857
  });
857
858
  }
858
859
  const sidecarsUnfinalized = await this.db.dataColumnSidecar.getManyBinary(fromHex(blockRootHex), indices);
@@ -3,7 +3,7 @@ import {StrictEventEmitter} from "strict-event-emitter-types";
3
3
  import {routes} from "@lodestar/api";
4
4
  import {CheckpointWithHex} from "@lodestar/fork-choice";
5
5
  import {CachedBeaconStateAllForks} from "@lodestar/state-transition";
6
- import {DataColumnSidecar, RootHex, deneb, phase0} from "@lodestar/types";
6
+ import {DataColumnSidecars, RootHex, deneb, phase0} from "@lodestar/types";
7
7
  import {PeerIdStr} from "../util/peerId.js";
8
8
  import {BlockInputSource, IBlockInput} from "./blocks/blockInput/types.js";
9
9
 
@@ -88,7 +88,7 @@ export type IChainEvents = ApiEvents & {
88
88
 
89
89
  [ChainEvent.updateTargetCustodyGroupCount]: (targetGroupCount: number) => void;
90
90
 
91
- [ChainEvent.publishDataColumns]: (sidecars: DataColumnSidecar[]) => void;
91
+ [ChainEvent.publishDataColumns]: (sidecars: DataColumnSidecars) => void;
92
92
 
93
93
  [ChainEvent.publishBlobSidecars]: (sidecars: deneb.BlobSidecar[]) => void;
94
94
 
@@ -11,6 +11,7 @@ import {
11
11
  import {
12
12
  BeaconBlock,
13
13
  BlindedBeaconBlock,
14
+ DataColumnSidecars,
14
15
  Epoch,
15
16
  Root,
16
17
  RootHex,
@@ -23,7 +24,6 @@ import {
23
24
  altair,
24
25
  capella,
25
26
  deneb,
26
- fulu,
27
27
  phase0,
28
28
  rewards,
29
29
  } from "@lodestar/types";
@@ -224,7 +224,7 @@ export interface IBeaconChain {
224
224
  ): Promise<{block: SignedBeaconBlock; executionOptimistic: boolean; finalized: boolean} | null>;
225
225
  getBlobSidecars(blockSlot: Slot, blockRootHex: string): Promise<deneb.BlobSidecars | null>;
226
226
  getSerializedBlobSidecars(blockSlot: Slot, blockRootHex: string): Promise<Uint8Array | null>;
227
- getDataColumnSidecars(blockSlot: Slot, blockRootHex: string): Promise<fulu.DataColumnSidecars>;
227
+ getDataColumnSidecars(blockSlot: Slot, blockRootHex: string): Promise<DataColumnSidecars>;
228
228
  getSerializedDataColumnSidecars(
229
229
  blockSlot: Slot,
230
230
  blockRootHex: string,
@@ -4,6 +4,7 @@ import {
4
4
  BUILDER_INDEX_SELF_BUILD,
5
5
  ForkName,
6
6
  ForkPostBellatrix,
7
+ ForkPostCapella,
7
8
  ForkPostDeneb,
8
9
  ForkPostFulu,
9
10
  ForkPostGloas,
@@ -567,8 +568,14 @@ export async function produceBlockBody<T extends BlockType>(
567
568
  });
568
569
  }
569
570
 
570
- if (ForkSeq[fork] >= ForkSeq.capella) {
571
- const {blsToExecutionChanges, executionPayload} = blockBody as capella.BeaconBlockBody;
571
+ if (ForkSeq[fork] >= ForkSeq.gloas) {
572
+ const {blsToExecutionChanges, payloadAttestations} = blockBody as BeaconBlockBody<ForkPostGloas>;
573
+ Object.assign(logMeta, {
574
+ blsToExecutionChanges: blsToExecutionChanges.length,
575
+ payloadAttestations: payloadAttestations.length,
576
+ });
577
+ } else if (ForkSeq[fork] >= ForkSeq.capella) {
578
+ const {blsToExecutionChanges, executionPayload} = blockBody as BeaconBlockBody<ForkPostCapella & ForkPreGloas>;
572
579
  Object.assign(logMeta, {
573
580
  blsToExecutionChanges: blsToExecutionChanges.length,
574
581
  });
package/src/db/beacon.ts CHANGED
@@ -15,6 +15,8 @@ import {
15
15
  CheckpointHeaderRepository,
16
16
  DataColumnSidecarArchiveRepository,
17
17
  DataColumnSidecarRepository,
18
+ ExecutionPayloadEnvelopeArchiveRepository,
19
+ ExecutionPayloadEnvelopeRepository,
18
20
  ProposerSlashingRepository,
19
21
  StateArchiveRepository,
20
22
  SyncCommitteeRepository,
@@ -36,6 +38,9 @@ export class BeaconDb implements IBeaconDb {
36
38
  dataColumnSidecar: DataColumnSidecarRepository;
37
39
  dataColumnSidecarArchive: DataColumnSidecarArchiveRepository;
38
40
 
41
+ executionPayloadEnvelope: ExecutionPayloadEnvelopeRepository;
42
+ executionPayloadEnvelopeArchive: ExecutionPayloadEnvelopeArchiveRepository;
43
+
39
44
  stateArchive: StateArchiveRepository;
40
45
  checkpointState: CheckpointStateRepository;
41
46
 
@@ -65,6 +70,9 @@ export class BeaconDb implements IBeaconDb {
65
70
  this.dataColumnSidecar = new DataColumnSidecarRepository(config, db);
66
71
  this.dataColumnSidecarArchive = new DataColumnSidecarArchiveRepository(config, db);
67
72
 
73
+ this.executionPayloadEnvelope = new ExecutionPayloadEnvelopeRepository(config, db);
74
+ this.executionPayloadEnvelopeArchive = new ExecutionPayloadEnvelopeArchiveRepository(config, db);
75
+
68
76
  this.stateArchive = new StateArchiveRepository(config, db);
69
77
  this.checkpointState = new CheckpointStateRepository(config, db);
70
78
  this.voluntaryExit = new VoluntaryExitRepository(config, db);
package/src/db/buckets.ts CHANGED
@@ -69,6 +69,9 @@ export enum Bucket {
69
69
 
70
70
  fulu_dataColumnSidecars = 57, // FULU BeaconBlockRoot -> DataColumnSidecars
71
71
  fulu_dataColumnSidecarsArchive = 58, // FULU BeaconBlockSlot -> DataColumnSidecars
72
+
73
+ gloas_executionPayloadEnvelope = 59, // GLOAS BeaconBlockRoot -> SignedExecutionPayloadEnvelope
74
+ gloas_executionPayloadEnvelopeArchive = 60, // GLOAS Slot -> SignedExecutionPayloadEnvelope
72
75
  }
73
76
 
74
77
  export function getBucketNameByValue<T extends Bucket>(enumValue: T): keyof typeof Bucket {
@@ -12,6 +12,8 @@ import {
12
12
  CheckpointHeaderRepository,
13
13
  DataColumnSidecarArchiveRepository,
14
14
  DataColumnSidecarRepository,
15
+ ExecutionPayloadEnvelopeArchiveRepository,
16
+ ExecutionPayloadEnvelopeRepository,
15
17
  ProposerSlashingRepository,
16
18
  StateArchiveRepository,
17
19
  SyncCommitteeRepository,
@@ -35,6 +37,9 @@ export interface IBeaconDb {
35
37
  dataColumnSidecar: DataColumnSidecarRepository;
36
38
  dataColumnSidecarArchive: DataColumnSidecarArchiveRepository;
37
39
 
40
+ executionPayloadEnvelope: ExecutionPayloadEnvelopeRepository;
41
+ executionPayloadEnvelopeArchive: ExecutionPayloadEnvelopeArchiveRepository;
42
+
38
43
  // finalized states
39
44
  stateArchive: StateArchiveRepository;
40
45
  // checkpoint states
@@ -1,7 +1,8 @@
1
1
  import {ChainForkConfig} from "@lodestar/config";
2
2
  import {Db, PrefixedRepository, decodeNumberForDbKey, encodeNumberForDbKey} from "@lodestar/db";
3
3
  import {NUMBER_OF_COLUMNS} from "@lodestar/params";
4
- import {ColumnIndex, Root, fulu, ssz} from "@lodestar/types";
4
+ import {ColumnIndex, DataColumnSidecar, Root, isGloasDataColumnSidecar, ssz} from "@lodestar/types";
5
+ import {isGloasDataColumnSidecarBytes} from "../../util/multifork.js";
5
6
  import {Bucket, getBucketNameByValue} from "../buckets.js";
6
7
 
7
8
  const COLUMN_INDEX_BYTE_SIZE = 2;
@@ -15,7 +16,7 @@ type BlockRoot = Root;
15
16
  *
16
17
  * Indexed data by `blockRoot` + `columnIndex`
17
18
  */
18
- export class DataColumnSidecarRepository extends PrefixedRepository<BlockRoot, ColumnIndex, fulu.DataColumnSidecar> {
19
+ export class DataColumnSidecarRepository extends PrefixedRepository<BlockRoot, ColumnIndex, DataColumnSidecar> {
19
20
  constructor(config: ChainForkConfig, db: Db) {
20
21
  const bucket = Bucket.fulu_dataColumnSidecars;
21
22
  super(config, db, bucket, ssz.fulu.DataColumnSidecar, getBucketNameByValue(bucket));
@@ -24,10 +25,24 @@ export class DataColumnSidecarRepository extends PrefixedRepository<BlockRoot, C
24
25
  /**
25
26
  * Id is hashTreeRoot of unsigned BeaconBlock
26
27
  */
27
- getId(value: fulu.DataColumnSidecar): ColumnIndex {
28
+ getId(value: DataColumnSidecar): ColumnIndex {
28
29
  return value.index;
29
30
  }
30
31
 
32
+ encodeValue(value: DataColumnSidecar): Uint8Array {
33
+ if (isGloasDataColumnSidecar(value)) {
34
+ return ssz.gloas.DataColumnSidecar.serialize(value);
35
+ }
36
+ return ssz.fulu.DataColumnSidecar.serialize(value);
37
+ }
38
+
39
+ decodeValue(data: Uint8Array): DataColumnSidecar {
40
+ if (isGloasDataColumnSidecarBytes(data)) {
41
+ return ssz.gloas.DataColumnSidecar.deserialize(data);
42
+ }
43
+ return ssz.fulu.DataColumnSidecar.deserialize(data);
44
+ }
45
+
31
46
  encodeKeyRaw(prefix: BlockRoot, id: ColumnIndex): Uint8Array {
32
47
  return Buffer.concat([prefix, encodeNumberForDbKey(id, COLUMN_INDEX_BYTE_SIZE)]);
33
48
  }
@@ -1,7 +1,8 @@
1
1
  import {ChainForkConfig} from "@lodestar/config";
2
2
  import {Db, PrefixedRepository, decodeNumberForDbKey, encodeNumberForDbKey} from "@lodestar/db";
3
3
  import {NUMBER_OF_COLUMNS} from "@lodestar/params";
4
- import {ColumnIndex, Slot, fulu, ssz} from "@lodestar/types";
4
+ import {ColumnIndex, DataColumnSidecar, Slot, isGloasDataColumnSidecar, ssz} from "@lodestar/types";
5
+ import {isGloasDataColumnSidecarBytes} from "../../util/multifork.js";
5
6
  import {Bucket, getBucketNameByValue} from "../buckets.js";
6
7
 
7
8
  const COLUMN_INDEX_BYTE_SIZE = 2;
@@ -13,7 +14,7 @@ const SLOT_BYTE_SIZE = 8;
13
14
  *
14
15
  * Indexed data by `slot` + `columnIndex`
15
16
  */
16
- export class DataColumnSidecarArchiveRepository extends PrefixedRepository<Slot, ColumnIndex, fulu.DataColumnSidecar> {
17
+ export class DataColumnSidecarArchiveRepository extends PrefixedRepository<Slot, ColumnIndex, DataColumnSidecar> {
17
18
  constructor(config: ChainForkConfig, db: Db) {
18
19
  const bucket = Bucket.fulu_dataColumnSidecarsArchive;
19
20
  super(config, db, bucket, ssz.fulu.DataColumnSidecar, getBucketNameByValue(bucket));
@@ -22,10 +23,24 @@ export class DataColumnSidecarArchiveRepository extends PrefixedRepository<Slot,
22
23
  /**
23
24
  * Id is hashTreeRoot of unsigned BeaconBlock
24
25
  */
25
- getId(value: fulu.DataColumnSidecar): ColumnIndex {
26
+ getId(value: DataColumnSidecar): ColumnIndex {
26
27
  return value.index;
27
28
  }
28
29
 
30
+ encodeValue(value: DataColumnSidecar): Uint8Array {
31
+ if (isGloasDataColumnSidecar(value)) {
32
+ return ssz.gloas.DataColumnSidecar.serialize(value);
33
+ }
34
+ return ssz.fulu.DataColumnSidecar.serialize(value);
35
+ }
36
+
37
+ decodeValue(data: Uint8Array): DataColumnSidecar {
38
+ if (isGloasDataColumnSidecarBytes(data)) {
39
+ return ssz.gloas.DataColumnSidecar.deserialize(data);
40
+ }
41
+ return ssz.fulu.DataColumnSidecar.deserialize(data);
42
+ }
43
+
29
44
  encodeKeyRaw(prefix: Slot, id: ColumnIndex): Uint8Array {
30
45
  return Buffer.concat([
31
46
  encodeNumberForDbKey(prefix, SLOT_BYTE_SIZE),
@@ -0,0 +1,26 @@
1
+ import {ChainForkConfig} from "@lodestar/config";
2
+ import {Db, Repository} from "@lodestar/db";
3
+ import {Root, gloas, ssz} from "@lodestar/types";
4
+ import {Bucket, getBucketNameByValue} from "../buckets.js";
5
+
6
+ type BlockRoot = Root;
7
+
8
+ /**
9
+ * Used to store unfinalized `SignedExecutionPayloadEnvelope`
10
+ *
11
+ * Indexed by beacon block root (root of the beacon block that contains the bid)
12
+ */
13
+ export class ExecutionPayloadEnvelopeRepository extends Repository<BlockRoot, gloas.SignedExecutionPayloadEnvelope> {
14
+ constructor(config: ChainForkConfig, db: Db) {
15
+ const bucket = Bucket.gloas_executionPayloadEnvelope;
16
+ super(config, db, bucket, ssz.gloas.SignedExecutionPayloadEnvelope, getBucketNameByValue(bucket));
17
+ }
18
+
19
+ /**
20
+ * Id is the beacon block root (not execution payload hash)
21
+ * This allows correlation with the block that contains the bid
22
+ */
23
+ getId(value: gloas.SignedExecutionPayloadEnvelope): BlockRoot {
24
+ return value.message.beaconBlockRoot;
25
+ }
26
+ }
@@ -0,0 +1,32 @@
1
+ import {ChainForkConfig} from "@lodestar/config";
2
+ import {BUCKET_LENGTH, Db, Repository, encodeKey as encodeDbKey} from "@lodestar/db";
3
+ import {Slot, gloas, ssz} from "@lodestar/types";
4
+ import {bytesToInt} from "@lodestar/utils";
5
+ import {Bucket, getBucketNameByValue} from "../buckets.js";
6
+
7
+ /**
8
+ * Used to store finalized `SignedExecutionPayloadEnvelope`
9
+ *
10
+ * Indexed by slot for chronological archival
11
+ */
12
+ export class ExecutionPayloadEnvelopeArchiveRepository extends Repository<Slot, gloas.SignedExecutionPayloadEnvelope> {
13
+ constructor(config: ChainForkConfig, db: Db) {
14
+ const bucket = Bucket.gloas_executionPayloadEnvelopeArchive;
15
+ super(config, db, bucket, ssz.gloas.SignedExecutionPayloadEnvelope, getBucketNameByValue(bucket));
16
+ }
17
+
18
+ /**
19
+ * Id is the slot from the envelope
20
+ */
21
+ getId(value: gloas.SignedExecutionPayloadEnvelope): Slot {
22
+ return value.message.slot;
23
+ }
24
+
25
+ encodeKey(id: Slot): Uint8Array {
26
+ return encodeDbKey(this.bucket, id);
27
+ }
28
+
29
+ decodeKey(data: Uint8Array): number {
30
+ return bytesToInt(data.subarray(BUCKET_LENGTH), "be");
31
+ }
32
+ }
@@ -8,6 +8,8 @@ export {BlockArchiveRepository} from "./blockArchive.js";
8
8
  export {BLSToExecutionChangeRepository} from "./blsToExecutionChange.js";
9
9
  export {DataColumnSidecarRepository} from "./dataColumnSidecar.js";
10
10
  export {DataColumnSidecarArchiveRepository} from "./dataColumnSidecarArchive.js";
11
+ export {ExecutionPayloadEnvelopeRepository} from "./executionPayloadEnvelope.js";
12
+ export {ExecutionPayloadEnvelopeArchiveRepository} from "./executionPayloadEnvelopeArchive.js";
11
13
  export {BestLightClientUpdateRepository} from "./lightclientBestUpdate.js";
12
14
  export {CheckpointHeaderRepository} from "./lightclientCheckpointHeader.js";
13
15
  export {SyncCommitteeRepository} from "./lightclientSyncCommittee.js";
@@ -11,6 +11,7 @@ import {computeEpochAtSlot} from "@lodestar/state-transition";
11
11
  import {
12
12
  AttesterSlashing,
13
13
  DataColumnSidecar,
14
+ DataColumnSidecars,
14
15
  LightClientBootstrap,
15
16
  LightClientFinalityUpdate,
16
17
  LightClientOptimisticUpdate,
@@ -26,6 +27,7 @@ import {
26
27
  deneb,
27
28
  fulu,
28
29
  gloas,
30
+ isGloasDataColumnSidecar,
29
31
  phase0,
30
32
  } from "@lodestar/types";
31
33
  import {prettyPrintIndices, sleep} from "@lodestar/utils";
@@ -35,7 +37,7 @@ import {computeSubnetForDataColumnSidecar} from "../chain/validation/dataColumnS
35
37
  import {IBeaconDb} from "../db/interface.js";
36
38
  import {Metrics, RegistryMetricCreator} from "../metrics/index.js";
37
39
  import {IClock} from "../util/clock.js";
38
- import {CustodyConfig, isGloasDataColumnSidecar} from "../util/dataColumns.js";
40
+ import {CustodyConfig} from "../util/dataColumns.js";
39
41
  import {PeerIdStr, peerIdToString} from "../util/peerId.js";
40
42
  import {promiseAllMaybeAsync} from "../util/promises.js";
41
43
  import {BeaconBlocksByRootRequest, BlobSidecarsByRootRequest, DataColumnSidecarsByRootRequest} from "../util/types.js";
@@ -781,7 +783,7 @@ export class Network implements INetwork {
781
783
  this.core.setTargetGroupCount(count);
782
784
  };
783
785
 
784
- private onPublishDataColumns = (sidecars: DataColumnSidecar[]): Promise<number[]> => {
786
+ private onPublishDataColumns = (sidecars: DataColumnSidecars): Promise<number[]> => {
785
787
  return promiseAllMaybeAsync(sidecars.map((sidecar) => () => this.publishDataColumnSidecar(sidecar)));
786
788
  };
787
789
 
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,7 +16,6 @@ import {
15
16
  BeaconBlockBody,
16
17
  ColumnIndex,
17
18
  CustodyIndex,
18
- DataColumnSidecar,
19
19
  Root,
20
20
  SSZTypesFor,
21
21
  SignedBeaconBlock,
@@ -272,7 +272,7 @@ export async function getCellsAndProofs(
272
272
  */
273
273
  export function getBlobKzgCommitments(
274
274
  fork: ForkName,
275
- signedBlock: SignedBeaconBlock<ForkPostFulu>
275
+ signedBlock: SignedBeaconBlock<ForkPostDeneb>
276
276
  ): deneb.KZGCommitment[] {
277
277
  if (isForkPostGloas(fork)) {
278
278
  return (signedBlock as gloas.SignedBeaconBlock).message.body.signedExecutionPayloadBid.message.blobKzgCommitments;
@@ -280,11 +280,6 @@ export function getBlobKzgCommitments(
280
280
  return (signedBlock.message.body as BeaconBlockBody<ForkPostFulu & ForkPreGloas>).blobKzgCommitments;
281
281
  }
282
282
 
283
- /** Type guard for `gloas.DataColumnSidecar` */
284
- export function isGloasDataColumnSidecar(sidecar: DataColumnSidecar): sidecar is gloas.DataColumnSidecar {
285
- return (sidecar as gloas.DataColumnSidecar).beaconBlockRoot !== undefined;
286
- }
287
-
288
283
  /**
289
284
  * Given a signed block header and the commitments, inclusion proof, cells/proofs associated with
290
285
  * each blob in the block, assemble the sidecars which can be distributed to peers.