@lodestar/beacon-node 1.37.0 → 1.38.0-dev.1ddbe5d870

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 (104) hide show
  1. package/README.md +1 -1
  2. package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
  3. package/lib/api/impl/beacon/state/utils.js +5 -3
  4. package/lib/api/impl/beacon/state/utils.js.map +1 -1
  5. package/lib/chain/blocks/importBlock.d.ts.map +1 -1
  6. package/lib/chain/blocks/importBlock.js +4 -4
  7. package/lib/chain/blocks/importBlock.js.map +1 -1
  8. package/lib/chain/blocks/index.d.ts.map +1 -1
  9. package/lib/chain/blocks/index.js +2 -1
  10. package/lib/chain/blocks/index.js.map +1 -1
  11. package/lib/chain/blocks/types.d.ts +5 -1
  12. package/lib/chain/blocks/types.d.ts.map +1 -1
  13. package/lib/chain/blocks/verifyBlock.d.ts +2 -0
  14. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  15. package/lib/chain/blocks/verifyBlock.js +18 -10
  16. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  17. package/lib/chain/blocks/verifyBlocksSignatures.d.ts +3 -3
  18. package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
  19. package/lib/chain/blocks/verifyBlocksSignatures.js +2 -2
  20. package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
  21. package/lib/chain/chain.js +2 -2
  22. package/lib/chain/chain.js.map +1 -1
  23. package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
  24. package/lib/chain/opPools/aggregatedAttestationPool.js +3 -1
  25. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  26. package/lib/chain/rewards/syncCommitteeRewards.d.ts +2 -2
  27. package/lib/chain/rewards/syncCommitteeRewards.d.ts.map +1 -1
  28. package/lib/chain/rewards/syncCommitteeRewards.js +1 -2
  29. package/lib/chain/rewards/syncCommitteeRewards.js.map +1 -1
  30. package/lib/chain/validation/attesterSlashing.js +2 -2
  31. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  32. package/lib/chain/validation/blobSidecar.d.ts.map +1 -1
  33. package/lib/chain/validation/blobSidecar.js +2 -2
  34. package/lib/chain/validation/blobSidecar.js.map +1 -1
  35. package/lib/chain/validation/block.js +1 -1
  36. package/lib/chain/validation/block.js.map +1 -1
  37. package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
  38. package/lib/chain/validation/dataColumnSidecar.js +2 -2
  39. package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
  40. package/lib/chain/validation/proposerSlashing.js +1 -1
  41. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  42. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts +2 -2
  43. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts.map +1 -1
  44. package/lib/chain/validation/signatureSets/contributionAndProof.js +2 -3
  45. package/lib/chain/validation/signatureSets/contributionAndProof.js.map +1 -1
  46. package/lib/chain/validation/signatureSets/syncCommittee.d.ts +2 -2
  47. package/lib/chain/validation/signatureSets/syncCommittee.d.ts.map +1 -1
  48. package/lib/chain/validation/signatureSets/syncCommittee.js +2 -2
  49. package/lib/chain/validation/signatureSets/syncCommittee.js.map +1 -1
  50. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts +2 -2
  51. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts.map +1 -1
  52. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js +3 -3
  53. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js.map +1 -1
  54. package/lib/chain/validation/syncCommittee.js +1 -1
  55. package/lib/chain/validation/syncCommittee.js.map +1 -1
  56. package/lib/chain/validation/syncCommitteeContributionAndProof.d.ts.map +1 -1
  57. package/lib/chain/validation/syncCommitteeContributionAndProof.js +4 -3
  58. package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
  59. package/lib/chain/validation/voluntaryExit.js +1 -1
  60. package/lib/chain/validation/voluntaryExit.js.map +1 -1
  61. package/lib/network/gossip/encoding.d.ts +4 -2
  62. package/lib/network/gossip/encoding.d.ts.map +1 -1
  63. package/lib/network/gossip/encoding.js +24 -9
  64. package/lib/network/gossip/encoding.js.map +1 -1
  65. package/lib/network/gossip/gossipsub.d.ts.map +1 -1
  66. package/lib/network/gossip/gossipsub.js +6 -5
  67. package/lib/network/gossip/gossipsub.js.map +1 -1
  68. package/lib/network/gossip/metrics.d.ts +8 -0
  69. package/lib/network/gossip/metrics.d.ts.map +1 -1
  70. package/lib/network/gossip/metrics.js +12 -0
  71. package/lib/network/gossip/metrics.js.map +1 -1
  72. package/lib/sync/backfill/backfill.d.ts.map +1 -1
  73. package/lib/sync/backfill/backfill.js +4 -2
  74. package/lib/sync/backfill/backfill.js.map +1 -1
  75. package/lib/sync/backfill/verify.d.ts +2 -2
  76. package/lib/sync/backfill/verify.d.ts.map +1 -1
  77. package/lib/sync/backfill/verify.js +3 -3
  78. package/lib/sync/backfill/verify.js.map +1 -1
  79. package/package.json +15 -15
  80. package/src/api/impl/beacon/state/utils.ts +5 -3
  81. package/src/chain/blocks/importBlock.ts +5 -4
  82. package/src/chain/blocks/index.ts +2 -1
  83. package/src/chain/blocks/types.ts +5 -1
  84. package/src/chain/blocks/verifyBlock.ts +35 -11
  85. package/src/chain/blocks/verifyBlocksSignatures.ts +5 -3
  86. package/src/chain/chain.ts +2 -2
  87. package/src/chain/opPools/aggregatedAttestationPool.ts +5 -1
  88. package/src/chain/rewards/syncCommitteeRewards.ts +2 -2
  89. package/src/chain/validation/attesterSlashing.ts +2 -2
  90. package/src/chain/validation/blobSidecar.ts +10 -2
  91. package/src/chain/validation/block.ts +1 -1
  92. package/src/chain/validation/dataColumnSidecar.ts +6 -1
  93. package/src/chain/validation/proposerSlashing.ts +1 -1
  94. package/src/chain/validation/signatureSets/contributionAndProof.ts +3 -2
  95. package/src/chain/validation/signatureSets/syncCommittee.ts +3 -1
  96. package/src/chain/validation/signatureSets/syncCommitteeSelectionProof.ts +4 -2
  97. package/src/chain/validation/syncCommittee.ts +1 -1
  98. package/src/chain/validation/syncCommitteeContributionAndProof.ts +4 -5
  99. package/src/chain/validation/voluntaryExit.ts +1 -1
  100. package/src/network/gossip/encoding.ts +26 -9
  101. package/src/network/gossip/gossipsub.ts +8 -6
  102. package/src/network/gossip/metrics.ts +12 -0
  103. package/src/sync/backfill/backfill.ts +9 -2
  104. package/src/sync/backfill/verify.ts +8 -2
