@lodestar/beacon-node 1.43.0-dev.87cbe69c66 → 1.43.0-dev.8ad5d8be4c

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 (153) hide show
  1. package/lib/chain/blocks/blockInput/blockInput.d.ts +3 -0
  2. package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
  3. package/lib/chain/blocks/blockInput/blockInput.js +4 -1
  4. package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
  5. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  6. package/lib/chain/blocks/importBlock.js +0 -16
  7. package/lib/chain/blocks/importBlock.js.map +1 -1
  8. package/lib/chain/blocks/importExecutionPayload.d.ts +4 -0
  9. package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
  10. package/lib/chain/blocks/importExecutionPayload.js +12 -1
  11. package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
  12. package/lib/chain/blocks/index.d.ts.map +1 -1
  13. package/lib/chain/blocks/index.js +6 -7
  14. package/lib/chain/blocks/index.js.map +1 -1
  15. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +11 -1
  16. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
  17. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +23 -1
  18. package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
  19. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +16 -0
  20. package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
  21. package/lib/chain/blocks/utils/chainSegment.d.ts +1 -3
  22. package/lib/chain/blocks/utils/chainSegment.d.ts.map +1 -1
  23. package/lib/chain/blocks/utils/chainSegment.js +29 -26
  24. package/lib/chain/blocks/utils/chainSegment.js.map +1 -1
  25. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -1
  26. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +5 -4
  27. package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -1
  28. package/lib/chain/chain.d.ts.map +1 -1
  29. package/lib/chain/chain.js +25 -10
  30. package/lib/chain/chain.js.map +1 -1
  31. package/lib/chain/initState.d.ts.map +1 -1
  32. package/lib/chain/initState.js +6 -1
  33. package/lib/chain/initState.js.map +1 -1
  34. package/lib/chain/prepareNextSlot.js +1 -1
  35. package/lib/chain/prepareNextSlot.js.map +1 -1
  36. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +14 -10
  37. package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
  38. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +51 -17
  39. package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
  40. package/lib/chain/seenCache/seenProposerPreferences.d.ts +1 -1
  41. package/lib/chain/seenCache/seenProposerPreferences.d.ts.map +1 -1
  42. package/lib/chain/seenCache/seenProposerPreferences.js +6 -11
  43. package/lib/chain/seenCache/seenProposerPreferences.js.map +1 -1
  44. package/lib/metrics/metrics/lodestar.d.ts +4 -0
  45. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  46. package/lib/metrics/metrics/lodestar.js +5 -0
  47. package/lib/metrics/metrics/lodestar.js.map +1 -1
  48. package/lib/network/gossip/topic.d.ts +749 -2
  49. package/lib/network/gossip/topic.d.ts.map +1 -1
  50. package/lib/network/interface.d.ts +1 -0
  51. package/lib/network/interface.d.ts.map +1 -1
  52. package/lib/network/network.d.ts +1 -0
  53. package/lib/network/network.d.ts.map +1 -1
  54. package/lib/network/network.js +3 -0
  55. package/lib/network/network.js.map +1 -1
  56. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  57. package/lib/network/processor/gossipHandlers.js +45 -1
  58. package/lib/network/processor/gossipHandlers.js.map +1 -1
  59. package/lib/network/reqresp/ReqRespBeaconNode.d.ts.map +1 -1
  60. package/lib/network/reqresp/ReqRespBeaconNode.js +1 -1
  61. package/lib/network/reqresp/ReqRespBeaconNode.js.map +1 -1
  62. package/lib/network/reqresp/handlers/beaconBlocksByHead.d.ts +9 -0
  63. package/lib/network/reqresp/handlers/beaconBlocksByHead.d.ts.map +1 -0
  64. package/lib/network/reqresp/handlers/beaconBlocksByHead.js +61 -0
  65. package/lib/network/reqresp/handlers/beaconBlocksByHead.js.map +1 -0
  66. package/lib/network/reqresp/handlers/index.d.ts.map +1 -1
  67. package/lib/network/reqresp/handlers/index.js +5 -0
  68. package/lib/network/reqresp/handlers/index.js.map +1 -1
  69. package/lib/network/reqresp/interface.d.ts +1 -1
  70. package/lib/network/reqresp/interface.js +1 -1
  71. package/lib/network/reqresp/protocols.d.ts +1 -0
  72. package/lib/network/reqresp/protocols.d.ts.map +1 -1
  73. package/lib/network/reqresp/protocols.js +5 -0
  74. package/lib/network/reqresp/protocols.js.map +1 -1
  75. package/lib/network/reqresp/rateLimit.d.ts.map +1 -1
  76. package/lib/network/reqresp/rateLimit.js +4 -0
  77. package/lib/network/reqresp/rateLimit.js.map +1 -1
  78. package/lib/network/reqresp/score.d.ts.map +1 -1
  79. package/lib/network/reqresp/score.js +1 -0
  80. package/lib/network/reqresp/score.js.map +1 -1
  81. package/lib/network/reqresp/types.d.ts +3 -0
  82. package/lib/network/reqresp/types.d.ts.map +1 -1
  83. package/lib/network/reqresp/types.js +3 -0
  84. package/lib/network/reqresp/types.js.map +1 -1
  85. package/lib/sync/constants.d.ts +7 -1
  86. package/lib/sync/constants.d.ts.map +1 -1
  87. package/lib/sync/constants.js +7 -4
  88. package/lib/sync/constants.js.map +1 -1
  89. package/lib/sync/range/batch.d.ts +32 -6
  90. package/lib/sync/range/batch.d.ts.map +1 -1
  91. package/lib/sync/range/batch.js +215 -41
  92. package/lib/sync/range/batch.js.map +1 -1
  93. package/lib/sync/range/chain.d.ts +16 -2
  94. package/lib/sync/range/chain.d.ts.map +1 -1
  95. package/lib/sync/range/chain.js +77 -4
  96. package/lib/sync/range/chain.js.map +1 -1
  97. package/lib/sync/range/range.d.ts.map +1 -1
  98. package/lib/sync/range/range.js +54 -5
  99. package/lib/sync/range/range.js.map +1 -1
  100. package/lib/sync/range/utils/peerBalancer.d.ts +2 -1
  101. package/lib/sync/range/utils/peerBalancer.d.ts.map +1 -1
  102. package/lib/sync/range/utils/peerBalancer.js +8 -4
  103. package/lib/sync/range/utils/peerBalancer.js.map +1 -1
  104. package/lib/sync/sync.d.ts.map +1 -1
  105. package/lib/sync/sync.js +13 -0
  106. package/lib/sync/sync.js.map +1 -1
  107. package/lib/sync/unknownBlock.d.ts +7 -0
  108. package/lib/sync/unknownBlock.d.ts.map +1 -1
  109. package/lib/sync/unknownBlock.js +127 -10
  110. package/lib/sync/unknownBlock.js.map +1 -1
  111. package/lib/sync/utils/downloadByRange.d.ts +36 -9
  112. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  113. package/lib/sync/utils/downloadByRange.js +89 -42
  114. package/lib/sync/utils/downloadByRange.js.map +1 -1
  115. package/lib/sync/utils/rateLimit.d.ts +2 -0
  116. package/lib/sync/utils/rateLimit.d.ts.map +1 -0
  117. package/lib/sync/utils/rateLimit.js +15 -0
  118. package/lib/sync/utils/rateLimit.js.map +1 -0
  119. package/package.json +16 -16
  120. package/src/chain/blocks/blockInput/blockInput.ts +4 -1
  121. package/src/chain/blocks/importBlock.ts +0 -18
  122. package/src/chain/blocks/importExecutionPayload.ts +18 -6
  123. package/src/chain/blocks/index.ts +5 -7
  124. package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +31 -2
  125. package/src/chain/blocks/payloadEnvelopeInput/types.ts +17 -0
  126. package/src/chain/blocks/utils/chainSegment.ts +30 -27
  127. package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +7 -4
  128. package/src/chain/chain.ts +29 -9
  129. package/src/chain/initState.ts +9 -1
  130. package/src/chain/prepareNextSlot.ts +1 -1
  131. package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +66 -20
  132. package/src/chain/seenCache/seenProposerPreferences.ts +7 -12
  133. package/src/metrics/metrics/lodestar.ts +6 -0
  134. package/src/network/interface.ts +1 -0
  135. package/src/network/network.ts +12 -0
  136. package/src/network/processor/gossipHandlers.ts +53 -1
  137. package/src/network/reqresp/ReqRespBeaconNode.ts +1 -0
  138. package/src/network/reqresp/handlers/beaconBlocksByHead.ts +91 -0
  139. package/src/network/reqresp/handlers/index.ts +5 -0
  140. package/src/network/reqresp/interface.ts +1 -1
  141. package/src/network/reqresp/protocols.ts +6 -0
  142. package/src/network/reqresp/rateLimit.ts +4 -0
  143. package/src/network/reqresp/score.ts +1 -0
  144. package/src/network/reqresp/types.ts +5 -0
  145. package/src/sync/constants.ts +8 -4
  146. package/src/sync/range/batch.ts +256 -47
  147. package/src/sync/range/chain.ts +94 -5
  148. package/src/sync/range/range.ts +68 -5
  149. package/src/sync/range/utils/peerBalancer.ts +9 -3
  150. package/src/sync/sync.ts +13 -1
  151. package/src/sync/unknownBlock.ts +157 -10
  152. package/src/sync/utils/downloadByRange.ts +156 -44
  153. package/src/sync/utils/rateLimit.ts +16 -0
