@lodestar/beacon-node 1.45.0-dev.b620872107 → 1.45.0-dev.bdb9aa149d

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.
@@ -65,8 +65,6 @@ import {
65
65
  AttestationError,
66
66
  AttestationErrorCode,
67
67
  GossipAction,
68
- ProposerPreferencesError,
69
- ProposerPreferencesErrorCode,
70
68
  SyncCommitteeError,
71
69
  SyncCommitteeErrorCode,
72
70
  } from "../../../chain/errors/index.js";
@@ -76,7 +74,6 @@ import {BlockType, ProduceFullDeneb, ProduceFullGloas} from "../../../chain/prod
76
74
  import {RegenCaller} from "../../../chain/regen/index.js";
77
75
  import {CheckpointHex} from "../../../chain/stateCache/types.js";
78
76
  import {validateApiAggregateAndProof} from "../../../chain/validation/index.js";
79
- import {validateGossipProposerPreferences} from "../../../chain/validation/proposerPreferences.js";
80
77
  import {validateSyncCommitteeGossipContributionAndProof} from "../../../chain/validation/syncCommitteeContributionAndProof.js";
81
78
  import {ZERO_HASH} from "../../../constants/index.js";
82
79
  import {BuilderStatus, NoBidReceived} from "../../../execution/builder/http.js";
@@ -1121,8 +1118,8 @@ export function getValidatorApi(
1121
1118
 
1122
1119
  const block = chain.forkChoice.getCanonicalBlockAtSlot(slot);
1123
1120
  if (!block) {
1124
- // No canonical block is seen at slot. Return 204 so vc can skip casting payload attestation.
1125
- return {data: undefined, meta: {version: fork}, status: 204};
1121
+ // No block is seen at slot. Return 404 so vc can skip casting payload attestation.
1122
+ throw new ApiError(404, `No canonical block found at slot=${slot}`);
1126
1123
  }
1127
1124
 
1128
1125
  const payloadInput = chain.seenPayloadEnvelopeInputCache.get(block.blockRoot);
@@ -1774,46 +1771,6 @@ export function getValidatorApi(
1774
1771
  });
1775
1772
  },
1776
1773
 
1777
- async submitProposerPreferences({signedProposerPreferences}) {
1778
- const failures: FailureList = [];
1779
-
1780
- await Promise.all(
1781
- signedProposerPreferences.map(async (signed, i) => {
1782
- try {
1783
- await validateGossipProposerPreferences(chain, signed);
1784
-
1785
- chain.proposerPreferencesPool.add(signed);
1786
- await network.publishProposerPreferences(signed);
1787
- chain.emitter.emit(routes.events.EventType.proposerPreferences, {
1788
- version: config.getForkName(signed.message.proposalSlot),
1789
- data: signed,
1790
- });
1791
- } catch (e) {
1792
- const logCtx = {
1793
- slot: signed.message.proposalSlot,
1794
- validatorIndex: signed.message.validatorIndex,
1795
- dependentRoot: toRootHex(signed.message.dependentRoot),
1796
- };
1797
-
1798
- if (e instanceof ProposerPreferencesError && e.type.code === ProposerPreferencesErrorCode.ALREADY_KNOWN) {
1799
- logger.debug("Ignoring known signed proposer preferences", logCtx);
1800
- return;
1801
- }
1802
-
1803
- failures.push({index: i, message: (e as Error).message});
1804
- logger.verbose(`Error on submitProposerPreferences [${i}]`, logCtx, e as Error);
1805
- if (e instanceof ProposerPreferencesError && e.action === GossipAction.REJECT) {
1806
- chain.persistInvalidSszValue(ssz.gloas.SignedProposerPreferences, signed, "api_reject");
1807
- }
1808
- }
1809
- })
1810
- );
1811
-
1812
- if (failures.length > 0) {
1813
- throw new IndexedError("Error processing signed proposer preferences", failures);
1814
- }
1815
- },
1816
-
1817
1774
  async getExecutionPayloadEnvelope({slot, beaconBlockRoot}) {
1818
1775
  const fork = config.getForkName(slot);
1819
1776
 
@@ -43,7 +43,6 @@ import {
43
43
  ValidatorIndex,
44
44
  Wei,
45
45
  altair,
46
- bellatrix,
47
46
  capella,
48
47
  deneb,
49
48
  electra,
@@ -831,19 +830,28 @@ export function getPayloadAttributesForSSE(
831
830
  feeRecipient,
832
831
  });
833
832
 
834
- const ssePayloadAttributes = {
833
+ let parentBlockNumber: number;
834
+ if (isForkPostGloas(fork)) {
835
+ const parentBlock = chain.forkChoice.getBlockHexAndBlockHash(
836
+ toRootHex(parentBlockRoot),
837
+ toRootHex(parentBlockHash)
838
+ );
839
+ if (parentBlock?.executionPayloadBlockHash == null) {
840
+ throw Error(`Parent block not found in fork choice root=${toRootHex(parentBlockRoot)}`);
841
+ }
842
+ parentBlockNumber = parentBlock.executionPayloadNumber;
843
+ } else {
844
+ parentBlockNumber = prepareState.payloadBlockNumber;
845
+ }
846
+
847
+ const ssePayloadAttributes: SSEPayloadAttributes = {
835
848
  proposerIndex: prepareState.getBeaconProposer(prepareSlot),
836
849
  proposalSlot: prepareSlot,
850
+ parentBlockNumber,
837
851
  parentBlockRoot,
838
852
  parentBlockHash,
839
853
  payloadAttributes,
840
- } as SSEPayloadAttributes;
841
-
842
- if (!isForkPostGloas(fork)) {
843
- // Removed in Gloas, builders can get the block number from the EL via the block hash if required
844
- (ssePayloadAttributes as bellatrix.SSEPayloadAttributes).parentBlockNumber = prepareState.payloadBlockNumber;
845
- }
846
-
854
+ };
847
855
  return ssePayloadAttributes;
848
856
  }
