@lodestar/state-transition 1.41.0-dev.d41697c085 → 1.41.0-dev.dce096d70c
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/lib/block/externalData.d.ts +2 -1
- package/lib/block/externalData.d.ts.map +1 -1
- package/lib/block/externalData.js +2 -0
- package/lib/block/externalData.js.map +1 -1
- package/lib/block/isValidIndexedAttestation.d.ts +3 -3
- package/lib/block/isValidIndexedAttestation.d.ts.map +1 -1
- package/lib/block/isValidIndexedAttestation.js +4 -4
- package/lib/block/isValidIndexedAttestation.js.map +1 -1
- package/lib/block/isValidIndexedPayloadAttestation.js +1 -1
- package/lib/block/isValidIndexedPayloadAttestation.js.map +1 -1
- package/lib/block/processAttestationPhase0.js +1 -1
- package/lib/block/processAttestationPhase0.js.map +1 -1
- package/lib/block/processAttestationsAltair.js +1 -1
- package/lib/block/processAttestationsAltair.js.map +1 -1
- package/lib/block/processAttesterSlashing.d.ts +2 -2
- package/lib/block/processAttesterSlashing.d.ts.map +1 -1
- package/lib/block/processAttesterSlashing.js +3 -3
- package/lib/block/processAttesterSlashing.js.map +1 -1
- package/lib/block/processExecutionPayloadEnvelope.js +5 -1
- package/lib/block/processExecutionPayloadEnvelope.js.map +1 -1
- package/lib/block/processProposerSlashing.d.ts +2 -2
- package/lib/block/processProposerSlashing.d.ts.map +1 -1
- package/lib/block/processProposerSlashing.js +3 -3
- package/lib/block/processProposerSlashing.js.map +1 -1
- package/lib/block/processRandao.js +1 -1
- package/lib/block/processRandao.js.map +1 -1
- package/lib/block/processSyncCommittee.js +1 -1
- package/lib/block/processSyncCommittee.js.map +1 -1
- package/lib/block/processVoluntaryExit.js +1 -1
- package/lib/block/processVoluntaryExit.js.map +1 -1
- package/lib/block/processWithdrawalRequest.js +2 -2
- package/lib/block/processWithdrawalRequest.js.map +1 -1
- package/lib/cache/epochCache.d.ts +8 -15
- package/lib/cache/epochCache.d.ts.map +1 -1
- package/lib/cache/epochCache.js +34 -33
- package/lib/cache/epochCache.js.map +1 -1
- package/lib/cache/pubkeyCache.d.ts +21 -6
- package/lib/cache/pubkeyCache.d.ts.map +1 -1
- package/lib/cache/pubkeyCache.js +39 -14
- package/lib/cache/pubkeyCache.js.map +1 -1
- package/lib/cache/stateCache.d.ts +1 -1
- package/lib/cache/stateCache.d.ts.map +1 -1
- package/lib/cache/stateCache.js +3 -7
- package/lib/cache/stateCache.js.map +1 -1
- package/lib/cache/syncCommitteeCache.d.ts +3 -2
- package/lib/cache/syncCommitteeCache.d.ts.map +1 -1
- package/lib/cache/syncCommitteeCache.js +4 -4
- package/lib/cache/syncCommitteeCache.js.map +1 -1
- package/lib/index.d.ts +3 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/lib/lightClient/proofs.d.ts +10 -0
- package/lib/lightClient/proofs.d.ts.map +1 -0
- package/lib/lightClient/proofs.js +63 -0
- package/lib/lightClient/proofs.js.map +1 -0
- package/lib/lightClient/types.d.ts +34 -0
- package/lib/lightClient/types.d.ts.map +1 -0
- package/lib/lightClient/types.js +2 -0
- package/lib/lightClient/types.js.map +1 -0
- package/lib/rewards/attestationsRewards.d.ts +2 -2
- package/lib/rewards/attestationsRewards.d.ts.map +1 -1
- package/lib/rewards/attestationsRewards.js +4 -4
- package/lib/rewards/attestationsRewards.js.map +1 -1
- package/lib/rewards/syncCommitteeRewards.d.ts +2 -2
- package/lib/rewards/syncCommitteeRewards.d.ts.map +1 -1
- package/lib/rewards/syncCommitteeRewards.js +5 -2
- package/lib/rewards/syncCommitteeRewards.js.map +1 -1
- package/lib/signatureSets/proposer.d.ts +2 -2
- package/lib/signatureSets/proposer.d.ts.map +1 -1
- package/lib/signatureSets/proposer.js +2 -2
- package/lib/signatureSets/proposer.js.map +1 -1
- package/lib/signatureSets/randao.d.ts +2 -2
- package/lib/signatureSets/randao.d.ts.map +1 -1
- package/lib/signatureSets/randao.js +2 -2
- package/lib/signatureSets/randao.js.map +1 -1
- package/lib/signatureSets/voluntaryExits.d.ts +2 -2
- package/lib/signatureSets/voluntaryExits.d.ts.map +1 -1
- package/lib/signatureSets/voluntaryExits.js +2 -2
- package/lib/signatureSets/voluntaryExits.js.map +1 -1
- package/lib/stateTransition.d.ts +2 -1
- package/lib/stateTransition.d.ts.map +1 -1
- package/lib/stateTransition.js +2 -1
- package/lib/stateTransition.js.map +1 -1
- package/lib/stateView/beaconStateView.d.ts +144 -0
- package/lib/stateView/beaconStateView.d.ts.map +1 -0
- package/lib/stateView/beaconStateView.js +496 -0
- package/lib/stateView/beaconStateView.js.map +1 -0
- package/lib/stateView/index.d.ts +3 -0
- package/lib/stateView/index.d.ts.map +1 -0
- package/lib/stateView/index.js +3 -0
- package/lib/stateView/index.js.map +1 -0
- package/lib/stateView/interface.d.ts +118 -0
- package/lib/stateView/interface.d.ts.map +1 -0
- package/lib/stateView/interface.js +2 -0
- package/lib/stateView/interface.js.map +1 -0
- package/lib/util/signatureSets.d.ts +7 -7
- package/lib/util/signatureSets.d.ts.map +1 -1
- package/lib/util/signatureSets.js +18 -12
- package/lib/util/signatureSets.js.map +1 -1
- package/lib/util/weakSubjectivity.js +1 -1
- package/lib/util/weakSubjectivity.js.map +1 -1
- package/package.json +7 -7
- package/src/block/externalData.ts +2 -0
- package/src/block/isValidIndexedAttestation.ts +5 -5
- package/src/block/isValidIndexedPayloadAttestation.ts +1 -1
- package/src/block/processAttestationPhase0.ts +1 -1
- package/src/block/processAttestationsAltair.ts +1 -1
- package/src/block/processAttesterSlashing.ts +4 -4
- package/src/block/processExecutionPayloadEnvelope.ts +5 -1
- package/src/block/processProposerSlashing.ts +4 -4
- package/src/block/processRandao.ts +1 -1
- package/src/block/processSyncCommittee.ts +1 -1
- package/src/block/processVoluntaryExit.ts +1 -1
- package/src/block/processWithdrawalRequest.ts +2 -2
- package/src/cache/epochCache.ts +44 -36
- package/src/cache/pubkeyCache.ts +62 -21
- package/src/cache/stateCache.ts +4 -8
- package/src/cache/syncCommitteeCache.ts +4 -5
- package/src/index.ts +3 -1
- package/src/lightClient/proofs.ts +83 -0
- package/src/lightClient/types.ts +33 -0
- package/src/rewards/attestationsRewards.ts +5 -5
- package/src/rewards/syncCommitteeRewards.ts +6 -5
- package/src/signatureSets/proposer.ts +3 -3
- package/src/signatureSets/randao.ts +3 -7
- package/src/signatureSets/voluntaryExits.ts +3 -3
- package/src/stateTransition.ts +2 -1
- package/src/stateView/beaconStateView.ts +744 -0
- package/src/stateView/index.ts +2 -0
- package/src/stateView/interface.ts +196 -0
- package/src/util/signatureSets.ts +23 -17
- package/src/util/weakSubjectivity.ts +1 -1
package/src/cache/epochCache.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {PublicKey} from "@chainsafe/blst";
|
|
2
|
-
import {PubkeyIndexMap} from "@chainsafe/pubkey-index-map";
|
|
3
2
|
import {BeaconConfig, ChainConfig, createBeaconConfig} from "@lodestar/config";
|
|
4
3
|
import {
|
|
5
4
|
ATTESTATION_SUBNET_COUNT,
|
|
@@ -56,7 +55,7 @@ import {computeBaseRewardPerIncrement, computeSyncParticipantReward} from "../ut
|
|
|
56
55
|
import {sumTargetUnslashedBalanceIncrements} from "../util/targetUnslashedBalance.js";
|
|
57
56
|
import {EffectiveBalanceIncrements, getEffectiveBalanceIncrementsWithLen} from "./effectiveBalanceIncrements.js";
|
|
58
57
|
import {EpochTransitionCache} from "./epochTransitionCache.js";
|
|
59
|
-
import {
|
|
58
|
+
import {PubkeyCache, createPubkeyCache, syncPubkeys} from "./pubkeyCache.js";
|
|
60
59
|
import {CachedBeaconStateAllForks, CachedBeaconStateFulu} from "./stateCache.js";
|
|
61
60
|
import {
|
|
62
61
|
SyncCommitteeCache,
|
|
@@ -71,8 +70,7 @@ export const PROPOSER_WEIGHT_FACTOR = PROPOSER_WEIGHT / (WEIGHT_DENOMINATOR - PR
|
|
|
71
70
|
|
|
72
71
|
export type EpochCacheImmutableData = {
|
|
73
72
|
config: BeaconConfig;
|
|
74
|
-
|
|
75
|
-
index2pubkey: Index2PubkeyCache;
|
|
73
|
+
pubkeyCache: PubkeyCache;
|
|
76
74
|
};
|
|
77
75
|
|
|
78
76
|
export type EpochCacheOpts = {
|
|
@@ -111,15 +109,9 @@ export class EpochCache {
|
|
|
111
109
|
/**
|
|
112
110
|
* Unique globally shared pubkey registry. There should only exist one for the entire application.
|
|
113
111
|
*
|
|
114
|
-
*
|
|
112
|
+
* Couples both index→pubkey and pubkey→index lookups, keeping them in sync atomically.
|
|
115
113
|
*/
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Unique globally shared pubkey registry. There should only exist one for the entire application.
|
|
119
|
-
*
|
|
120
|
-
* $VALIDATOR_COUNT x BLST deserialized pubkey (Jacobian coordinates)
|
|
121
|
-
*/
|
|
122
|
-
index2pubkey: Index2PubkeyCache;
|
|
114
|
+
pubkeyCache: PubkeyCache;
|
|
123
115
|
/**
|
|
124
116
|
* Indexes of the block proposers for the current epoch.
|
|
125
117
|
* For pre-fulu, this is computed and cached from the current shuffling.
|
|
@@ -234,7 +226,9 @@ export class EpochCache {
|
|
|
234
226
|
/** TODO: Indexed SyncCommitteeCache */
|
|
235
227
|
nextSyncCommitteeIndexed: SyncCommitteeCache;
|
|
236
228
|
|
|
237
|
-
// TODO GLOAS: See if we need to
|
|
229
|
+
// TODO GLOAS: See if we need to cache PTC for next epoch
|
|
230
|
+
// PTC for previous epoch, required for slot N block validating slot N-1 attestations
|
|
231
|
+
previousPayloadTimelinessCommittees: Uint32Array[];
|
|
238
232
|
// PTC for current epoch, computed eagerly at epoch transition
|
|
239
233
|
payloadTimelinessCommittees: Uint32Array[];
|
|
240
234
|
|
|
@@ -249,8 +243,7 @@ export class EpochCache {
|
|
|
249
243
|
|
|
250
244
|
constructor(data: {
|
|
251
245
|
config: BeaconConfig;
|
|
252
|
-
|
|
253
|
-
index2pubkey: Index2PubkeyCache;
|
|
246
|
+
pubkeyCache: PubkeyCache;
|
|
254
247
|
proposers: number[];
|
|
255
248
|
proposersPrevEpoch: number[] | null;
|
|
256
249
|
proposersNextEpoch: ProposersDeferred;
|
|
@@ -275,13 +268,13 @@ export class EpochCache {
|
|
|
275
268
|
previousTargetUnslashedBalanceIncrements: number;
|
|
276
269
|
currentSyncCommitteeIndexed: SyncCommitteeCache;
|
|
277
270
|
nextSyncCommitteeIndexed: SyncCommitteeCache;
|
|
271
|
+
previousPayloadTimelinessCommittees: Uint32Array[];
|
|
278
272
|
payloadTimelinessCommittees: Uint32Array[];
|
|
279
273
|
epoch: Epoch;
|
|
280
274
|
syncPeriod: SyncPeriod;
|
|
281
275
|
}) {
|
|
282
276
|
this.config = data.config;
|
|
283
|
-
this.
|
|
284
|
-
this.index2pubkey = data.index2pubkey;
|
|
277
|
+
this.pubkeyCache = data.pubkeyCache;
|
|
285
278
|
this.proposers = data.proposers;
|
|
286
279
|
this.proposersPrevEpoch = data.proposersPrevEpoch;
|
|
287
280
|
this.proposersNextEpoch = data.proposersNextEpoch;
|
|
@@ -306,6 +299,7 @@ export class EpochCache {
|
|
|
306
299
|
this.previousTargetUnslashedBalanceIncrements = data.previousTargetUnslashedBalanceIncrements;
|
|
307
300
|
this.currentSyncCommitteeIndexed = data.currentSyncCommitteeIndexed;
|
|
308
301
|
this.nextSyncCommitteeIndexed = data.nextSyncCommitteeIndexed;
|
|
302
|
+
this.previousPayloadTimelinessCommittees = data.previousPayloadTimelinessCommittees;
|
|
309
303
|
this.payloadTimelinessCommittees = data.payloadTimelinessCommittees;
|
|
310
304
|
this.epoch = data.epoch;
|
|
311
305
|
this.syncPeriod = data.syncPeriod;
|
|
@@ -319,7 +313,7 @@ export class EpochCache {
|
|
|
319
313
|
*/
|
|
320
314
|
static createFromState(
|
|
321
315
|
state: BeaconStateAllForks,
|
|
322
|
-
{config,
|
|
316
|
+
{config, pubkeyCache}: EpochCacheImmutableData,
|
|
323
317
|
opts?: EpochCacheOpts
|
|
324
318
|
): EpochCache {
|
|
325
319
|
const currentEpoch = computeEpochAtSlot(state.slot);
|
|
@@ -335,9 +329,9 @@ export class EpochCache {
|
|
|
335
329
|
const validatorCount = validators.length;
|
|
336
330
|
|
|
337
331
|
// syncPubkeys here to ensure EpochCacheImmutableData is popualted before computing the rest of caches
|
|
338
|
-
// - computeSyncCommitteeCache() needs a fully populated
|
|
332
|
+
// - computeSyncCommitteeCache() needs a fully populated pubkeyCache
|
|
339
333
|
if (!opts?.skipSyncPubkeys) {
|
|
340
|
-
syncPubkeys(
|
|
334
|
+
syncPubkeys(pubkeyCache, validators);
|
|
341
335
|
}
|
|
342
336
|
|
|
343
337
|
const effectiveBalanceIncrements = getEffectiveBalanceIncrementsWithLen(validatorCount);
|
|
@@ -450,14 +444,15 @@ export class EpochCache {
|
|
|
450
444
|
// Allow to skip populating sync committee for initializeBeaconStateFromEth1()
|
|
451
445
|
if (afterAltairFork && !opts?.skipSyncCommitteeCache) {
|
|
452
446
|
const altairState = state as BeaconStateAltair;
|
|
453
|
-
currentSyncCommitteeIndexed = computeSyncCommitteeCache(altairState.currentSyncCommittee,
|
|
454
|
-
nextSyncCommitteeIndexed = computeSyncCommitteeCache(altairState.nextSyncCommittee,
|
|
447
|
+
currentSyncCommitteeIndexed = computeSyncCommitteeCache(altairState.currentSyncCommittee, pubkeyCache);
|
|
448
|
+
nextSyncCommitteeIndexed = computeSyncCommitteeCache(altairState.nextSyncCommittee, pubkeyCache);
|
|
455
449
|
} else {
|
|
456
450
|
currentSyncCommitteeIndexed = new SyncCommitteeCacheEmpty();
|
|
457
451
|
nextSyncCommitteeIndexed = new SyncCommitteeCacheEmpty();
|
|
458
452
|
}
|
|
459
453
|
|
|
460
|
-
// Compute PTC
|
|
454
|
+
// Compute PTC for all slots in the prev/current epoch
|
|
455
|
+
let previousPayloadTimelinessCommittees: Uint32Array[] = [];
|
|
461
456
|
let payloadTimelinessCommittees: Uint32Array[] = [];
|
|
462
457
|
if (currentEpoch >= config.GLOAS_FORK_EPOCH) {
|
|
463
458
|
payloadTimelinessCommittees = computePayloadTimelinessCommitteesForEpoch(
|
|
@@ -466,6 +461,15 @@ export class EpochCache {
|
|
|
466
461
|
currentShuffling.committees,
|
|
467
462
|
effectiveBalanceIncrements
|
|
468
463
|
);
|
|
464
|
+
|
|
465
|
+
if (!isGenesis && previousEpoch >= config.GLOAS_FORK_EPOCH) {
|
|
466
|
+
previousPayloadTimelinessCommittees = computePayloadTimelinessCommitteesForEpoch(
|
|
467
|
+
state,
|
|
468
|
+
previousEpoch,
|
|
469
|
+
previousShuffling.committees,
|
|
470
|
+
effectiveBalanceIncrements
|
|
471
|
+
);
|
|
472
|
+
}
|
|
469
473
|
}
|
|
470
474
|
|
|
471
475
|
// Precompute churnLimit for efficient initiateValidatorExit() during block proposing MUST be recompute everytime the
|
|
@@ -514,8 +518,7 @@ export class EpochCache {
|
|
|
514
518
|
|
|
515
519
|
return new EpochCache({
|
|
516
520
|
config,
|
|
517
|
-
|
|
518
|
-
index2pubkey,
|
|
521
|
+
pubkeyCache,
|
|
519
522
|
proposers,
|
|
520
523
|
// On first epoch, set to null to prevent unnecessary work since this is only used for metrics
|
|
521
524
|
proposersPrevEpoch: null,
|
|
@@ -541,6 +544,7 @@ export class EpochCache {
|
|
|
541
544
|
currentTargetUnslashedBalanceIncrements,
|
|
542
545
|
currentSyncCommitteeIndexed,
|
|
543
546
|
nextSyncCommitteeIndexed,
|
|
547
|
+
previousPayloadTimelinessCommittees,
|
|
544
548
|
payloadTimelinessCommittees,
|
|
545
549
|
epoch: currentEpoch,
|
|
546
550
|
syncPeriod: computeSyncPeriodAtEpoch(currentEpoch),
|
|
@@ -557,8 +561,7 @@ export class EpochCache {
|
|
|
557
561
|
return new EpochCache({
|
|
558
562
|
config: this.config,
|
|
559
563
|
// Common append-only structures shared with all states, no need to clone
|
|
560
|
-
|
|
561
|
-
index2pubkey: this.index2pubkey,
|
|
564
|
+
pubkeyCache: this.pubkeyCache,
|
|
562
565
|
// Immutable data
|
|
563
566
|
proposers: this.proposers,
|
|
564
567
|
proposersPrevEpoch: this.proposersPrevEpoch,
|
|
@@ -587,6 +590,7 @@ export class EpochCache {
|
|
|
587
590
|
currentTargetUnslashedBalanceIncrements: this.currentTargetUnslashedBalanceIncrements,
|
|
588
591
|
currentSyncCommitteeIndexed: this.currentSyncCommitteeIndexed,
|
|
589
592
|
nextSyncCommitteeIndexed: this.nextSyncCommitteeIndexed,
|
|
593
|
+
previousPayloadTimelinessCommittees: this.previousPayloadTimelinessCommittees,
|
|
590
594
|
payloadTimelinessCommittees: this.payloadTimelinessCommittees,
|
|
591
595
|
epoch: this.epoch,
|
|
592
596
|
syncPeriod: this.syncPeriod,
|
|
@@ -698,6 +702,8 @@ export class EpochCache {
|
|
|
698
702
|
|
|
699
703
|
this.proposersPrevEpoch = this.proposers;
|
|
700
704
|
if (upcomingEpoch >= this.config.GLOAS_FORK_EPOCH) {
|
|
705
|
+
// Shift and compute current epoch PTC eagerly for all slots
|
|
706
|
+
this.previousPayloadTimelinessCommittees = this.payloadTimelinessCommittees;
|
|
701
707
|
this.payloadTimelinessCommittees = computePayloadTimelinessCommitteesForEpoch(
|
|
702
708
|
state,
|
|
703
709
|
upcomingEpoch,
|
|
@@ -882,16 +888,15 @@ export class EpochCache {
|
|
|
882
888
|
* Return pubkey given the validator index.
|
|
883
889
|
*/
|
|
884
890
|
getPubkey(index: ValidatorIndex): PublicKey | undefined {
|
|
885
|
-
return this.
|
|
891
|
+
return this.pubkeyCache.get(index);
|
|
886
892
|
}
|
|
887
893
|
|
|
888
894
|
getValidatorIndex(pubkey: Uint8Array): ValidatorIndex | null {
|
|
889
|
-
return this.
|
|
895
|
+
return this.pubkeyCache.getIndex(pubkey);
|
|
890
896
|
}
|
|
891
897
|
|
|
892
898
|
addPubkey(index: ValidatorIndex, pubkey: Uint8Array): void {
|
|
893
|
-
this.
|
|
894
|
-
this.index2pubkey[index] = PublicKey.fromBytes(pubkey); // Optimize for aggregation
|
|
899
|
+
this.pubkeyCache.set(index, pubkey);
|
|
895
900
|
}
|
|
896
901
|
|
|
897
902
|
getShufflingAtSlot(slot: Slot): EpochShuffling {
|
|
@@ -1029,11 +1034,15 @@ export class EpochCache {
|
|
|
1029
1034
|
throw new Error("Payload Timeliness Committee is not available before gloas fork");
|
|
1030
1035
|
}
|
|
1031
1036
|
|
|
1032
|
-
if (epoch
|
|
1033
|
-
|
|
1037
|
+
if (epoch === this.epoch) {
|
|
1038
|
+
return this.payloadTimelinessCommittees[slot % SLOTS_PER_EPOCH];
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
if (epoch === this.epoch - 1 && this.previousPayloadTimelinessCommittees.length > 0) {
|
|
1042
|
+
return this.previousPayloadTimelinessCommittees[slot % SLOTS_PER_EPOCH];
|
|
1034
1043
|
}
|
|
1035
1044
|
|
|
1036
|
-
|
|
1045
|
+
throw new Error(`Payload Timeliness Committee is not available for slot=${slot}`);
|
|
1037
1046
|
}
|
|
1038
1047
|
|
|
1039
1048
|
getIndexedPayloadAttestation(
|
|
@@ -1099,7 +1108,6 @@ export function createEmptyEpochCacheImmutableData(
|
|
|
1099
1108
|
return {
|
|
1100
1109
|
config: createBeaconConfig(chainConfig, state.genesisValidatorsRoot),
|
|
1101
1110
|
// This is a test state, there's no need to have a global shared cache of keys
|
|
1102
|
-
|
|
1103
|
-
index2pubkey: [],
|
|
1111
|
+
pubkeyCache: createPubkeyCache(),
|
|
1104
1112
|
};
|
|
1105
1113
|
}
|
package/src/cache/pubkeyCache.ts
CHANGED
|
@@ -1,33 +1,74 @@
|
|
|
1
1
|
import {PublicKey} from "@chainsafe/blst";
|
|
2
2
|
import {PubkeyIndexMap} from "@chainsafe/pubkey-index-map";
|
|
3
|
-
import {phase0} from "@lodestar/types";
|
|
3
|
+
import {ValidatorIndex, phase0} from "@lodestar/types";
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Unified pubkey cache coupling index→pubkey and pubkey→index lookups.
|
|
7
|
+
* Both directions are kept in sync atomically via `set()`.
|
|
8
|
+
*/
|
|
9
|
+
export interface PubkeyCache {
|
|
10
|
+
/** Get deserialized PublicKey by validator index */
|
|
11
|
+
get(index: ValidatorIndex): PublicKey | undefined;
|
|
12
|
+
/** Get deserialized PublicKey by validator index or throw if not found */
|
|
13
|
+
getOrThrow(index: ValidatorIndex): PublicKey;
|
|
14
|
+
/** Get validator index by pubkey bytes */
|
|
15
|
+
getIndex(pubkey: Uint8Array): ValidatorIndex | null;
|
|
16
|
+
/** Set both directions atomically. Takes raw pubkey bytes — deserialization is handled internally. */
|
|
17
|
+
set(index: ValidatorIndex, pubkey: Uint8Array): void;
|
|
18
|
+
/** Number of entries */
|
|
19
|
+
readonly size: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
class StandardPubkeyCache implements PubkeyCache {
|
|
23
|
+
private readonly pubkey2index: PubkeyIndexMap;
|
|
24
|
+
private readonly index2pubkey: (PublicKey | undefined)[];
|
|
25
|
+
|
|
26
|
+
constructor(pubkey2index?: PubkeyIndexMap, index2pubkey?: (PublicKey | undefined)[]) {
|
|
27
|
+
this.pubkey2index = pubkey2index ?? new PubkeyIndexMap();
|
|
28
|
+
this.index2pubkey = index2pubkey ?? [];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
get size(): number {
|
|
32
|
+
return this.pubkey2index.size;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
get(index: ValidatorIndex): PublicKey | undefined {
|
|
36
|
+
return this.index2pubkey[index];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
getOrThrow(index: ValidatorIndex): PublicKey {
|
|
40
|
+
const pubkey = this.get(index);
|
|
41
|
+
if (!pubkey) throw Error(`Missing pubkey for validator index ${index}`);
|
|
42
|
+
return pubkey;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
getIndex(pubkey: Uint8Array): ValidatorIndex | null {
|
|
46
|
+
return this.pubkey2index.get(pubkey);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
set(index: ValidatorIndex, pubkey: Uint8Array): void {
|
|
50
|
+
this.pubkey2index.set(pubkey, index);
|
|
51
|
+
// Pubkeys must be checked for group + inf. This must be done only once when the validator deposit is processed.
|
|
52
|
+
// Afterwards any public key in the state is considered validated.
|
|
53
|
+
// > Do not do any validation here
|
|
54
|
+
this.index2pubkey[index] = PublicKey.fromBytes(pubkey); // Optimize for aggregation
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function createPubkeyCache(): PubkeyCache {
|
|
59
|
+
return new StandardPubkeyCache();
|
|
60
|
+
}
|
|
6
61
|
|
|
7
62
|
/**
|
|
8
63
|
* Checks the pubkey indices against a state and adds missing pubkeys
|
|
9
64
|
*
|
|
10
|
-
* Mutates `
|
|
65
|
+
* Mutates `pubkeyCache`
|
|
11
66
|
*
|
|
12
|
-
* If pubkey
|
|
67
|
+
* If pubkey cache is empty: SLOW CODE - 🐢
|
|
13
68
|
*/
|
|
14
|
-
export function syncPubkeys(
|
|
15
|
-
validators: phase0.Validator[],
|
|
16
|
-
pubkey2index: PubkeyIndexMap,
|
|
17
|
-
index2pubkey: Index2PubkeyCache
|
|
18
|
-
): void {
|
|
19
|
-
if (pubkey2index.size !== index2pubkey.length) {
|
|
20
|
-
throw new Error(`Pubkey indices have fallen out of sync: ${pubkey2index.size} != ${index2pubkey.length}`);
|
|
21
|
-
}
|
|
22
|
-
|
|
69
|
+
export function syncPubkeys(pubkeyCache: PubkeyCache, validators: phase0.Validator[]): void {
|
|
23
70
|
const newCount = validators.length;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const pubkey = validators[i].pubkey;
|
|
27
|
-
pubkey2index.set(pubkey, i);
|
|
28
|
-
// Pubkeys must be checked for group + inf. This must be done only once when the validator deposit is processed.
|
|
29
|
-
// Afterwards any public key is the state consider validated.
|
|
30
|
-
// > Do not do any validation here
|
|
31
|
-
index2pubkey[i] = PublicKey.fromBytes(pubkey); // Optimize for aggregation
|
|
71
|
+
for (let i = pubkeyCache.size; i < newCount; i++) {
|
|
72
|
+
pubkeyCache.set(i, validators[i].pubkey);
|
|
32
73
|
}
|
|
33
74
|
}
|
package/src/cache/stateCache.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import {PublicKey} from "@chainsafe/blst";
|
|
2
1
|
import {BeaconConfig} from "@lodestar/config";
|
|
3
2
|
import {loadState} from "../util/loadState/loadState.js";
|
|
4
3
|
import {EpochCache, EpochCacheImmutableData, EpochCacheOpts} from "./epochCache.js";
|
|
@@ -168,7 +167,7 @@ export function createCachedBeaconState<T extends BeaconStateAllForks>(
|
|
|
168
167
|
* Check loadState() api for more details
|
|
169
168
|
* // TODO: rename to loadUnfinalizedCachedBeaconState() due to ELECTRA
|
|
170
169
|
*/
|
|
171
|
-
export function loadCachedBeaconState<T extends
|
|
170
|
+
export function loadCachedBeaconState<T extends CachedBeaconStateAllForks>(
|
|
172
171
|
cachedSeedState: T,
|
|
173
172
|
stateBytes: Uint8Array,
|
|
174
173
|
opts?: EpochCacheOpts,
|
|
@@ -180,22 +179,19 @@ export function loadCachedBeaconState<T extends BeaconStateAllForks & BeaconStat
|
|
|
180
179
|
stateBytes,
|
|
181
180
|
seedValidatorsBytes
|
|
182
181
|
);
|
|
183
|
-
const {
|
|
182
|
+
const {pubkeyCache} = cachedSeedState.epochCtx;
|
|
184
183
|
// Get the validators sub tree once for all the loop
|
|
185
184
|
const validators = migratedState.validators;
|
|
186
185
|
for (const validatorIndex of modifiedValidators) {
|
|
187
186
|
const validator = validators.getReadonly(validatorIndex);
|
|
188
|
-
|
|
189
|
-
pubkey2index.set(pubkey, validatorIndex);
|
|
190
|
-
index2pubkey[validatorIndex] = PublicKey.fromBytes(pubkey);
|
|
187
|
+
pubkeyCache.set(validatorIndex, validator.pubkey);
|
|
191
188
|
}
|
|
192
189
|
|
|
193
190
|
return createCachedBeaconState(
|
|
194
191
|
migratedState,
|
|
195
192
|
{
|
|
196
193
|
config: cachedSeedState.config,
|
|
197
|
-
|
|
198
|
-
index2pubkey,
|
|
194
|
+
pubkeyCache,
|
|
199
195
|
},
|
|
200
196
|
{...(opts ?? {}), ...{skipSyncPubkeys: true}}
|
|
201
197
|
) as T;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import {PubkeyIndexMap} from "@chainsafe/pubkey-index-map";
|
|
2
1
|
import {CompositeViewDU} from "@chainsafe/ssz";
|
|
3
2
|
import {ValidatorIndex, ssz} from "@lodestar/types";
|
|
4
3
|
import {toPubkeyHex} from "@lodestar/utils";
|
|
@@ -39,9 +38,9 @@ export function getSyncCommitteeCache(validatorIndices: Uint32Array): SyncCommit
|
|
|
39
38
|
|
|
40
39
|
export function computeSyncCommitteeCache(
|
|
41
40
|
syncCommittee: CompositeViewDU<typeof ssz.altair.SyncCommittee>,
|
|
42
|
-
|
|
41
|
+
pubkeyCache: {getIndex(pubkey: Uint8Array): number | null}
|
|
43
42
|
): SyncCommitteeCache {
|
|
44
|
-
const validatorIndices = computeSyncCommitteeValidatorIndices(syncCommittee,
|
|
43
|
+
const validatorIndices = computeSyncCommitteeValidatorIndices(syncCommittee, pubkeyCache);
|
|
45
44
|
const validatorIndexMap = computeValidatorSyncCommitteeIndexMap(validatorIndices);
|
|
46
45
|
return {
|
|
47
46
|
validatorIndices,
|
|
@@ -79,12 +78,12 @@ export function computeValidatorSyncCommitteeIndexMap(
|
|
|
79
78
|
*/
|
|
80
79
|
function computeSyncCommitteeValidatorIndices(
|
|
81
80
|
syncCommittee: CompositeViewDU<typeof ssz.altair.SyncCommittee>,
|
|
82
|
-
|
|
81
|
+
pubkeyCache: {getIndex(pubkey: Uint8Array): number | null}
|
|
83
82
|
): Uint32Array {
|
|
84
83
|
const pubkeys = syncCommittee.pubkeys.getAllReadonly();
|
|
85
84
|
const validatorIndices = new Uint32Array(pubkeys.length);
|
|
86
85
|
for (const [i, pubkey] of pubkeys.entries()) {
|
|
87
|
-
const validatorIndex =
|
|
86
|
+
const validatorIndex = pubkeyCache.getIndex(pubkey);
|
|
88
87
|
if (validatorIndex === null) {
|
|
89
88
|
throw Error(`SyncCommittee pubkey is unknown ${toPubkeyHex(pubkey)}`);
|
|
90
89
|
}
|
package/src/index.ts
CHANGED
|
@@ -25,7 +25,7 @@ export {
|
|
|
25
25
|
createEmptyEpochCacheImmutableData,
|
|
26
26
|
} from "./cache/epochCache.js";
|
|
27
27
|
export {type EpochTransitionCache, beforeProcessEpoch} from "./cache/epochTransitionCache.js";
|
|
28
|
-
export {type
|
|
28
|
+
export {type PubkeyCache, createPubkeyCache, syncPubkeys} from "./cache/pubkeyCache.js";
|
|
29
29
|
// Main state caches
|
|
30
30
|
export {
|
|
31
31
|
type BeaconStateCache,
|
|
@@ -35,12 +35,14 @@ export {
|
|
|
35
35
|
isStateValidatorsNodesPopulated,
|
|
36
36
|
loadCachedBeaconState,
|
|
37
37
|
} from "./cache/stateCache.js";
|
|
38
|
+
export {type SyncCommitteeCache} from "./cache/syncCommitteeCache.js";
|
|
38
39
|
export * from "./constants/index.js";
|
|
39
40
|
export type {EpochTransitionStep} from "./epoch/index.js";
|
|
40
41
|
export {type BeaconStateTransitionMetrics, getMetrics} from "./metrics.js";
|
|
41
42
|
export * from "./rewards/index.js";
|
|
42
43
|
export * from "./signatureSets/index.js";
|
|
43
44
|
export * from "./stateTransition.js";
|
|
45
|
+
export * from "./stateView/index.js";
|
|
44
46
|
export type {
|
|
45
47
|
BeaconStateAllForks,
|
|
46
48
|
BeaconStateAltair,
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import {Tree} from "@chainsafe/persistent-merkle-tree";
|
|
2
|
+
import {
|
|
3
|
+
BLOCK_BODY_EXECUTION_PAYLOAD_GINDEX,
|
|
4
|
+
FINALIZED_ROOT_GINDEX,
|
|
5
|
+
FINALIZED_ROOT_GINDEX_ELECTRA,
|
|
6
|
+
ForkName,
|
|
7
|
+
ForkPostBellatrix,
|
|
8
|
+
isForkPostElectra,
|
|
9
|
+
} from "@lodestar/params";
|
|
10
|
+
import {BeaconBlockBody, SSZTypesFor, ssz} from "@lodestar/types";
|
|
11
|
+
import {BeaconStateAllForks, CachedBeaconStateAllForks} from "../types.js";
|
|
12
|
+
import {SyncCommitteeWitness} from "./types.js";
|
|
13
|
+
|
|
14
|
+
export function getSyncCommitteesWitness(fork: ForkName, state: BeaconStateAllForks): SyncCommitteeWitness {
|
|
15
|
+
const n1 = state.node;
|
|
16
|
+
let witness: Uint8Array[];
|
|
17
|
+
let currentSyncCommitteeRoot: Uint8Array;
|
|
18
|
+
let nextSyncCommitteeRoot: Uint8Array;
|
|
19
|
+
|
|
20
|
+
if (isForkPostElectra(fork)) {
|
|
21
|
+
const n2 = n1.left;
|
|
22
|
+
const n5 = n2.right;
|
|
23
|
+
const n10 = n5.left;
|
|
24
|
+
const n21 = n10.right;
|
|
25
|
+
const n43 = n21.right;
|
|
26
|
+
|
|
27
|
+
currentSyncCommitteeRoot = n43.left.root; // n86
|
|
28
|
+
nextSyncCommitteeRoot = n43.right.root; // n87
|
|
29
|
+
|
|
30
|
+
// Witness branch is sorted by descending gindex
|
|
31
|
+
witness = [
|
|
32
|
+
n21.left.root, // 42
|
|
33
|
+
n10.left.root, // 20
|
|
34
|
+
n5.right.root, // 11
|
|
35
|
+
n2.left.root, // 4
|
|
36
|
+
n1.right.root, // 3
|
|
37
|
+
];
|
|
38
|
+
} else {
|
|
39
|
+
const n3 = n1.right; // [1]0110
|
|
40
|
+
const n6 = n3.left; // 1[0]110
|
|
41
|
+
const n13 = n6.right; // 10[1]10
|
|
42
|
+
const n27 = n13.right; // 101[1]0
|
|
43
|
+
currentSyncCommitteeRoot = n27.left.root; // n54 1011[0]
|
|
44
|
+
nextSyncCommitteeRoot = n27.right.root; // n55 1011[1]
|
|
45
|
+
|
|
46
|
+
// Witness branch is sorted by descending gindex
|
|
47
|
+
witness = [
|
|
48
|
+
n13.left.root, // 26
|
|
49
|
+
n6.left.root, // 12
|
|
50
|
+
n3.right.root, // 7
|
|
51
|
+
n1.left.root, // 2
|
|
52
|
+
];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
witness,
|
|
57
|
+
currentSyncCommitteeRoot,
|
|
58
|
+
nextSyncCommitteeRoot,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function getNextSyncCommitteeBranch(syncCommitteesWitness: SyncCommitteeWitness): Uint8Array[] {
|
|
63
|
+
// Witness branch is sorted by descending gindex
|
|
64
|
+
return [syncCommitteesWitness.currentSyncCommitteeRoot, ...syncCommitteesWitness.witness];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function getCurrentSyncCommitteeBranch(syncCommitteesWitness: SyncCommitteeWitness): Uint8Array[] {
|
|
68
|
+
// Witness branch is sorted by descending gindex
|
|
69
|
+
return [syncCommitteesWitness.nextSyncCommitteeRoot, ...syncCommitteesWitness.witness];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function getFinalizedRootProof(state: CachedBeaconStateAllForks): Uint8Array[] {
|
|
73
|
+
const finalizedRootGindex = state.epochCtx.isPostElectra() ? FINALIZED_ROOT_GINDEX_ELECTRA : FINALIZED_ROOT_GINDEX;
|
|
74
|
+
return new Tree(state.node).getSingleProof(BigInt(finalizedRootGindex));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function getBlockBodyExecutionHeaderProof(
|
|
78
|
+
fork: ForkPostBellatrix,
|
|
79
|
+
body: BeaconBlockBody<ForkPostBellatrix>
|
|
80
|
+
): Uint8Array[] {
|
|
81
|
+
const bodyView = (ssz[fork].BeaconBlockBody as SSZTypesFor<ForkPostBellatrix, "BeaconBlockBody">).toView(body);
|
|
82
|
+
return new Tree(bodyView.node).getSingleProof(BigInt(BLOCK_BODY_EXECUTION_PAYLOAD_GINDEX));
|
|
83
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* We aren't creating the sync committee proofs separately because our ssz library automatically adds leaves to composite types,
|
|
3
|
+
* so they're already included in the state proof, currently with no way to specify otherwise
|
|
4
|
+
*
|
|
5
|
+
* remove two offsets so the # of offsets in the state proof will be the # expected
|
|
6
|
+
* This is a hack, but properly setting the offsets in the state proof would require either removing witnesses needed for the committees
|
|
7
|
+
* or setting the roots of the committees in the state proof
|
|
8
|
+
* this will always be 1, syncProofLeavesLength
|
|
9
|
+
*
|
|
10
|
+
*
|
|
11
|
+
* With empty state (minimal)
|
|
12
|
+
* - `genesisTime = 0xffffffff`
|
|
13
|
+
* - `genesisValidatorsRoot = Buffer.alloc(32, 1)`
|
|
14
|
+
*
|
|
15
|
+
* Proof:
|
|
16
|
+
* ```
|
|
17
|
+
* offsets: [ 5, 4, 3, 2, 1 ]
|
|
18
|
+
* leaves: [
|
|
19
|
+
* '0xffffffff00000000000000000000000000000000000000000000000000000000',
|
|
20
|
+
* '0x0101010101010101010101010101010101010101010101010101010101010101',
|
|
21
|
+
* '0xb11b8bcf59425d6c99019cca1d2c2e47b51a2f74917a67ad132274f43e13ec43',
|
|
22
|
+
* '0x74bd1f2437cdf74b0904ee525d8da070a3fa27570942bf42cbab3dc5939600f0',
|
|
23
|
+
* '0x7f06739e5a42360c56e519a511675901c95402ea9877edc0d9a87471b1374a6a',
|
|
24
|
+
* '0x9f534204ba3c0b69fcb42a11987bfcbc5aea0463e5b0614312ded4b62cf3a380'
|
|
25
|
+
* ]
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export type SyncCommitteeWitness = {
|
|
29
|
+
/** Vector[Bytes32, 4] or Vector[Bytes32, 5] depending on the fork */
|
|
30
|
+
witness: Uint8Array[];
|
|
31
|
+
currentSyncCommitteeRoot: Uint8Array;
|
|
32
|
+
nextSyncCommitteeRoot: Uint8Array;
|
|
33
|
+
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import {PubkeyIndexMap} from "@chainsafe/pubkey-index-map";
|
|
2
1
|
import {BeaconConfig} from "@lodestar/config";
|
|
3
2
|
import {
|
|
4
3
|
EFFECTIVE_BALANCE_INCREMENT,
|
|
@@ -16,6 +15,7 @@ import {
|
|
|
16
15
|
import {ValidatorIndex, rewards} from "@lodestar/types";
|
|
17
16
|
import {fromHex} from "@lodestar/utils";
|
|
18
17
|
import {EpochTransitionCache, beforeProcessEpoch} from "../cache/epochTransitionCache.js";
|
|
18
|
+
import {PubkeyCache} from "../cache/pubkeyCache.js";
|
|
19
19
|
import {CachedBeaconStateAllForks, CachedBeaconStateAltair} from "../types.js";
|
|
20
20
|
import {
|
|
21
21
|
FLAG_ELIGIBLE_ATTESTER,
|
|
@@ -34,7 +34,7 @@ const defaultAttestationsPenalty = {target: 0, source: 0};
|
|
|
34
34
|
|
|
35
35
|
export async function computeAttestationsRewards(
|
|
36
36
|
config: BeaconConfig,
|
|
37
|
-
|
|
37
|
+
pubkeyCache: PubkeyCache,
|
|
38
38
|
state: CachedBeaconStateAllForks,
|
|
39
39
|
validatorIds?: (ValidatorIndex | string)[]
|
|
40
40
|
): Promise<rewards.AttestationsRewards> {
|
|
@@ -53,7 +53,7 @@ export async function computeAttestationsRewards(
|
|
|
53
53
|
);
|
|
54
54
|
const totalRewards = computeTotalAttestationsRewardsAltair(
|
|
55
55
|
config,
|
|
56
|
-
|
|
56
|
+
pubkeyCache,
|
|
57
57
|
stateAltair,
|
|
58
58
|
transitionCache,
|
|
59
59
|
idealRewards,
|
|
@@ -142,7 +142,7 @@ function computeIdealAttestationsRewardsAndPenaltiesAltair(
|
|
|
142
142
|
// Same calculation as `getRewardsAndPenaltiesAltair` but returns the breakdown of rewards instead of aggregated
|
|
143
143
|
function computeTotalAttestationsRewardsAltair(
|
|
144
144
|
config: BeaconConfig,
|
|
145
|
-
|
|
145
|
+
pubkeyCache: PubkeyCache,
|
|
146
146
|
state: CachedBeaconStateAltair,
|
|
147
147
|
transitionCache: EpochTransitionCache,
|
|
148
148
|
idealRewards: rewards.IdealAttestationsReward[],
|
|
@@ -153,7 +153,7 @@ function computeTotalAttestationsRewardsAltair(
|
|
|
153
153
|
const {flags} = transitionCache;
|
|
154
154
|
const {epochCtx} = state;
|
|
155
155
|
const validatorIndices = validatorIds
|
|
156
|
-
.map((id) => (typeof id === "number" ? id :
|
|
156
|
+
.map((id) => (typeof id === "number" ? id : pubkeyCache.getIndex(fromHex(id))))
|
|
157
157
|
.filter((index) => index !== undefined); // Validator indices to include in the result
|
|
158
158
|
|
|
159
159
|
const inactivityPenaltyDenominator = config.INACTIVITY_SCORE_BIAS * INACTIVITY_PENALTY_QUOTIENT_ALTAIR;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {BeaconConfig} from "@lodestar/config";
|
|
2
2
|
import {ForkName, SYNC_COMMITTEE_SIZE} from "@lodestar/params";
|
|
3
3
|
import {BeaconBlock, ValidatorIndex, altair, rewards} from "@lodestar/types";
|
|
4
|
-
import {
|
|
4
|
+
import {PubkeyCache} from "../cache/pubkeyCache.js";
|
|
5
5
|
import {CachedBeaconStateAllForks, CachedBeaconStateAltair} from "../cache/stateCache.js";
|
|
6
6
|
|
|
7
7
|
export async function computeSyncCommitteeRewards(
|
|
8
8
|
config: BeaconConfig,
|
|
9
|
-
|
|
9
|
+
pubkeyCache: PubkeyCache,
|
|
10
10
|
block: BeaconBlock,
|
|
11
11
|
preState: CachedBeaconStateAllForks,
|
|
12
12
|
validatorIds: (ValidatorIndex | string)[] = []
|
|
@@ -47,9 +47,10 @@ export async function computeSyncCommitteeRewards(
|
|
|
47
47
|
|
|
48
48
|
if (validatorIds.length) {
|
|
49
49
|
const filtersSet = new Set(validatorIds);
|
|
50
|
-
return rewards.filter(
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
return rewards.filter((reward) => {
|
|
51
|
+
const pubkeyHex = pubkeyCache.get(reward.validatorIndex)?.toHex();
|
|
52
|
+
return filtersSet.has(reward.validatorIndex) || (pubkeyHex !== undefined && filtersSet.has(pubkeyHex));
|
|
53
|
+
});
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
return rewards;
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {BeaconConfig} from "@lodestar/config";
|
|
2
2
|
import {DOMAIN_BEACON_PROPOSER} from "@lodestar/params";
|
|
3
3
|
import {SignedBeaconBlock, SignedBlindedBeaconBlock, Slot, isBlindedBeaconBlock, phase0, ssz} from "@lodestar/types";
|
|
4
|
-
import {
|
|
4
|
+
import {PubkeyCache} from "../cache/pubkeyCache.js";
|
|
5
5
|
import {computeSigningRoot} from "../util/index.js";
|
|
6
6
|
import {ISignatureSet, SignatureSetType, verifySignatureSet} from "../util/signatureSets.js";
|
|
7
7
|
|
|
8
8
|
export function verifyProposerSignature(
|
|
9
9
|
config: BeaconConfig,
|
|
10
|
-
|
|
10
|
+
pubkeyCache: PubkeyCache,
|
|
11
11
|
signedBlock: SignedBeaconBlock | SignedBlindedBeaconBlock
|
|
12
12
|
): boolean {
|
|
13
13
|
const signatureSet = getBlockProposerSignatureSet(config, signedBlock);
|
|
14
|
-
return verifySignatureSet(signatureSet,
|
|
14
|
+
return verifySignatureSet(signatureSet, pubkeyCache);
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export function getBlockProposerSignatureSet(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {BeaconConfig} from "@lodestar/config";
|
|
2
2
|
import {DOMAIN_RANDAO} from "@lodestar/params";
|
|
3
3
|
import {BeaconBlock, ssz} from "@lodestar/types";
|
|
4
|
-
import {
|
|
4
|
+
import {PubkeyCache} from "../cache/pubkeyCache.js";
|
|
5
5
|
import {
|
|
6
6
|
ISignatureSet,
|
|
7
7
|
SignatureSetType,
|
|
@@ -10,12 +10,8 @@ import {
|
|
|
10
10
|
verifySignatureSet,
|
|
11
11
|
} from "../util/index.js";
|
|
12
12
|
|
|
13
|
-
export function verifyRandaoSignature(
|
|
14
|
-
config
|
|
15
|
-
index2pubkey: Index2PubkeyCache,
|
|
16
|
-
block: BeaconBlock
|
|
17
|
-
): boolean {
|
|
18
|
-
return verifySignatureSet(getRandaoRevealSignatureSet(config, block), index2pubkey);
|
|
13
|
+
export function verifyRandaoSignature(config: BeaconConfig, pubkeyCache: PubkeyCache, block: BeaconBlock): boolean {
|
|
14
|
+
return verifySignatureSet(getRandaoRevealSignatureSet(config, block), pubkeyCache);
|
|
19
15
|
}
|
|
20
16
|
|
|
21
17
|
/**
|