@lodestar/beacon-node 1.39.0-dev.aceb5b7416 → 1.39.0-dev.c151a164f2

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 (119) hide show
  1. package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
  2. package/lib/chain/blocks/verifyBlock.js +1 -1
  3. package/lib/chain/blocks/verifyBlock.js.map +1 -1
  4. package/lib/chain/blocks/verifyBlocksSignatures.d.ts +2 -1
  5. package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
  6. package/lib/chain/blocks/verifyBlocksSignatures.js +2 -2
  7. package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
  8. package/lib/chain/chain.d.ts.map +1 -1
  9. package/lib/chain/chain.js +6 -4
  10. package/lib/chain/chain.js.map +1 -1
  11. package/lib/chain/opPools/aggregatedAttestationPool.d.ts +4 -4
  12. package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
  13. package/lib/chain/opPools/aggregatedAttestationPool.js +4 -4
  14. package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
  15. package/lib/chain/opPools/opPool.d.ts +3 -0
  16. package/lib/chain/opPools/opPool.d.ts.map +1 -1
  17. package/lib/chain/opPools/opPool.js +9 -8
  18. package/lib/chain/opPools/opPool.js.map +1 -1
  19. package/lib/chain/produceBlock/produceBlockBody.js +2 -2
  20. package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
  21. package/lib/chain/rewards/attestationsRewards.d.ts +2 -1
  22. package/lib/chain/rewards/attestationsRewards.d.ts.map +1 -1
  23. package/lib/chain/rewards/attestationsRewards.js +8 -8
  24. package/lib/chain/rewards/attestationsRewards.js.map +1 -1
  25. package/lib/chain/rewards/blockRewards.d.ts +2 -1
  26. package/lib/chain/rewards/blockRewards.d.ts.map +1 -1
  27. package/lib/chain/rewards/blockRewards.js +5 -5
  28. package/lib/chain/rewards/blockRewards.js.map +1 -1
  29. package/lib/chain/rewards/syncCommitteeRewards.d.ts +2 -1
  30. package/lib/chain/rewards/syncCommitteeRewards.d.ts.map +1 -1
  31. package/lib/chain/rewards/syncCommitteeRewards.js +2 -2
  32. package/lib/chain/rewards/syncCommitteeRewards.js.map +1 -1
  33. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +4 -1
  34. package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
  35. package/lib/chain/stateCache/persistentCheckpointsCache.js +4 -2
  36. package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
  37. package/lib/chain/validation/attesterSlashing.js +1 -1
  38. package/lib/chain/validation/attesterSlashing.js.map +1 -1
  39. package/lib/chain/validation/block.js +1 -1
  40. package/lib/chain/validation/block.js.map +1 -1
  41. package/lib/chain/validation/blsToExecutionChange.js +1 -1
  42. package/lib/chain/validation/proposerSlashing.js +1 -1
  43. package/lib/chain/validation/proposerSlashing.js.map +1 -1
  44. package/lib/chain/validation/signatureSets/aggregateAndProof.js +1 -1
  45. package/lib/chain/validation/signatureSets/aggregateAndProof.js.map +1 -1
  46. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts +2 -1
  47. package/lib/chain/validation/signatureSets/contributionAndProof.d.ts.map +1 -1
  48. package/lib/chain/validation/signatureSets/contributionAndProof.js +2 -2
  49. package/lib/chain/validation/signatureSets/contributionAndProof.js.map +1 -1
  50. package/lib/chain/validation/signatureSets/syncCommittee.d.ts +2 -1
  51. package/lib/chain/validation/signatureSets/syncCommittee.d.ts.map +1 -1
  52. package/lib/chain/validation/signatureSets/syncCommittee.js +2 -2
  53. package/lib/chain/validation/signatureSets/syncCommittee.js.map +1 -1
  54. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts +2 -1
  55. package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts.map +1 -1
  56. package/lib/chain/validation/signatureSets/syncCommitteeContribution.js +2 -2
  57. package/lib/chain/validation/signatureSets/syncCommitteeContribution.js.map +1 -1
  58. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts +2 -1
  59. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts.map +1 -1
  60. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js +1 -2
  61. package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js.map +1 -1
  62. package/lib/chain/validation/syncCommittee.js +1 -1
  63. package/lib/chain/validation/syncCommittee.js.map +1 -1
  64. package/lib/chain/validation/syncCommitteeContributionAndProof.d.ts.map +1 -1
  65. package/lib/chain/validation/syncCommitteeContributionAndProof.js +3 -3
  66. package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
  67. package/lib/chain/validation/voluntaryExit.js +1 -1
  68. package/lib/chain/validation/voluntaryExit.js.map +1 -1
  69. package/lib/db/beacon.d.ts +2 -0
  70. package/lib/db/beacon.d.ts.map +1 -1
  71. package/lib/db/beacon.js +32 -0
  72. package/lib/db/beacon.js.map +1 -1
  73. package/lib/db/buckets.d.ts +12 -0
  74. package/lib/db/buckets.d.ts.map +1 -1
  75. package/lib/db/buckets.js +12 -6
  76. package/lib/db/buckets.js.map +1 -1
  77. package/lib/db/interface.d.ts +1 -0
  78. package/lib/db/interface.d.ts.map +1 -1
  79. package/lib/db/repositories/blockArchiveIndex.d.ts +2 -2
  80. package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
  81. package/lib/node/nodejs.d.ts.map +1 -1
  82. package/lib/node/nodejs.js +10 -0
  83. package/lib/node/nodejs.js.map +1 -1
  84. package/lib/sync/backfill/backfill.d.ts.map +1 -1
  85. package/lib/sync/backfill/backfill.js +2 -4
  86. package/lib/sync/backfill/backfill.js.map +1 -1
  87. package/lib/sync/backfill/verify.d.ts +1 -1
  88. package/lib/sync/backfill/verify.d.ts.map +1 -1
  89. package/lib/sync/backfill/verify.js +2 -2
  90. package/lib/sync/backfill/verify.js.map +1 -1
  91. package/package.json +14 -14
  92. package/src/chain/blocks/verifyBlock.ts +1 -0
  93. package/src/chain/blocks/verifyBlocksSignatures.ts +3 -1
  94. package/src/chain/chain.ts +6 -4
  95. package/src/chain/opPools/aggregatedAttestationPool.ts +7 -7
  96. package/src/chain/opPools/opPool.ts +8 -8
  97. package/src/chain/produceBlock/produceBlockBody.ts +2 -2
  98. package/src/chain/rewards/attestationsRewards.ts +13 -4
  99. package/src/chain/rewards/blockRewards.ts +6 -3
  100. package/src/chain/rewards/syncCommitteeRewards.ts +3 -1
  101. package/src/chain/stateCache/persistentCheckpointsCache.ts +15 -2
  102. package/src/chain/validation/attesterSlashing.ts +1 -1
  103. package/src/chain/validation/block.ts +1 -1
  104. package/src/chain/validation/blsToExecutionChange.ts +1 -1
  105. package/src/chain/validation/proposerSlashing.ts +1 -1
  106. package/src/chain/validation/signatureSets/aggregateAndProof.ts +1 -1
  107. package/src/chain/validation/signatureSets/contributionAndProof.ts +3 -1
  108. package/src/chain/validation/signatureSets/syncCommittee.ts +3 -1
  109. package/src/chain/validation/signatureSets/syncCommitteeContribution.ts +3 -1
  110. package/src/chain/validation/signatureSets/syncCommitteeSelectionProof.ts +2 -1
  111. package/src/chain/validation/syncCommittee.ts +1 -1
  112. package/src/chain/validation/syncCommitteeContributionAndProof.ts +8 -3
  113. package/src/chain/validation/voluntaryExit.ts +1 -1
  114. package/src/db/beacon.ts +38 -1
  115. package/src/db/buckets.ts +12 -6
  116. package/src/db/interface.ts +2 -0
  117. package/src/node/nodejs.ts +11 -0
  118. package/src/sync/backfill/backfill.ts +8 -3
  119. package/src/sync/backfill/verify.ts +3 -1