@@ -2,16 +2,17 @@ import {DOMAIN_CONTRIBUTION_AND_PROOF} from "@lodestar/params";
2
2
  import {
3
3
  CachedBeaconStateAllForks,
4
4
  ISignatureSet,
5
+ Index2PubkeyCache,
5
6
  SignatureSetType,
6
7
  computeSigningRoot,
7
8
  } from "@lodestar/state-transition";
8
9
  import {altair, ssz} from "@lodestar/types";
9
10
 
10
11
  export function getContributionAndProofSignatureSet(
12
+ index2pubkey: Index2PubkeyCache,
11
13
  state: CachedBeaconStateAllForks,
12
14
  signedContributionAndProof: altair.SignedContributionAndProof
13
15
  ): ISignatureSet {
14
- const {epochCtx} = state;
15
16
  const domain = state.config.getDomain(
16
17
  state.slot,
17
18
  DOMAIN_CONTRIBUTION_AND_PROOF,
@@ -20,7 +21,7 @@ export function getContributionAndProofSignatureSet(
20
21
  const signingData = signedContributionAndProof.message;
21
22
  return {
22
23
  type: SignatureSetType.single,
23
- pubkey: epochCtx.index2pubkey[signedContributionAndProof.message.aggregatorIndex],
24
+ pubkey: index2pubkey[signedContributionAndProof.message.aggregatorIndex],
24
25
  signingRoot: computeSigningRoot(ssz.altair.ContributionAndProof, signingData, domain),
25
26
  signature: signedContributionAndProof.signature,
26
27
  };
@@ -2,12 +2,14 @@ import {DOMAIN_SYNC_COMMITTEE} from "@lodestar/params";
2
2
  import {
3
3
  CachedBeaconStateAllForks,
4
4
  ISignatureSet,
5
+ Index2PubkeyCache,
5
6
  SignatureSetType,
6
7
  computeSigningRoot,
7
8
  } from "@lodestar/state-transition";
8
9
  import {altair, ssz} from "@lodestar/types";
9
10
 
10
11
  export function getSyncCommitteeSignatureSet(
12
+ index2pubkey: Index2PubkeyCache,
11
13
  state: CachedBeaconStateAllForks,
12
14
  syncCommittee: altair.SyncCommitteeMessage
13
15
  ): ISignatureSet {
@@ -15,7 +17,7 @@ export function getSyncCommitteeSignatureSet(
15
17
 
16
18
  return {
17
19
  type: SignatureSetType.single,
18
- pubkey: state.epochCtx.index2pubkey[syncCommittee.validatorIndex],
20
+ pubkey: index2pubkey[syncCommittee.validatorIndex],
19
21
  signingRoot: computeSigningRoot(ssz.Root, syncCommittee.beaconBlockRoot, domain),
20
22
  signature: syncCommittee.signature,
21
23
  };
@@ -2,16 +2,18 @@ import {DOMAIN_SYNC_COMMITTEE_SELECTION_PROOF} from "@lodestar/params";
2
2
  import {
3
3
  CachedBeaconStateAllForks,
4
4
  ISignatureSet,
5
+ Index2PubkeyCache,
5
6
  SignatureSetType,
6
7
  computeSigningRoot,
7
8
  } from "@lodestar/state-transition";
8
9
  import {altair, ssz} from "@lodestar/types";
9
10
 
10
11
  export function getSyncCommitteeSelectionProofSignatureSet(
12
+ index2pubkey: Index2PubkeyCache,
11
13
  state: CachedBeaconStateAllForks,
12
14
  contributionAndProof: altair.ContributionAndProof
13
15
  ): ISignatureSet {
14
- const {epochCtx, config} = state;
16
+ const {config} = state;
15
17
  const slot = contributionAndProof.contribution.slot;
16
18
  const domain = config.getDomain(state.slot, DOMAIN_SYNC_COMMITTEE_SELECTION_PROOF, slot);
17
19
  const signingData: altair.SyncAggregatorSelectionData = {
@@ -20,7 +22,7 @@ export function getSyncCommitteeSelectionProofSignatureSet(
20
22
  };
21
23
  return {
22
24
  type: SignatureSetType.single,
23
- pubkey: epochCtx.index2pubkey[contributionAndProof.aggregatorIndex],
25
+ pubkey: index2pubkey[contributionAndProof.aggregatorIndex],
24
26
  signingRoot: computeSigningRoot(ssz.altair.SyncAggregatorSelectionData, signingData, domain),
25
27
  signature: contributionAndProof.selectionProof,
26
28
  };
@@ -89,7 +89,7 @@ async function validateSyncCommitteeSigOnly(
89
89
  syncCommittee: altair.SyncCommitteeMessage,
90
90
  prioritizeBls = false
91
91
  ): Promise<void> {
92
- const signatureSet = getSyncCommitteeSignatureSet(headState, syncCommittee);
92
+ const signatureSet = getSyncCommitteeSignatureSet(chain.index2pubkey, headState, syncCommittee);
93
93
  if (!(await chain.bls.verifySignatureSets([signatureSet], {batchable: true, priority: prioritizeBls}))) {
94
94
  throw new SyncCommitteeError(GossipAction.REJECT, {
95
95
  code: SyncCommitteeErrorCode.INVALID_SIGNATURE,
@@ -21,6 +21,7 @@ export async function validateSyncCommitteeGossipContributionAndProof(
21
21
  const contributionAndProof = signedContributionAndProof.message;
22
22
  const {contribution, aggregatorIndex} = contributionAndProof;
23
23
  const {subcommitteeIndex, slot} = contribution;
24
+ const {index2pubkey} = chain;
24
25
 
25
26
  const headState = chain.getHeadState();
26
27
  validateGossipSyncCommitteeExceptSig(chain, headState, subcommitteeIndex, {
@@ -73,16 +74,14 @@ export async function validateSyncCommitteeGossipContributionAndProof(
73
74
  // i.e. state.validators[contribution_and_proof.aggregator_index].pubkey in get_sync_subcommittee_pubkeys(state, contribution.subcommittee_index).
74
75
  // > Checked in validateGossipSyncCommitteeExceptSig()
75
76
 
76
- const participantPubkeys = syncCommitteeParticipantIndices.map(
77
- (validatorIndex) => headState.epochCtx.index2pubkey[validatorIndex]
78
- );
77
+ const participantPubkeys = syncCommitteeParticipantIndices.map((validatorIndex) => index2pubkey[validatorIndex]);
79
78
  const signatureSets = [
80
79
  // [REJECT] The contribution_and_proof.selection_proof is a valid signature of the SyncAggregatorSelectionData
81
80
  // derived from the contribution by the validator with index contribution_and_proof.aggregator_index.
82
- getSyncCommitteeSelectionProofSignatureSet(headState, contributionAndProof),
81
+ getSyncCommitteeSelectionProofSignatureSet(index2pubkey, headState, contributionAndProof),
83
82
 
84
83
  // [REJECT] The aggregator signature, signed_contribution_and_proof.signature, is valid.
85
- getContributionAndProofSignatureSet(headState, signedContributionAndProof),
84
+ getContributionAndProofSignatureSet(index2pubkey, headState, signedContributionAndProof),
86
85
 
87
86
  // [REJECT] The aggregate signature is valid for the message beacon_block_root and aggregate pubkey derived from
88
87
  // the participation info in aggregation_bits for the subcommittee specified by the contribution.subcommittee_index.
@@ -59,7 +59,7 @@ async function validateVoluntaryExit(
59
59
  });
60
60
  }
61
61
 
62
- const signatureSet = getVoluntaryExitSignatureSet(state, voluntaryExit);
62
+ const signatureSet = getVoluntaryExitSignatureSet(chain.index2pubkey, state, voluntaryExit);
63
63
  if (!(await chain.bls.verifySignatureSets([signatureSet], {batchable: true, priority: prioritizeBls}))) {
64
64
  throw new VoluntaryExitError(GossipAction.REJECT, {
65
65
  code: VoluntaryExitErrorCode.INVALID_SIGNATURE,
@@ -1,13 +1,14 @@
1
1
  import {Message} from "@libp2p/interface";
2
2
  // snappyjs is better for compression for smaller payloads
3
- import {compress, uncompress} from "snappyjs";
4
3
  import xxhashFactory from "xxhash-wasm";
5
4
  import {digest} from "@chainsafe/as-sha256";
6
5
  import {RPC} from "@chainsafe/libp2p-gossipsub/message";
7
6
  import {DataTransform} from "@chainsafe/libp2p-gossipsub/types";
7
+ import snappyWasm from "@chainsafe/snappy-wasm";
8
8
  import {ForkName} from "@lodestar/params";
9
9
  import {intToBytes} from "@lodestar/utils";
10
10
  import {MESSAGE_DOMAIN_VALID_SNAPPY} from "./constants.js";
11
+ import {Eth2GossipsubMetrics} from "./metrics.js";
11
12
  import {GossipTopicCache, getGossipSSZType} from "./topic.js";
12
13
 
13
14
  // Load WASM
@@ -16,6 +17,10 @@ const xxhash = await xxhashFactory();
16
17
  // Use salt to prevent msgId from being mined for collisions
17
18
  const h64Seed = BigInt(Math.floor(Math.random() * 1e9));
18
19
 
20
+ // create singleton snappy encoder + decoder
21
+ const encoder = new snappyWasm.Encoder();
22
+ const decoder = new snappyWasm.Decoder();
23
+
19
24
  // Shared buffer to convert msgId to string
20
25
  const sharedMsgIdBuf = Buffer.alloc(20);
21
26
 
@@ -70,7 +75,8 @@ export function msgIdFn(gossipTopicCache: GossipTopicCache, msg: Message): Uint8
70
75
  export class DataTransformSnappy implements DataTransform {
71
76
  constructor(
72
77
  private readonly gossipTopicCache: GossipTopicCache,
73
- private readonly maxSizePerMessage: number
78
+ private readonly maxSizePerMessage: number,
79
+ private readonly metrics: Eth2GossipsubMetrics | null
74
80
  ) {}
75
81
 
76
82
  /**
@@ -80,13 +86,15 @@ export class DataTransformSnappy implements DataTransform {
80
86
  * - `outboundTransform()`: compress snappy payload
81
87
  */
82
88
  inboundTransform(topicStr: string, data: Uint8Array): Uint8Array {
83
- const uncompressedData = uncompress(data, this.maxSizePerMessage);
89
+ // check uncompressed data length before we actually decompress
90
+ const uncompressedDataLength = snappyWasm.decompress_len(data);
91
+ if (uncompressedDataLength > this.maxSizePerMessage) {
92
+ throw Error(`ssz_snappy decoded data length ${uncompressedDataLength} > ${this.maxSizePerMessage}`);
93
+ }
84
94
 
85
- // check uncompressed data length before we extract beacon block root, slot or
86
- // attestation data at later steps
87
- const uncompressedDataLength = uncompressedData.length;
88
95
  const topic = this.gossipTopicCache.getTopic(topicStr);
89
96
  const sszType = getGossipSSZType(topic);
97
+ this.metrics?.dataTransform.inbound.inc({type: topic.type});
90
98
 
91
99
  if (uncompressedDataLength < sszType.minSize) {
92
100
  throw Error(`ssz_snappy decoded data length ${uncompressedDataLength} < ${sszType.minSize}`);
@@ -95,6 +103,10 @@ export class DataTransformSnappy implements DataTransform {
95
103
  throw Error(`ssz_snappy decoded data length ${uncompressedDataLength} > ${sszType.maxSize}`);
96
104
  }
97
105
 
106
+ // Only after sanity length checks, we can decompress the data
107
+ // Using Buffer.alloc() instead of Buffer.allocUnsafe() to mitigate high GC pressure observed in some environments
108
+ const uncompressedData = Buffer.alloc(uncompressedDataLength);
109
+ decoder.decompress_into(data, uncompressedData);
98
110
  return uncompressedData;
99
111
  }
100
112
 
@@ -102,11 +114,16 @@ export class DataTransformSnappy implements DataTransform {
102
114
  * Takes the data to be published (a topic and associated data) transforms the data. The
103
115
  * transformed data will then be used to create a `RawGossipsubMessage` to be sent to peers.
104
116
  */
105
- outboundTransform(_topicStr: string, data: Uint8Array): Uint8Array {
117
+ outboundTransform(topicStr: string, data: Uint8Array): Uint8Array {
118
+ const topic = this.gossipTopicCache.getTopic(topicStr);
119
+ this.metrics?.dataTransform.outbound.inc({type: topic.type});
106
120
  if (data.length > this.maxSizePerMessage) {
107
121
  throw Error(`ssz_snappy encoded data length ${data.length} > ${this.maxSizePerMessage}`);
108
122
  }
109
- // No need to parse topic, everything is snappy compressed
110
- return compress(data);
123
+
124
+ // Using Buffer.alloc() instead of Buffer.allocUnsafe() to mitigate high GC pressure observed in some environments
125
+ const compressedData = Buffer.alloc(snappyWasm.max_compress_len(data.length));
126
+ const compressedLen = encoder.compress_into(data, compressedData);
127
+ return compressedData.subarray(0, compressedLen);
111
128
  }
112
129
  }
@@ -89,6 +89,13 @@ export class Eth2Gossipsub extends GossipSub {
89
89
  const gossipTopicCache = new GossipTopicCache(config);
90
90
 
91
91
  const scoreParams = computeGossipPeerScoreParams({config, eth2Context: modules.eth2Context});
92
+ let metrics: Eth2GossipsubMetrics | null = null;
93
+ if (metricsRegister) {
94
+ metrics = createEth2GossipsubMetrics(metricsRegister);
95
+ metrics.gossipMesh.peersByType.addCollect(() =>
96
+ this.onScrapeLodestarMetrics(metrics as Eth2GossipsubMetrics, networkConfig)
97
+ );
98
+ }
92
99
 
93
100
  // Gossipsub parameters defined here:
94
101
  // https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/phase0/p2p-interface.md#the-gossip-domain-gossipsub
@@ -116,7 +123,7 @@ export class Eth2Gossipsub extends GossipSub {
116
123
  fastMsgIdFn: fastMsgIdFn,
117
124
  msgIdFn: msgIdFn.bind(msgIdFn, gossipTopicCache),
118
125
  msgIdToStrFn: msgIdToStrFn,
119
- dataTransform: new DataTransformSnappy(gossipTopicCache, config.MAX_PAYLOAD_SIZE),
126
+ dataTransform: new DataTransformSnappy(gossipTopicCache, config.MAX_PAYLOAD_SIZE, metrics),
120
127
  metricsRegister: metricsRegister as MetricsRegister | null,
121
128
  metricsTopicStrToLabel: metricsRegister
122
129
  ? getMetricsTopicStrToLabel(networkConfig, {disableLightClientServer: opts.disableLightClientServer ?? false})
@@ -141,11 +148,6 @@ export class Eth2Gossipsub extends GossipSub {
141
148
  this.events = events;
142
149
  this.gossipTopicCache = gossipTopicCache;
143
150
 
144
- if (metricsRegister) {
145
- const metrics = createEth2GossipsubMetrics(metricsRegister);
146
- metrics.gossipMesh.peersByType.addCollect(() => this.onScrapeLodestarMetrics(metrics, networkConfig));
147
- }
148
-
149
151
  this.addEventListener("gossipsub:message", this.onGossipsubMessage.bind(this));
150
152
  this.events.on(NetworkEvent.gossipMessageValidationResult, this.onValidationResult.bind(this));
151
153
 
@@ -67,5 +67,17 @@ export function createEth2GossipsubMetrics(register: RegistryMetricCreator) {
67
67
  labelNames: ["subnet", "boundary"],
68
68
  }),
69
69
  },
70
+ dataTransform: {
71
+ inbound: register.counter<{type: GossipType}>({
72
+ name: "lodestar_gossip_data_transform_inbound_total",
73
+ help: "Total number of inbound data transforms by gossip type",
74
+ labelNames: ["type"],
75
+ }),
76
+ outbound: register.counter<{type: GossipType}>({
77
+ name: "lodestar_gossip_data_transform_outbound_total",
78
+ help: "Total number of outbound data transforms by gossip type",
79
+ labelNames: ["type"],
80
+ }),
81
+ },
70
82
  };
71
83
  }
@@ -750,7 +750,9 @@ export class BackfillSync extends (EventEmitter as {new (): BackfillSyncEmitter}
750
750
 
751
751
  // GENESIS_SLOT doesn't has valid signature
752
752
  if (anchorBlock.message.slot === GENESIS_SLOT) return;
753
- await verifyBlockProposerSignature(this.chain.bls, this.chain.getHeadState(), [anchorBlock]);
753
+ await verifyBlockProposerSignature(this.chain.index2pubkey, this.chain.bls, this.chain.getHeadState(), [
754
+ anchorBlock,
755
+ ]);
754
756
 
755
757
  // We can write to the disk if this is ahead of prevFinalizedCheckpointBlock otherwise
756
758
  // we will need to go make checks on the top of sync loop before writing as it might
@@ -815,7 +817,12 @@ export class BackfillSync extends (EventEmitter as {new (): BackfillSyncEmitter}
815
817
 
816
818
  // If any of the block's proposer signature fail, we can't trust this peer at all
817
819
  if (verifiedBlocks.length > 0) {
818
- await verifyBlockProposerSignature(this.chain.bls, this.chain.getHeadState(), verifiedBlocks);
820
+ await verifyBlockProposerSignature(
821
+ this.chain.index2pubkey,
822
+ this.chain.bls,
823
+ this.chain.getHeadState(),
824
+ verifiedBlocks
825
+ );
819
826
 
820
827
  // This is bad, like super bad. Abort the backfill
821
828
  if (!nextAnchor)
@@ -1,6 +1,11 @@
1
1
  import {BeaconConfig} from "@lodestar/config";
2
2
  import {GENESIS_SLOT} from "@lodestar/params";
3
- import {CachedBeaconStateAllForks, ISignatureSet, getBlockProposerSignatureSet} from "@lodestar/state-transition";
3
+ import {
4
+ CachedBeaconStateAllForks,
5
+ ISignatureSet,
6
+ Index2PubkeyCache,
7
+ getBlockProposerSignatureSet,
8
+ } from "@lodestar/state-transition";
4
9
  import {Root, SignedBeaconBlock, Slot, ssz} from "@lodestar/types";
5
10
  import {IBlsVerifier} from "../../chain/bls/index.js";
6
11
  import {BackfillSyncError, BackfillSyncErrorCode} from "./errors.js";
@@ -41,6 +46,7 @@ export function verifyBlockSequence(
41
46
  }
42
47
 
43
48
  export async function verifyBlockProposerSignature(
49
+ index2pubkey: Index2PubkeyCache,
44
50
  bls: IBlsVerifier,
45
51
  state: CachedBeaconStateAllForks,
46
52
  blocks: SignedBeaconBlock[]
@@ -48,7 +54,7 @@ export async function verifyBlockProposerSignature(
48
54
  if (blocks.length === 1 && blocks[0].message.slot === GENESIS_SLOT) return;
49
55
  const signatures = blocks.reduce((sigs: ISignatureSet[], block) => {
50
56
  // genesis block doesn't have valid signature
51
- if (block.message.slot !== GENESIS_SLOT) sigs.push(getBlockProposerSignatureSet(state, block));
57
+ if (block.message.slot !== GENESIS_SLOT) sigs.push(getBlockProposerSignatureSet(index2pubkey, state, block));
52
58
  return sigs;
53
59
  }, []);
54
60