@@ -35,6 +35,7 @@ import {
35
35
  IBlockInput,
36
36
  isBlockInputColumns,
37
37
  } from "../../chain/blocks/blockInput/index.js";
38
+ import {PayloadError, PayloadErrorCode} from "../../chain/blocks/importExecutionPayload.js";
38
39
  import {PayloadEnvelopeInput, PayloadEnvelopeInputSource} from "../../chain/blocks/payloadEnvelopeInput/index.js";
39
40
  import {BlobSidecarValidation} from "../../chain/blocks/types.js";
40
41
  import {ChainEvent} from "../../chain/emitter.js";
@@ -607,6 +608,24 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
607
608
  // Returns the delay between the start of `block.slot` and `current time`
608
609
  const delaySec = chain.clock.secFromSlot(slot);
609
610
  metrics?.gossipBlock.elapsedTimeTillProcessed.observe(delaySec);
611
+
612
+ if (isForkPostGloas(blockInput.forkName)) {
613
+ const payloadInput = chain.seenPayloadEnvelopeInputCache.get(blockInput.blockRootHex);
614
+ // This payloadInput should have been created just after gossip validation
615
+ if (!payloadInput) {
616
+ throw Error(
617
+ `PayloadEnvelopeInput not seeded for block ${blockInput.blockRootHex} during gossip processing`
618
+ );
619
+ }
620
+
621
+ // Immediately attempt fetch of data columns from execution engine as the bid contains kzg commitments
622
+ // which is all the information we need so there is no reason to delay until execution payload arrives
623
+ // TODO GLOAS: If we want EL retries after this initial attempt, add an explicit retry policy here
624
+ // (for example later in the slot). Do not couple retries to incoming gossip columns.
625
+ // Columns fetched here feed payloadInput.addColumn, which resolves waitForAllData for any
626
+ // in-flight importExecutionPayload. No processExecutionPayload trigger needed from this path.
627
+ chain.getBlobsTracker.triggerGetBlobs(payloadInput);
628
+ }
610
629
  })
