@lodestar/beacon-node 1.39.0-dev.2fe8de2346 → 1.39.0-dev.3932675174
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.
- package/README.md +1 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +6 -0
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.js +1 -1
- package/lib/chain/blocks/verifyBlock.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +4 -2
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksSignatures.d.ts +2 -1
- package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksSignatures.js +3 -2
- package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
- package/lib/chain/chain.d.ts +9 -9
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +33 -38
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +3 -3
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/interface.d.ts +4 -7
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/interface.js.map +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.d.ts +6 -7
- package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.js +8 -133
- package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
- package/lib/chain/opPools/opPool.d.ts +3 -0
- package/lib/chain/opPools/opPool.d.ts.map +1 -1
- package/lib/chain/opPools/opPool.js +9 -8
- package/lib/chain/opPools/opPool.js.map +1 -1
- package/lib/chain/prepareNextSlot.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +1 -6
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +3 -3
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +0 -4
- package/lib/chain/regen/interface.d.ts.map +1 -1
- package/lib/chain/shufflingCache.d.ts +5 -12
- package/lib/chain/shufflingCache.d.ts.map +1 -1
- package/lib/chain/shufflingCache.js +12 -50
- package/lib/chain/shufflingCache.js.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +4 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js +4 -2
- package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
- package/lib/chain/validation/aggregateAndProof.js +9 -0
- package/lib/chain/validation/aggregateAndProof.js.map +1 -1
- package/lib/chain/validation/attesterSlashing.d.ts.map +1 -1
- package/lib/chain/validation/attesterSlashing.js +2 -2
- package/lib/chain/validation/attesterSlashing.js.map +1 -1
- package/lib/chain/validation/blobSidecar.d.ts.map +1 -1
- package/lib/chain/validation/blobSidecar.js +2 -3
- package/lib/chain/validation/blobSidecar.js.map +1 -1
- package/lib/chain/validation/block.d.ts.map +1 -1
- package/lib/chain/validation/block.js +3 -3
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/blsToExecutionChange.d.ts.map +1 -1
- package/lib/chain/validation/blsToExecutionChange.js +10 -3
- package/lib/chain/validation/blsToExecutionChange.js.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.js +2 -3
- package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
- package/lib/chain/validation/proposerSlashing.js +3 -2
- package/lib/chain/validation/proposerSlashing.js.map +1 -1
- package/lib/chain/validation/signatureSets/aggregateAndProof.js +1 -1
- package/lib/chain/validation/signatureSets/aggregateAndProof.js.map +1 -1
- package/lib/chain/validation/signatureSets/contributionAndProof.d.ts +2 -1
- package/lib/chain/validation/signatureSets/contributionAndProof.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/contributionAndProof.js +2 -2
- package/lib/chain/validation/signatureSets/contributionAndProof.js.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommittee.d.ts +2 -1
- package/lib/chain/validation/signatureSets/syncCommittee.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommittee.js +2 -2
- package/lib/chain/validation/signatureSets/syncCommittee.js.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts +2 -1
- package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommitteeContribution.js +2 -2
- package/lib/chain/validation/signatureSets/syncCommitteeContribution.js.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts +2 -1
- package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js +1 -2
- package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js.map +1 -1
- package/lib/chain/validation/syncCommittee.js +1 -1
- package/lib/chain/validation/syncCommittee.js.map +1 -1
- package/lib/chain/validation/syncCommitteeContributionAndProof.d.ts.map +1 -1
- package/lib/chain/validation/syncCommitteeContributionAndProof.js +3 -3
- package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
- package/lib/chain/validation/voluntaryExit.js +1 -1
- package/lib/chain/validation/voluntaryExit.js.map +1 -1
- package/lib/db/beacon.d.ts +2 -0
- package/lib/db/beacon.d.ts.map +1 -1
- package/lib/db/beacon.js +32 -0
- package/lib/db/beacon.js.map +1 -1
- package/lib/db/buckets.d.ts +12 -0
- package/lib/db/buckets.d.ts.map +1 -1
- package/lib/db/buckets.js +12 -6
- package/lib/db/buckets.js.map +1 -1
- package/lib/db/interface.d.ts +1 -0
- package/lib/db/interface.d.ts.map +1 -1
- package/lib/db/repositories/blockArchiveIndex.d.ts +2 -2
- package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
- package/lib/execution/engine/mock.d.ts +9 -6
- package/lib/execution/engine/mock.d.ts.map +1 -1
- package/lib/execution/engine/mock.js +34 -7
- package/lib/execution/engine/mock.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +1 -6
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +3 -17
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/network/peers/discover.d.ts.map +1 -1
- package/lib/network/peers/discover.js.map +1 -1
- package/lib/node/nodejs.d.ts +6 -3
- package/lib/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js +30 -3
- package/lib/node/nodejs.js.map +1 -1
- package/lib/node/notifier.d.ts.map +1 -1
- package/lib/node/notifier.js +9 -6
- package/lib/node/notifier.js.map +1 -1
- package/lib/sync/backfill/backfill.d.ts.map +1 -1
- package/lib/sync/backfill/backfill.js +2 -4
- package/lib/sync/backfill/backfill.js.map +1 -1
- package/lib/sync/backfill/verify.d.ts +2 -2
- package/lib/sync/backfill/verify.d.ts.map +1 -1
- package/lib/sync/backfill/verify.js +3 -3
- package/lib/sync/backfill/verify.js.map +1 -1
- package/package.json +28 -20
- package/src/chain/blocks/importBlock.ts +7 -0
- package/src/chain/blocks/verifyBlock.ts +1 -0
- package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +9 -2
- package/src/chain/blocks/verifyBlocksSignatures.ts +13 -3
- package/src/chain/chain.ts +45 -44
- package/src/chain/forkChoice/index.ts +3 -2
- package/src/chain/interface.ts +4 -6
- package/src/chain/opPools/aggregatedAttestationPool.ts +12 -187
- package/src/chain/opPools/opPool.ts +8 -8
- package/src/chain/prepareNextSlot.ts +1 -6
- package/src/chain/produceBlock/produceBlockBody.ts +3 -3
- package/src/chain/regen/interface.ts +0 -4
- package/src/chain/shufflingCache.ts +15 -61
- package/src/chain/stateCache/persistentCheckpointsCache.ts +15 -2
- package/src/chain/validation/aggregateAndProof.ts +12 -0
- package/src/chain/validation/attesterSlashing.ts +14 -2
- package/src/chain/validation/blobSidecar.ts +3 -3
- package/src/chain/validation/block.ts +3 -2
- package/src/chain/validation/blsToExecutionChange.ts +10 -8
- package/src/chain/validation/dataColumnSidecar.ts +3 -3
- package/src/chain/validation/proposerSlashing.ts +8 -2
- package/src/chain/validation/signatureSets/aggregateAndProof.ts +1 -1
- package/src/chain/validation/signatureSets/contributionAndProof.ts +3 -1
- package/src/chain/validation/signatureSets/syncCommittee.ts +3 -1
- package/src/chain/validation/signatureSets/syncCommitteeContribution.ts +3 -1
- package/src/chain/validation/signatureSets/syncCommitteeSelectionProof.ts +2 -1
- package/src/chain/validation/syncCommittee.ts +1 -1
- package/src/chain/validation/syncCommitteeContributionAndProof.ts +8 -3
- package/src/chain/validation/voluntaryExit.ts +1 -1
- package/src/db/beacon.ts +38 -1
- package/src/db/buckets.ts +12 -6
- package/src/db/interface.ts +2 -0
- package/src/execution/engine/mock.ts +40 -13
- package/src/metrics/metrics/lodestar.ts +3 -17
- package/src/network/peers/discover.ts +3 -3
- package/src/node/nodejs.ts +37 -4
- package/src/node/notifier.ts +13 -7
- package/src/sync/backfill/backfill.ts +2 -9
- package/src/sync/backfill/verify.ts +3 -8
- package/lib/chain/rewards/attestationsRewards.d.ts +0 -7
- package/lib/chain/rewards/attestationsRewards.d.ts.map +0 -1
- package/lib/chain/rewards/attestationsRewards.js +0 -112
- package/lib/chain/rewards/attestationsRewards.js.map +0 -1
- package/lib/chain/rewards/blockRewards.d.ts +0 -14
- package/lib/chain/rewards/blockRewards.d.ts.map +0 -1
- package/lib/chain/rewards/blockRewards.js +0 -94
- package/lib/chain/rewards/blockRewards.js.map +0 -1
- package/lib/chain/rewards/syncCommitteeRewards.d.ts +0 -6
- package/lib/chain/rewards/syncCommitteeRewards.d.ts.map +0 -1
- package/lib/chain/rewards/syncCommitteeRewards.js +0 -36
- package/lib/chain/rewards/syncCommitteeRewards.js.map +0 -1
- package/src/chain/rewards/attestationsRewards.ts +0 -197
- package/src/chain/rewards/blockRewards.ts +0 -150
- package/src/chain/rewards/syncCommitteeRewards.ts +0 -58
package/src/chain/chain.ts
CHANGED
|
@@ -14,13 +14,14 @@ import {
|
|
|
14
14
|
EpochShuffling,
|
|
15
15
|
Index2PubkeyCache,
|
|
16
16
|
computeAnchorCheckpoint,
|
|
17
|
+
computeAttestationsRewards,
|
|
18
|
+
computeBlockRewards,
|
|
17
19
|
computeEndSlotAtEpoch,
|
|
18
20
|
computeEpochAtSlot,
|
|
19
21
|
computeStartSlotAtEpoch,
|
|
20
|
-
|
|
22
|
+
computeSyncCommitteeRewards,
|
|
21
23
|
getEffectiveBalanceIncrementsZeroInactive,
|
|
22
24
|
getEffectiveBalancesFromStateBytes,
|
|
23
|
-
isCachedBeaconState,
|
|
24
25
|
processSlots,
|
|
25
26
|
} from "@lodestar/state-transition";
|
|
26
27
|
import {
|
|
@@ -38,6 +39,7 @@ import {
|
|
|
38
39
|
Wei,
|
|
39
40
|
isBlindedBeaconBlock,
|
|
40
41
|
phase0,
|
|
42
|
+
rewards,
|
|
41
43
|
} from "@lodestar/types";
|
|
42
44
|
import {Logger, fromHex, gweiToWei, isErrorAborted, pruneSetToMax, sleep, toRootHex} from "@lodestar/utils";
|
|
43
45
|
import {ProcessShutdownCallback} from "@lodestar/validator";
|
|
@@ -50,6 +52,7 @@ import {computeNodeIdFromPrivateKey} from "../network/subnets/interface.js";
|
|
|
50
52
|
import {BufferPool} from "../util/bufferPool.js";
|
|
51
53
|
import {Clock, ClockEvent, IClock} from "../util/clock.js";
|
|
52
54
|
import {CustodyConfig, getValidatorsCustodyRequirement} from "../util/dataColumns.js";
|
|
55
|
+
import {callInNextEventLoop} from "../util/eventLoop.js";
|
|
53
56
|
import {ensureDir, writeIfNotExist} from "../util/file.js";
|
|
54
57
|
import {isOptimisticBlock} from "../util/forkChoice.js";
|
|
55
58
|
import {SerializedCache} from "../util/serializedCache.js";
|
|
@@ -79,9 +82,6 @@ import {AssembledBlockType, BlockType, ProduceResult} from "./produceBlock/index
|
|
|
79
82
|
import {BlockAttributes, produceBlockBody, produceCommonBlockBody} from "./produceBlock/produceBlockBody.js";
|
|
80
83
|
import {QueuedStateRegenerator, RegenCaller} from "./regen/index.js";
|
|
81
84
|
import {ReprocessController} from "./reprocess.js";
|
|
82
|
-
import {AttestationsRewards, computeAttestationsRewards} from "./rewards/attestationsRewards.js";
|
|
83
|
-
import {BlockRewards, computeBlockRewards} from "./rewards/blockRewards.js";
|
|
84
|
-
import {SyncCommitteeRewards, computeSyncCommitteeRewards} from "./rewards/syncCommitteeRewards.js";
|
|
85
85
|
import {
|
|
86
86
|
SeenAggregators,
|
|
87
87
|
SeenAttesters,
|
|
@@ -142,7 +142,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
142
142
|
readonly aggregatedAttestationPool: AggregatedAttestationPool;
|
|
143
143
|
readonly syncCommitteeMessagePool: SyncCommitteeMessagePool;
|
|
144
144
|
readonly syncContributionAndProofPool;
|
|
145
|
-
readonly opPool
|
|
145
|
+
readonly opPool: OpPool;
|
|
146
146
|
|
|
147
147
|
// Gossip seen cache
|
|
148
148
|
readonly seenAttesters = new SeenAttesters();
|
|
@@ -204,6 +204,8 @@ export class BeaconChain implements IBeaconChain {
|
|
|
204
204
|
{
|
|
205
205
|
privateKey,
|
|
206
206
|
config,
|
|
207
|
+
pubkey2index,
|
|
208
|
+
index2pubkey,
|
|
207
209
|
db,
|
|
208
210
|
dbName,
|
|
209
211
|
dataDir,
|
|
@@ -219,6 +221,8 @@ export class BeaconChain implements IBeaconChain {
|
|
|
219
221
|
}: {
|
|
220
222
|
privateKey: PrivateKey;
|
|
221
223
|
config: BeaconConfig;
|
|
224
|
+
pubkey2index: PubkeyIndexMap;
|
|
225
|
+
index2pubkey: Index2PubkeyCache;
|
|
222
226
|
db: IBeaconDb;
|
|
223
227
|
dbName: string;
|
|
224
228
|
dataDir: string;
|
|
@@ -228,7 +232,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
228
232
|
clock?: IClock;
|
|
229
233
|
metrics: Metrics | null;
|
|
230
234
|
validatorMonitor: ValidatorMonitor | null;
|
|
231
|
-
anchorState:
|
|
235
|
+
anchorState: CachedBeaconStateAllForks;
|
|
232
236
|
isAnchorStateFinalized: boolean;
|
|
233
237
|
executionEngine: IExecutionEngine;
|
|
234
238
|
executionBuilder?: IExecutionBuilder;
|
|
@@ -260,6 +264,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
260
264
|
this.aggregatedAttestationPool = new AggregatedAttestationPool(this.config, metrics);
|
|
261
265
|
this.syncCommitteeMessagePool = new SyncCommitteeMessagePool(config, clock, this.opts?.preaggregateSlotDistance);
|
|
262
266
|
this.syncContributionAndProofPool = new SyncContributionAndProofPool(config, clock, metrics, logger);
|
|
267
|
+
this.opPool = new OpPool(config);
|
|
263
268
|
|
|
264
269
|
this.seenAggregatedAttestations = new SeenAggregatedAttestations(metrics);
|
|
265
270
|
this.seenContributionAndProof = new SeenContributionAndProof(metrics);
|
|
@@ -286,39 +291,26 @@ export class BeaconChain implements IBeaconChain {
|
|
|
286
291
|
logger,
|
|
287
292
|
});
|
|
288
293
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
// When the BeaconStateCache is created in initializeBeaconStateFromEth1 it may be incorrect. Until we can ensure that
|
|
293
|
-
// it's safe to re-use _ANY_ BeaconStateCache, this option is disabled by default and only used in tests.
|
|
294
|
-
const cachedState =
|
|
295
|
-
isCachedBeaconState(anchorState) && opts.skipCreateStateCacheIfAvailable
|
|
296
|
-
? anchorState
|
|
297
|
-
: createCachedBeaconState(anchorState, {
|
|
298
|
-
config,
|
|
299
|
-
pubkey2index: new PubkeyIndexMap(),
|
|
300
|
-
index2pubkey: [],
|
|
301
|
-
});
|
|
302
|
-
this._earliestAvailableSlot = cachedState.slot;
|
|
303
|
-
|
|
304
|
-
this.shufflingCache = cachedState.epochCtx.shufflingCache = new ShufflingCache(metrics, logger, this.opts, [
|
|
294
|
+
this._earliestAvailableSlot = anchorState.slot;
|
|
295
|
+
|
|
296
|
+
this.shufflingCache = new ShufflingCache(metrics, logger, this.opts, [
|
|
305
297
|
{
|
|
306
|
-
shuffling:
|
|
307
|
-
decisionRoot:
|
|
298
|
+
shuffling: anchorState.epochCtx.previousShuffling,
|
|
299
|
+
decisionRoot: anchorState.epochCtx.previousDecisionRoot,
|
|
308
300
|
},
|
|
309
301
|
{
|
|
310
|
-
shuffling:
|
|
311
|
-
decisionRoot:
|
|
302
|
+
shuffling: anchorState.epochCtx.currentShuffling,
|
|
303
|
+
decisionRoot: anchorState.epochCtx.currentDecisionRoot,
|
|
312
304
|
},
|
|
313
305
|
{
|
|
314
|
-
shuffling:
|
|
315
|
-
decisionRoot:
|
|
306
|
+
shuffling: anchorState.epochCtx.nextShuffling,
|
|
307
|
+
decisionRoot: anchorState.epochCtx.nextDecisionRoot,
|
|
316
308
|
},
|
|
317
309
|
]);
|
|
318
310
|
|
|
319
|
-
//
|
|
320
|
-
this.pubkey2index =
|
|
321
|
-
this.index2pubkey =
|
|
311
|
+
// Global cache of validators pubkey/index mapping
|
|
312
|
+
this.pubkey2index = pubkey2index;
|
|
313
|
+
this.index2pubkey = index2pubkey;
|
|
322
314
|
|
|
323
315
|
const fileDataStore = opts.nHistoricalStatesFileDataStore ?? true;
|
|
324
316
|
const blockStateCache = this.opts.nHistoricalStates
|
|
@@ -334,6 +326,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
334
326
|
this.cpStateDatastore = fileDataStore ? new FileCPStateDatastore(dataDir) : new DbCPStateDatastore(this.db);
|
|
335
327
|
checkpointStateCache = new PersistentCheckpointStateCache(
|
|
336
328
|
{
|
|
329
|
+
config,
|
|
337
330
|
metrics,
|
|
338
331
|
logger,
|
|
339
332
|
clock,
|
|
@@ -348,15 +341,15 @@ export class BeaconChain implements IBeaconChain {
|
|
|
348
341
|
}
|
|
349
342
|
|
|
350
343
|
const {checkpoint} = computeAnchorCheckpoint(config, anchorState);
|
|
351
|
-
blockStateCache.add(
|
|
352
|
-
blockStateCache.setHeadState(
|
|
353
|
-
checkpointStateCache.add(checkpoint,
|
|
344
|
+
blockStateCache.add(anchorState);
|
|
345
|
+
blockStateCache.setHeadState(anchorState);
|
|
346
|
+
checkpointStateCache.add(checkpoint, anchorState);
|
|
354
347
|
|
|
355
348
|
const forkChoice = initializeForkChoice(
|
|
356
349
|
config,
|
|
357
350
|
emitter,
|
|
358
351
|
clock.currentSlot,
|
|
359
|
-
|
|
352
|
+
anchorState,
|
|
360
353
|
isAnchorStateFinalized,
|
|
361
354
|
opts,
|
|
362
355
|
this.justifiedBalancesGetter.bind(this),
|
|
@@ -426,6 +419,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
426
419
|
clock.addListener(ClockEvent.epoch, this.onClockEpoch.bind(this));
|
|
427
420
|
emitter.addListener(ChainEvent.forkChoiceFinalized, this.onForkChoiceFinalized.bind(this));
|
|
428
421
|
emitter.addListener(ChainEvent.forkChoiceJustified, this.onForkChoiceJustified.bind(this));
|
|
422
|
+
emitter.addListener(ChainEvent.checkpoint, this.onCheckpoint.bind(this));
|
|
429
423
|
}
|
|
430
424
|
|
|
431
425
|
async init(): Promise<void> {
|
|
@@ -989,8 +983,8 @@ export class BeaconChain implements IBeaconChain {
|
|
|
989
983
|
this.metrics?.gossipAttestation.useHeadBlockState.inc({caller: regenCaller});
|
|
990
984
|
state = await this.regen.getState(attHeadBlock.stateRoot, regenCaller);
|
|
991
985
|
}
|
|
992
|
-
|
|
993
|
-
|
|
986
|
+
// resolve the promise to unblock other calls of the same epoch and dependent root
|
|
987
|
+
this.shufflingCache.processState(state);
|
|
994
988
|
return state.epochCtx.getShufflingAtEpoch(attEpoch);
|
|
995
989
|
}
|
|
996
990
|
|
|
@@ -1174,6 +1168,13 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1174
1168
|
this.logger.verbose("Fork choice justified", {epoch: cp.epoch, root: cp.rootHex});
|
|
1175
1169
|
}
|
|
1176
1170
|
|
|
1171
|
+
private onCheckpoint(this: BeaconChain, _checkpoint: phase0.Checkpoint, state: CachedBeaconStateAllForks): void {
|
|
1172
|
+
// Defer to not block other checkpoint event handlers, which can cause lightclient update delays
|
|
1173
|
+
callInNextEventLoop(() => {
|
|
1174
|
+
this.shufflingCache.processState(state);
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1177
1178
|
private async onForkChoiceFinalized(this: BeaconChain, cp: CheckpointWithHex): Promise<void> {
|
|
1178
1179
|
this.logger.verbose("Fork choice finalized", {epoch: cp.epoch, root: cp.rootHex});
|
|
1179
1180
|
this.seenBlockProposers.prune(computeStartSlotAtEpoch(cp.epoch));
|
|
@@ -1295,7 +1296,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1295
1296
|
}
|
|
1296
1297
|
}
|
|
1297
1298
|
|
|
1298
|
-
async getBlockRewards(block: BeaconBlock | BlindedBeaconBlock): Promise<BlockRewards> {
|
|
1299
|
+
async getBlockRewards(block: BeaconBlock | BlindedBeaconBlock): Promise<rewards.BlockRewards> {
|
|
1299
1300
|
let preState = this.regen.getPreStateSync(block);
|
|
1300
1301
|
|
|
1301
1302
|
if (preState === null) {
|
|
@@ -1306,13 +1307,13 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1306
1307
|
|
|
1307
1308
|
const postState = this.regen.getStateSync(toRootHex(block.stateRoot)) ?? undefined;
|
|
1308
1309
|
|
|
1309
|
-
return computeBlockRewards(block, preState.clone(), postState?.clone());
|
|
1310
|
+
return computeBlockRewards(this.config, block, preState.clone(), postState?.clone());
|
|
1310
1311
|
}
|
|
1311
1312
|
|
|
1312
1313
|
async getAttestationsRewards(
|
|
1313
1314
|
epoch: Epoch,
|
|
1314
1315
|
validatorIds?: (ValidatorIndex | string)[]
|
|
1315
|
-
): Promise<{rewards: AttestationsRewards; executionOptimistic: boolean; finalized: boolean}> {
|
|
1316
|
+
): Promise<{rewards: rewards.AttestationsRewards; executionOptimistic: boolean; finalized: boolean}> {
|
|
1316
1317
|
// We use end slot of (epoch + 1) to ensure we have seen all attestations. On-time or late. Any late attestation beyond this slot is not considered
|
|
1317
1318
|
const slot = computeEndSlotAtEpoch(epoch + 1);
|
|
1318
1319
|
const stateResult = await this.getStateBySlot(slot, {allowRegen: false}); // No regen if state not in cache
|
|
@@ -1330,7 +1331,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1330
1331
|
throw Error(`State is not in cache for slot ${slot}`);
|
|
1331
1332
|
}
|
|
1332
1333
|
|
|
1333
|
-
const rewards = await computeAttestationsRewards(this.pubkey2index, cachedState, validatorIds);
|
|
1334
|
+
const rewards = await computeAttestationsRewards(this.config, this.pubkey2index, cachedState, validatorIds);
|
|
1334
1335
|
|
|
1335
1336
|
return {rewards, executionOptimistic, finalized};
|
|
1336
1337
|
}
|
|
@@ -1338,7 +1339,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1338
1339
|
async getSyncCommitteeRewards(
|
|
1339
1340
|
block: BeaconBlock | BlindedBeaconBlock,
|
|
1340
1341
|
validatorIds?: (ValidatorIndex | string)[]
|
|
1341
|
-
): Promise<SyncCommitteeRewards> {
|
|
1342
|
+
): Promise<rewards.SyncCommitteeRewards> {
|
|
1342
1343
|
let preState = this.regen.getPreStateSync(block);
|
|
1343
1344
|
|
|
1344
1345
|
if (preState === null) {
|
|
@@ -1347,6 +1348,6 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1347
1348
|
|
|
1348
1349
|
preState = processSlots(preState, block.slot); // Dial preState's slot to block.slot
|
|
1349
1350
|
|
|
1350
|
-
return computeSyncCommitteeRewards(this.index2pubkey, block, preState.clone(), validatorIds);
|
|
1351
|
+
return computeSyncCommitteeRewards(this.config, this.index2pubkey, block, preState.clone(), validatorIds);
|
|
1351
1352
|
}
|
|
1352
1353
|
}
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
getBlockRootAtSlot,
|
|
19
19
|
getEffectiveBalanceIncrementsZeroInactive,
|
|
20
20
|
isExecutionStateType,
|
|
21
|
+
isMergeTransitionComplete,
|
|
21
22
|
} from "@lodestar/state-transition";
|
|
22
23
|
import {Slot, ssz} from "@lodestar/types";
|
|
23
24
|
import {Logger, toRootHex} from "@lodestar/utils";
|
|
@@ -134,7 +135,7 @@ export function initializeForkChoiceFromFinalizedState(
|
|
|
134
135
|
unrealizedFinalizedEpoch: finalizedCheckpoint.epoch,
|
|
135
136
|
unrealizedFinalizedRoot: toRootHex(finalizedCheckpoint.root),
|
|
136
137
|
|
|
137
|
-
...(isExecutionStateType(state)
|
|
138
|
+
...(isExecutionStateType(state) && isMergeTransitionComplete(state)
|
|
138
139
|
? {
|
|
139
140
|
executionPayloadBlockHash: toRootHex(state.latestExecutionPayloadHeader.blockHash),
|
|
140
141
|
executionPayloadNumber: state.latestExecutionPayloadHeader.blockNumber,
|
|
@@ -215,7 +216,7 @@ export function initializeForkChoiceFromUnfinalizedState(
|
|
|
215
216
|
unrealizedFinalizedEpoch: finalizedCheckpoint.epoch,
|
|
216
217
|
unrealizedFinalizedRoot: toRootHex(finalizedCheckpoint.root),
|
|
217
218
|
|
|
218
|
-
...(isExecutionStateType(unfinalizedState)
|
|
219
|
+
...(isExecutionStateType(unfinalizedState) && isMergeTransitionComplete(unfinalizedState)
|
|
219
220
|
? {
|
|
220
221
|
executionPayloadBlockHash: toRootHex(unfinalizedState.latestExecutionPayloadHeader.blockHash),
|
|
221
222
|
executionPayloadNumber: unfinalizedState.latestExecutionPayloadHeader.blockNumber,
|
package/src/chain/interface.ts
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
altair,
|
|
24
24
|
capella,
|
|
25
25
|
phase0,
|
|
26
|
+
rewards,
|
|
26
27
|
} from "@lodestar/types";
|
|
27
28
|
import {Logger} from "@lodestar/utils";
|
|
28
29
|
import {IExecutionBuilder, IExecutionEngine} from "../execution/index.js";
|
|
@@ -48,9 +49,6 @@ import {IChainOptions} from "./options.js";
|
|
|
48
49
|
import {AssembledBlockType, BlockAttributes, BlockType, ProduceResult} from "./produceBlock/produceBlockBody.js";
|
|
49
50
|
import {IStateRegenerator, RegenCaller} from "./regen/index.js";
|
|
50
51
|
import {ReprocessController} from "./reprocess.js";
|
|
51
|
-
import {AttestationsRewards} from "./rewards/attestationsRewards.js";
|
|
52
|
-
import {BlockRewards} from "./rewards/blockRewards.js";
|
|
53
|
-
import {SyncCommitteeRewards} from "./rewards/syncCommitteeRewards.js";
|
|
54
52
|
import {
|
|
55
53
|
SeenAggregators,
|
|
56
54
|
SeenAttesters,
|
|
@@ -255,15 +253,15 @@ export interface IBeaconChain {
|
|
|
255
253
|
regenCanAcceptWork(): boolean;
|
|
256
254
|
blsThreadPoolCanAcceptWork(): boolean;
|
|
257
255
|
|
|
258
|
-
getBlockRewards(blockRef: BeaconBlock | BlindedBeaconBlock): Promise<BlockRewards>;
|
|
256
|
+
getBlockRewards(blockRef: BeaconBlock | BlindedBeaconBlock): Promise<rewards.BlockRewards>;
|
|
259
257
|
getAttestationsRewards(
|
|
260
258
|
epoch: Epoch,
|
|
261
259
|
validatorIds?: (ValidatorIndex | string)[]
|
|
262
|
-
): Promise<{rewards: AttestationsRewards; executionOptimistic: boolean; finalized: boolean}>;
|
|
260
|
+
): Promise<{rewards: rewards.AttestationsRewards; executionOptimistic: boolean; finalized: boolean}>;
|
|
263
261
|
getSyncCommitteeRewards(
|
|
264
262
|
blockRef: BeaconBlock | BlindedBeaconBlock,
|
|
265
263
|
validatorIds?: (ValidatorIndex | string)[]
|
|
266
|
-
): Promise<SyncCommitteeRewards>;
|
|
264
|
+
): Promise<rewards.SyncCommitteeRewards>;
|
|
267
265
|
}
|
|
268
266
|
|
|
269
267
|
export type SSZObjectType =
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import {Signature, aggregateSignatures} from "@chainsafe/blst";
|
|
2
2
|
import {BitArray} from "@chainsafe/ssz";
|
|
3
|
-
import {
|
|
3
|
+
import {BeaconConfig} from "@lodestar/config";
|
|
4
4
|
import {IForkChoice} from "@lodestar/fork-choice";
|
|
5
5
|
import {
|
|
6
6
|
ForkName,
|
|
7
7
|
ForkSeq,
|
|
8
|
-
MAX_ATTESTATIONS,
|
|
9
8
|
MAX_ATTESTATIONS_ELECTRA,
|
|
10
9
|
MAX_COMMITTEES_PER_SLOT,
|
|
11
10
|
MIN_ATTESTATION_INCLUSION_DELAY,
|
|
@@ -23,7 +22,6 @@ import {
|
|
|
23
22
|
CachedBeaconStateAllForks,
|
|
24
23
|
CachedBeaconStateAltair,
|
|
25
24
|
CachedBeaconStateGloas,
|
|
26
|
-
CachedBeaconStatePhase0,
|
|
27
25
|
EffectiveBalanceIncrements,
|
|
28
26
|
RootCache,
|
|
29
27
|
computeEpochAtSlot,
|
|
@@ -32,17 +30,7 @@ import {
|
|
|
32
30
|
getAttestationParticipationStatus,
|
|
33
31
|
getBlockRootAtSlot,
|
|
34
32
|
} from "@lodestar/state-transition";
|
|
35
|
-
import {
|
|
36
|
-
Attestation,
|
|
37
|
-
Epoch,
|
|
38
|
-
RootHex,
|
|
39
|
-
Slot,
|
|
40
|
-
ValidatorIndex,
|
|
41
|
-
electra,
|
|
42
|
-
isElectraAttestation,
|
|
43
|
-
phase0,
|
|
44
|
-
ssz,
|
|
45
|
-
} from "@lodestar/types";
|
|
33
|
+
import {Attestation, Epoch, RootHex, Slot, electra, isElectraAttestation, phase0, ssz} from "@lodestar/types";
|
|
46
34
|
import {MapDef, assert, toRootHex} from "@lodestar/utils";
|
|
47
35
|
import {Metrics} from "../../metrics/metrics.js";
|
|
48
36
|
import {IntersectResult, intersectUint8Arrays} from "../../util/bitArray.js";
|
|
@@ -54,8 +42,6 @@ type DataRootHex = string;
|
|
|
54
42
|
|
|
55
43
|
type CommitteeIndex = number;
|
|
56
44
|
|
|
57
|
-
// for pre-electra
|
|
58
|
-
type AttestationWithScore = {attestation: Attestation; score: number};
|
|
59
45
|
/**
|
|
60
46
|
* for electra, this is to consolidate aggregated attestations of the same attestation data into a single attestation to be included in block
|
|
61
47
|
* note that this is local definition in this file and it's NOT validator consolidation
|
|
@@ -110,15 +96,6 @@ const MAX_RETAINED_ATTESTATIONS_PER_GROUP = 4;
|
|
|
110
96
|
*/
|
|
111
97
|
const MAX_RETAINED_ATTESTATIONS_PER_GROUP_ELECTRA = 8;
|
|
112
98
|
|
|
113
|
-
/**
|
|
114
|
-
* Pre-electra, each slot has 64 committees, and each block has 128 attestations max so in average
|
|
115
|
-
* we get 2 attestation per groups.
|
|
116
|
-
* Starting from Jan 2024, we have a performance issue getting attestations for a block. Based on the
|
|
117
|
-
* fact that lot of groups will have only 1 full participation attestation, increase this number
|
|
118
|
-
* a bit higher than average. This also help decrease number of slots to search for attestations.
|
|
119
|
-
*/
|
|
120
|
-
const MAX_ATTESTATIONS_PER_GROUP = 3;
|
|
121
|
-
|
|
122
99
|
/**
|
|
123
100
|
* For electra, there is on chain aggregation of attestations across committees, so we can just pick up to 8
|
|
124
101
|
* attestations per group, sort by scores to get first 8.
|
|
@@ -162,7 +139,7 @@ export class AggregatedAttestationPool {
|
|
|
162
139
|
private lowestPermissibleSlot = 0;
|
|
163
140
|
|
|
164
141
|
constructor(
|
|
165
|
-
private readonly config:
|
|
142
|
+
private readonly config: BeaconConfig,
|
|
166
143
|
private readonly metrics: Metrics | null = null
|
|
167
144
|
) {
|
|
168
145
|
metrics?.opPool.aggregatedAttestationPool.attDataPerSlot.addCollect(() => this.onScrapeMetrics(metrics));
|
|
@@ -241,112 +218,11 @@ export class AggregatedAttestationPool {
|
|
|
241
218
|
* Get attestations to be included in a block pre-electra. Returns up to $MAX_ATTESTATIONS items
|
|
242
219
|
*/
|
|
243
220
|
getAttestationsForBlockPreElectra(
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
221
|
+
_fork: ForkName,
|
|
222
|
+
_forkChoice: IForkChoice,
|
|
223
|
+
_state: CachedBeaconStateAllForks
|
|
247
224
|
): phase0.Attestation[] {
|
|
248
|
-
|
|
249
|
-
const stateEpoch = state.epochCtx.epoch;
|
|
250
|
-
const statePrevEpoch = stateEpoch - 1;
|
|
251
|
-
|
|
252
|
-
const notSeenValidatorsFn = getNotSeenValidatorsFn(state);
|
|
253
|
-
const validateAttestationDataFn = getValidateAttestationDataFn(forkChoice, state);
|
|
254
|
-
|
|
255
|
-
const attestationsByScore: AttestationWithScore[] = [];
|
|
256
|
-
|
|
257
|
-
const slots = Array.from(this.attestationGroupByIndexByDataHexBySlot.keys()).sort((a, b) => b - a);
|
|
258
|
-
let minScore = Number.MAX_SAFE_INTEGER;
|
|
259
|
-
let slotCount = 0;
|
|
260
|
-
slot: for (const slot of slots) {
|
|
261
|
-
slotCount++;
|
|
262
|
-
const attestationGroupByIndexByDataHash = this.attestationGroupByIndexByDataHexBySlot.get(slot);
|
|
263
|
-
// should not happen
|
|
264
|
-
if (!attestationGroupByIndexByDataHash) {
|
|
265
|
-
throw Error(`No aggregated attestation pool for slot=${slot}`);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
const epoch = computeEpochAtSlot(slot);
|
|
269
|
-
// validateAttestation condition: Attestation target epoch not in previous or current epoch
|
|
270
|
-
if (!(epoch === stateEpoch || epoch === statePrevEpoch)) {
|
|
271
|
-
continue; // Invalid attestations
|
|
272
|
-
}
|
|
273
|
-
// validateAttestation condition: Attestation slot not within inclusion window
|
|
274
|
-
if (
|
|
275
|
-
!(
|
|
276
|
-
slot + MIN_ATTESTATION_INCLUSION_DELAY <= stateSlot &&
|
|
277
|
-
// Post deneb, attestations are valid for current and previous epoch
|
|
278
|
-
(ForkSeq[fork] >= ForkSeq.deneb || stateSlot <= slot + SLOTS_PER_EPOCH)
|
|
279
|
-
)
|
|
280
|
-
) {
|
|
281
|
-
continue; // Invalid attestations
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
const inclusionDistance = stateSlot - slot;
|
|
285
|
-
for (const attestationGroupByIndex of attestationGroupByIndexByDataHash.values()) {
|
|
286
|
-
for (const [committeeIndex, attestationGroup] of attestationGroupByIndex.entries()) {
|
|
287
|
-
const notSeenCommitteeMembers = notSeenValidatorsFn(epoch, slot, committeeIndex);
|
|
288
|
-
if (notSeenCommitteeMembers === null || notSeenCommitteeMembers.size === 0) {
|
|
289
|
-
continue;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
if (
|
|
293
|
-
slotCount > 2 &&
|
|
294
|
-
attestationsByScore.length >= MAX_ATTESTATIONS &&
|
|
295
|
-
notSeenCommitteeMembers.size / inclusionDistance < minScore
|
|
296
|
-
) {
|
|
297
|
-
// after 2 slots, there are a good chance that we have 2 * MAX_ATTESTATIONS attestations and break the for loop early
|
|
298
|
-
// if not, we may have to scan all slots in the pool
|
|
299
|
-
// if we have enough attestations and the max possible score is lower than scores of `attestationsByScore`, we should skip
|
|
300
|
-
// otherwise it takes time to check attestation, add it and remove it later after the sort by score
|
|
301
|
-
continue;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
if (validateAttestationDataFn(attestationGroup.data) !== null) {
|
|
305
|
-
continue;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
// TODO: Is it necessary to validateAttestation for:
|
|
309
|
-
// - Attestation committee index not within current committee count
|
|
310
|
-
// - Attestation aggregation bits length does not match committee length
|
|
311
|
-
//
|
|
312
|
-
// These properties should not change after being validate in gossip
|
|
313
|
-
// IF they have to be validated, do it only with one attestation per group since same data
|
|
314
|
-
// The committeeCountPerSlot can be precomputed once per slot
|
|
315
|
-
const getAttestationsResult = attestationGroup.getAttestationsForBlock(
|
|
316
|
-
fork,
|
|
317
|
-
state.epochCtx.effectiveBalanceIncrements,
|
|
318
|
-
notSeenCommitteeMembers,
|
|
319
|
-
MAX_ATTESTATIONS_PER_GROUP
|
|
320
|
-
);
|
|
321
|
-
for (const {attestation, newSeenEffectiveBalance} of getAttestationsResult.result) {
|
|
322
|
-
const score = newSeenEffectiveBalance / inclusionDistance;
|
|
323
|
-
if (score < minScore) {
|
|
324
|
-
minScore = score;
|
|
325
|
-
}
|
|
326
|
-
attestationsByScore.push({
|
|
327
|
-
attestation,
|
|
328
|
-
score,
|
|
329
|
-
});
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
// Stop accumulating attestations there are enough that may have good scoring
|
|
333
|
-
if (attestationsByScore.length >= MAX_ATTESTATIONS * 2) {
|
|
334
|
-
break slot;
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
const sortedAttestationsByScore = attestationsByScore.sort((a, b) => b.score - a.score);
|
|
341
|
-
const attestationsForBlock: phase0.Attestation[] = [];
|
|
342
|
-
for (const [i, attestationWithScore] of sortedAttestationsByScore.entries()) {
|
|
343
|
-
if (i >= MAX_ATTESTATIONS) {
|
|
344
|
-
break;
|
|
345
|
-
}
|
|
346
|
-
// attestations could be modified in this op pool, so we need to clone for block
|
|
347
|
-
attestationsForBlock.push(ssz.phase0.Attestation.clone(attestationWithScore.attestation));
|
|
348
|
-
}
|
|
349
|
-
return attestationsForBlock;
|
|
225
|
+
throw new Error("Does not support producing blocks for pre-electra forks anymore");
|
|
350
226
|
}
|
|
351
227
|
|
|
352
228
|
/**
|
|
@@ -362,7 +238,7 @@ export class AggregatedAttestationPool {
|
|
|
362
238
|
const statePrevEpoch = stateEpoch - 1;
|
|
363
239
|
const rootCache = new RootCache(state);
|
|
364
240
|
|
|
365
|
-
const notSeenValidatorsFn = getNotSeenValidatorsFn(state);
|
|
241
|
+
const notSeenValidatorsFn = getNotSeenValidatorsFn(this.config, state);
|
|
366
242
|
const validateAttestationDataFn = getValidateAttestationDataFn(forkChoice, state);
|
|
367
243
|
|
|
368
244
|
const slots = Array.from(this.attestationGroupByIndexByDataHexBySlot.keys()).sort((a, b) => b - a);
|
|
@@ -656,7 +532,7 @@ export class MatchingDataAttestationGroup {
|
|
|
656
532
|
private readonly attestations: AttestationWithIndex[] = [];
|
|
657
533
|
|
|
658
534
|
constructor(
|
|
659
|
-
private readonly config:
|
|
535
|
+
private readonly config: BeaconConfig,
|
|
660
536
|
readonly committee: Uint32Array,
|
|
661
537
|
readonly data: phase0.AttestationData
|
|
662
538
|
) {}
|
|
@@ -864,41 +740,10 @@ export function aggregateConsolidation({byCommittee, attData}: AttestationsConso
|
|
|
864
740
|
* Pre-compute participation from a CachedBeaconStateAllForks, for use to check if an attestation's committee
|
|
865
741
|
* has already attested or not.
|
|
866
742
|
*/
|
|
867
|
-
export function getNotSeenValidatorsFn(state: CachedBeaconStateAllForks): GetNotSeenValidatorsFn {
|
|
743
|
+
export function getNotSeenValidatorsFn(config: BeaconConfig, state: CachedBeaconStateAllForks): GetNotSeenValidatorsFn {
|
|
868
744
|
const stateSlot = state.slot;
|
|
869
|
-
if (
|
|
870
|
-
|
|
871
|
-
// As we are close to altair, this is not really important, it's mainly for e2e.
|
|
872
|
-
// The performance is not great due to the different BeaconState data structure to altair.
|
|
873
|
-
// check for phase0 block already
|
|
874
|
-
const phase0State = state as CachedBeaconStatePhase0;
|
|
875
|
-
const stateEpoch = computeEpochAtSlot(stateSlot);
|
|
876
|
-
|
|
877
|
-
const previousEpochParticipants = extractParticipationPhase0(
|
|
878
|
-
phase0State.previousEpochAttestations.getAllReadonly(),
|
|
879
|
-
state
|
|
880
|
-
);
|
|
881
|
-
const currentEpochParticipants = extractParticipationPhase0(
|
|
882
|
-
phase0State.currentEpochAttestations.getAllReadonly(),
|
|
883
|
-
state
|
|
884
|
-
);
|
|
885
|
-
|
|
886
|
-
return (epoch: Epoch, slot: Slot, committeeIndex: number) => {
|
|
887
|
-
const participants =
|
|
888
|
-
epoch === stateEpoch ? currentEpochParticipants : epoch === stateEpoch - 1 ? previousEpochParticipants : null;
|
|
889
|
-
if (participants === null) {
|
|
890
|
-
return null;
|
|
891
|
-
}
|
|
892
|
-
const committee = state.epochCtx.getBeaconCommittee(slot, committeeIndex);
|
|
893
|
-
|
|
894
|
-
const notSeenCommitteeMembers = new Set<number>();
|
|
895
|
-
for (const [i, validatorIndex] of committee.entries()) {
|
|
896
|
-
if (!participants.has(validatorIndex)) {
|
|
897
|
-
notSeenCommitteeMembers.add(i);
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
return notSeenCommitteeMembers.size === 0 ? null : notSeenCommitteeMembers;
|
|
901
|
-
};
|
|
745
|
+
if (config.getForkName(stateSlot) === ForkName.phase0) {
|
|
746
|
+
throw new Error("getNotSeenValidatorsFn is not supported phase0 state");
|
|
902
747
|
}
|
|
903
748
|
|
|
904
749
|
// altair and future forks
|
|
@@ -942,26 +787,6 @@ export function getNotSeenValidatorsFn(state: CachedBeaconStateAllForks): GetNot
|
|
|
942
787
|
};
|
|
943
788
|
}
|
|
944
789
|
|
|
945
|
-
export function extractParticipationPhase0(
|
|
946
|
-
attestations: phase0.PendingAttestation[],
|
|
947
|
-
state: CachedBeaconStateAllForks
|
|
948
|
-
): Set<ValidatorIndex> {
|
|
949
|
-
const {epochCtx} = state;
|
|
950
|
-
const allParticipants = new Set<ValidatorIndex>();
|
|
951
|
-
for (const att of attestations) {
|
|
952
|
-
const aggregationBits = att.aggregationBits;
|
|
953
|
-
const attData = att.data;
|
|
954
|
-
const attSlot = attData.slot;
|
|
955
|
-
const committeeIndex = attData.index;
|
|
956
|
-
const committee = epochCtx.getBeaconCommittee(attSlot, committeeIndex);
|
|
957
|
-
const participants = aggregationBits.intersectValues(committee);
|
|
958
|
-
for (const participant of participants) {
|
|
959
|
-
allParticipants.add(participant);
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
return allParticipants;
|
|
963
|
-
}
|
|
964
|
-
|
|
965
790
|
/**
|
|
966
791
|
* This returns a function to validate if an attestation data is compatible to a state.
|
|
967
792
|
*
|
|
@@ -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
|
|
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
|
|
|
@@ -117,12 +117,7 @@ export class PrepareNextSlotScheduler {
|
|
|
117
117
|
// the slot 0 of next epoch will likely use this Previous Root Checkpoint state for state transition so we transfer cache here
|
|
118
118
|
// the resulting state with cache will be cached in Checkpoint State Cache which is used for the upcoming block processing
|
|
119
119
|
// for other slots dontTransferCached=true because we don't run state transition on this state
|
|
120
|
-
|
|
121
|
-
// Shuffling calculation will be done asynchronously when passing asyncShufflingCalculation=true. Shuffling will be queued in
|
|
122
|
-
// beforeProcessEpoch and should theoretically be ready immediately after the synchronous epoch transition finished and the
|
|
123
|
-
// event loop is free. In long periods of non-finality too many forks will cause the shufflingCache to throw an error for
|
|
124
|
-
// too many queued shufflings so only run async during normal epoch transition. See issue ChainSafe/lodestar#7244
|
|
125
|
-
{dontTransferCache: !isEpochTransition, asyncShufflingCalculation: true},
|
|
120
|
+
{dontTransferCache: !isEpochTransition},
|
|
126
121
|
RegenCaller.precomputeEpoch
|
|
127
122
|
);
|
|
128
123
|
|