@lodestar/beacon-node 1.43.0-dev.be5f70c0c8 → 1.43.0-dev.c98da75ec7

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 (97) hide show
  1. package/lib/api/impl/beacon/pool/index.d.ts.map +1 -1
  2. package/lib/api/impl/beacon/pool/index.js +46 -5
  3. package/lib/api/impl/beacon/pool/index.js.map +1 -1
  4. package/lib/chain/blocks/utils/chainSegment.d.ts +1 -3
  5. package/lib/chain/blocks/utils/chainSegment.d.ts.map +1 -1
  6. package/lib/chain/blocks/utils/chainSegment.js +29 -26
  7. package/lib/chain/blocks/utils/chainSegment.js.map +1 -1
  8. package/lib/chain/chain.d.ts +2 -1
  9. package/lib/chain/chain.d.ts.map +1 -1
  10. package/lib/chain/chain.js +3 -1
  11. package/lib/chain/chain.js.map +1 -1
  12. package/lib/chain/errors/executionPayloadBid.d.ts +19 -1
  13. package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -1
  14. package/lib/chain/errors/executionPayloadBid.js +3 -0
  15. package/lib/chain/errors/executionPayloadBid.js.map +1 -1
  16. package/lib/chain/interface.d.ts +2 -1
  17. package/lib/chain/interface.d.ts.map +1 -1
  18. package/lib/chain/interface.js.map +1 -1
  19. package/lib/chain/lightClient/index.d.ts.map +1 -1
  20. package/lib/chain/lightClient/index.js +1 -1
  21. package/lib/chain/lightClient/index.js.map +1 -1
  22. package/lib/chain/opPools/index.d.ts +1 -0
  23. package/lib/chain/opPools/index.d.ts.map +1 -1
  24. package/lib/chain/opPools/index.js +1 -0
  25. package/lib/chain/opPools/index.js.map +1 -1
  26. package/lib/chain/opPools/payloadAttestationPool.d.ts +1 -1
  27. package/lib/chain/opPools/payloadAttestationPool.d.ts.map +1 -1
  28. package/lib/chain/opPools/payloadAttestationPool.js +30 -10
  29. package/lib/chain/opPools/payloadAttestationPool.js.map +1 -1
  30. package/lib/chain/opPools/proposerPreferencesPool.d.ts +29 -0
  31. package/lib/chain/opPools/proposerPreferencesPool.d.ts.map +1 -0
  32. package/lib/chain/opPools/proposerPreferencesPool.js +56 -0
  33. package/lib/chain/opPools/proposerPreferencesPool.js.map +1 -0
  34. package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
  35. package/lib/chain/validation/executionPayloadBid.js +64 -16
  36. package/lib/chain/validation/executionPayloadBid.js.map +1 -1
  37. package/lib/chain/validation/payloadAttestationMessage.d.ts +1 -1
  38. package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
  39. package/lib/chain/validation/payloadAttestationMessage.js +5 -3
  40. package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
  41. package/lib/metrics/metrics/lodestar.d.ts +4 -0
  42. package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
  43. package/lib/metrics/metrics/lodestar.js +5 -0
  44. package/lib/metrics/metrics/lodestar.js.map +1 -1
  45. package/lib/network/interface.d.ts +1 -0
  46. package/lib/network/interface.d.ts.map +1 -1
  47. package/lib/network/network.d.ts +1 -0
  48. package/lib/network/network.d.ts.map +1 -1
  49. package/lib/network/network.js +5 -0
  50. package/lib/network/network.js.map +1 -1
  51. package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
  52. package/lib/network/processor/gossipHandlers.js +39 -4
  53. package/lib/network/processor/gossipHandlers.js.map +1 -1
  54. package/lib/sync/range/batch.d.ts +20 -3
  55. package/lib/sync/range/batch.d.ts.map +1 -1
  56. package/lib/sync/range/batch.js +54 -10
  57. package/lib/sync/range/batch.js.map +1 -1
  58. package/lib/sync/range/chain.d.ts.map +1 -1
  59. package/lib/sync/range/chain.js +3 -1
  60. package/lib/sync/range/chain.js.map +1 -1
  61. package/lib/sync/range/range.d.ts.map +1 -1
  62. package/lib/sync/range/range.js +40 -2
  63. package/lib/sync/range/range.js.map +1 -1
  64. package/lib/sync/range/utils/peerBalancer.d.ts +2 -1
  65. package/lib/sync/range/utils/peerBalancer.d.ts.map +1 -1
  66. package/lib/sync/range/utils/peerBalancer.js +8 -4
  67. package/lib/sync/range/utils/peerBalancer.js.map +1 -1
  68. package/lib/sync/utils/downloadByRange.d.ts +7 -1
  69. package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
  70. package/lib/sync/utils/downloadByRange.js +2 -0
  71. package/lib/sync/utils/downloadByRange.js.map +1 -1
  72. package/lib/util/dependentRoot.d.ts +6 -2
  73. package/lib/util/dependentRoot.d.ts.map +1 -1
  74. package/lib/util/dependentRoot.js +20 -16
  75. package/lib/util/dependentRoot.js.map +1 -1
  76. package/package.json +14 -15
  77. package/src/api/impl/beacon/pool/index.ts +56 -3
  78. package/src/chain/blocks/utils/chainSegment.ts +30 -27
  79. package/src/chain/chain.ts +3 -0
  80. package/src/chain/errors/executionPayloadBid.ts +22 -1
  81. package/src/chain/interface.ts +2 -0
  82. package/src/chain/lightClient/index.ts +6 -6
  83. package/src/chain/opPools/index.ts +1 -0
  84. package/src/chain/opPools/payloadAttestationPool.ts +34 -10
  85. package/src/chain/opPools/proposerPreferencesPool.ts +59 -0
  86. package/src/chain/validation/executionPayloadBid.ts +67 -17
  87. package/src/chain/validation/payloadAttestationMessage.ts +6 -4
  88. package/src/metrics/metrics/lodestar.ts +6 -0
  89. package/src/network/interface.ts +1 -0
  90. package/src/network/network.ts +11 -0
  91. package/src/network/processor/gossipHandlers.ts +43 -3
  92. package/src/sync/range/batch.ts +71 -11
  93. package/src/sync/range/chain.ts +3 -1
  94. package/src/sync/range/range.ts +52 -2
  95. package/src/sync/range/utils/peerBalancer.ts +9 -3
  96. package/src/sync/utils/downloadByRange.ts +8 -0
  97. package/src/util/dependentRoot.ts +22 -18