611
630
  .catch((e) => {
612
631
  // Adjust verbosity based on error type
@@ -1130,7 +1149,40 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
1130
1149
  });
1131
1150
 
1132
1151
  chain.processExecutionPayload(payloadInput, {validSignature: true}).catch((e) => {
1133
- chain.logger.debug("Error processing execution payload from gossip", {slot, root: blockRootHex}, e as Error);
1152
+ // Adjust verbosity based on error type
1153
+ let logLevel: LogLevel;
1154
+
1155
+ if (e instanceof PayloadError) {
1156
+ switch (e.type.code) {
1157
+ // BLOCK_NOT_IN_FORK_CHOICE should not happen, validateGossipExecutionPayloadEnvelope above
1158
+ // already verified the block is in fork choice
1159
+ case PayloadErrorCode.BLOCK_NOT_IN_FORK_CHOICE:
1160
+ case PayloadErrorCode.MISS_BLOCK_STATE:
1161
+ case PayloadErrorCode.EXECUTION_ENGINE_ERROR:
1162
+ // Errors might indicate an issue with our node or the connected EL client
1163
+ logLevel = LogLevel.error;
1164
+ break;
1165
+ // INVALID_SIGNATURE should not happen, signature is verified during gossip validation
1166
+ case PayloadErrorCode.INVALID_SIGNATURE:
1167
+ case PayloadErrorCode.ENVELOPE_VERIFICATION_ERROR:
1168
+ case PayloadErrorCode.EXECUTION_ENGINE_INVALID:
1169
+ core.reportPeer(peerIdStr, PeerAction.LowToleranceError, "BadGossipPayload");
1170
+ // Misbehaving peer, but could highlight an issue in another client
1171
+ logLevel = LogLevel.warn;
1172
+ break;
1173
+ }
1174
+ } else {
1175
+ // Any unexpected error
1176
+ logLevel = LogLevel.error;
1177
+ }
1178
+ metrics?.gossipExecutionPayloadEnvelope.processPayloadErrors.inc({
1179
+ error: e instanceof PayloadError ? e.type.code : "NOT_PAYLOAD_ERROR",
1180
+ });
1181
+ chain.logger[logLevel](
1182
+ "Error processing execution payload from gossip",
1183
+ {slot, peer: peerIdStr, root: blockRootHex},
1184
+ e as Error
1185
+ );
1134
1186
  });
