@lodestar/beacon-node 1.44.0-dev.552cdce8d0 → 1.44.0-dev.6c5c48ad59

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 (164) hide show
  1. package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/blocks/index.js +30 -0
  3. package/lib/api/impl/beacon/blocks/index.js.map +1 -1
  4. package/lib/api/impl/beacon/pool/index.d.ts.map +1 -1
  5. package/lib/api/impl/beacon/pool/index.js +1 -1
  6. package/lib/api/impl/beacon/pool/index.js.map +1 -1
  7. package/lib/api/impl/config/constants.d.ts +1 -0
  8. package/lib/api/impl/config/constants.d.ts.map +1 -1
  9. package/lib/api/impl/config/constants.js +2 -1
  10. package/lib/api/impl/config/constants.js.map +1 -1
  11. package/lib/api/impl/debug/index.d.ts.map +1 -1
  12. package/lib/api/impl/debug/index.js +69 -12
  13. package/lib/api/impl/debug/index.js.map +1 -1
  14. package/lib/api/impl/validator/index.d.ts.map +1 -1
  15. package/lib/api/impl/validator/index.js +101 -42
  16. package/lib/api/impl/validator/index.js.map +1 -1
  17. package/lib/chain/archiveStore/archiveStore.d.ts +0 -1
  18. package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
  19. package/lib/chain/archiveStore/archiveStore.js +0 -4
  20. package/lib/chain/archiveStore/archiveStore.js.map +1 -1
  21. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  22. package/lib/chain/blocks/importBlock.js +5 -2
  23. package/lib/chain/blocks/importBlock.js.map +1 -1
  24. package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
  25. package/lib/chain/blocks/importExecutionPayload.js +5 -3
  26. package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
  27. package/lib/chain/chain.d.ts +1 -1
  28. package/lib/chain/chain.d.ts.map +1 -1
  29. package/lib/chain/chain.js +2 -1
  30. package/lib/chain/chain.js.map +1 -1
  31. package/lib/chain/errors/executionPayloadBid.d.ts +11 -1
  32. package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -1
  33. package/lib/chain/errors/executionPayloadBid.js +2 -0
  34. package/lib/chain/errors/executionPayloadBid.js.map +1 -1
  35. package/lib/chain/errors/payloadAttestation.d.ts +6 -0
  36. package/lib/chain/errors/payloadAttestation.d.ts.map +1 -1
  37. package/lib/chain/errors/payloadAttestation.js +1 -0
  38. package/lib/chain/errors/payloadAttestation.js.map +1 -1
  39. package/lib/chain/forkChoice/index.d.ts.map +1 -1
  40. package/lib/chain/forkChoice/index.js +14 -4
  41. package/lib/chain/forkChoice/index.js.map +1 -1
  42. package/lib/chain/opPools/executionPayloadBidPool.d.ts +4 -4
  43. package/lib/chain/opPools/executionPayloadBidPool.d.ts.map +1 -1
  44. package/lib/chain/opPools/executionPayloadBidPool.js +6 -4
  45. package/lib/chain/opPools/executionPayloadBidPool.js.map +1 -1
  46. package/lib/chain/prepareNextSlot.d.ts.map +1 -1
  47. package/lib/chain/prepareNextSlot.js +2 -1
  48. package/lib/chain/prepareNextSlot.js.map +1 -1
  49. package/lib/chain/produceBlock/produceBlockBody.d.ts +7 -1
  50. package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
  51. package/lib/chain/produceBlock/produceBlockBody.js +107 -18
  52. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  53. package/lib/chain/regen/interface.d.ts +2 -1
  54. package/lib/chain/regen/interface.d.ts.map +1 -1
  55. package/lib/chain/regen/interface.js +2 -0
  56. package/lib/chain/regen/interface.js.map +1 -1
  57. package/lib/chain/regen/queued.d.ts +0 -1
  58. package/lib/chain/regen/queued.d.ts.map +1 -1
  59. package/lib/chain/regen/queued.js +0 -4
  60. package/lib/chain/regen/queued.js.map +1 -1
  61. package/lib/chain/stateCache/fifoBlockStateCache.d.ts +0 -5
  62. package/lib/chain/stateCache/fifoBlockStateCache.d.ts.map +1 -1
  63. package/lib/chain/stateCache/fifoBlockStateCache.js +0 -5
  64. package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
  65. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +1 -4
  66. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  67. package/lib/chain/stateCache/persistentCheckpointsCache.js +5 -2
  68. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  69. package/lib/chain/stateCache/types.d.ts +0 -2
  70. package/lib/chain/stateCache/types.d.ts.map +1 -1
  71. package/lib/chain/stateCache/types.js.map +1 -1
  72. package/lib/chain/validation/executionPayloadBid.d.ts +7 -3
  73. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
  74. package/lib/chain/validation/executionPayloadBid.js +58 -15
  75. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  76. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
  77. package/lib/chain/validation/payloadAttestationMessage.js +24 -4
  78. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  79. package/lib/chain/validatorMonitor.d.ts +1 -0
  80. package/lib/chain/validatorMonitor.d.ts.map +1 -1
  81. package/lib/chain/validatorMonitor.js +16 -0
  82. package/lib/chain/validatorMonitor.js.map +1 -1
  83. package/lib/execution/builder/index.d.ts +1 -2
  84. package/lib/execution/builder/index.d.ts.map +1 -1
  85. package/lib/execution/builder/index.js +0 -1
  86. package/lib/execution/builder/index.js.map +1 -1
  87. package/lib/execution/engine/interface.d.ts +1 -0
  88. package/lib/execution/engine/interface.d.ts.map +1 -1
  89. package/lib/execution/engine/types.d.ts +2 -0
  90. package/lib/execution/engine/types.d.ts.map +1 -1
  91. package/lib/execution/engine/types.js +2 -0
  92. package/lib/execution/engine/types.js.map +1 -1
  93. package/lib/metrics/metrics/lodestar.d.ts +1 -1
  94. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  95. package/lib/metrics/metrics/lodestar.js +4 -3
  96. package/lib/metrics/metrics/lodestar.js.map +1 -1
  97. package/lib/network/gossip/topic.d.ts +1 -1
  98. package/lib/network/interface.d.ts +1 -0
  99. package/lib/network/interface.d.ts.map +1 -1
  100. package/lib/network/network.d.ts +1 -0
  101. package/lib/network/network.d.ts.map +1 -1
  102. package/lib/network/network.js +5 -0
  103. package/lib/network/network.js.map +1 -1
  104. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  105. package/lib/network/processor/gossipHandlers.js +12 -4
  106. package/lib/network/processor/gossipHandlers.js.map +1 -1
  107. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
  108. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +5 -0
  109. package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
  110. package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js +1 -1
  111. package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js.map +1 -1
  112. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +3 -3
  113. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -1
  114. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.d.ts +2 -1
  115. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.d.ts.map +1 -1
  116. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js +15 -1
  117. package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js.map +1 -1
  118. package/lib/network/reqresp/handlers/index.js +2 -2
  119. package/lib/network/reqresp/handlers/index.js.map +1 -1
  120. package/lib/network/reqresp/utils/dataColumnResponseValidation.d.ts.map +1 -1
  121. package/lib/network/reqresp/utils/dataColumnResponseValidation.js +22 -3
  122. package/lib/network/reqresp/utils/dataColumnResponseValidation.js.map +1 -1
  123. package/package.json +14 -16
  124. package/src/api/impl/beacon/blocks/index.ts +36 -0
  125. package/src/api/impl/beacon/pool/index.ts +3 -1
  126. package/src/api/impl/config/constants.ts +2 -0
  127. package/src/api/impl/debug/index.ts +73 -12
  128. package/src/api/impl/validator/index.ts +112 -43
  129. package/src/chain/archiveStore/archiveStore.ts +0 -5
  130. package/src/chain/blocks/importBlock.ts +10 -2
  131. package/src/chain/blocks/importExecutionPayload.ts +8 -2
  132. package/src/chain/chain.ts +2 -0
  133. package/src/chain/errors/executionPayloadBid.ts +6 -1
  134. package/src/chain/errors/payloadAttestation.ts +2 -0
  135. package/src/chain/forkChoice/index.ts +14 -4
  136. package/src/chain/opPools/executionPayloadBidPool.ts +10 -9
  137. package/src/chain/prepareNextSlot.ts +2 -1
  138. package/src/chain/produceBlock/produceBlockBody.ts +158 -25
  139. package/src/chain/regen/interface.ts +2 -1
  140. package/src/chain/regen/queued.ts +0 -5
  141. package/src/chain/stateCache/fifoBlockStateCache.ts +0 -6
  142. package/src/chain/stateCache/persistentCheckpointsCache.ts +6 -2
  143. package/src/chain/stateCache/types.ts +0 -2
  144. package/src/chain/validation/executionPayloadBid.ts +66 -19
  145. package/src/chain/validation/payloadAttestationMessage.ts +26 -4
  146. package/src/chain/validatorMonitor.ts +18 -0
  147. package/src/execution/builder/index.ts +1 -4
  148. package/src/execution/engine/interface.ts +1 -0
  149. package/src/execution/engine/types.ts +4 -0
  150. package/src/metrics/metrics/lodestar.ts +4 -3
  151. package/src/network/interface.ts +1 -0
  152. package/src/network/network.ts +11 -0
  153. package/src/network/processor/gossipHandlers.ts +17 -4
  154. package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +6 -0
  155. package/src/network/reqresp/handlers/dataColumnSidecarsByRoot.ts +1 -1
  156. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +3 -3
  157. package/src/network/reqresp/handlers/executionPayloadEnvelopesByRoot.ts +20 -1
  158. package/src/network/reqresp/handlers/index.ts +2 -2
  159. package/src/network/reqresp/utils/dataColumnResponseValidation.ts +21 -3
  160. package/lib/execution/builder/utils.d.ts +0 -5
  161. package/lib/execution/builder/utils.d.ts.map +0 -1
  162. package/lib/execution/builder/utils.js +0 -17
  163. package/lib/execution/builder/utils.js.map +0 -1
  164. package/src/execution/builder/utils.ts +0 -19