@@ -52,7 +52,8 @@ export class ChainPeersBalancer {
52
52
 
53
53
  /**
54
54
  * Return the most suitable peer to retry
55
- * Sort peers by (1) no failed request (2) less active requests, then pick first
55
+ * Sort peers by (1) less active requests (2) most columns we need.
56
+ * Peers that failed this batch or already succeeded for the same request are excluded inside `filterPeers`.
56
57
  */
57
58
  bestPeerToRetryBatch(batch: Batch): PeerSyncMeta | undefined {
58
59
  if (batch.state.status !== BatchStatus.AwaitingDownload) {
@@ -63,10 +64,8 @@ export class ChainPeersBalancer {
63
64
  const pendingDataColumns = columnsRequest?.columns ?? this.custodyConfig.sampledColumns;
64
65
  const eligiblePeers = this.filterPeers(batch, pendingDataColumns, false);
65
66
 
66
- const failedPeers = new Set(batch.getFailedPeers());
67
67
  const sortedBestPeers = sortBy(
68
68
  eligiblePeers,
69
- ({syncInfo}) => (failedPeers.has(syncInfo.peerId) ? 1 : 0), // prefer peers without failed requests
70
69
  ({syncInfo}) => this.activeRequestsByPeer.get(syncInfo.peerId) ?? 0, // prefer peers with least active req
71
70
  ({columns}) => -1 * columns // prefer peers with the most columns
72
71
  );
@@ -117,9 +116,16 @@ export class ChainPeersBalancer {
117
116
  return eligiblePeers;
118
117
  }
119
118
 
119
+ // Skip peers that failed this batch, or that already returned the exact current request shape.
120
+ const failedPeers = new Set<PeerIdStr>(batch.getFailedPeers());
121
+
120
122
  for (const peer of this.peers) {
121
123
  const {earliestAvailableSlot, target, peerId} = peer;
122
124
 
125
+ if (failedPeers.has(peerId) || batch.hasPeerSucceededCurrentRequest(peer)) {
126
+ continue;
127
+ }
128
+
123
129
  const activeRequest = this.activeRequestsByPeer.get(peerId) ?? 0;
124
130
  if (noActiveRequest && activeRequest > 0) {
125
131
  // consumer wants to find peer with no active request, but this peer has active request
@@ -1155,6 +1155,9 @@ export enum DownloadByRangeErrorCode {
1155
1155
 
1156
1156
  /** Envelope beaconBlockRoot does not match the block's root */
1157
1157
  INVALID_ENVELOPE_BEACON_BLOCK_ROOT = "DOWNLOAD_BY_RANGE_ERROR_INVALID_ENVELOPE_BEACON_BLOCK_ROOT",
1158
+
1159
+ /** Block segment + envelopes failed chain-segment linearity / FULL-chain checks */
1160
+ INVALID_CHAIN_SEGMENT = "DOWNLOAD_BY_RANGE_ERROR_INVALID_CHAIN_SEGMENT",
1158
1161
  }
1159
1162
 
1160
1163
  export type DownloadByRangeErrorType =
@@ -1252,6 +1255,11 @@ export type DownloadByRangeErrorType =
1252
1255
  slot: Slot;
1253
1256
  expected: string;
1254
1257
  actual: string;
1258
+ }
1259
+ | {
1260
+ code: DownloadByRangeErrorCode.INVALID_CHAIN_SEGMENT;
1261
+ slot: Slot;
1262
+ reason: string;
1255
1263
  };
1256
1264
 
1257
1265
  export class DownloadByRangeError extends LodestarError<DownloadByRangeErrorType> {}
@@ -2,45 +2,49 @@ import {EpochDifference, IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
2
2
  import {Epoch, RootHex} from "@lodestar/types";
3
3
 
4
4
  /**
5
- * Get dependent root of a shuffling given attestation epoch and head block.
5
+ * Get dependent root of a shuffling given a message epoch and a proto block.
6
+ *
7
+ * Pre-gloas, this is used for attestation validation
8
+ * Post-gloas, this is also used for execution_payload_bid validation because post-fulu,
9
+ * a dependent root of a proposal duties is 1-epoch look ahead (instead of 0 as of pre-fulu)
6
10
  */
7
11
  export function getShufflingDependentRoot(
8
12
  forkChoice: IForkChoice,
9
- attEpoch: Epoch,
10
- blockEpoch: Epoch,
11
- attHeadBlock: ProtoBlock
13
+ msgEpoch: Epoch,
14
+ protoBlockEpoch: Epoch,
15
+ protoBlock: ProtoBlock
12
16
  ): RootHex {
13
17
  let shufflingDependentRoot: RootHex;
14
- if (blockEpoch === attEpoch) {
18
+ if (protoBlockEpoch === msgEpoch) {
15
19
  // current shuffling, this is equivalent to `headState.currentShuffling`
16
- // given blockEpoch = attEpoch = n
20
+ // given protoBlockEpoch = msgEpoch = n
17
21
  // epoch: (n-2) (n-1) n (n+1)
18
22
  // |-------|-------|-------|-------|
19
- // attHeadBlock ------------------------^
23
+ // protoBlock ------------------------^
20
24
  // shufflingDependentRoot ------^
21
- shufflingDependentRoot = forkChoice.getDependentRoot(attHeadBlock, EpochDifference.previous);
22
- } else if (blockEpoch === attEpoch - 1) {
25
+ shufflingDependentRoot = forkChoice.getDependentRoot(protoBlock, EpochDifference.previous);
26
+ } else if (protoBlockEpoch === msgEpoch - 1) {
23
27
  // next shuffling, this is equivalent to `headState.nextShuffling`
24
- // given blockEpoch = n-1, attEpoch = n
28
+ // given protoBlockEpoch = n-1, msgEpoch = n
25
29
  // epoch: (n-2) (n-1) n (n+1)
26
30
  // |-------|-------|-------|-------|
27
- // attHeadBlock -------------------^
31
+ // protoBlock -------------------^
28
32
  // shufflingDependentRoot ------^
29
- shufflingDependentRoot = forkChoice.getDependentRoot(attHeadBlock, EpochDifference.current);
30
- } else if (blockEpoch < attEpoch - 1) {
33
+ shufflingDependentRoot = forkChoice.getDependentRoot(protoBlock, EpochDifference.current);
34
+ } else if (protoBlockEpoch < msgEpoch - 1) {
31
35
  // this never happens with default chain option of maxSkipSlots = 32, however we still need to handle it
32
36
  // check the verifyHeadBlockAndTargetRoot() function above
33
- // given blockEpoch = n-2, attEpoch = n
37
+ // given protoBlockEpoch = n-2, msgEpoch = n
34
38
  // epoch: (n-2) (n-1) n (n+1)
35
39
  // |-------|-------|-------|-------|
36
- // attHeadBlock -----------^
40
+ // protoBlock -----------^
37
41
  // shufflingDependentRoot -----^
38
- shufflingDependentRoot = attHeadBlock.blockRoot;
42
+ shufflingDependentRoot = protoBlock.blockRoot;
39
43
  // use lodestar_gossip_attestation_head_slot_to_attestation_slot metric to track this case
40
44
  } else {
41
- // blockEpoch > attEpoch
45
+ // protoBlockEpoch > msgEpoch
42
46
  // should not happen, handled in verifyAttestationTargetRoot
43
- throw Error(`attestation epoch ${attEpoch} is before head block epoch ${blockEpoch}`);
47
+ throw Error(`message epoch ${msgEpoch} is before proto block epoch ${protoBlockEpoch}`);
44
48
  }
45
49
 
46
50
  return shufflingDependentRoot;