1135
1187
  },
1136
1188
  [GossipType.payload_attestation_message]: async ({
@@ -286,6 +286,7 @@ export class ReqRespBeaconNode extends ReqResp {
286
286
  // instead of protocol version. This is not easily fixable with our current architecture.
287
287
  // See https://github.com/ChainSafe/lodestar/pull/8168 for more details.
288
288
  [protocols.StatusV2(fork, this.config), this.onStatus.bind(this)],
289
+ [protocols.BeaconBlocksByHead(fork, this.config), this.getHandler(ReqRespMethod.BeaconBlocksByHead)],
289
290
  [
290
291
  protocols.DataColumnSidecarsByRoot(fork, this.config),
291
292
  this.getHandler(ReqRespMethod.DataColumnSidecarsByRoot),
@@ -0,0 +1,91 @@
1
+ import {PeerId} from "@libp2p/interface";
2
+ import {BeaconConfig} from "@lodestar/config";
3
+ import {ForkName, GENESIS_EPOCH, GENESIS_SLOT, isForkPostDeneb} from "@lodestar/params";
4
+ import {RespStatus, ResponseError, ResponseOutgoing} from "@lodestar/reqresp";
5
+ import {computeEpochAtSlot, computeStartSlotAtEpoch} from "@lodestar/state-transition";
6
+ import {fulu} from "@lodestar/types";
7
+ import {toRootHex} from "@lodestar/utils";
8
+ import {IBeaconChain} from "../../../chain/index.js";
9
+ import {getParentRootFromSignedBeaconBlockSerialized} from "../../../util/sszBytes.js";
10
+ import {prettyPrintPeerId} from "../../util.js";
11
+
12
+ // See https://github.com/ethereum/consensus-specs/pull/5181
13
+ export async function* onBeaconBlocksByHead(
14
+ request: fulu.BeaconBlocksByHeadRequest,
15
+ chain: IBeaconChain,
16
+ peerId: PeerId,
17
+ peerClient: string
18
+ ): AsyncIterable<ResponseOutgoing> {
19
+ const currentFork = chain.config.getForkName(chain.clock.currentSlot);
20
+ const {beaconRoot, count} = validateBeaconBlocksByHeadRequest(currentFork, chain.config, request);
21
+
22
+ const requestedRootHex = toRootHex(beaconRoot);
23
+ let blockRootHex = requestedRootHex;
24
+ const minimumRequestEpoch = Math.max(
25
+ GENESIS_EPOCH,
26
+ chain.clock.currentEpoch - chain.config.MIN_EPOCHS_FOR_BLOCK_REQUESTS
27
+ );
28
+ const minimumRequestSlot = computeStartSlotAtEpoch(minimumRequestEpoch);
29
+
30
+ for (let blocksSent = 0; blocksSent < count; blocksSent++) {
31
+ const blockBytes = await chain.getSerializedBlockByRoot(blockRootHex);
32
+ if (!blockBytes) {
33
+ if (blocksSent === 0) {
34
+ throw new ResponseError(RespStatus.RESOURCE_UNAVAILABLE, `Unknown block root ${requestedRootHex}`);
35
+ }
36
+ return;
37
+ }
38
+
39
+ if (blockBytes.slot < minimumRequestSlot) {
40
+ if (blocksSent === 0) {
41
+ chain.logger.verbose("Peer requested unavailable block for BeaconBlocksByHead", {
42
+ peer: prettyPrintPeerId(peerId),
43
+ client: peerClient,
44
+ requestedRoot: requestedRootHex,
45
+ slot: blockBytes.slot,
46
+ minimumRequestSlot,
47
+ });
48
+ }
49
+ return;
50
+ }
51
+
52
+ yield {
53
+ data: blockBytes.block,
54
+ boundary: chain.config.getForkBoundaryAtEpoch(computeEpochAtSlot(blockBytes.slot)),
55
+ };
56
+
57
+ if (blockBytes.slot === GENESIS_SLOT) {
58
+ return;
59
+ }
60
+
61
+ const parentRootHex = getParentRootFromSignedBeaconBlockSerialized(blockBytes.block);
62
+ if (parentRootHex === null) {
63
+ throw new ResponseError(
64
+ RespStatus.SERVER_ERROR,
65
+ `Invalid block bytes for root ${blockRootHex} slot ${blockBytes.slot}`
66
+ );
67
+ }
68
+ blockRootHex = parentRootHex;
69
+ }
70
+ }
71
+
72
+ export function validateBeaconBlocksByHeadRequest(
73
+ fork: ForkName,
74
+ config: BeaconConfig,
75
+ request: fulu.BeaconBlocksByHeadRequest
76
+ ): fulu.BeaconBlocksByHeadRequest {
77
+ const {beaconRoot} = request;
78
+ let {count} = request;
79
+
80
+ if (count < 1) {
81
+ throw new ResponseError(RespStatus.INVALID_REQUEST, "count < 1");
82
+ }
83
+
84
+ const maxRequestBlocks = isForkPostDeneb(fork) ? config.MAX_REQUEST_BLOCKS_DENEB : config.MAX_REQUEST_BLOCKS;
85
+
86
+ if (count > maxRequestBlocks) {
87
+ count = maxRequestBlocks;
88
+ }
89
+
90
+ return {beaconRoot, count};
91
+ }
@@ -9,6 +9,7 @@ import {
9
9
  ExecutionPayloadEnvelopesByRootRequestType,
10
10
  } from "../../../util/types.js";
11
11
  import {GetReqRespHandlerFn, ReqRespMethod} from "../types.js";
12
+ import {onBeaconBlocksByHead} from "./beaconBlocksByHead.js";
12
13
  import {onBeaconBlocksByRange} from "./beaconBlocksByRange.js";
13
14
  import {onBeaconBlocksByRoot} from "./beaconBlocksByRoot.js";
14
15
  import {onBlobSidecarsByRange} from "./blobSidecarsByRange.js";
@@ -47,6 +48,10 @@ export function getReqRespHandlers({db, chain}: {db: IBeaconDb; chain: IBeaconCh
47
48
  const body = BeaconBlocksByRootRequestType(fork, chain.config).deserialize(req.data);
48
49
  return onBeaconBlocksByRoot(body, chain);
49
50
  },
51
+ [ReqRespMethod.BeaconBlocksByHead]: (req, peerId, peerClient) => {
52
+ const body = ssz.fulu.BeaconBlocksByHeadRequest.deserialize(req.data);
53
+ return onBeaconBlocksByHead(body, chain, peerId, peerClient);
54
+ },
50
55
  [ReqRespMethod.BlobSidecarsByRoot]: (req) => {
51
56
  const fork = chain.config.getForkName(chain.clock.currentSlot);
52
57
  const body = BlobSidecarsByRootRequestType(fork, chain.config).deserialize(req.data);
@@ -33,7 +33,7 @@ export enum RespStatus {
33
33
  */
34
34
  SERVER_ERROR = 2,
35
35
  /**
36
- * The responder does not have requested resource. The response payload adheres to the ErrorMessage schema (described below). Note: This response code is only valid as a response to BlocksByRange
36
+ * The responder does not have requested resource. The response payload adheres to the ErrorMessage schema.
37
37
  */
38
38
  RESOURCE_UNAVAILABLE = 3,
39
39
  /**
@@ -70,6 +70,12 @@ export const BeaconBlocksByRootV2 = toProtocol({
70
70
  contextBytesType: ContextBytesType.ForkDigest,
71
71
  });
72
72
 
73
+ export const BeaconBlocksByHead = toProtocol({
74
+ method: ReqRespMethod.BeaconBlocksByHead,
75
+ version: Version.V1,
76
+ contextBytesType: ContextBytesType.ForkDigest,
77
+ });
78
+
73
79
  export const BlobSidecarsByRange = toProtocol({
74
80
  method: ReqRespMethod.BlobSidecarsByRange,
75
81
  version: Version.V1,
@@ -40,6 +40,10 @@ export const rateLimitQuotas: (fork: ForkName, config: BeaconConfig) => Record<R
40
40
  },
41
41
  getRequestCount: getRequestCountFn(fork, config, ReqRespMethod.BeaconBlocksByRoot, (req) => req.length),
42
42
  },
43
+ [ReqRespMethod.BeaconBlocksByHead]: {
44
+ byPeer: {quota: config.MAX_REQUEST_BLOCKS_DENEB, quotaTimeMs: 10_000},
45
+ getRequestCount: getRequestCountFn(fork, config, ReqRespMethod.BeaconBlocksByHead, (req) => req.count),
46
+ },
43
47
  [ReqRespMethod.BlobSidecarsByRange]: {
44
48
  // Rationale: MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK
45
49
  byPeer: {
@@ -46,6 +46,7 @@ export function onOutgoingReqRespError(e: RequestError, method: ReqRespMethod):
46
46
  return PeerAction.LowToleranceError;
47
47
  case ReqRespMethod.BeaconBlocksByRange:
48
48
  case ReqRespMethod.BeaconBlocksByRoot:
49
+ case ReqRespMethod.BeaconBlocksByHead:
49
50
  case ReqRespMethod.ExecutionPayloadEnvelopesByRoot:
50
51
  case ReqRespMethod.ExecutionPayloadEnvelopesByRange:
51
52
  return PeerAction.MidToleranceError;
@@ -42,6 +42,7 @@ export enum ReqRespMethod {
42
42
  Metadata = "metadata",
43
43
  BeaconBlocksByRange = "beacon_blocks_by_range",
44
44
  BeaconBlocksByRoot = "beacon_blocks_by_root",
45
+ BeaconBlocksByHead = "beacon_blocks_by_head",
45
46
  BlobSidecarsByRange = "blob_sidecars_by_range",
46
47
  BlobSidecarsByRoot = "blob_sidecars_by_root",
47
48
  DataColumnSidecarsByRange = "data_column_sidecars_by_range",
@@ -62,6 +63,7 @@ export type RequestBodyByMethod = {
62
63
  [ReqRespMethod.Metadata]: null;
63
64
  [ReqRespMethod.BeaconBlocksByRange]: phase0.BeaconBlocksByRangeRequest;
64
65
  [ReqRespMethod.BeaconBlocksByRoot]: BeaconBlocksByRootRequest;
66
+ [ReqRespMethod.BeaconBlocksByHead]: fulu.BeaconBlocksByHeadRequest;
65
67
  [ReqRespMethod.BlobSidecarsByRange]: deneb.BlobSidecarsByRangeRequest;
66
68
  [ReqRespMethod.BlobSidecarsByRoot]: BlobSidecarsByRootRequest;
67
69
  [ReqRespMethod.DataColumnSidecarsByRange]: fulu.DataColumnSidecarsByRangeRequest;
@@ -82,6 +84,7 @@ type ResponseBodyByMethod = {
82
84
  // Do not matter
83
85
  [ReqRespMethod.BeaconBlocksByRange]: SignedBeaconBlock;
84
86
  [ReqRespMethod.BeaconBlocksByRoot]: SignedBeaconBlock;
87
+ [ReqRespMethod.BeaconBlocksByHead]: SignedBeaconBlock;
85
88
  [ReqRespMethod.BlobSidecarsByRange]: deneb.BlobSidecar;
86
89
  [ReqRespMethod.BlobSidecarsByRoot]: deneb.BlobSidecar;
87
90
  [ReqRespMethod.DataColumnSidecarsByRange]: DataColumnSidecar;
@@ -111,6 +114,7 @@ export const requestSszTypeByMethod: (
111
114
 
112
115
  [ReqRespMethod.BeaconBlocksByRange]: ssz.phase0.BeaconBlocksByRangeRequest,
113
116
  [ReqRespMethod.BeaconBlocksByRoot]: BeaconBlocksByRootRequestType(fork, config),
117
+ [ReqRespMethod.BeaconBlocksByHead]: ssz.fulu.BeaconBlocksByHeadRequest,
114
118
  [ReqRespMethod.BlobSidecarsByRange]: ssz.deneb.BlobSidecarsByRangeRequest,
115
119
  [ReqRespMethod.BlobSidecarsByRoot]: BlobSidecarsByRootRequestType(fork, config),
116
120
  [ReqRespMethod.DataColumnSidecarsByRange]: ssz.fulu.DataColumnSidecarsByRangeRequest,
@@ -142,6 +146,7 @@ export const responseSszTypeByMethod: {[K in ReqRespMethod]: ResponseTypeGetter<
142
146
  version === Version.V1 ? ssz.phase0.Metadata : version === Version.V2 ? ssz.altair.Metadata : ssz.fulu.Metadata,
143
147
  [ReqRespMethod.BeaconBlocksByRange]: blocksResponseType,
144
148
  [ReqRespMethod.BeaconBlocksByRoot]: blocksResponseType,
149
+ [ReqRespMethod.BeaconBlocksByHead]: (fork) => ssz[fork].SignedBeaconBlock,
145
150
  [ReqRespMethod.BlobSidecarsByRange]: () => ssz.deneb.BlobSidecar,
146
151
  [ReqRespMethod.BlobSidecarsByRoot]: () => ssz.deneb.BlobSidecar,
147
152
  [ReqRespMethod.LightClientBootstrap]: (fork) => sszTypesFor(onlyPostAltairFork(fork)).LightClientBootstrap,
@@ -5,10 +5,14 @@ export const PARALLEL_HEAD_CHAINS = 2;
5
5
  export const MIN_FINALIZED_CHAIN_VALIDATED_EPOCHS = 10;
6
6
 
7
7
  /** The number of times to retry a batch before it is considered failed. */
8
- // export const MAX_BATCH_DOWNLOAD_ATTEMPTS = 5;
9
- // this constant is increased a lot for peerDAS because we may have many failed download due to rate limit not implemented yet
10
- // TODO: change it back to 5 when this issue is implemented https://github.com/ChainSafe/lodestar/issues/8033
11
- export const MAX_BATCH_DOWNLOAD_ATTEMPTS = 20;
8
+ export const MAX_BATCH_DOWNLOAD_ATTEMPTS = 5;
9
+
10
+ /**
11
+ * Backoff before assigning more range-sync batches to a peer that rate-limited us.
12
+ *
13
+ * Note: this is used when rate limited due to MAX_CONCURRENT_REQUESTS
14
+ */
15
+ export const RATE_LIMITED_PEER_BACKOFF_MS = 5_000;
12
16
 
13
17
  /**
14
18
  * Consider batch faulty after downloading and processing this number of times