Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: clean up single-used functions in Electra #7132

Merged
merged 4 commits into from
Oct 12, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions packages/state-transition/src/constants/constants.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
export const ZERO_HASH = Buffer.alloc(32, 0);
export const EMPTY_SIGNATURE = Buffer.alloc(96, 0);
export const ZERO_HASH = new Uint8Array(32).fill(0);
export const EMPTY_SIGNATURE = new Uint8Array(96).fill(0);
export const SECONDS_PER_DAY = 86400;
export const BASE_REWARDS_PER_EPOCH = 4;
export const G2_POINT_AT_INFINITY = Buffer.from(
"c000000000000000000000000000000000000000000000000000000000000000" +
"0000000000000000000000000000000000000000000000000000000000000000" +
"0000000000000000000000000000000000000000000000000000000000000000",
"hex"
export const G2_POINT_AT_INFINITY = new Uint8Array(
Buffer.from(
"c000000000000000000000000000000000000000000000000000000000000000" +
"0000000000000000000000000000000000000000000000000000000000000000" +
"0000000000000000000000000000000000000000000000000000000000000000",
"hex"
)
);
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ import {
HYSTERESIS_QUOTIENT,
HYSTERESIS_UPWARD_MULTIPLIER,
MAX_EFFECTIVE_BALANCE,
MAX_EFFECTIVE_BALANCE_ELECTRA,
MIN_ACTIVATION_BALANCE,
TIMELY_TARGET_FLAG_INDEX,
} from "@lodestar/params";
import {EpochTransitionCache, CachedBeaconStateAllForks, BeaconStateAltair} from "../types.js";
import {hasCompoundingWithdrawalCredential} from "../util/electra.js";
import {getMaxEffectiveBalance} from "../util/validator.js";

/** Same to https://github.com/ethereum/eth2.0-specs/blob/v1.1.0-alpha.5/specs/altair/beacon-chain.md#has_flag */
const TIMELY_TARGET = 1 << TIMELY_TARGET_FLAG_INDEX;
Expand Down Expand Up @@ -46,7 +44,6 @@ export function processEffectiveBalanceUpdates(
// so it's recycled here for performance.
const balances = cache.balances ?? state.balances.getAll();
const currentEpochValidators = cache.validators;
const newCompoundingValidators = cache.newCompoundingValidators ?? new Set();

let numUpdate = 0;
for (let i = 0, len = balances.length; i < len; i++) {
Expand All @@ -61,10 +58,7 @@ export function processEffectiveBalanceUpdates(
effectiveBalanceLimit = MAX_EFFECTIVE_BALANCE;
} else {
// from electra, effectiveBalanceLimit is per validator
const isCompoundingValidator =
hasCompoundingWithdrawalCredential(currentEpochValidators[i].withdrawalCredentials) ||
newCompoundingValidators.has(i);
effectiveBalanceLimit = isCompoundingValidator ? MAX_EFFECTIVE_BALANCE_ELECTRA : MIN_ACTIVATION_BALANCE;
effectiveBalanceLimit = getMaxEffectiveBalance(currentEpochValidators[i].withdrawalCredentials);
}

if (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {ValidatorIndex} from "@lodestar/types";
import {CachedBeaconStateElectra, EpochTransitionCache} from "../types.js";
import {decreaseBalance, increaseBalance} from "../util/balance.js";
import {getActiveBalance} from "../util/validator.js";
import {getMaxEffectiveBalance} from "../util/validator.js";
import {switchToCompoundingValidator} from "../util/electra.js";

/**
Expand Down Expand Up @@ -40,12 +40,13 @@ export function processPendingConsolidations(state: CachedBeaconStateElectra, ca
switchToCompoundingValidator(state, targetIndex);
newCompoundingValidators.add(targetIndex);
// Move active balance to target. Excess balance is withdrawable.
const activeBalance = getActiveBalance(state, sourceIndex);
decreaseBalance(state, sourceIndex, activeBalance);
increaseBalance(state, targetIndex, activeBalance);
const maxEffectiveBalance = getMaxEffectiveBalance(state.validators.getReadonly(sourceIndex).withdrawalCredentials);
const sourceEffectiveBalance = Math.min(state.balances.get(sourceIndex), maxEffectiveBalance);
decreaseBalance(state, sourceIndex, sourceEffectiveBalance);
increaseBalance(state, targetIndex, sourceEffectiveBalance);
if (cachedBalances) {
cachedBalances[sourceIndex] -= activeBalance;
cachedBalances[targetIndex] += activeBalance;
cachedBalances[sourceIndex] -= sourceEffectiveBalance;
cachedBalances[targetIndex] += sourceEffectiveBalance;
}

nextPendingConsolidation++;
Expand Down
69 changes: 20 additions & 49 deletions packages/state-transition/src/slot/upgradeStateToElectra.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import {Epoch, ValidatorIndex, ssz} from "@lodestar/types";
import {FAR_FUTURE_EPOCH, UNSET_DEPOSIT_REQUESTS_START_INDEX} from "@lodestar/params";
import {FAR_FUTURE_EPOCH, GENESIS_SLOT, UNSET_DEPOSIT_REQUESTS_START_INDEX} from "@lodestar/params";
import {CachedBeaconStateDeneb} from "../types.js";
import {CachedBeaconStateElectra, getCachedBeaconState} from "../cache/stateCache.js";
import {
hasCompoundingWithdrawalCredential,
queueEntireBalanceAndResetValidator,
queueExcessActiveBalance,
} from "../util/electra.js";
import {hasCompoundingWithdrawalCredential, queueExcessActiveBalance} from "../util/electra.js";
import {computeActivationExitEpoch} from "../util/epoch.js";
import {getActivationExitChurnLimit, getConsolidationChurnLimit} from "../util/validator.js";
import {G2_POINT_AT_INFINITY} from "../constants/constants.js";

/**
* Upgrade a state from Deneb to Electra.
Expand Down Expand Up @@ -93,7 +90,23 @@ export function upgradeStateToElectra(stateDeneb: CachedBeaconStateDeneb): Cache
});

for (const validatorIndex of preActivation) {
queueEntireBalanceAndResetValidator(stateElectraView as CachedBeaconStateElectra, validatorIndex);
const stateElectra = stateElectraView as CachedBeaconStateElectra;
const balance = stateElectra.balances.get(validatorIndex);
stateElectra.balances.set(validatorIndex, 0);

const validator = stateElectra.validators.get(validatorIndex);
validator.effectiveBalance = 0;
stateElectra.epochCtx.effectiveBalanceIncrementsSet(validatorIndex, 0);
validator.activationEligibilityEpoch = FAR_FUTURE_EPOCH;

const pendingDeposit = ssz.electra.PendingDeposit.toViewDU({
pubkey: validator.pubkey,
withdrawalCredentials: validator.withdrawalCredentials,
amount: balance,
signature: G2_POINT_AT_INFINITY,
slot: GENESIS_SLOT,
});
stateElectra.pendingDeposits.push(pendingDeposit);
}

for (let i = 0; i < validatorsArr.length; i++) {
Expand All @@ -114,45 +127,3 @@ export function upgradeStateToElectra(stateDeneb: CachedBeaconStateDeneb): Cache

return stateElectra;
}

export function upgradeStateToElectraOriginal(stateDeneb: CachedBeaconStateDeneb): CachedBeaconStateElectra {
const {config} = stateDeneb;

const stateElectraNode = ssz.deneb.BeaconState.commitViewDU(stateDeneb);
const stateElectraView = ssz.electra.BeaconState.getViewDU(stateElectraNode);

const stateElectra = getCachedBeaconState(stateElectraView, stateDeneb);

stateElectra.fork = ssz.phase0.Fork.toViewDU({
previousVersion: stateDeneb.fork.currentVersion,
currentVersion: config.ELECTRA_FORK_VERSION,
epoch: stateDeneb.epochCtx.epoch,
});

// default value of depositRequestsStartIndex is UNSET_DEPOSIT_REQUESTS_START_INDEX
stateElectra.depositRequestsStartIndex = UNSET_DEPOSIT_REQUESTS_START_INDEX;

const validatorsArr = stateElectra.validators.getAllReadonly();

for (let i = 0; i < validatorsArr.length; i++) {
const validator = validatorsArr[i];

// [EIP-7251]: add validators that are not yet active to pending balance deposits
if (validator.activationEligibilityEpoch === FAR_FUTURE_EPOCH) {
queueEntireBalanceAndResetValidator(stateElectra, i);
}

// [EIP-7251]: Ensure early adopters of compounding credentials go through the activation churn
const withdrawalCredential = validator.withdrawalCredentials;
if (hasCompoundingWithdrawalCredential(withdrawalCredential)) {
queueExcessActiveBalance(stateElectra, i);
}
}

// Commit new added fields ViewDU to the root node
stateElectra.commit();
// Clear cache to ensure the cache of deneb fields is not used by new ELECTRA fields
stateElectra["clearCache"]();

return stateElectra;
}
21 changes: 1 addition & 20 deletions packages/state-transition/src/util/electra.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {COMPOUNDING_WITHDRAWAL_PREFIX, FAR_FUTURE_EPOCH, GENESIS_SLOT, MIN_ACTIVATION_BALANCE} from "@lodestar/params";
import {COMPOUNDING_WITHDRAWAL_PREFIX, GENESIS_SLOT, MIN_ACTIVATION_BALANCE} from "@lodestar/params";
import {ValidatorIndex, ssz} from "@lodestar/types";
import {CachedBeaconStateElectra} from "../types.js";
import {G2_POINT_AT_INFINITY} from "../constants/constants.js";
Expand Down Expand Up @@ -47,22 +47,3 @@ export function queueExcessActiveBalance(state: CachedBeaconStateElectra, index:
state.pendingDeposits.push(pendingDeposit);
}
}

export function queueEntireBalanceAndResetValidator(state: CachedBeaconStateElectra, index: ValidatorIndex): void {
const balance = state.balances.get(index);
state.balances.set(index, 0);

const validator = state.validators.get(index);
validator.effectiveBalance = 0;
state.epochCtx.effectiveBalanceIncrementsSet(index, 0);
validator.activationEligibilityEpoch = FAR_FUTURE_EPOCH;

const pendingDeposit = ssz.electra.PendingDeposit.toViewDU({
pubkey: validator.pubkey,
withdrawalCredentials: validator.withdrawalCredentials,
amount: balance,
signature: G2_POINT_AT_INFINITY,
slot: GENESIS_SLOT,
});
state.pendingDeposits.push(pendingDeposit);
}
8 changes: 0 additions & 8 deletions packages/state-transition/src/util/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,6 @@ export function getMaxEffectiveBalance(withdrawalCredentials: Uint8Array): numbe
}
}

export function getActiveBalance(state: CachedBeaconStateElectra, validatorIndex: ValidatorIndex): number {
const validatorMaxEffectiveBalance = getMaxEffectiveBalance(
state.validators.getReadonly(validatorIndex).withdrawalCredentials
);

return Math.min(state.balances.get(validatorIndex), validatorMaxEffectiveBalance);
}

export function getPendingBalanceToWithdraw(state: CachedBeaconStateElectra, validatorIndex: ValidatorIndex): number {
return state.pendingPartialWithdrawals
.getAllReadonly()
Expand Down
Loading