@@ -245,6 +245,8 @@ export type PayloadAttributesRpc = {
245
245
  parentBeaconBlockRoot?: DATA;
246
246
  /** QUANTITY, 64 Bits - value for the slot number field of the new payload (EIP-7843) */
247
247
  slotNumber?: QUANTITY;
248
+ /** QUANTITY, 64 Bits - target value for the gasLimit field of the new payload (GLOAS, execution-apis#796) */
249
+ targetGasLimit?: QUANTITY;
248
250
  };
249
251
 
250
252
  export type ClientVersionRpc = {
@@ -425,6 +427,7 @@ export function serializePayloadAttributes(data: PayloadAttributes): PayloadAttr
425
427
  withdrawals: data.withdrawals?.map(serializeWithdrawal),
426
428
  parentBeaconBlockRoot: data.parentBeaconBlockRoot ? bytesToData(data.parentBeaconBlockRoot) : undefined,
427
429
  slotNumber: data.slotNumber !== undefined ? numToQuantity(data.slotNumber) : undefined,
430
+ targetGasLimit: data.targetGasLimit !== undefined ? numToQuantity(data.targetGasLimit) : undefined,
428
431
  };
429
432
  }
430
433
 
@@ -442,6 +445,7 @@ export function deserializePayloadAttributes(data: PayloadAttributesRpc): Payloa
442
445
  withdrawals: data.withdrawals?.map((withdrawal) => deserializeWithdrawal(withdrawal)),