849
857
 
@@ -35,7 +35,7 @@ import {
35
35
  computeGossipPeerScoreParams,
36
36
  gossipScoreThresholds,
37
37
  } from "./scoringParameters.js";
38
- import {GossipTopicCache, getAllowedTopics, getCoreTopicsAtFork, stringifyGossipTopic} from "./topic.js";
38
+ import {GossipTopicCache, getCoreTopicsAtFork, stringifyGossipTopic} from "./topic.js";
39
39
 
40
40
  /** As specified in https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/phase0/p2p-interface.md */
41
41
  const GOSSIPSUB_HEARTBEAT_INTERVAL = 0.7 * 1000;
@@ -140,7 +140,6 @@ export class Eth2Gossipsub {
140
140
  const gossipsubInstance = gossipsub({
141
141
  globalSignaturePolicy: StrictNoSign,
142
142
  allowPublishToZeroTopicPeers: allowPublishToZeroPeers,
143
- allowedTopics: getAllowedTopics(networkConfig),
144
143
  D: gossipsubD ?? GOSSIP_D,
145
144
  Dlo: gossipsubDLow ?? GOSSIP_D_LOW,
146
145
  Dhi: gossipsubDHigh ?? GOSSIP_D_HIGH,
@@ -246,7 +246,7 @@ export function parseGossipTopic(forkDigestContext: ForkDigestContext, topicStr:
246
246
  export function getCoreTopicsAtFork(
247
247
  networkConfig: NetworkConfig,
248
248
  fork: ForkName,
249
- opts: {subscribeAllSubnets?: boolean; subscribeAllColumnSubnets?: boolean; disableLightClientServer?: boolean}
249
+ opts: {subscribeAllSubnets?: boolean; disableLightClientServer?: boolean}
250
250
  ): GossipTopicTypeMap[keyof GossipTopicTypeMap][] {
251
251
  // Common topics for all forks
252
252
  const topics: GossipTopicTypeMap[keyof GossipTopicTypeMap][] = [
@@ -266,7 +266,7 @@ export function getCoreTopicsAtFork(
266
266
 
267
267
  // After fulu also track data_column_sidecar_{index}
268
268
  if (ForkSeq[fork] >= ForkSeq.fulu) {
269
- topics.push(...getDataColumnSidecarTopics(networkConfig, opts.subscribeAllColumnSubnets));
269
+ topics.push(...getDataColumnSidecarTopics(networkConfig));
270
270
  }
271
271
 
272
272
  // After Deneb and before Fulu also track blob_sidecar_{subnet_id}
@@ -309,39 +309,15 @@ export function getCoreTopicsAtFork(
309
309
  return topics;
310
310
  }
311
311
 
312
- /**
313
- * Build the complete set of valid gossip topic strings across every fork boundary.
314
- */
315
- export function getAllowedTopics(networkConfig: NetworkConfig): Set<string> {
316
- const {config} = networkConfig;
317
- const allowedTopics = new Set<string>();
318
-
319
- for (const boundary of config.forkBoundariesAscendingEpochOrder) {
320
- const topics = getCoreTopicsAtFork(networkConfig, boundary.fork, {
321
- subscribeAllSubnets: true,
322
- subscribeAllColumnSubnets: true,
323
- disableLightClientServer: false,
324
- });
325
- for (const topic of topics) {
326
- allowedTopics.add(stringifyGossipTopic(config, {...topic, boundary}));
327
- }
328
- }
329
-
330
- return allowedTopics;
331
- }
332
-
333
312
  /**
334
313
  * Pick data column subnets to subscribe to post-fulu.
335
314
  */
336
315
  export function getDataColumnSidecarTopics(
337
- networkConfig: NetworkConfig,
338
- subscribeAllColumnSubnets = false
316
+ networkConfig: NetworkConfig
339
317
  ): GossipTopicTypeMap[keyof GossipTopicTypeMap][] {
340
318
  const topics: GossipTopicTypeMap[keyof GossipTopicTypeMap][] = [];
341
319
 
342
- const subnets = subscribeAllColumnSubnets
343
- ? Array.from({length: networkConfig.config.DATA_COLUMN_SIDECAR_SUBNET_COUNT}, (_, i) => i)
344
- : networkConfig.custodyConfig.sampledSubnets;
320
+ const subnets = networkConfig.custodyConfig.sampledSubnets;
345
321
  for (const subnet of subnets) {
346
322
  topics.push({type: GossipType.data_column_sidecar, subnet});
347
323
  }
@@ -1274,7 +1274,7 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
1274
1274
  await validateGossipProposerPreferences(chain, signedProposerPreferences);
1275
1275
 
1276
1276
  chain.emitter.emit(routes.events.EventType.proposerPreferences, {
1277
- version: config.getForkName(signedProposerPreferences.message.proposalSlot),
1277
+ version: ForkName.gloas,
1278
1278
  data: signedProposerPreferences,
1279
1279
  });
1280
1280
  },