@lodestar/state-transition 1.35.0-dev.98d359db41 → 1.35.0-dev.a70bac5bd3
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/block/index.d.ts +2 -2
- package/lib/block/index.js +2 -2
- package/lib/block/index.js.map +1 -1
- package/lib/block/processAttestationPhase0.js +2 -1
- package/lib/block/processAttestationPhase0.js.map +1 -1
- package/lib/block/processAttestationsAltair.d.ts +1 -1
- package/lib/block/processAttestationsAltair.js +1 -1
- package/lib/block/processAttestationsAltair.js.map +1 -1
- package/lib/block/processAttesterSlashing.js.map +1 -1
- package/lib/block/processBlsToExecutionChange.js.map +1 -1
- package/lib/block/processConsolidationRequest.js.map +1 -1
- package/lib/block/processDeposit.d.ts +2 -2
- package/lib/block/processDeposit.js +1 -1
- package/lib/block/processDeposit.js.map +1 -1
- package/lib/block/processDepositRequest.js.map +1 -1
- package/lib/block/processOperations.js.map +1 -1
- package/lib/block/processSyncCommittee.js +2 -1
- package/lib/block/processSyncCommittee.js.map +1 -1
- package/lib/block/processWithdrawalRequest.js.map +1 -1
- package/lib/block/processWithdrawals.js.map +1 -1
- package/lib/block/slashValidator.js.map +1 -1
- package/lib/cache/epochCache.js +0 -130
- package/lib/cache/epochCache.js.map +1 -1
- package/lib/cache/epochTransitionCache.js.map +1 -1
- package/lib/epoch/index.js.map +1 -1
- package/lib/epoch/processSlashings.js.map +1 -1
- package/lib/index.d.ts +17 -17
- package/lib/index.js +16 -16
- package/lib/index.js.map +1 -1
- package/lib/signatureSets/blsToExecutionChange.js.map +1 -1
- package/lib/signatureSets/index.d.ts +1 -1
- package/lib/signatureSets/index.js +1 -1
- package/lib/signatureSets/index.js.map +1 -1
- package/lib/slot/upgradeStateToDeneb.d.ts +2 -1
- package/lib/slot/upgradeStateToDeneb.js.map +1 -1
- package/lib/slot/upgradeStateToGloas.js +2 -2
- package/lib/slot/upgradeStateToGloas.js.map +1 -1
- package/lib/types.d.ts +2 -2
- package/lib/util/blindedBlock.js.map +1 -1
- package/lib/util/execution.js.map +1 -1
- package/lib/util/genesis.js +4 -4
- package/lib/util/genesis.js.map +1 -1
- package/lib/util/index.d.ts +5 -5
- package/lib/util/index.js +5 -5
- package/lib/util/index.js.map +1 -1
- package/lib/util/interop.js +1 -1
- package/lib/util/interop.js.map +1 -1
- package/lib/util/rootCache.js +2 -5
- package/lib/util/rootCache.js.map +1 -1
- package/lib/util/seed.js +2 -1
- package/lib/util/seed.js.map +1 -1
- package/lib/util/weakSubjectivity.js.map +1 -1
- package/package.json +11 -13
- package/lib/block/externalData.d.ts.map +0 -1
- package/lib/block/index.d.ts.map +0 -1
- package/lib/block/initiateValidatorExit.d.ts.map +0 -1
- package/lib/block/isValidIndexedAttestation.d.ts.map +0 -1
- package/lib/block/processAttestationPhase0.d.ts.map +0 -1
- package/lib/block/processAttestations.d.ts.map +0 -1
- package/lib/block/processAttestationsAltair.d.ts.map +0 -1
- package/lib/block/processAttesterSlashing.d.ts.map +0 -1
- package/lib/block/processBlobKzgCommitments.d.ts.map +0 -1
- package/lib/block/processBlockHeader.d.ts.map +0 -1
- package/lib/block/processBlsToExecutionChange.d.ts.map +0 -1
- package/lib/block/processConsolidationRequest.d.ts.map +0 -1
- package/lib/block/processDeposit.d.ts.map +0 -1
- package/lib/block/processDepositRequest.d.ts.map +0 -1
- package/lib/block/processEth1Data.d.ts.map +0 -1
- package/lib/block/processExecutionPayload.d.ts.map +0 -1
- package/lib/block/processOperations.d.ts.map +0 -1
- package/lib/block/processProposerSlashing.d.ts.map +0 -1
- package/lib/block/processRandao.d.ts.map +0 -1
- package/lib/block/processSyncCommittee.d.ts.map +0 -1
- package/lib/block/processVoluntaryExit.d.ts.map +0 -1
- package/lib/block/processWithdrawalRequest.d.ts.map +0 -1
- package/lib/block/processWithdrawals.d.ts.map +0 -1
- package/lib/block/slashValidator.d.ts.map +0 -1
- package/lib/block/types.d.ts.map +0 -1
- package/lib/cache/effectiveBalanceIncrements.d.ts.map +0 -1
- package/lib/cache/epochCache.d.ts.map +0 -1
- package/lib/cache/epochTransitionCache.d.ts.map +0 -1
- package/lib/cache/pubkeyCache.d.ts.map +0 -1
- package/lib/cache/rewardCache.d.ts.map +0 -1
- package/lib/cache/stateCache.d.ts.map +0 -1
- package/lib/cache/syncCommitteeCache.d.ts.map +0 -1
- package/lib/cache/types.d.ts.map +0 -1
- package/lib/constants/constants.d.ts.map +0 -1
- package/lib/constants/index.d.ts.map +0 -1
- package/lib/epoch/computeUnrealizedCheckpoints.d.ts.map +0 -1
- package/lib/epoch/getAttestationDeltas.d.ts.map +0 -1
- package/lib/epoch/getRewardsAndPenalties.d.ts.map +0 -1
- package/lib/epoch/index.d.ts.map +0 -1
- package/lib/epoch/processEffectiveBalanceUpdates.d.ts.map +0 -1
- package/lib/epoch/processEth1DataReset.d.ts.map +0 -1
- package/lib/epoch/processHistoricalRootsUpdate.d.ts.map +0 -1
- package/lib/epoch/processHistoricalSummariesUpdate.d.ts.map +0 -1
- package/lib/epoch/processInactivityUpdates.d.ts.map +0 -1
- package/lib/epoch/processJustificationAndFinalization.d.ts.map +0 -1
- package/lib/epoch/processParticipationFlagUpdates.d.ts.map +0 -1
- package/lib/epoch/processParticipationRecordUpdates.d.ts.map +0 -1
- package/lib/epoch/processPendingAttestations.d.ts.map +0 -1
- package/lib/epoch/processPendingConsolidations.d.ts.map +0 -1
- package/lib/epoch/processPendingDeposits.d.ts.map +0 -1
- package/lib/epoch/processProposerLookahead.d.ts.map +0 -1
- package/lib/epoch/processRandaoMixesReset.d.ts.map +0 -1
- package/lib/epoch/processRegistryUpdates.d.ts.map +0 -1
- package/lib/epoch/processRewardsAndPenalties.d.ts.map +0 -1
- package/lib/epoch/processSlashings.d.ts.map +0 -1
- package/lib/epoch/processSlashingsReset.d.ts.map +0 -1
- package/lib/epoch/processSyncCommitteeUpdates.d.ts.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/metrics.d.ts.map +0 -1
- package/lib/signatureSets/attesterSlashings.d.ts.map +0 -1
- package/lib/signatureSets/blsToExecutionChange.d.ts.map +0 -1
- package/lib/signatureSets/index.d.ts.map +0 -1
- package/lib/signatureSets/indexedAttestation.d.ts.map +0 -1
- package/lib/signatureSets/proposer.d.ts.map +0 -1
- package/lib/signatureSets/proposerSlashings.d.ts.map +0 -1
- package/lib/signatureSets/randao.d.ts.map +0 -1
- package/lib/signatureSets/voluntaryExits.d.ts.map +0 -1
- package/lib/slot/index.d.ts.map +0 -1
- package/lib/slot/upgradeStateToAltair.d.ts.map +0 -1
- package/lib/slot/upgradeStateToBellatrix.d.ts.map +0 -1
- package/lib/slot/upgradeStateToCapella.d.ts.map +0 -1
- package/lib/slot/upgradeStateToDeneb.d.ts.map +0 -1
- package/lib/slot/upgradeStateToElectra.d.ts.map +0 -1
- package/lib/slot/upgradeStateToFulu.d.ts.map +0 -1
- package/lib/slot/upgradeStateToGloas.d.ts.map +0 -1
- package/lib/stateTransition.d.ts.map +0 -1
- package/lib/types.d.ts.map +0 -1
- package/lib/util/aggregator.d.ts.map +0 -1
- package/lib/util/altair.d.ts.map +0 -1
- package/lib/util/array.d.ts.map +0 -1
- package/lib/util/attestation.d.ts.map +0 -1
- package/lib/util/attesterStatus.d.ts.map +0 -1
- package/lib/util/balance.d.ts.map +0 -1
- package/lib/util/blindedBlock.d.ts.map +0 -1
- package/lib/util/blockRoot.d.ts.map +0 -1
- package/lib/util/calculateCommitteeAssignments.d.ts.map +0 -1
- package/lib/util/capella.d.ts.map +0 -1
- package/lib/util/computeAnchorCheckpoint.d.ts.map +0 -1
- package/lib/util/deposit.d.ts.map +0 -1
- package/lib/util/domain.d.ts.map +0 -1
- package/lib/util/electra.d.ts.map +0 -1
- package/lib/util/epoch.d.ts.map +0 -1
- package/lib/util/epochShuffling.d.ts.map +0 -1
- package/lib/util/execution.d.ts.map +0 -1
- package/lib/util/finality.d.ts.map +0 -1
- package/lib/util/fulu.d.ts.map +0 -1
- package/lib/util/genesis.d.ts.map +0 -1
- package/lib/util/index.d.ts.map +0 -1
- package/lib/util/interop.d.ts.map +0 -1
- package/lib/util/loadState/findModifiedInactivityScores.d.ts.map +0 -1
- package/lib/util/loadState/findModifiedValidators.d.ts.map +0 -1
- package/lib/util/loadState/index.d.ts.map +0 -1
- package/lib/util/loadState/loadState.d.ts.map +0 -1
- package/lib/util/loadState/loadValidator.d.ts.map +0 -1
- package/lib/util/rootCache.d.ts.map +0 -1
- package/lib/util/seed.d.ts.map +0 -1
- package/lib/util/shufflingDecisionRoot.d.ts.map +0 -1
- package/lib/util/signatureSets.d.ts.map +0 -1
- package/lib/util/signingRoot.d.ts.map +0 -1
- package/lib/util/slot.d.ts.map +0 -1
- package/lib/util/sszBytes.d.ts.map +0 -1
- package/lib/util/syncCommittee.d.ts.map +0 -1
- package/lib/util/targetUnslashedBalance.d.ts.map +0 -1
- package/lib/util/validator.d.ts.map +0 -1
- package/lib/util/weakSubjectivity.d.ts.map +0 -1
- package/src/block/externalData.ts +0 -26
- package/src/block/index.ts +0 -81
- package/src/block/initiateValidatorExit.ts +0 -62
- package/src/block/isValidIndexedAttestation.ts +0 -70
- package/src/block/processAttestationPhase0.ts +0 -158
- package/src/block/processAttestations.ts +0 -25
- package/src/block/processAttestationsAltair.ts +0 -184
- package/src/block/processAttesterSlashing.ts +0 -59
- package/src/block/processBlobKzgCommitments.ts +0 -21
- package/src/block/processBlockHeader.ts +0 -54
- package/src/block/processBlsToExecutionChange.ts +0 -78
- package/src/block/processConsolidationRequest.ts +0 -147
- package/src/block/processDeposit.ts +0 -166
- package/src/block/processDepositRequest.ts +0 -19
- package/src/block/processEth1Data.ts +0 -86
- package/src/block/processExecutionPayload.ts +0 -84
- package/src/block/processOperations.ts +0 -83
- package/src/block/processProposerSlashing.ts +0 -66
- package/src/block/processRandao.ts +0 -27
- package/src/block/processSyncCommittee.ts +0 -117
- package/src/block/processVoluntaryExit.ts +0 -55
- package/src/block/processWithdrawalRequest.ts +0 -98
- package/src/block/processWithdrawals.ts +0 -207
- package/src/block/slashValidator.ts +0 -98
- package/src/block/types.ts +0 -9
- package/src/cache/effectiveBalanceIncrements.ts +0 -39
- package/src/cache/epochCache.ts +0 -1213
- package/src/cache/epochTransitionCache.ts +0 -542
- package/src/cache/pubkeyCache.ts +0 -33
- package/src/cache/rewardCache.ts +0 -19
- package/src/cache/stateCache.ts +0 -268
- package/src/cache/syncCommitteeCache.ts +0 -96
- package/src/cache/types.ts +0 -18
- package/src/constants/constants.ts +0 -12
- package/src/constants/index.ts +0 -1
- package/src/epoch/computeUnrealizedCheckpoints.ts +0 -55
- package/src/epoch/getAttestationDeltas.ts +0 -169
- package/src/epoch/getRewardsAndPenalties.ts +0 -137
- package/src/epoch/index.ts +0 -202
- package/src/epoch/processEffectiveBalanceUpdates.ts +0 -111
- package/src/epoch/processEth1DataReset.ts +0 -17
- package/src/epoch/processHistoricalRootsUpdate.ts +0 -25
- package/src/epoch/processHistoricalSummariesUpdate.ts +0 -23
- package/src/epoch/processInactivityUpdates.ts +0 -60
- package/src/epoch/processJustificationAndFinalization.ts +0 -90
- package/src/epoch/processParticipationFlagUpdates.ts +0 -27
- package/src/epoch/processParticipationRecordUpdates.ts +0 -14
- package/src/epoch/processPendingAttestations.ts +0 -75
- package/src/epoch/processPendingConsolidations.ts +0 -59
- package/src/epoch/processPendingDeposits.ts +0 -136
- package/src/epoch/processProposerLookahead.ts +0 -39
- package/src/epoch/processRandaoMixesReset.ts +0 -18
- package/src/epoch/processRegistryUpdates.ts +0 -65
- package/src/epoch/processRewardsAndPenalties.ts +0 -58
- package/src/epoch/processSlashings.ts +0 -97
- package/src/epoch/processSlashingsReset.ts +0 -20
- package/src/epoch/processSyncCommitteeUpdates.ts +0 -44
- package/src/index.ts +0 -67
- package/src/metrics.ts +0 -169
- package/src/signatureSets/attesterSlashings.ts +0 -39
- package/src/signatureSets/blsToExecutionChange.ts +0 -43
- package/src/signatureSets/index.ts +0 -73
- package/src/signatureSets/indexedAttestation.ts +0 -51
- package/src/signatureSets/proposer.ts +0 -47
- package/src/signatureSets/proposerSlashings.ts +0 -41
- package/src/signatureSets/randao.ts +0 -31
- package/src/signatureSets/voluntaryExits.ts +0 -44
- package/src/slot/index.ts +0 -32
- package/src/slot/upgradeStateToAltair.ts +0 -149
- package/src/slot/upgradeStateToBellatrix.ts +0 -63
- package/src/slot/upgradeStateToCapella.ts +0 -71
- package/src/slot/upgradeStateToDeneb.ts +0 -40
- package/src/slot/upgradeStateToElectra.ts +0 -126
- package/src/slot/upgradeStateToFulu.ts +0 -31
- package/src/slot/upgradeStateToGloas.ts +0 -29
- package/src/stateTransition.ts +0 -305
- package/src/types.ts +0 -26
- package/src/util/aggregator.ts +0 -33
- package/src/util/altair.ts +0 -13
- package/src/util/array.ts +0 -53
- package/src/util/attestation.ts +0 -36
- package/src/util/attesterStatus.ts +0 -83
- package/src/util/balance.ts +0 -83
- package/src/util/blindedBlock.ts +0 -144
- package/src/util/blockRoot.ts +0 -72
- package/src/util/calculateCommitteeAssignments.ts +0 -43
- package/src/util/capella.ts +0 -8
- package/src/util/computeAnchorCheckpoint.ts +0 -38
- package/src/util/deposit.ts +0 -22
- package/src/util/domain.ts +0 -31
- package/src/util/electra.ts +0 -68
- package/src/util/epoch.ts +0 -135
- package/src/util/epochShuffling.ts +0 -185
- package/src/util/execution.ts +0 -177
- package/src/util/finality.ts +0 -17
- package/src/util/fulu.ts +0 -43
- package/src/util/genesis.ts +0 -343
- package/src/util/index.ts +0 -29
- package/src/util/interop.ts +0 -22
- package/src/util/loadState/findModifiedInactivityScores.ts +0 -47
- package/src/util/loadState/findModifiedValidators.ts +0 -46
- package/src/util/loadState/index.ts +0 -2
- package/src/util/loadState/loadState.ts +0 -225
- package/src/util/loadState/loadValidator.ts +0 -77
- package/src/util/rootCache.ts +0 -37
- package/src/util/seed.ts +0 -381
- package/src/util/shufflingDecisionRoot.ts +0 -78
- package/src/util/signatureSets.ts +0 -65
- package/src/util/signingRoot.ts +0 -13
- package/src/util/slot.ts +0 -27
- package/src/util/sszBytes.ts +0 -52
- package/src/util/syncCommittee.ts +0 -69
- package/src/util/targetUnslashedBalance.ts +0 -30
- package/src/util/validator.ts +0 -105
- package/src/util/weakSubjectivity.ts +0 -186
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
EFFECTIVE_BALANCE_INCREMENT,
|
|
3
|
-
ForkSeq,
|
|
4
|
-
INACTIVITY_PENALTY_QUOTIENT_ALTAIR,
|
|
5
|
-
INACTIVITY_PENALTY_QUOTIENT_BELLATRIX,
|
|
6
|
-
PARTICIPATION_FLAG_WEIGHTS,
|
|
7
|
-
TIMELY_HEAD_FLAG_INDEX,
|
|
8
|
-
TIMELY_SOURCE_FLAG_INDEX,
|
|
9
|
-
TIMELY_TARGET_FLAG_INDEX,
|
|
10
|
-
WEIGHT_DENOMINATOR,
|
|
11
|
-
} from "@lodestar/params";
|
|
12
|
-
import {CachedBeaconStateAltair, EpochTransitionCache} from "../types.js";
|
|
13
|
-
import {
|
|
14
|
-
FLAG_ELIGIBLE_ATTESTER,
|
|
15
|
-
FLAG_PREV_HEAD_ATTESTER_UNSLASHED,
|
|
16
|
-
FLAG_PREV_SOURCE_ATTESTER_UNSLASHED,
|
|
17
|
-
FLAG_PREV_TARGET_ATTESTER_UNSLASHED,
|
|
18
|
-
hasMarkers,
|
|
19
|
-
} from "../util/attesterStatus.js";
|
|
20
|
-
import {isInInactivityLeak} from "../util/index.js";
|
|
21
|
-
|
|
22
|
-
type RewardPenaltyItem = {
|
|
23
|
-
baseReward: number;
|
|
24
|
-
timelySourceReward: number;
|
|
25
|
-
timelySourcePenalty: number;
|
|
26
|
-
timelyTargetReward: number;
|
|
27
|
-
timelyTargetPenalty: number;
|
|
28
|
-
timelyHeadReward: number;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* This data is reused and never gc.
|
|
33
|
-
*/
|
|
34
|
-
const rewards = new Array<number>();
|
|
35
|
-
const penalties = new Array<number>();
|
|
36
|
-
/**
|
|
37
|
-
* An aggregate of getFlagIndexDeltas and getInactivityPenaltyDeltas that loop through process.flags 1 time instead of 4.
|
|
38
|
-
*
|
|
39
|
-
* - On normal mainnet conditions
|
|
40
|
-
* - prevSourceAttester: 98%
|
|
41
|
-
* - prevTargetAttester: 96%
|
|
42
|
-
* - prevHeadAttester: 93%
|
|
43
|
-
* - currSourceAttester: 95%
|
|
44
|
-
* - currTargetAttester: 93%
|
|
45
|
-
* - currHeadAttester: 91%
|
|
46
|
-
* - unslashed: 100%
|
|
47
|
-
* - eligibleAttester: 98%
|
|
48
|
-
*/
|
|
49
|
-
export function getRewardsAndPenaltiesAltair(
|
|
50
|
-
state: CachedBeaconStateAltair,
|
|
51
|
-
cache: EpochTransitionCache
|
|
52
|
-
): [number[], number[]] {
|
|
53
|
-
// TODO: Is there a cheaper way to measure length that going to `state.validators`?
|
|
54
|
-
const validatorCount = state.validators.length;
|
|
55
|
-
const activeIncrements = cache.totalActiveStakeByIncrement;
|
|
56
|
-
rewards.length = validatorCount;
|
|
57
|
-
rewards.fill(0);
|
|
58
|
-
penalties.length = validatorCount;
|
|
59
|
-
penalties.fill(0);
|
|
60
|
-
|
|
61
|
-
const isInInactivityLeakBn = isInInactivityLeak(state);
|
|
62
|
-
// effectiveBalance is multiple of EFFECTIVE_BALANCE_INCREMENT and less than MAX_EFFECTIVE_BALANCE
|
|
63
|
-
// so there are limited values of them like 32, 31, 30
|
|
64
|
-
const rewardPenaltyItemCache = new Map<number, RewardPenaltyItem>();
|
|
65
|
-
const {config, epochCtx} = state;
|
|
66
|
-
const fork = config.getForkSeq(state.slot);
|
|
67
|
-
|
|
68
|
-
const inactivityPenalityMultiplier =
|
|
69
|
-
fork === ForkSeq.altair ? INACTIVITY_PENALTY_QUOTIENT_ALTAIR : INACTIVITY_PENALTY_QUOTIENT_BELLATRIX;
|
|
70
|
-
const penaltyDenominator = config.INACTIVITY_SCORE_BIAS * inactivityPenalityMultiplier;
|
|
71
|
-
|
|
72
|
-
const {flags} = cache;
|
|
73
|
-
for (let i = 0; i < flags.length; i++) {
|
|
74
|
-
const flag = flags[i];
|
|
75
|
-
if (!hasMarkers(flag, FLAG_ELIGIBLE_ATTESTER)) {
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const effectiveBalanceIncrement = epochCtx.effectiveBalanceIncrements[i];
|
|
80
|
-
|
|
81
|
-
let rewardPenaltyItem = rewardPenaltyItemCache.get(effectiveBalanceIncrement);
|
|
82
|
-
if (!rewardPenaltyItem) {
|
|
83
|
-
const baseReward = effectiveBalanceIncrement * cache.baseRewardPerIncrement;
|
|
84
|
-
const tsWeigh = PARTICIPATION_FLAG_WEIGHTS[TIMELY_SOURCE_FLAG_INDEX];
|
|
85
|
-
const ttWeigh = PARTICIPATION_FLAG_WEIGHTS[TIMELY_TARGET_FLAG_INDEX];
|
|
86
|
-
const thWeigh = PARTICIPATION_FLAG_WEIGHTS[TIMELY_HEAD_FLAG_INDEX];
|
|
87
|
-
const tsUnslashedParticipatingIncrements = cache.prevEpochUnslashedStake.sourceStakeByIncrement;
|
|
88
|
-
const ttUnslashedParticipatingIncrements = cache.prevEpochUnslashedStake.targetStakeByIncrement;
|
|
89
|
-
const thUnslashedParticipatingIncrements = cache.prevEpochUnslashedStake.headStakeByIncrement;
|
|
90
|
-
const tsRewardNumerator = baseReward * tsWeigh * tsUnslashedParticipatingIncrements;
|
|
91
|
-
const ttRewardNumerator = baseReward * ttWeigh * ttUnslashedParticipatingIncrements;
|
|
92
|
-
const thRewardNumerator = baseReward * thWeigh * thUnslashedParticipatingIncrements;
|
|
93
|
-
rewardPenaltyItem = {
|
|
94
|
-
baseReward: baseReward,
|
|
95
|
-
timelySourceReward: Math.floor(tsRewardNumerator / (activeIncrements * WEIGHT_DENOMINATOR)),
|
|
96
|
-
timelyTargetReward: Math.floor(ttRewardNumerator / (activeIncrements * WEIGHT_DENOMINATOR)),
|
|
97
|
-
timelyHeadReward: Math.floor(thRewardNumerator / (activeIncrements * WEIGHT_DENOMINATOR)),
|
|
98
|
-
timelySourcePenalty: Math.floor((baseReward * tsWeigh) / WEIGHT_DENOMINATOR),
|
|
99
|
-
timelyTargetPenalty: Math.floor((baseReward * ttWeigh) / WEIGHT_DENOMINATOR),
|
|
100
|
-
};
|
|
101
|
-
rewardPenaltyItemCache.set(effectiveBalanceIncrement, rewardPenaltyItem);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const {timelySourceReward, timelySourcePenalty, timelyTargetReward, timelyTargetPenalty, timelyHeadReward} =
|
|
105
|
-
rewardPenaltyItem;
|
|
106
|
-
|
|
107
|
-
// same logic to getFlagIndexDeltas
|
|
108
|
-
if (hasMarkers(flag, FLAG_PREV_SOURCE_ATTESTER_UNSLASHED)) {
|
|
109
|
-
if (!isInInactivityLeakBn) {
|
|
110
|
-
rewards[i] += timelySourceReward;
|
|
111
|
-
}
|
|
112
|
-
} else {
|
|
113
|
-
penalties[i] += timelySourcePenalty;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (hasMarkers(flag, FLAG_PREV_TARGET_ATTESTER_UNSLASHED)) {
|
|
117
|
-
if (!isInInactivityLeakBn) {
|
|
118
|
-
rewards[i] += timelyTargetReward;
|
|
119
|
-
}
|
|
120
|
-
} else {
|
|
121
|
-
penalties[i] += timelyTargetPenalty;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (hasMarkers(flag, FLAG_PREV_HEAD_ATTESTER_UNSLASHED) && !isInInactivityLeakBn) {
|
|
125
|
-
rewards[i] += timelyHeadReward;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Same logic to getInactivityPenaltyDeltas
|
|
129
|
-
// TODO: if we have limited value in inactivityScores we can provide a cache too
|
|
130
|
-
if (!hasMarkers(flag, FLAG_PREV_TARGET_ATTESTER_UNSLASHED)) {
|
|
131
|
-
const penaltyNumerator = effectiveBalanceIncrement * EFFECTIVE_BALANCE_INCREMENT * state.inactivityScores.get(i);
|
|
132
|
-
penalties[i] += Math.floor(penaltyNumerator / penaltyDenominator);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return [rewards, penalties];
|
|
137
|
-
}
|
package/src/epoch/index.ts
DELETED
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ForkSeq,
|
|
3
|
-
MAX_ATTESTER_SLASHINGS,
|
|
4
|
-
MAX_EFFECTIVE_BALANCE,
|
|
5
|
-
MAX_VALIDATORS_PER_COMMITTEE,
|
|
6
|
-
SLOTS_PER_EPOCH,
|
|
7
|
-
} from "@lodestar/params";
|
|
8
|
-
import {BeaconStateTransitionMetrics} from "../metrics.js";
|
|
9
|
-
import {
|
|
10
|
-
CachedBeaconStateAllForks,
|
|
11
|
-
CachedBeaconStateAltair,
|
|
12
|
-
CachedBeaconStateCapella,
|
|
13
|
-
CachedBeaconStateElectra,
|
|
14
|
-
CachedBeaconStateFulu,
|
|
15
|
-
CachedBeaconStatePhase0,
|
|
16
|
-
EpochTransitionCache,
|
|
17
|
-
} from "../types.js";
|
|
18
|
-
import {processEffectiveBalanceUpdates} from "./processEffectiveBalanceUpdates.js";
|
|
19
|
-
import {processEth1DataReset} from "./processEth1DataReset.js";
|
|
20
|
-
import {processHistoricalRootsUpdate} from "./processHistoricalRootsUpdate.js";
|
|
21
|
-
import {processHistoricalSummariesUpdate} from "./processHistoricalSummariesUpdate.js";
|
|
22
|
-
import {processInactivityUpdates} from "./processInactivityUpdates.js";
|
|
23
|
-
import {processJustificationAndFinalization} from "./processJustificationAndFinalization.js";
|
|
24
|
-
import {processParticipationFlagUpdates} from "./processParticipationFlagUpdates.js";
|
|
25
|
-
import {processParticipationRecordUpdates} from "./processParticipationRecordUpdates.js";
|
|
26
|
-
import {processPendingConsolidations} from "./processPendingConsolidations.js";
|
|
27
|
-
import {processPendingDeposits} from "./processPendingDeposits.js";
|
|
28
|
-
import {processProposerLookahead} from "./processProposerLookahead.js";
|
|
29
|
-
import {processRandaoMixesReset} from "./processRandaoMixesReset.js";
|
|
30
|
-
import {processRegistryUpdates} from "./processRegistryUpdates.js";
|
|
31
|
-
import {processRewardsAndPenalties} from "./processRewardsAndPenalties.js";
|
|
32
|
-
import {processSlashings} from "./processSlashings.js";
|
|
33
|
-
import {processSlashingsReset} from "./processSlashingsReset.js";
|
|
34
|
-
import {processSyncCommitteeUpdates} from "./processSyncCommitteeUpdates.js";
|
|
35
|
-
|
|
36
|
-
// For spec tests
|
|
37
|
-
export {getRewardsAndPenalties} from "./processRewardsAndPenalties.js";
|
|
38
|
-
export {
|
|
39
|
-
processJustificationAndFinalization,
|
|
40
|
-
processInactivityUpdates,
|
|
41
|
-
processRewardsAndPenalties,
|
|
42
|
-
processRegistryUpdates,
|
|
43
|
-
processSlashings,
|
|
44
|
-
processEth1DataReset,
|
|
45
|
-
processEffectiveBalanceUpdates,
|
|
46
|
-
processSlashingsReset,
|
|
47
|
-
processRandaoMixesReset,
|
|
48
|
-
processHistoricalRootsUpdate,
|
|
49
|
-
processParticipationRecordUpdates,
|
|
50
|
-
processParticipationFlagUpdates,
|
|
51
|
-
processSyncCommitteeUpdates,
|
|
52
|
-
processHistoricalSummariesUpdate,
|
|
53
|
-
processPendingDeposits,
|
|
54
|
-
processPendingConsolidations,
|
|
55
|
-
processProposerLookahead,
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
export {computeUnrealizedCheckpoints} from "./computeUnrealizedCheckpoints.js";
|
|
59
|
-
|
|
60
|
-
const maxValidatorsPerStateSlashing = SLOTS_PER_EPOCH * MAX_ATTESTER_SLASHINGS * MAX_VALIDATORS_PER_COMMITTEE;
|
|
61
|
-
const maxSafeValidators = Math.floor(Number.MAX_SAFE_INTEGER / MAX_EFFECTIVE_BALANCE);
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Epoch transition steps tracked in metrics
|
|
65
|
-
*/
|
|
66
|
-
export enum EpochTransitionStep {
|
|
67
|
-
beforeProcessEpoch = "beforeProcessEpoch",
|
|
68
|
-
afterProcessEpoch = "afterProcessEpoch",
|
|
69
|
-
finalProcessEpoch = "finalProcessEpoch",
|
|
70
|
-
processJustificationAndFinalization = "processJustificationAndFinalization",
|
|
71
|
-
processInactivityUpdates = "processInactivityUpdates",
|
|
72
|
-
processRegistryUpdates = "processRegistryUpdates",
|
|
73
|
-
processSlashings = "processSlashings",
|
|
74
|
-
processRewardsAndPenalties = "processRewardsAndPenalties",
|
|
75
|
-
processEffectiveBalanceUpdates = "processEffectiveBalanceUpdates",
|
|
76
|
-
processParticipationFlagUpdates = "processParticipationFlagUpdates",
|
|
77
|
-
processSyncCommitteeUpdates = "processSyncCommitteeUpdates",
|
|
78
|
-
processPendingDeposits = "processPendingDeposits",
|
|
79
|
-
processPendingConsolidations = "processPendingConsolidations",
|
|
80
|
-
processProposerLookahead = "processProposerLookahead",
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export function processEpoch(
|
|
84
|
-
fork: ForkSeq,
|
|
85
|
-
state: CachedBeaconStateAllForks,
|
|
86
|
-
cache: EpochTransitionCache,
|
|
87
|
-
metrics?: BeaconStateTransitionMetrics | null
|
|
88
|
-
): void {
|
|
89
|
-
// state.slashings is initially a Gwei (BigInt) vector, however since Nov 2023 it's converted to UintNum64 (number) vector in the state transition because:
|
|
90
|
-
// - state.slashings[nextEpoch % EPOCHS_PER_SLASHINGS_VECTOR] is reset per epoch in processSlashingsReset()
|
|
91
|
-
// - max slashed validators per epoch is SLOTS_PER_EPOCH * MAX_ATTESTER_SLASHINGS * MAX_VALIDATORS_PER_COMMITTEE which is 32 * 2 * 2048 = 131072 on mainnet
|
|
92
|
-
// - with that and 32_000_000_000 MAX_EFFECTIVE_BALANCE or 2048_000_000_000 MAX_EFFECTIVE_BALANCE_ELECTRA, it still fits in a number given that Math.floor(Number.MAX_SAFE_INTEGER / 32_000_000_000) = 281474
|
|
93
|
-
if (maxValidatorsPerStateSlashing > maxSafeValidators) {
|
|
94
|
-
throw new Error("Lodestar does not support this network, parameters don't fit number value inside state.slashings");
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
{
|
|
98
|
-
const timer = metrics?.epochTransitionStepTime.startTimer({
|
|
99
|
-
step: EpochTransitionStep.processJustificationAndFinalization,
|
|
100
|
-
});
|
|
101
|
-
processJustificationAndFinalization(state, cache);
|
|
102
|
-
timer?.();
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (fork >= ForkSeq.altair) {
|
|
106
|
-
const timer = metrics?.epochTransitionStepTime.startTimer({step: EpochTransitionStep.processInactivityUpdates});
|
|
107
|
-
processInactivityUpdates(state as CachedBeaconStateAltair, cache);
|
|
108
|
-
timer?.();
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// processRewardsAndPenalties() is 2nd step in the specs, we optimize to do it
|
|
112
|
-
// after processSlashings() to update balances only once
|
|
113
|
-
// processRewardsAndPenalties(state, cache);
|
|
114
|
-
{
|
|
115
|
-
metrics?.validatorsInActivationQueue.set(cache.indicesEligibleForActivationQueue.length);
|
|
116
|
-
metrics?.validatorsInExitQueue.set(cache.indicesToEject.length);
|
|
117
|
-
const timer = metrics?.epochTransitionStepTime.startTimer({step: EpochTransitionStep.processRegistryUpdates});
|
|
118
|
-
processRegistryUpdates(fork, state, cache);
|
|
119
|
-
timer?.();
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// accumulate slashing penalties and only update balances once in processRewardsAndPenalties()
|
|
123
|
-
let slashingPenalties: number[];
|
|
124
|
-
{
|
|
125
|
-
const timer = metrics?.epochTransitionStepTime.startTimer({step: EpochTransitionStep.processSlashings});
|
|
126
|
-
slashingPenalties = processSlashings(state, cache, false);
|
|
127
|
-
timer?.();
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
{
|
|
131
|
-
const timer = metrics?.epochTransitionStepTime.startTimer({step: EpochTransitionStep.processRewardsAndPenalties});
|
|
132
|
-
processRewardsAndPenalties(state, cache, slashingPenalties);
|
|
133
|
-
timer?.();
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
processEth1DataReset(state, cache);
|
|
137
|
-
|
|
138
|
-
if (fork >= ForkSeq.electra) {
|
|
139
|
-
const stateElectra = state as CachedBeaconStateElectra;
|
|
140
|
-
{
|
|
141
|
-
const timer = metrics?.epochTransitionStepTime.startTimer({
|
|
142
|
-
step: EpochTransitionStep.processPendingDeposits,
|
|
143
|
-
});
|
|
144
|
-
processPendingDeposits(stateElectra, cache);
|
|
145
|
-
timer?.();
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
{
|
|
149
|
-
const timer = metrics?.epochTransitionStepTime.startTimer({
|
|
150
|
-
step: EpochTransitionStep.processPendingConsolidations,
|
|
151
|
-
});
|
|
152
|
-
processPendingConsolidations(stateElectra, cache);
|
|
153
|
-
timer?.();
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
{
|
|
158
|
-
const timer = metrics?.epochTransitionStepTime.startTimer({
|
|
159
|
-
step: EpochTransitionStep.processEffectiveBalanceUpdates,
|
|
160
|
-
});
|
|
161
|
-
const numUpdate = processEffectiveBalanceUpdates(fork, state, cache);
|
|
162
|
-
timer?.();
|
|
163
|
-
metrics?.numEffectiveBalanceUpdates.set(numUpdate);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
processSlashingsReset(state, cache);
|
|
167
|
-
processRandaoMixesReset(state, cache);
|
|
168
|
-
|
|
169
|
-
if (fork >= ForkSeq.capella) {
|
|
170
|
-
processHistoricalSummariesUpdate(state as CachedBeaconStateCapella, cache);
|
|
171
|
-
} else {
|
|
172
|
-
processHistoricalRootsUpdate(state, cache);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
if (fork === ForkSeq.phase0) {
|
|
176
|
-
processParticipationRecordUpdates(state as CachedBeaconStatePhase0);
|
|
177
|
-
} else {
|
|
178
|
-
{
|
|
179
|
-
const timer = metrics?.epochTransitionStepTime.startTimer({
|
|
180
|
-
step: EpochTransitionStep.processParticipationFlagUpdates,
|
|
181
|
-
});
|
|
182
|
-
processParticipationFlagUpdates(state as CachedBeaconStateAltair);
|
|
183
|
-
timer?.();
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
{
|
|
187
|
-
const timer = metrics?.epochTransitionStepTime.startTimer({
|
|
188
|
-
step: EpochTransitionStep.processSyncCommitteeUpdates,
|
|
189
|
-
});
|
|
190
|
-
processSyncCommitteeUpdates(fork, state as CachedBeaconStateAltair);
|
|
191
|
-
timer?.();
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
if (fork >= ForkSeq.fulu) {
|
|
196
|
-
const timer = metrics?.epochTransitionStepTime.startTimer({
|
|
197
|
-
step: EpochTransitionStep.processProposerLookahead,
|
|
198
|
-
});
|
|
199
|
-
processProposerLookahead(fork, state as CachedBeaconStateFulu, cache);
|
|
200
|
-
timer?.();
|
|
201
|
-
}
|
|
202
|
-
}
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
EFFECTIVE_BALANCE_INCREMENT,
|
|
3
|
-
ForkSeq,
|
|
4
|
-
HYSTERESIS_DOWNWARD_MULTIPLIER,
|
|
5
|
-
HYSTERESIS_QUOTIENT,
|
|
6
|
-
HYSTERESIS_UPWARD_MULTIPLIER,
|
|
7
|
-
MAX_EFFECTIVE_BALANCE,
|
|
8
|
-
MAX_EFFECTIVE_BALANCE_ELECTRA,
|
|
9
|
-
MIN_ACTIVATION_BALANCE,
|
|
10
|
-
TIMELY_TARGET_FLAG_INDEX,
|
|
11
|
-
} from "@lodestar/params";
|
|
12
|
-
import {BeaconStateAltair, CachedBeaconStateAllForks, EpochTransitionCache} from "../types.js";
|
|
13
|
-
|
|
14
|
-
/** Same to https://github.com/ethereum/eth2.0-specs/blob/v1.1.0-alpha.5/specs/altair/beacon-chain.md#has_flag */
|
|
15
|
-
const TIMELY_TARGET = 1 << TIMELY_TARGET_FLAG_INDEX;
|
|
16
|
-
/**
|
|
17
|
-
* Update effective balances if validator.balance has changed enough
|
|
18
|
-
*
|
|
19
|
-
* PERF: Cost 'proportional' to $VALIDATOR_COUNT, to iterate over all balances. Then cost is proportional to the amount
|
|
20
|
-
* of validators whose effectiveBalance changed. Worst case is a massive network leak or a big slashing event which
|
|
21
|
-
* causes a large amount of the network to decrease their balance simultaneously.
|
|
22
|
-
*
|
|
23
|
-
* - On normal mainnet conditions 0 validators change their effective balance
|
|
24
|
-
* - In case of big innactivity event a medium portion of validators may have their effectiveBalance updated
|
|
25
|
-
*
|
|
26
|
-
* Return number of validators updated
|
|
27
|
-
*/
|
|
28
|
-
export function processEffectiveBalanceUpdates(
|
|
29
|
-
fork: ForkSeq,
|
|
30
|
-
state: CachedBeaconStateAllForks,
|
|
31
|
-
cache: EpochTransitionCache
|
|
32
|
-
): number {
|
|
33
|
-
const HYSTERESIS_INCREMENT = EFFECTIVE_BALANCE_INCREMENT / HYSTERESIS_QUOTIENT;
|
|
34
|
-
const DOWNWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_DOWNWARD_MULTIPLIER;
|
|
35
|
-
const UPWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_UPWARD_MULTIPLIER;
|
|
36
|
-
const {validators, epochCtx} = state;
|
|
37
|
-
const {effectiveBalanceIncrements} = epochCtx;
|
|
38
|
-
const forkSeq = epochCtx.config.getForkSeq(state.slot);
|
|
39
|
-
let nextEpochTotalActiveBalanceByIncrement = 0;
|
|
40
|
-
|
|
41
|
-
// update effective balances with hysteresis
|
|
42
|
-
|
|
43
|
-
// epochTransitionCache.balances is initialized in processRewardsAndPenalties()
|
|
44
|
-
// and updated in processPendingDeposits() and processPendingConsolidations()
|
|
45
|
-
// so it's recycled here for performance.
|
|
46
|
-
const balances = cache.balances ?? state.balances.getAll();
|
|
47
|
-
const isCompoundingValidatorArr = cache.isCompoundingValidatorArr;
|
|
48
|
-
|
|
49
|
-
let numUpdate = 0;
|
|
50
|
-
for (let i = 0, len = balances.length; i < len; i++) {
|
|
51
|
-
const balance = balances[i];
|
|
52
|
-
|
|
53
|
-
// PERF: It's faster to access to get() every single element (4ms) than to convert to regular array then loop (9ms)
|
|
54
|
-
let effectiveBalanceIncrement = effectiveBalanceIncrements[i];
|
|
55
|
-
let effectiveBalance = effectiveBalanceIncrement * EFFECTIVE_BALANCE_INCREMENT;
|
|
56
|
-
|
|
57
|
-
let effectiveBalanceLimit: number;
|
|
58
|
-
if (fork < ForkSeq.electra) {
|
|
59
|
-
effectiveBalanceLimit = MAX_EFFECTIVE_BALANCE;
|
|
60
|
-
} else {
|
|
61
|
-
// from electra, effectiveBalanceLimit is per validator
|
|
62
|
-
effectiveBalanceLimit = isCompoundingValidatorArr[i] ? MAX_EFFECTIVE_BALANCE_ELECTRA : MIN_ACTIVATION_BALANCE;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (
|
|
66
|
-
// Too big
|
|
67
|
-
effectiveBalance > balance + DOWNWARD_THRESHOLD ||
|
|
68
|
-
// Too small. Check effectiveBalance < MAX_EFFECTIVE_BALANCE to prevent unnecessary updates
|
|
69
|
-
(effectiveBalance < effectiveBalanceLimit && effectiveBalance + UPWARD_THRESHOLD < balance)
|
|
70
|
-
) {
|
|
71
|
-
// Update the state tree
|
|
72
|
-
// Should happen rarely, so it's fine to update the tree
|
|
73
|
-
const validator = validators.get(i);
|
|
74
|
-
|
|
75
|
-
effectiveBalance = Math.min(balance - (balance % EFFECTIVE_BALANCE_INCREMENT), effectiveBalanceLimit);
|
|
76
|
-
validator.effectiveBalance = effectiveBalance;
|
|
77
|
-
// Also update the fast cached version
|
|
78
|
-
const newEffectiveBalanceIncrement = Math.floor(effectiveBalance / EFFECTIVE_BALANCE_INCREMENT);
|
|
79
|
-
|
|
80
|
-
// TODO: describe issue. Compute progressive target balances
|
|
81
|
-
// Must update target balances for consistency, see comments below
|
|
82
|
-
if (forkSeq >= ForkSeq.altair) {
|
|
83
|
-
const deltaEffectiveBalanceIncrement = newEffectiveBalanceIncrement - effectiveBalanceIncrement;
|
|
84
|
-
const {previousEpochParticipation, currentEpochParticipation} = state as BeaconStateAltair;
|
|
85
|
-
|
|
86
|
-
if (!validator.slashed && (previousEpochParticipation.get(i) & TIMELY_TARGET) === TIMELY_TARGET) {
|
|
87
|
-
epochCtx.previousTargetUnslashedBalanceIncrements += deltaEffectiveBalanceIncrement;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// currentTargetUnslashedBalanceIncrements is transfered to previousTargetUnslashedBalanceIncrements in afterEpochTransitionCache
|
|
91
|
-
// at epoch transition of next epoch (in EpochTransitionCache), prevTargetUnslStake is calculated based on newEffectiveBalanceIncrement
|
|
92
|
-
if (!validator.slashed && (currentEpochParticipation.get(i) & TIMELY_TARGET) === TIMELY_TARGET) {
|
|
93
|
-
epochCtx.currentTargetUnslashedBalanceIncrements += deltaEffectiveBalanceIncrement;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
effectiveBalanceIncrement = newEffectiveBalanceIncrement;
|
|
98
|
-
effectiveBalanceIncrements[i] = effectiveBalanceIncrement;
|
|
99
|
-
numUpdate++;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// TODO: Do this in afterEpochTransitionCache, looping a Uint8Array should be very cheap
|
|
103
|
-
if (cache.isActiveNextEpoch[i]) {
|
|
104
|
-
// We track nextEpochTotalActiveBalanceByIncrement as ETH to fit total network balance in a JS number (53 bits)
|
|
105
|
-
nextEpochTotalActiveBalanceByIncrement += effectiveBalanceIncrement;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
cache.nextEpochTotalActiveBalanceByIncrement = nextEpochTotalActiveBalanceByIncrement;
|
|
110
|
-
return numUpdate;
|
|
111
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import {EPOCHS_PER_ETH1_VOTING_PERIOD} from "@lodestar/params";
|
|
2
|
-
import {ssz} from "@lodestar/types";
|
|
3
|
-
import {CachedBeaconStateAllForks, EpochTransitionCache} from "../types.js";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Reset eth1DataVotes tree every `EPOCHS_PER_ETH1_VOTING_PERIOD`.
|
|
7
|
-
*
|
|
8
|
-
* PERF: Almost no (constant) cost
|
|
9
|
-
*/
|
|
10
|
-
export function processEth1DataReset(state: CachedBeaconStateAllForks, cache: EpochTransitionCache): void {
|
|
11
|
-
const nextEpoch = cache.currentEpoch + 1;
|
|
12
|
-
|
|
13
|
-
// reset eth1 data votes
|
|
14
|
-
if (nextEpoch % EPOCHS_PER_ETH1_VOTING_PERIOD === 0) {
|
|
15
|
-
state.eth1DataVotes = ssz.phase0.Eth1DataVotes.defaultViewDU();
|
|
16
|
-
}
|
|
17
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import {SLOTS_PER_EPOCH, SLOTS_PER_HISTORICAL_ROOT} from "@lodestar/params";
|
|
2
|
-
import {ssz} from "@lodestar/types";
|
|
3
|
-
import {intDiv} from "@lodestar/utils";
|
|
4
|
-
import {CachedBeaconStateAllForks, EpochTransitionCache} from "../types.js";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Persist blockRoots and stateRoots to historicalRoots.
|
|
8
|
-
*
|
|
9
|
-
* PERF: Very low (constant) cost. Most of the HistoricalBatch should already be hashed.
|
|
10
|
-
*/
|
|
11
|
-
export function processHistoricalRootsUpdate(state: CachedBeaconStateAllForks, cache: EpochTransitionCache): void {
|
|
12
|
-
const nextEpoch = cache.currentEpoch + 1;
|
|
13
|
-
|
|
14
|
-
// set historical root accumulator
|
|
15
|
-
if (nextEpoch % intDiv(SLOTS_PER_HISTORICAL_ROOT, SLOTS_PER_EPOCH) === 0) {
|
|
16
|
-
state.historicalRoots.push(
|
|
17
|
-
// HistoricalBatchRoots = Non-spec'ed helper type to allow efficient hashing in epoch transition.
|
|
18
|
-
// This type is like a 'Header' of HistoricalBatch where its fields are hashed.
|
|
19
|
-
ssz.phase0.HistoricalBatchRoots.hashTreeRoot({
|
|
20
|
-
blockRoots: state.blockRoots.hashTreeRoot(),
|
|
21
|
-
stateRoots: state.stateRoots.hashTreeRoot(),
|
|
22
|
-
})
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import {SLOTS_PER_EPOCH, SLOTS_PER_HISTORICAL_ROOT} from "@lodestar/params";
|
|
2
|
-
import {ssz} from "@lodestar/types";
|
|
3
|
-
import {intDiv} from "@lodestar/utils";
|
|
4
|
-
import {CachedBeaconStateCapella, EpochTransitionCache} from "../types.js";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Persist blockRoots and stateRoots to historicalSummaries.
|
|
8
|
-
*
|
|
9
|
-
* PERF: Very low (constant) cost. Most of the HistoricalSummaries should already be hashed.
|
|
10
|
-
*/
|
|
11
|
-
export function processHistoricalSummariesUpdate(state: CachedBeaconStateCapella, cache: EpochTransitionCache): void {
|
|
12
|
-
const nextEpoch = cache.currentEpoch + 1;
|
|
13
|
-
|
|
14
|
-
// set historical root accumulator
|
|
15
|
-
if (nextEpoch % intDiv(SLOTS_PER_HISTORICAL_ROOT, SLOTS_PER_EPOCH) === 0) {
|
|
16
|
-
state.historicalSummaries.push(
|
|
17
|
-
ssz.capella.HistoricalSummary.toViewDU({
|
|
18
|
-
blockSummaryRoot: state.blockRoots.hashTreeRoot(),
|
|
19
|
-
stateSummaryRoot: state.stateRoots.hashTreeRoot(),
|
|
20
|
-
})
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import {GENESIS_EPOCH} from "@lodestar/params";
|
|
2
|
-
import {CachedBeaconStateAltair, EpochTransitionCache} from "../types.js";
|
|
3
|
-
import * as attesterStatusUtil from "../util/attesterStatus.js";
|
|
4
|
-
import {isInInactivityLeak} from "../util/index.js";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* This data is reused and never gc.
|
|
8
|
-
*/
|
|
9
|
-
const inactivityScoresArr = new Array<number>();
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Mutates `inactivityScores` from pre-calculated validator flags.
|
|
13
|
-
*
|
|
14
|
-
* PERF: Cost = iterate over an array of size $VALIDATOR_COUNT + 'proportional' to how many validtors are inactive or
|
|
15
|
-
* have been inactive in the past, i.e. that require an update to their inactivityScore. Worst case = all validators
|
|
16
|
-
* need to update their non-zero `inactivityScore`.
|
|
17
|
-
*
|
|
18
|
-
* - On normal mainnet conditions
|
|
19
|
-
* - prevTargetAttester: 96%
|
|
20
|
-
* - unslashed: 100%
|
|
21
|
-
* - eligibleAttester: 98%
|
|
22
|
-
*
|
|
23
|
-
* TODO: Compute from altair testnet inactivityScores updates on average
|
|
24
|
-
*/
|
|
25
|
-
export function processInactivityUpdates(state: CachedBeaconStateAltair, cache: EpochTransitionCache): void {
|
|
26
|
-
if (state.epochCtx.epoch === GENESIS_EPOCH) {
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const {config, inactivityScores} = state;
|
|
31
|
-
const {INACTIVITY_SCORE_BIAS, INACTIVITY_SCORE_RECOVERY_RATE} = config;
|
|
32
|
-
const {flags} = cache;
|
|
33
|
-
const inActivityLeak = isInInactivityLeak(state);
|
|
34
|
-
|
|
35
|
-
// this avoids importing FLAG_ELIGIBLE_ATTESTER inside the for loop, check the compiled code
|
|
36
|
-
const {FLAG_PREV_TARGET_ATTESTER_UNSLASHED, FLAG_ELIGIBLE_ATTESTER, hasMarkers} = attesterStatusUtil;
|
|
37
|
-
|
|
38
|
-
inactivityScoresArr.length = state.validators.length;
|
|
39
|
-
inactivityScores.getAll(inactivityScoresArr);
|
|
40
|
-
|
|
41
|
-
for (let i = 0; i < flags.length; i++) {
|
|
42
|
-
const flag = flags[i];
|
|
43
|
-
if (hasMarkers(flag, FLAG_ELIGIBLE_ATTESTER)) {
|
|
44
|
-
let inactivityScore = inactivityScoresArr[i];
|
|
45
|
-
|
|
46
|
-
const prevInactivityScore = inactivityScore;
|
|
47
|
-
if (hasMarkers(flag, FLAG_PREV_TARGET_ATTESTER_UNSLASHED)) {
|
|
48
|
-
inactivityScore -= Math.min(1, inactivityScore);
|
|
49
|
-
} else {
|
|
50
|
-
inactivityScore += INACTIVITY_SCORE_BIAS;
|
|
51
|
-
}
|
|
52
|
-
if (!inActivityLeak) {
|
|
53
|
-
inactivityScore -= Math.min(INACTIVITY_SCORE_RECOVERY_RATE, inactivityScore);
|
|
54
|
-
}
|
|
55
|
-
if (inactivityScore !== prevInactivityScore) {
|
|
56
|
-
inactivityScores.set(i, inactivityScore);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import {BitArray} from "@chainsafe/ssz";
|
|
2
|
-
import {GENESIS_EPOCH} from "@lodestar/params";
|
|
3
|
-
import {ssz} from "@lodestar/types";
|
|
4
|
-
import {CachedBeaconStateAllForks, EpochTransitionCache} from "../types.js";
|
|
5
|
-
import {computeEpochAtSlot, getBlockRoot} from "../util/index.js";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Update justified and finalized checkpoints depending on network participation.
|
|
9
|
-
*
|
|
10
|
-
* PERF: Very low (constant) cost. Persist small objects to the tree.
|
|
11
|
-
*/
|
|
12
|
-
export function processJustificationAndFinalization(
|
|
13
|
-
state: CachedBeaconStateAllForks,
|
|
14
|
-
cache: EpochTransitionCache
|
|
15
|
-
): void {
|
|
16
|
-
// Initial FFG checkpoint values have a `0x00` stub for `root`.
|
|
17
|
-
// Skip FFG updates in the first two epochs to avoid corner cases that might result in modifying this stub.
|
|
18
|
-
if (cache.currentEpoch <= GENESIS_EPOCH + 1) {
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
weighJustificationAndFinalization(
|
|
22
|
-
state,
|
|
23
|
-
cache.totalActiveStakeByIncrement,
|
|
24
|
-
cache.prevEpochUnslashedStake.targetStakeByIncrement,
|
|
25
|
-
cache.currEpochUnslashedTargetStakeByIncrement
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Updates `state` checkpoints based on previous and current target balance
|
|
31
|
-
*/
|
|
32
|
-
export function weighJustificationAndFinalization(
|
|
33
|
-
state: CachedBeaconStateAllForks,
|
|
34
|
-
totalActiveBalance: number,
|
|
35
|
-
previousEpochTargetBalance: number,
|
|
36
|
-
currentEpochTargetBalance: number
|
|
37
|
-
): void {
|
|
38
|
-
const currentEpoch = computeEpochAtSlot(state.slot);
|
|
39
|
-
const previousEpoch = currentEpoch - 1;
|
|
40
|
-
|
|
41
|
-
const oldPreviousJustifiedCheckpoint = state.previousJustifiedCheckpoint;
|
|
42
|
-
const oldCurrentJustifiedCheckpoint = state.currentJustifiedCheckpoint;
|
|
43
|
-
|
|
44
|
-
// Process justifications
|
|
45
|
-
state.previousJustifiedCheckpoint = state.currentJustifiedCheckpoint;
|
|
46
|
-
const bits = state.justificationBits.toBoolArray();
|
|
47
|
-
|
|
48
|
-
// Rotate bits
|
|
49
|
-
for (let i = bits.length - 1; i >= 1; i--) {
|
|
50
|
-
bits[i] = bits[i - 1];
|
|
51
|
-
}
|
|
52
|
-
bits[0] = false;
|
|
53
|
-
|
|
54
|
-
if (previousEpochTargetBalance * 3 >= totalActiveBalance * 2) {
|
|
55
|
-
state.currentJustifiedCheckpoint = ssz.phase0.Checkpoint.toViewDU({
|
|
56
|
-
epoch: previousEpoch,
|
|
57
|
-
root: getBlockRoot(state, previousEpoch),
|
|
58
|
-
});
|
|
59
|
-
bits[1] = true;
|
|
60
|
-
}
|
|
61
|
-
if (currentEpochTargetBalance * 3 >= totalActiveBalance * 2) {
|
|
62
|
-
state.currentJustifiedCheckpoint = ssz.phase0.Checkpoint.toViewDU({
|
|
63
|
-
epoch: currentEpoch,
|
|
64
|
-
root: getBlockRoot(state, currentEpoch),
|
|
65
|
-
});
|
|
66
|
-
bits[0] = true;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
state.justificationBits = ssz.phase0.JustificationBits.toViewDU(BitArray.fromBoolArray(bits));
|
|
70
|
-
|
|
71
|
-
// TODO: Consider rendering bits as array of boolean for faster repeated access here
|
|
72
|
-
|
|
73
|
-
// Process finalizations
|
|
74
|
-
// The 2nd/3rd/4th most recent epochs are all justified, the 2nd using the 4th as source
|
|
75
|
-
if (bits[1] && bits[2] && bits[3] && oldPreviousJustifiedCheckpoint.epoch + 3 === currentEpoch) {
|
|
76
|
-
state.finalizedCheckpoint = oldPreviousJustifiedCheckpoint;
|
|
77
|
-
}
|
|
78
|
-
// The 2nd/3rd most recent epochs are both justified, the 2nd using the 3rd as source
|
|
79
|
-
if (bits[1] && bits[2] && oldPreviousJustifiedCheckpoint.epoch + 2 === currentEpoch) {
|
|
80
|
-
state.finalizedCheckpoint = oldPreviousJustifiedCheckpoint;
|
|
81
|
-
}
|
|
82
|
-
// The 1st/2nd/3rd most recent epochs are all justified, the 1st using the 3rd as source
|
|
83
|
-
if (bits[0] && bits[1] && bits[2] && oldCurrentJustifiedCheckpoint.epoch + 2 === currentEpoch) {
|
|
84
|
-
state.finalizedCheckpoint = oldCurrentJustifiedCheckpoint;
|
|
85
|
-
}
|
|
86
|
-
// The 1st/2nd most recent epochs are both justified, the 1st using the 2nd as source
|
|
87
|
-
if (bits[0] && bits[1] && oldCurrentJustifiedCheckpoint.epoch + 1 === currentEpoch) {
|
|
88
|
-
state.finalizedCheckpoint = oldCurrentJustifiedCheckpoint;
|
|
89
|
-
}
|
|
90
|
-
}
|