443
446
  parentBeaconBlockRoot: data.parentBeaconBlockRoot ? dataToBytes(data.parentBeaconBlockRoot, 32) : undefined,
444
447
  slotNumber: data.slotNumber !== undefined ? quantityToNum(data.slotNumber) : undefined,
448
+ targetGasLimit: data.targetGasLimit !== undefined ? quantityToNum(data.targetGasLimit) : undefined,
445
449
  };
446
450
  }
447
451
 
@@ -987,10 +987,11 @@ export function createLodestarMetrics(
987
987
  }),
988
988
  },
989
989
  importPayload: {
990
- bySource: register.gauge<{source: PayloadEnvelopeInputSource}>({
991
- name: "lodestar_import_payload_by_source_total",
992
- help: "Total number of imported execution payload envelopes by source",
990
+ elapsedTimeTillImported: register.histogram<{source: PayloadEnvelopeInputSource}>({
991
+ name: "lodestar_import_payload_elapsed_time_till_imported_seconds",
992
+ help: "Time elapsed between slot time and the time execution payload envelope is imported (added to fork choice)",
993
993
  labelNames: ["source"],
994
+ buckets: [1, 2, 3, 6, 9, 12],
994
995
  }),
995
996
  columnsBySource: register.gauge<{source: PayloadEnvelopeInputSource}>({
996
997
  name: "lodestar_import_payload_columns_by_source_total",
@@ -113,6 +113,7 @@ export interface INetwork extends INetworkCorePublic {
113
113
  publishLightClientFinalityUpdate(update: LightClientFinalityUpdate): Promise<number>;
114
114
  publishLightClientOptimisticUpdate(update: LightClientOptimisticUpdate): Promise<number>;
115
115
  publishSignedExecutionPayloadEnvelope(signedEnvelope: gloas.SignedExecutionPayloadEnvelope): Promise<number>;
116
+ publishSignedExecutionPayloadBid(signedBid: gloas.SignedExecutionPayloadBid): Promise<number>;
116
117
  publishPayloadAttestationMessage(payloadAttestationMessage: gloas.PayloadAttestationMessage): Promise<number>;
117
118
  publishProposerPreferences(signedProposerPreferences: gloas.SignedProposerPreferences): Promise<number>;
118
119
 
@@ -515,6 +515,17 @@ export class Network implements INetwork {
515
515
  );
516
516
  }
517
517
 
518
+ async publishSignedExecutionPayloadBid(signedBid: gloas.SignedExecutionPayloadBid): Promise<number> {
519
+ const epoch = computeEpochAtSlot(signedBid.message.slot);
520
+ const boundary = this.config.getForkBoundaryAtEpoch(epoch);
521
+
522
+ return this.publishGossip<GossipType.execution_payload_bid>(
523
+ {type: GossipType.execution_payload_bid, boundary},
524
+ signedBid,
525
+ {ignoreDuplicatePublishError: true}
526
+ );
527
+ }
528
+
518
529
  async publishPayloadAttestationMessage(payloadAttestationMessage: gloas.PayloadAttestationMessage): Promise<number> {
519
530
  const epoch = computeEpochAtSlot(payloadAttestationMessage.data.slot);
520
531
  const boundary = this.config.getForkBoundaryAtEpoch(epoch);
@@ -1117,7 +1117,16 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
1117
1117
  }
1118
1118
 
1119
1119
  const slot = envelope.payload.slotNumber;
1120
- const delaySec = seenTimestampSec - computeTimeAtSlot(config, slot, chain.genesisTime);
1120
+ const delaySec = chain.clock.secFromSlot(slot, seenTimestampSec);
1121
+
1122
+ logger.debug("Received gossip payload envelope", {
1123
+ currentSlot: chain.clock.currentSlot,
1124
+ peerId: peerIdStr,
1125
+ slot,
1126
+ blockRoot: toRootHex(envelope.beaconBlockRoot),
1127
+ delaySec,
1128
+ });
1129
+
1121
1130
  metrics?.gossipExecutionPayloadEnvelope.elapsedTimeTillReceived.observe({source: OpSource.gossip}, delaySec);
1122
1131
  chain.validatorMonitor?.registerExecutionPayloadEnvelope(OpSource.gossip, delaySec, signedEnvelope);
1123
1132
 
@@ -1205,8 +1214,10 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
1205
1214
  }
1206
1215
  chain.forkChoice.notifyPtcMessages(
1207
1216
  toRootHex(payloadAttestationMessage.data.beaconBlockRoot),
1217
+ payloadAttestationMessage.data.slot,
1208
1218
  validationResult.validatorCommitteeIndices,
1209
- payloadAttestationMessage.data.payloadPresent
1219
+ payloadAttestationMessage.data.payloadPresent,
1220
+ payloadAttestationMessage.data.blobDataAvailable
1210
1221
  );
1211
1222
  },
1212
1223
  [GossipType.execution_payload_bid]: async ({
@@ -1215,16 +1226,18 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
1215
1226
  }: GossipHandlerParamGeneric<GossipType.execution_payload_bid>) => {
1216
1227
  const {serializedData} = gossipData;
1217
1228
  const executionPayloadBid = sszDeserialize(topic, serializedData);
1218
- await validateGossipExecutionPayloadBid(chain, executionPayloadBid);
1229
+ const {proposerIndex} = await validateGossipExecutionPayloadBid(chain, executionPayloadBid);
1219
1230
 
1220
1231
  // Handle valid payload bid by storing in a bid pool
1221
1232
  try {
1222
- const insertOutcome = chain.executionPayloadBidPool.add(executionPayloadBid.message);
1233
+ const insertOutcome = chain.executionPayloadBidPool.add(executionPayloadBid);
1223
1234
  metrics?.opPool.executionPayloadBidPool.gossipInsertOutcome.inc({insertOutcome});
1224
1235
  } catch (e) {
1225
1236
  logger.error("Error adding to executionPayloadBid pool", {}, e as Error);
1226
1237
  }
1227
1238
 
1239
+ chain.validatorMonitor?.registerExecutionPayloadBid(OpSource.gossip, proposerIndex, executionPayloadBid.message);
1240
+
1228
1241
  chain.emitter.emit(routes.events.EventType.executionPayloadBid, {
1229
1242
  version: config.getForkName(executionPayloadBid.message.slot),
1230
1243
  data: executionPayloadBid,
@@ -1,5 +1,6 @@
1
1
  import {PeerId} from "@libp2p/interface";
2
2
  import {ChainConfig} from "@lodestar/config";
3
+ import {PayloadStatus} from "@lodestar/fork-choice";
3
4
  import {ForkSeq, GENESIS_SLOT} from "@lodestar/params";
4
5
  import {RespStatus, ResponseError, ResponseOutgoing} from "@lodestar/reqresp";
5
6
  import {computeEpochAtSlot} from "@lodestar/state-transition";
@@ -104,6 +105,11 @@ export async function* onDataColumnSidecarsByRange(
104
105
 
105
106
  // Must include only columns in the range requested
106
107
  if (block.slot > archiveMaxSlot && block.slot >= startSlot && block.slot < endSlot) {
108
+ // Post-gloas, columns exist only for FULL blocks (pre-gloas blocks are always FULL)
109
+ if (block.payloadStatus !== PayloadStatus.FULL) {
110
+ continue;
111
+ }
112
+
107
113
  // Note: Here the forkChoice head may change due to a re-org, so the headChain reflects the canonical chain
108
114
  // at the time of the start of the request. Spec is clear the chain of columns must be consistent, but on
109
115
  // re-org there's no need to abort the request
@@ -30,7 +30,7 @@ export async function* onDataColumnSidecarsByRoot(
30
30
  const {blockRoot, columns: requestedColumns} = dataColumnsByRootIdentifier;
31
31
  const availableColumns = validateRequestedDataColumns(chain, requestedColumns);
32
32
  if (availableColumns.length === 0) {
33
- return;
33
+ continue;
34
34
  }
35
35
 
36
36
  const blockRootHex = toRootHex(blockRoot);
@@ -20,9 +20,9 @@ export async function* onExecutionPayloadEnvelopesByRange(
20
20
  }
21
21
 
22
22
  const finalized = db.executionPayloadEnvelopeArchive;
23
- const finalizedSlot = chain.forkChoice.getFinalizedCheckpointSlot();
24
- // The current finalized block's envelope is still in the hot db; archive migration happens
25
- // in the next finalization run (see migrateExecutionPayloadEnvelopesFromHotToColdDb).
23
+ // Use the finalized block's actual slot as the checkpoint epoch-boundary slot may be skipped
24
+ const finalizedSlot = chain.forkChoice.getFinalizedBlock().slot;
25
+ // The finalized block's envelope stays in the hot db until the next finalization run
26
26
  const archiveMaxSlot = finalizedSlot - 1;
27
27
 
28
28
  // Finalized range of envelopes
@@ -1,14 +1,18 @@
1
+ import {PeerId} from "@libp2p/interface";
1
2
  import {ResponseOutgoing} from "@lodestar/reqresp";
2
3
  import {computeEpochAtSlot} from "@lodestar/state-transition";
3
4
  import {toRootHex} from "@lodestar/utils";
4
5
  import {IBeaconChain} from "../../../chain/index.js";
5
6
  import {IBeaconDb} from "../../../db/index.js";
6
7
  import {ExecutionPayloadEnvelopesByRootRequest} from "../../../util/types.js";
8
+ import {prettyPrintPeerId} from "../../util.js";
7
9
 
8
10
  export async function* onExecutionPayloadEnvelopesByRoot(
9
11
  requestBody: ExecutionPayloadEnvelopesByRootRequest,
10
12
  chain: IBeaconChain,
11
- db: IBeaconDb
13
+ db: IBeaconDb,
14
+ peerId: PeerId,
15
+ peerClient: string
12
16
  ): AsyncIterable<ResponseOutgoing> {
13
17
  // The gloas req/resp spec uses MIN_EPOCHS_FOR_BLOCK_REQUESTS to define the minimum range peers MUST serve.
14
18
  // Archival nodes may still serve older retained payloads to allow genesis sync.
@@ -20,6 +24,14 @@ export async function* onExecutionPayloadEnvelopesByRoot(
20
24
  const slot = block ? block.slot : await db.blockArchive.getSlotByRoot(root);
21
25
 
22
26
  if (slot === null) {
27
+ chain.logger.debug(
28
+ "Cannot serve ExecutionPayloadEnvelopesByRoot: block root not in fork choice or block archive",
29
+ {
30
+ root: rootHex,
31
+ peer: prettyPrintPeerId(peerId),
32
+ client: peerClient,
33
+ }
34
+ );
23
35
  continue;
24
36
  }
25
37
 
@@ -29,6 +41,13 @@ export async function* onExecutionPayloadEnvelopesByRoot(
29
41
  data: envelopeBytes,
30
42
  boundary: chain.config.getForkBoundaryAtEpoch(computeEpochAtSlot(slot)),
31
43
  };
44
+ } else {
45
+ chain.logger.debug("Cannot serve ExecutionPayloadEnvelopesByRoot: envelope not found", {
46
+ slot,
47
+ root: rootHex,
48
+ peer: prettyPrintPeerId(peerId),
49
+ client: peerClient,
50
+ });
32
51
  }
33
52
  }
34
53
  }
@@ -70,9 +70,9 @@ export function getReqRespHandlers({db, chain}: {db: IBeaconDb; chain: IBeaconCh
70
70
  return onDataColumnSidecarsByRoot(body, chain, db, peerId, peerClient);
71
71
  },
72
72
 
73
- [ReqRespMethod.ExecutionPayloadEnvelopesByRoot]: (req) => {
73
+ [ReqRespMethod.ExecutionPayloadEnvelopesByRoot]: (req, peerId, peerClient) => {
74
74
  const body = ExecutionPayloadEnvelopesByRootRequestType(chain.config).deserialize(req.data);
75
- return onExecutionPayloadEnvelopesByRoot(body, chain, db);
75
+ return onExecutionPayloadEnvelopesByRoot(body, chain, db, peerId, peerClient);
76
76
  },
77
77
  [ReqRespMethod.ExecutionPayloadEnvelopesByRange]: (req) => {
78
78
  const body = ssz.gloas.ExecutionPayloadEnvelopesByRangeRequest.deserialize(req.data);
@@ -1,4 +1,5 @@
1
1
  import {LogData} from "@lodestar/logger";
2
+ import {ForkSeq} from "@lodestar/params";
2
3
  import {RespStatus, ResponseError} from "@lodestar/reqresp";
3
4
  import {ColumnIndex, Slot} from "@lodestar/types";
4
5
  import {prettyBytes, prettyPrintIndices, toRootHex} from "@lodestar/utils";
@@ -38,6 +39,13 @@ export async function handleColumnSidecarUnavailability({
38
39
 
39
40
  chain.logger.debug("dataColumnSidecar requested unavailable", logData);
40
41
 
42
+ // Post-gloas, columns exist only for FULL blocks; a finalized block is FULL if its envelope was
43
+ // archived. Bid blobsCount is unreliable here since an EMPTY block's bid may still commit to blobs
44
+ if (blockRoot === undefined && chain.config.getForkSeq(slot) >= ForkSeq.gloas) {
45
+ const envelopeBytes = await db.executionPayloadEnvelopeArchive.getBinary(slot);
46
+ if (!envelopeBytes) return;
47
+ }
48
+
41
49
  const blockBytes = blockRoot ? await db.block.getBinary(blockRoot) : await db.blockArchive.getBinary(slot);
42
50
  if (!blockBytes) {
43
51
  chain.logger.verbose(
@@ -71,9 +79,19 @@ export function validateRequestedDataColumns(chain: IBeaconChain, requestedColum
71
79
  throw new ResponseError(RespStatus.INVALID_REQUEST, "dataColumnSidecar requested without column indices");
72
80
  }
73
81
 
74
- const custodyColumns = chain.custodyConfig.custodyColumns;
75
- const availableColumns = requestedColumns.filter((c) => custodyColumns.includes(c));
76
- const missingColumns = requestedColumns.filter((c) => !custodyColumns.includes(c));
82
+ const {custodyColumns, custodyColumnsIndex} = chain.custodyConfig;
83
+ const availableColumns: ColumnIndex[] = [];
84
+ const missingColumns: ColumnIndex[] = [];
85
+ for (const c of requestedColumns) {
86
+ // `c` is peer-controlled and SSZ-deserialized as `uint64`, so it may exceed
87
+ // `NUMBER_OF_COLUMNS - 1`; `Uint8Array` returns `undefined` for OOB reads,
88
+ // and `undefined !== 0` would silently classify OOB indices as custodied.
89
+ if ((custodyColumnsIndex[c] ?? 0) !== 0) {
90
+ availableColumns.push(c);
91
+ } else {
92
+ missingColumns.push(c);
93
+ }
94
+ }
77
95
 
78
96
  if (missingColumns.length > 0) {
79
97
  chain.logger.verbose("Requested dataColumnSidecar for non-custody columns", {
@@ -1,5 +0,0 @@
1
- /**
2
- * Calculates expected gas limit based on parent gas limit and target gas limit
3
- */
4
- export declare function getExpectedGasLimit(parentGasLimit: number, targetGasLimit: number): number;
5
- //# sourceMappingURL=utils.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/execution/builder/utils.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAU1F"}
@@ -1,17 +0,0 @@
1
- /**
2
- * From https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md
3
- */
4
- const gasLimitAdjustmentFactor = 1024;
5
- /**
6
- * Calculates expected gas limit based on parent gas limit and target gas limit
7
- */
8
- export function getExpectedGasLimit(parentGasLimit, targetGasLimit) {
9
- const maxGasLimitDifference = Math.max(Math.floor(parentGasLimit / gasLimitAdjustmentFactor) - 1, 0);
10
- if (targetGasLimit > parentGasLimit) {
11
- const gasDiff = targetGasLimit - parentGasLimit;
12
- return parentGasLimit + Math.min(gasDiff, maxGasLimitDifference);
13
- }
14
- const gasDiff = parentGasLimit - targetGasLimit;
15
- return parentGasLimit - Math.min(gasDiff, maxGasLimitDifference);
16
- }
17
- //# sourceMappingURL=utils.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/execution/builder/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,wBAAwB,GAAG,IAAI,CAAC;AAEtC;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,cAAsB,EAAE,cAAsB,EAAU;IAC1F,MAAM,qBAAqB,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,wBAAwB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAErG,IAAI,cAAc,GAAG,cAAc,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,cAAc,GAAG,cAAc,CAAC;QAChD,OAAO,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,OAAO,GAAG,cAAc,GAAG,cAAc,CAAC;IAChD,OAAO,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC;AAAA,CAClE"}
@@ -1,19 +0,0 @@
1
- /**
2
- * From https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md
3
- */
4
- const gasLimitAdjustmentFactor = 1024;
5
-
6
- /**
7
- * Calculates expected gas limit based on parent gas limit and target gas limit
8
- */
9
- export function getExpectedGasLimit(parentGasLimit: number, targetGasLimit: number): number {
10
- const maxGasLimitDifference = Math.max(Math.floor(parentGasLimit / gasLimitAdjustmentFactor) - 1, 0);
11
-
12
- if (targetGasLimit > parentGasLimit) {
13
- const gasDiff = targetGasLimit - parentGasLimit;
14
- return parentGasLimit + Math.min(gasDiff, maxGasLimitDifference);
15
- }
16
-
17
- const gasDiff = parentGasLimit - targetGasLimit;
18
- return parentGasLimit - Math.min(gasDiff, maxGasLimitDifference);
19
- }