@@ -1,3 +1,4 @@
1
+ import {BeaconConfig} from "@lodestar/config";
1
2
  import {Id, Repository} from "@lodestar/db";
2
3
  import {
3
4
  BLS_WITHDRAWAL_PREFIX,
@@ -51,6 +52,8 @@ export class OpPool {
51
52
  /** Map of validator index -> SignedBLSToExecutionChange */
52
53
  private readonly blsToExecutionChanges = new Map<ValidatorIndex, SignedBLSToExecutionChangeVersioned>();
53
54
 
55
+ constructor(private readonly config: BeaconConfig) {}
56
+
54
57
  // Getters for metrics
55
58
 
56
59
  get attesterSlashingsSize(): number {
@@ -191,9 +194,8 @@ export class OpPool {
191
194
  phase0.SignedVoluntaryExit[],
192
195
  capella.SignedBLSToExecutionChange[],
193
196
  ] {
194
- const {config} = state;
195
197
  const stateEpoch = computeEpochAtSlot(state.slot);
196
- const stateFork = config.getForkSeq(state.slot);
198
+ const stateFork = this.config.getForkSeq(state.slot);
197
199
  const toBeSlashedIndices = new Set<ValidatorIndex>();
198
200
  const proposerSlashings: phase0.ProposerSlashing[] = [];
199
201
 
@@ -265,7 +267,7 @@ export class OpPool {
265
267
  // a future fork.
266
268
  isVoluntaryExitSignatureIncludable(
267
269
  stateFork,
268
- config.getForkSeq(computeStartSlotAtEpoch(voluntaryExit.message.epoch))
270
+ this.config.getForkSeq(computeStartSlotAtEpoch(voluntaryExit.message.epoch))
269
271
  )
270
272
  ) {
271
273
  voluntaryExits.push(voluntaryExit);
@@ -368,14 +370,13 @@ export class OpPool {
368
370
  * Prune if validator has already exited at or before the finalized checkpoint of the head.
369
371
  */
370
372
  private pruneVoluntaryExits(headState: CachedBeaconStateAllForks): void {
371
- const {config} = headState;
372
- const headStateFork = config.getForkSeq(headState.slot);
373
+ const headStateFork = this.config.getForkSeq(headState.slot);
373
374
  const finalizedEpoch = headState.finalizedCheckpoint.epoch;
374
375
 
375
376
  for (const [key, voluntaryExit] of this.voluntaryExits.entries()) {
376
377
  // VoluntaryExit messages signed in the previous fork become invalid and can never be included in any future
377
378
  // block, so just drop as the head state advances into the next fork.
378
- if (config.getForkSeq(computeStartSlotAtEpoch(voluntaryExit.message.epoch)) < headStateFork) {
379
+ if (this.config.getForkSeq(computeStartSlotAtEpoch(voluntaryExit.message.epoch)) < headStateFork) {
379
380
  this.voluntaryExits.delete(key);
380
381
  }
381
382
 
@@ -392,9 +393,8 @@ export class OpPool {
392
393
  * to opPool once gossipsub seen cache TTL passes.
393
394
  */
394
395
  private pruneBlsToExecutionChanges(headBlock: SignedBeaconBlock, headState: CachedBeaconStateAllForks): void {
395
- const {config} = headState;
396
396
  const recentBlsToExecutionChanges =
397
- config.getForkSeq(headBlock.message.slot) >= ForkSeq.capella
397
+ this.config.getForkSeq(headBlock.message.slot) >= ForkSeq.capella
398
398
  ? (headBlock as capella.SignedBeaconBlock).message.body.blsToExecutionChanges
399
399
  : [];
400
400
 
@@ -165,7 +165,7 @@ export async function produceBlockBody<T extends BlockType>(
165
165
  // even though shouldOverrideBuilder is relevant for the engine response, for simplicity of typing
166
166
  // we just return it undefined for the builder which anyway doesn't get consumed downstream
167
167
  let shouldOverrideBuilder: boolean | undefined;
168
- const fork = currentState.config.getForkName(blockSlot);
168
+ const fork = this.config.getForkName(blockSlot);
169
169
  const produceResult = {
170
170
  type: blockType,
171
171
  fork,
@@ -644,7 +644,7 @@ export async function produceCommonBlockBody<T extends BlockType>(
644
644
  ? this.metrics?.executionBlockProductionTimeSteps
645
645
  : this.metrics?.builderBlockProductionTimeSteps;
646
646
 
647
- const fork = currentState.config.getForkName(slot);
647
+ const fork = this.config.getForkName(slot);
648
648
 
649
649
  // TODO:
650
650
  // Iterate through the naive aggregation pool and ensure all the attestations from there
@@ -1,5 +1,6 @@
1
1
  import {PubkeyIndexMap} from "@chainsafe/pubkey-index-map";
2
2
  import {routes} from "@lodestar/api";
3
+ import {BeaconConfig} from "@lodestar/config";
3
4
  import {
4
5
  EFFECTIVE_BALANCE_INCREMENT,
5
6
  ForkName,
@@ -38,11 +39,12 @@ const defaultAttestationsReward = {head: 0, target: 0, source: 0, inclusionDelay
38
39
  const defaultAttestationsPenalty = {target: 0, source: 0};
39
40
 
40
41
  export async function computeAttestationsRewards(
42
+ config: BeaconConfig,
41
43
  pubkey2index: PubkeyIndexMap,
42
44
  state: CachedBeaconStateAllForks,
43
45
  validatorIds?: (ValidatorIndex | string)[]
44
46
  ): Promise<AttestationsRewards> {
45
- const fork = state.config.getForkName(state.slot);
47
+ const fork = config.getForkName(state.slot);
46
48
  if (fork === ForkName.phase0) {
47
49
  throw Error("Unsupported fork. Attestations rewards calculation is not available in phase0");
48
50
  }
@@ -50,8 +52,13 @@ export async function computeAttestationsRewards(
50
52
  const stateAltair = state as CachedBeaconStateAltair;
51
53
  const transitionCache = beforeProcessEpoch(stateAltair);
52
54
 
53
- const [idealRewards, penalties] = computeIdealAttestationsRewardsAndPenaltiesAltair(stateAltair, transitionCache);
55
+ const [idealRewards, penalties] = computeIdealAttestationsRewardsAndPenaltiesAltair(
56
+ config,
57
+ stateAltair,
58
+ transitionCache
59
+ );
54
60
  const totalRewards = computeTotalAttestationsRewardsAltair(
61
+ config,
55
62
  pubkey2index,
56
63
  stateAltair,
57
64
  transitionCache,
@@ -64,12 +71,13 @@ export async function computeAttestationsRewards(
64
71
  }
65
72
 
66
73
  function computeIdealAttestationsRewardsAndPenaltiesAltair(
74
+ config: BeaconConfig,
67
75
  state: CachedBeaconStateAllForks,
68
76
  transitionCache: EpochTransitionCache
69
77
  ): [IdealAttestationsReward[], AttestationsPenalty[]] {
70
78
  const baseRewardPerIncrement = transitionCache.baseRewardPerIncrement;
71
79
  const activeBalanceByIncrement = transitionCache.totalActiveStakeByIncrement;
72
- const fork = state.config.getForkName(state.slot);
80
+ const fork = config.getForkName(state.slot);
73
81
  const maxEffectiveBalance = isForkPostElectra(fork) ? MAX_EFFECTIVE_BALANCE_ELECTRA : MAX_EFFECTIVE_BALANCE;
74
82
  const maxEffectiveBalanceByIncrement = Math.floor(maxEffectiveBalance / EFFECTIVE_BALANCE_INCREMENT);
75
83
 
@@ -139,6 +147,7 @@ function computeIdealAttestationsRewardsAndPenaltiesAltair(
139
147
 
140
148
  // Same calculation as `getRewardsAndPenaltiesAltair` but returns the breakdown of rewards instead of aggregated
141
149
  function computeTotalAttestationsRewardsAltair(
150
+ config: BeaconConfig,
142
151
  pubkey2index: PubkeyIndexMap,
143
152
  state: CachedBeaconStateAltair,
144
153
  transitionCache: EpochTransitionCache,
@@ -148,7 +157,7 @@ function computeTotalAttestationsRewardsAltair(
148
157
  ): TotalAttestationsReward[] {
149
158
  const rewards = [];
150
159
  const {flags} = transitionCache;
151
- const {epochCtx, config} = state;
160
+ const {epochCtx} = state;
152
161
  const validatorIndices = validatorIds
153
162
  .map((id) => (typeof id === "number" ? id : pubkey2index.get(fromHex(id))))
154
163
  .filter((index) => index !== undefined); // Validator indices to include in the result
@@ -1,4 +1,5 @@
1
1
  import {routes} from "@lodestar/api";
2
+ import {BeaconConfig} from "@lodestar/config";
2
3
  import {
3
4
  ForkName,
4
5
  WHISTLEBLOWER_REWARD_QUOTIENT,
@@ -26,11 +27,12 @@ type SubRewardValue = number; // All reward values should be integer
26
27
  * 3) Reporting slashable behaviours from proposer and attester
27
28
  */
28
29
  export async function computeBlockRewards(
30
+ config: BeaconConfig,
29
31
  block: BeaconBlock,
30
32
  preState: CachedBeaconStateAllForks,
31
33
  postState?: CachedBeaconStateAllForks
32
34
  ): Promise<BlockRewards> {
33
- const fork = preState.config.getForkName(block.slot);
35
+ const fork = config.getForkName(block.slot);
34
36
  const {attestations: cachedAttestationsReward = 0, syncAggregate: cachedSyncAggregateReward = 0} =
35
37
  postState?.proposerRewards ?? {};
36
38
  let blockAttestationReward = cachedAttestationsReward;
@@ -40,7 +42,7 @@ export async function computeBlockRewards(
40
42
  blockAttestationReward =
41
43
  fork === ForkName.phase0
42
44
  ? computeBlockAttestationRewardPhase0(block as phase0.BeaconBlock, preState as CachedBeaconStatePhase0)
43
- : computeBlockAttestationRewardAltair(block as altair.BeaconBlock, preState as CachedBeaconStateAltair);
45
+ : computeBlockAttestationRewardAltair(config, block as altair.BeaconBlock, preState as CachedBeaconStateAltair);
44
46
  }
45
47
 
46
48
  if (syncAggregateReward === 0) {
@@ -78,10 +80,11 @@ function computeBlockAttestationRewardPhase0(
78
80
  * Reuses `processAttestationsAltair()`. Has dependency on RewardCache
79
81
  */
80
82
  function computeBlockAttestationRewardAltair(
83
+ config: BeaconConfig,
81
84
  block: altair.BeaconBlock,
82
85
  preState: CachedBeaconStateAltair
83
86
  ): SubRewardValue {
84
- const fork = preState.config.getForkSeq(block.slot);
87
+ const fork = config.getForkSeq(block.slot);
85
88
  const {attestations} = block.body;
86
89
 
87
90
  processAttestationsAltair(fork, preState, attestations, false);
@@ -1,4 +1,5 @@
1
1
  import {routes} from "@lodestar/api";
2
+ import {BeaconConfig} from "@lodestar/config";
2
3
  import {ForkName, SYNC_COMMITTEE_SIZE} from "@lodestar/params";
3
4
  import {CachedBeaconStateAllForks, CachedBeaconStateAltair, Index2PubkeyCache} from "@lodestar/state-transition";
4
5
  import {BeaconBlock, ValidatorIndex, altair} from "@lodestar/types";
@@ -7,12 +8,13 @@ export type SyncCommitteeRewards = routes.beacon.SyncCommitteeRewards;
7
8
  type BalanceRecord = {val: number}; // Use val for convenient way to increment/decrement balance
8
9
 
9
10
  export async function computeSyncCommitteeRewards(
11
+ config: BeaconConfig,
10
12
  index2pubkey: Index2PubkeyCache,
11
13
  block: BeaconBlock,
12
14
  preState: CachedBeaconStateAllForks,
13
15
  validatorIds: (ValidatorIndex | string)[] = []
14
16
  ): Promise<SyncCommitteeRewards> {
15
- const fork = preState.config.getForkName(block.slot);
17
+ const fork = config.getForkName(block.slot);
16
18
  if (fork === ForkName.phase0) {
17
19
  throw Error("Cannot get sync rewards as phase0 block does not have sync committee");
18
20
  }
@@ -1,4 +1,5 @@
1
1
  import {routes} from "@lodestar/api";
2
+ import {BeaconConfig} from "@lodestar/config";
2
3
  import {
3
4
  CachedBeaconStateAllForks,
4
5
  computeStartSlotAtEpoch,
@@ -24,6 +25,7 @@ export type PersistentCheckpointStateCacheOpts = {
24
25
  };
25
26
 
26
27
  type PersistentCheckpointStateCacheModules = {
28
+ config: BeaconConfig;
27
29
  metrics?: Metrics | null;
28
30
  logger: Logger;
29
31
  clock?: IClock | null;
@@ -107,6 +109,7 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
107
109
  private readonly cache: MapTracker<CacheKey, CacheItem>;
108
110
  /** Epoch -> Set<blockRoot> */
109
111
  private readonly epochIndex = new MapDef<Epoch, Set<RootHex>>(() => new Set<string>());
112
+ private readonly config: BeaconConfig;
110
113
  private readonly metrics: Metrics | null | undefined;
111
114
  private readonly logger: Logger;
112
115
  private readonly clock: IClock | null | undefined;
@@ -120,10 +123,20 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
120
123
  private readonly bufferPool?: BufferPool | null;
121
124
 
122
125
  constructor(
123
- {metrics, logger, clock, signal, datastore, blockStateCache, bufferPool}: PersistentCheckpointStateCacheModules,
126
+ {
127
+ config,
128
+ metrics,
129
+ logger,
130
+ clock,
131
+ signal,
132
+ datastore,
133
+ blockStateCache,
134
+ bufferPool,
135
+ }: PersistentCheckpointStateCacheModules,
124
136
  opts: PersistentCheckpointStateCacheOpts
125
137
  ) {
126
138
  this.cache = new MapTracker(metrics?.cpStateCache);
139
+ this.config = config;
127
140
  if (metrics) {
128
141
  this.metrics = metrics;
129
142
  metrics.cpStateCache.size.addCollect(() => {
@@ -484,7 +497,7 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
484
497
  }
485
498
 
486
499
  const blockSlot = state.slot;
487
- const processCPStatesTimeMs = state.config.getSlotComponentDurationMs(PROCESS_CHECKPOINT_STATES_BPS);
500
+ const processCPStatesTimeMs = this.config.getSlotComponentDurationMs(PROCESS_CHECKPOINT_STATES_BPS);
488
501
  // we always have clock in production, fallback value is only for test
489
502
  const msFromSlot = this.clock?.msFromSlot(blockSlot) ?? processCPStatesTimeMs;
490
503
  const msToProcessCPStates = processCPStatesTimeMs - msFromSlot;
@@ -51,7 +51,7 @@ export async function validateAttesterSlashing(
51
51
  });
52
52
  }
53
53
 
54
- const signatureSets = getAttesterSlashingSignatureSets(chain.index2pubkey, state, attesterSlashing);
54
+ const signatureSets = getAttesterSlashingSignatureSets(chain.config, chain.index2pubkey, state, attesterSlashing);
55
55
  if (!(await chain.bls.verifySignatureSets(signatureSets, {batchable: true, priority: prioritizeBls}))) {
56
56
  throw new AttesterSlashingError(GossipAction.REJECT, {
57
57
  code: AttesterSlashingErrorCode.INVALID,
@@ -153,7 +153,7 @@ export async function validateGossipBlock(
153
153
 
154
154
  // [REJECT] The proposer signature, signed_beacon_block.signature, is valid with respect to the proposer_index pubkey.
155
155
  if (!chain.seenBlockInputCache.isVerifiedProposerSignature(blockSlot, blockRoot, signedBlock.signature)) {
156
- const signatureSet = getBlockProposerSignatureSet(chain.index2pubkey, blockState, signedBlock);
156
+ const signatureSet = getBlockProposerSignatureSet(chain.config, chain.index2pubkey, blockState, signedBlock);
157
157
  // Don't batch so verification is not delayed
158
158
  if (!(await chain.bls.verifySignatureSets([signatureSet], {verifyOnMainThread: true}))) {
159
159
  throw new BlockGossipError(GossipAction.REJECT, {
@@ -41,7 +41,7 @@ async function validateBlsToExecutionChange(
41
41
  // NOTE: No need to advance head state since the signature's fork is handled with `broadcastedOnFork`,
42
42
  // and chanes relevant to `isValidBlsToExecutionChange()` happen only on processBlock(), not processEpoch()
43
43
  const state = chain.getHeadState();
44
- const {config} = state;
44
+ const {config} = chain;
45
45
 
46
46
  // [REJECT] All of the conditions within process_bls_to_execution_change pass validation.
47
47
  // verifySignature = false, verified in batch below
@@ -44,7 +44,7 @@ async function validateProposerSlashing(
44
44
  });
45
45
  }
46
46
 
47
- const signatureSets = getProposerSlashingSignatureSets(chain.index2pubkey, state, proposerSlashing);
47
+ const signatureSets = getProposerSlashingSignatureSets(chain.config, chain.index2pubkey, state, proposerSlashing);
48
48
  if (!(await chain.bls.verifySignatureSets(signatureSets, {batchable: true, priority: prioritizeBls}))) {
49
49
  throw new ProposerSlashingError(GossipAction.REJECT, {
50
50
  code: ProposerSlashingErrorCode.INVALID,
@@ -14,7 +14,7 @@ export function getAggregateAndProofSigningRoot(
14
14
  epoch: Epoch,
15
15
  aggregateAndProof: SignedAggregateAndProof
16
16
  ): Uint8Array {
17
- // previously, we call `const aggregatorDomain = state.config.getDomain(state.slot, DOMAIN_AGGREGATE_AND_PROOF, slot);`
17
+ // previously, we call `const aggregatorDomain = config.getDomain(state.slot, DOMAIN_AGGREGATE_AND_PROOF, slot);`
18
18
  // at fork boundary, it's required to dial to target epoch https://github.com/ChainSafe/lodestar/blob/v1.11.3/packages/beacon-node/src/chain/validation/attestation.ts#L573
19
19
  // instead of that, just use the fork of slot in the attestation data
20
20
  const slot = computeStartSlotAtEpoch(epoch);
@@ -1,3 +1,4 @@
1
+ import {BeaconConfig} from "@lodestar/config";
1
2
  import {DOMAIN_CONTRIBUTION_AND_PROOF} from "@lodestar/params";
2
3
  import {
3
4
  CachedBeaconStateAllForks,
@@ -9,11 +10,12 @@ import {
9
10
  import {altair, ssz} from "@lodestar/types";
10
11
 
11
12
  export function getContributionAndProofSignatureSet(
13
+ config: BeaconConfig,
12
14
  index2pubkey: Index2PubkeyCache,
13
15
  state: CachedBeaconStateAllForks,
14
16
  signedContributionAndProof: altair.SignedContributionAndProof
15
17
  ): ISignatureSet {
16
- const domain = state.config.getDomain(
18
+ const domain = config.getDomain(
17
19
  state.slot,
18
20
  DOMAIN_CONTRIBUTION_AND_PROOF,
19
21
  signedContributionAndProof.message.contribution.slot
@@ -1,3 +1,4 @@
1
+ import {BeaconConfig} from "@lodestar/config";
1
2
  import {DOMAIN_SYNC_COMMITTEE} from "@lodestar/params";
2
3
  import {
3
4
  CachedBeaconStateAllForks,
@@ -9,11 +10,12 @@ import {
9
10
  import {altair, ssz} from "@lodestar/types";
10
11
 
11
12
  export function getSyncCommitteeSignatureSet(
13
+ config: BeaconConfig,
12
14
  index2pubkey: Index2PubkeyCache,
13
15
  state: CachedBeaconStateAllForks,
14
16
  syncCommittee: altair.SyncCommitteeMessage
15
17
  ): ISignatureSet {
16
- const domain = state.config.getDomain(state.slot, DOMAIN_SYNC_COMMITTEE, syncCommittee.slot);
18
+ const domain = config.getDomain(state.slot, DOMAIN_SYNC_COMMITTEE, syncCommittee.slot);
17
19
 
18
20
  return {
19
21
  type: SignatureSetType.single,
@@ -1,14 +1,16 @@
1
1
  import {PublicKey} from "@chainsafe/blst";
2
+ import {BeaconConfig} from "@lodestar/config";
2
3
  import {DOMAIN_SYNC_COMMITTEE} from "@lodestar/params";
3
4
  import {CachedBeaconStateAltair, ISignatureSet, SignatureSetType, computeSigningRoot} from "@lodestar/state-transition";
4
5
  import {altair, ssz} from "@lodestar/types";
5
6
 
6
7
  export function getSyncCommitteeContributionSignatureSet(
8
+ config: BeaconConfig,
7
9
  state: CachedBeaconStateAltair,
8
10
  contribution: altair.SyncCommitteeContribution,
9
11
  pubkeys: PublicKey[]
10
12
  ): ISignatureSet {
11
- const domain = state.config.getDomain(state.slot, DOMAIN_SYNC_COMMITTEE, contribution.slot);
13
+ const domain = config.getDomain(state.slot, DOMAIN_SYNC_COMMITTEE, contribution.slot);
12
14
  return {
13
15
  type: SignatureSetType.aggregate,
14
16
  pubkeys,
@@ -1,3 +1,4 @@
1
+ import {BeaconConfig} from "@lodestar/config";
1
2
  import {DOMAIN_SYNC_COMMITTEE_SELECTION_PROOF} from "@lodestar/params";
2
3
  import {
3
4
  CachedBeaconStateAllForks,
@@ -9,11 +10,11 @@ import {
9
10
  import {altair, ssz} from "@lodestar/types";
10
11
 
11
12
  export function getSyncCommitteeSelectionProofSignatureSet(
13
+ config: BeaconConfig,
12
14
  index2pubkey: Index2PubkeyCache,
13
15
  state: CachedBeaconStateAllForks,
14
16
  contributionAndProof: altair.ContributionAndProof
15
17
  ): ISignatureSet {
16
- const {config} = state;
17
18
  const slot = contributionAndProof.contribution.slot;
18
19
  const domain = config.getDomain(state.slot, DOMAIN_SYNC_COMMITTEE_SELECTION_PROOF, slot);
19
20
  const signingData: altair.SyncAggregatorSelectionData = {
@@ -89,7 +89,7 @@ async function validateSyncCommitteeSigOnly(
89
89
  syncCommittee: altair.SyncCommitteeMessage,
90
90
  prioritizeBls = false
91
91
  ): Promise<void> {
92
- const signatureSet = getSyncCommitteeSignatureSet(chain.index2pubkey, headState, syncCommittee);
92
+ const signatureSet = getSyncCommitteeSignatureSet(chain.config, 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,
@@ -78,14 +78,19 @@ export async function validateSyncCommitteeGossipContributionAndProof(
78
78
  const signatureSets = [
79
79
  // [REJECT] The contribution_and_proof.selection_proof is a valid signature of the SyncAggregatorSelectionData
80
80
  // derived from the contribution by the validator with index contribution_and_proof.aggregator_index.
81
- getSyncCommitteeSelectionProofSignatureSet(index2pubkey, headState, contributionAndProof),
81
+ getSyncCommitteeSelectionProofSignatureSet(chain.config, index2pubkey, headState, contributionAndProof),
82
82
 
83
83
  // [REJECT] The aggregator signature, signed_contribution_and_proof.signature, is valid.
84
- getContributionAndProofSignatureSet(index2pubkey, headState, signedContributionAndProof),
84
+ getContributionAndProofSignatureSet(chain.config, index2pubkey, headState, signedContributionAndProof),
85
85
 
86
86
  // [REJECT] The aggregate signature is valid for the message beacon_block_root and aggregate pubkey derived from
87
87
  // the participation info in aggregation_bits for the subcommittee specified by the contribution.subcommittee_index.
88
- getSyncCommitteeContributionSignatureSet(headState as CachedBeaconStateAltair, contribution, participantPubkeys),
88
+ getSyncCommitteeContributionSignatureSet(
89
+ chain.config,
90
+ headState as CachedBeaconStateAltair,
91
+ contribution,
92
+ participantPubkeys
93
+ ),
89
94
  ];
90
95
 
91
96
  if (!(await chain.bls.verifySignatureSets(signatureSets, {batchable: true}))) {
@@ -59,7 +59,7 @@ async function validateVoluntaryExit(
59
59
  });
60
60
  }
61
61
 
62
- const signatureSet = getVoluntaryExitSignatureSet(chain.index2pubkey, state, voluntaryExit);
62
+ const signatureSet = getVoluntaryExitSignatureSet(chain.config, 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,
package/src/db/beacon.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import {ChainForkConfig} from "@lodestar/config";
2
- import {Db, LevelDbControllerMetrics} from "@lodestar/db";
2
+ import {Db, LevelDbControllerMetrics, encodeKey} from "@lodestar/db";
3
+ import {Bucket} from "./buckets.js";
3
4
  import {IBeaconDb} from "./interface.js";
4
5
  import {CheckpointStateRepository} from "./repositories/checkpointState.js";
5
6
  import {
@@ -95,4 +96,40 @@ export class BeaconDb implements IBeaconDb {
95
96
  // TODO: Enable once it's deemed safe
96
97
  // await this.block.batchDelete(await this.block.keys());
97
98
  }
99
+
100
+ async deleteDeprecatedEth1Data(): Promise<void> {
101
+ const deprecatedBuckets = [
102
+ Bucket.phase0_eth1Data,
103
+ Bucket.index_depositDataRoot,
104
+ Bucket.phase0_depositData,
105
+ Bucket.phase0_depositEvent,
106
+ Bucket.phase0_preGenesisState,
107
+ Bucket.phase0_preGenesisStateLastProcessedBlock,
108
+ ];
109
+
110
+ for (const bucket of deprecatedBuckets) {
111
+ await this.deleteBucketData(bucket);
112
+ }
113
+ }
114
+
115
+ private async deleteBucketData(bucket: Bucket): Promise<void> {
116
+ const minKey = encodeKey(bucket, Buffer.alloc(0));
117
+ const maxKey = encodeKey(bucket + 1, Buffer.alloc(0));
118
+
119
+ // Batch delete to avoid loading all keys into memory at once
120
+ const BATCH_DELETE_SIZE = 1000;
121
+ let keysBatch: Uint8Array[] = [];
122
+
123
+ for await (const key of this.db.keysStream({gte: minKey, lt: maxKey})) {
124
+ keysBatch.push(key);
125
+ if (keysBatch.length >= BATCH_DELETE_SIZE) {
126
+ await this.db.batchDelete(keysBatch);
127
+ keysBatch = [];
128
+ }
129
+ }
130
+
131
+ if (keysBatch.length > 0) {
132
+ await this.db.batchDelete(keysBatch);
133
+ }
134
+ }
98
135
  }
package/src/db/buckets.ts CHANGED
@@ -16,13 +16,16 @@ export enum Bucket {
16
16
  index_mainChain = 6, // Slot -> Root<BeaconBlock>
17
17
  // justified, finalized state and block hashes
18
18
  index_chainInfo = 7, // Key -> Number64 | stateHash | blockHash
19
- // phase0_eth1Data = 8, // DEPRECATED - eth1 deposit tracking is not required since electra
20
- // index_depositDataRoot = 9, // DEPRECATED - eth1 deposit tracking is not required since electra
19
+ /** @deprecated Eth1 deposit tracking is not required since electra, only kept around to delete data from existing databases */
20
+ phase0_eth1Data = 8,
21
+ /** @deprecated Eth1 deposit tracking is not required since electra, only kept around to delete data from existing databases */
22
+ index_depositDataRoot = 9,
21
23
 
22
24
  // op pool
23
25
  // phase0_attestation = 10, // DEPRECATED on v0.25.0
24
26
  // phase0_aggregateAndProof = 11, // Root -> AggregateAndProof, DEPRECATED on v.27.0
25
- // phase0_depositData = 12, // DEPRECATED - eth1 deposit tracking is not required since electra
27
+ /** @deprecated Eth1 deposit tracking is not required since electra, only kept around to delete data from existing databases */
28
+ phase0_depositData = 12,
26
29
  phase0_exit = 13, // ValidatorIndex -> VoluntaryExit
27
30
  phase0_proposerSlashing = 14, // ValidatorIndex -> ProposerSlashing
28
31
  allForks_attesterSlashing = 15, // Root -> AttesterSlashing
@@ -31,15 +34,18 @@ export enum Bucket {
31
34
  allForks_checkpointState = 17, // Root -> BeaconState
32
35
 
33
36
  // allForks_pendingBlock = 25, // Root -> SignedBeaconBlock // DEPRECATED on v0.30.0
34
- // phase0_depositEvent = 19, // DEPRECATED - eth1 deposit tracking is not required since electra
37
+ /** @deprecated Eth1 deposit tracking is not required since electra, only kept around to delete data from existing databases */
38
+ phase0_depositEvent = 19,
35
39
 
36
40
  index_stateArchiveRootIndex = 26, // State Root -> slot
37
41
 
38
42
  deneb_blobSidecars = 27, // DENEB BeaconBlockRoot -> BlobSidecars
39
43
  deneb_blobSidecarsArchive = 28, // DENEB BeaconBlockSlot -> BlobSidecars
40
44
 
41
- // phase0_preGenesisState = 30, // DEPRECATED - genesis from eth1 is no longer supported
42
- // phase0_preGenesisStateLastProcessedBlock = 31, // DEPRECATED - genesis from eth1 is no longer supported
45
+ /** @deprecated Genesis from eth1 is no longer supported, only kept around to delete data from existing databases */
46
+ phase0_preGenesisState = 30,
47
+ /** @deprecated Genesis from eth1 is no longer supported, only kept around to delete data from existing databases */
48
+ phase0_preGenesisStateLastProcessedBlock = 31,
43
49
 
44
50
  // Lightclient server
45
51
  // altair_bestUpdatePerCommitteePeriod = 30, // DEPRECATED on v0.32.0
@@ -56,6 +56,8 @@ export interface IBeaconDb {
56
56
 
57
57
  pruneHotDb(): Promise<void>;
58
58
 
59
+ deleteDeprecatedEth1Data(): Promise<void>;
60
+
59
61
  /** Close the connection to the db instance and close the db store. */
60
62
  close(): Promise<void>;
61
63
  /** To inject metrics after CLI initialization */
@@ -197,6 +197,17 @@ export class BeaconNode {
197
197
  // TODO: Should this call be awaited?
198
198
  await db.pruneHotDb();
199
199
 
200
+ // Delete deprecated eth1 data to free up disk space for users
201
+ logger.debug("Deleting deprecated eth1 data from database");
202
+ const startTime = Date.now();
203
+ db.deleteDeprecatedEth1Data()
204
+ .then(() => {
205
+ logger.debug("Deleted deprecated eth1 data", {durationMs: Date.now() - startTime});
206
+ })
207
+ .catch((e) => {
208
+ logger.error("Failed to delete deprecated eth1 data", {}, e);
209
+ });
210
+
200
211
  const monitoring = opts.monitoring.endpoint
201
212
  ? new MonitoringService(
202
213
  "beacon",
@@ -750,9 +750,13 @@ 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.index2pubkey, this.chain.bls, this.chain.getHeadState(), [
754
- anchorBlock,
755
- ]);
753
+ await verifyBlockProposerSignature(
754
+ this.chain.config,
755
+ this.chain.index2pubkey,
756
+ this.chain.bls,
757
+ this.chain.getHeadState(),
758
+ [anchorBlock]
759
+ );
756
760
 
757
761
  // We can write to the disk if this is ahead of prevFinalizedCheckpointBlock otherwise
758
762
  // we will need to go make checks on the top of sync loop before writing as it might
@@ -818,6 +822,7 @@ export class BackfillSync extends (EventEmitter as {new (): BackfillSyncEmitter}
818
822
  // If any of the block's proposer signature fail, we can't trust this peer at all
819
823
  if (verifiedBlocks.length > 0) {
820
824
  await verifyBlockProposerSignature(
825
+ this.chain.config,
821
826
  this.chain.index2pubkey,
822
827
  this.chain.bls,
823
828
  this.chain.getHeadState(),
@@ -46,6 +46,7 @@ export function verifyBlockSequence(
46
46
  }
47
47
 
48
48
  export async function verifyBlockProposerSignature(
49
+ config: BeaconConfig,
49
50
  index2pubkey: Index2PubkeyCache,
50
51
  bls: IBlsVerifier,
51
52
  state: CachedBeaconStateAllForks,
@@ -54,7 +55,8 @@ export async function verifyBlockProposerSignature(
54
55
  if (blocks.length === 1 && blocks[0].message.slot === GENESIS_SLOT) return;
55
56
  const signatures = blocks.reduce((sigs: ISignatureSet[], block) => {
56
57
  // genesis block doesn't have valid signature
57
- if (block.message.slot !== GENESIS_SLOT) sigs.push(getBlockProposerSignatureSet(index2pubkey, state, block));
58
+ if (block.message.slot !== GENESIS_SLOT)
59
+ sigs.push(getBlockProposerSignatureSet(config, index2pubkey, state, block));
58
60
  return sigs;
59
61
  }, []);
60
62