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

EIP-7251 - Added minActivationBalance #8190

Merged
merged 3 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,7 @@
public class WithdrawalPrefixes {
public static final Bytes BLS_WITHDRAWAL_PREFIX = Bytes.fromHexString("0x00");
public static final byte ETH1_ADDRESS_WITHDRAWAL_BYTE = 0x01;
public static final byte COMPOUNDING_WITHDRAWAL_BYTE = 0x02;
public static final Bytes ETH1_ADDRESS_WITHDRAWAL_PREFIX = Bytes.of(ETH1_ADDRESS_WITHDRAWAL_BYTE);
public static final Bytes COMPOUNDING_WITHDRAWAL_PREFIX = Bytes.of(COMPOUNDING_WITHDRAWAL_BYTE);
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public abstract class AbstractEpochProcessor implements EpochProcessor {
protected final BeaconStateMutators beaconStateMutators;

private static final Logger LOG = LogManager.getLogger();
protected final UInt64 maxEffectiveBalance;
// Used to log once per epoch (throttlingPeriod = 1)
private final Throttler<Logger> loggerThrottler = new Throttler<>(LOG, UInt64.ONE);

Expand All @@ -83,6 +84,7 @@ protected AbstractEpochProcessor(
this.beaconStateUtil = beaconStateUtil;
this.validatorStatusFactory = validatorStatusFactory;
this.schemaDefinitions = schemaDefinitions;
this.maxEffectiveBalance = specConfig.getMaxEffectiveBalance();
}

/**
Expand Down Expand Up @@ -310,20 +312,14 @@ public void processRegistryUpdates(
SszMutableList<Validator> validators = state.getValidators();
final UInt64 currentEpoch = beaconStateAccessors.getCurrentEpoch(state);
final UInt64 finalizedEpoch = state.getFinalizedCheckpoint().getEpoch();
final UInt64 maxEffectiveBalance = specConfig.getMaxEffectiveBalance();
final UInt64 ejectionBalance = specConfig.getEjectionBalance();
final Supplier<ValidatorExitContext> validatorExitContextSupplier =
beaconStateMutators.createValidatorExitContextSupplier(state);

for (int index = 0; index < validators.size(); index++) {
final ValidatorStatus status = statuses.get(index);

// Slightly optimised form of isEligibleForActivationQueue to avoid accessing the
// state for the majority of validators. Can't be eligible for activation if already active
// or if effective balance is too low. Only get the validator if both those checks pass to
// confirm it isn't already in the queue.
if (!status.isActiveInCurrentEpoch()
&& status.getCurrentEpochEffectiveBalance().equals(maxEffectiveBalance)) {
if (isEligibleForActivationQueue(status)) {
final Validator validator = validators.get(index);
if (validator.getActivationEligibilityEpoch().equals(SpecConfig.FAR_FUTURE_EPOCH)) {
validators.set(
Expand Down Expand Up @@ -381,6 +377,17 @@ public void processRegistryUpdates(
}
}

/**
* Can't be eligible for activation if already active or if effective balance is too low.
*
* @param status - Validator status
* @return true if validator is eligible to be added to the activation queue
*/
protected boolean isEligibleForActivationQueue(final ValidatorStatus status) {
return !status.isActiveInCurrentEpoch()
&& status.getCurrentEpochEffectiveBalance().equals(maxEffectiveBalance);
}

/** Processes slashings */
@Override
public void processSlashings(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,22 @@
import tech.pegasys.teku.spec.logic.common.util.LightClientUtil;
import tech.pegasys.teku.spec.logic.common.util.SyncCommitteeUtil;
import tech.pegasys.teku.spec.logic.common.util.ValidatorsUtil;
import tech.pegasys.teku.spec.logic.versions.altair.helpers.BeaconStateAccessorsAltair;
import tech.pegasys.teku.spec.logic.versions.altair.statetransition.epoch.ValidatorStatusFactoryAltair;
import tech.pegasys.teku.spec.logic.versions.bellatrix.helpers.BeaconStateMutatorsBellatrix;
import tech.pegasys.teku.spec.logic.versions.bellatrix.helpers.BellatrixTransitionHelpers;
import tech.pegasys.teku.spec.logic.versions.bellatrix.util.BlindBlockUtilBellatrix;
import tech.pegasys.teku.spec.logic.versions.capella.block.BlockProcessorCapella;
import tech.pegasys.teku.spec.logic.versions.capella.operations.validation.OperationValidatorCapella;
import tech.pegasys.teku.spec.logic.versions.capella.statetransition.epoch.EpochProcessorCapella;
import tech.pegasys.teku.spec.logic.versions.deneb.helpers.BeaconStateAccessorsDeneb;
import tech.pegasys.teku.spec.logic.versions.deneb.helpers.MiscHelpersDeneb;
import tech.pegasys.teku.spec.logic.versions.deneb.operations.validation.AttestationDataValidatorDeneb;
import tech.pegasys.teku.spec.logic.versions.deneb.util.AttestationUtilDeneb;
import tech.pegasys.teku.spec.logic.versions.deneb.util.ForkChoiceUtilDeneb;
import tech.pegasys.teku.spec.logic.versions.electra.block.BlockProcessorElectra;
import tech.pegasys.teku.spec.logic.versions.electra.forktransition.ElectraStateUpgrade;
import tech.pegasys.teku.spec.logic.versions.electra.helpers.BeaconStateAccessorsElectra;
import tech.pegasys.teku.spec.logic.versions.electra.helpers.MiscHelpersElectra;
import tech.pegasys.teku.spec.logic.versions.electra.helpers.PredicatesElectra;
import tech.pegasys.teku.spec.logic.versions.electra.statetransition.epoch.EpochProcessorElectra;
import tech.pegasys.teku.spec.schemas.SchemaDefinitionsElectra;

public class SpecLogicElectra extends AbstractSpecLogic {
Expand All @@ -53,15 +53,15 @@ public class SpecLogicElectra extends AbstractSpecLogic {
private SpecLogicElectra(
final Predicates predicates,
final MiscHelpersDeneb miscHelpers,
final BeaconStateAccessorsAltair beaconStateAccessors,
final BeaconStateAccessorsElectra beaconStateAccessors,
final BeaconStateMutatorsBellatrix beaconStateMutators,
final OperationSignatureVerifier operationSignatureVerifier,
final ValidatorsUtil validatorsUtil,
final BeaconStateUtil beaconStateUtil,
final AttestationUtil attestationUtil,
final OperationValidator operationValidator,
final ValidatorStatusFactoryAltair validatorStatusFactory,
final EpochProcessorCapella epochProcessor,
final EpochProcessorElectra epochProcessor,
final BlockProcessorCapella blockProcessor,
final ForkChoiceUtil forkChoiceUtil,
final BlockProposalUtil blockProposalUtil,
Expand Down Expand Up @@ -93,11 +93,11 @@ private SpecLogicElectra(
public static SpecLogicElectra create(
final SpecConfigElectra config, final SchemaDefinitionsElectra schemaDefinitions) {
// Helpers
final Predicates predicates = new Predicates(config);
final PredicatesElectra predicates = new PredicatesElectra(config);
final MiscHelpersElectra miscHelpers =
new MiscHelpersElectra(config, predicates, schemaDefinitions);
final BeaconStateAccessorsDeneb beaconStateAccessors =
new BeaconStateAccessorsDeneb(config, predicates, miscHelpers);
final BeaconStateAccessorsElectra beaconStateAccessors =
new BeaconStateAccessorsElectra(config, predicates, miscHelpers);
final BeaconStateMutatorsBellatrix beaconStateMutators =
new BeaconStateMutatorsBellatrix(config, miscHelpers, beaconStateAccessors);

Expand Down Expand Up @@ -126,8 +126,8 @@ public static SpecLogicElectra create(
predicates,
miscHelpers,
beaconStateAccessors);
final EpochProcessorCapella epochProcessor =
new EpochProcessorCapella(
final EpochProcessorElectra epochProcessor =
new EpochProcessorElectra(
config,
miscHelpers,
beaconStateAccessors,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright Consensys Software Inc., 2024
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/

package tech.pegasys.teku.spec.logic.versions.electra.helpers;

import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.spec.config.SpecConfigDeneb;
import tech.pegasys.teku.spec.datastructures.state.Validator;
import tech.pegasys.teku.spec.logic.versions.deneb.helpers.BeaconStateAccessorsDeneb;
import tech.pegasys.teku.spec.logic.versions.deneb.helpers.MiscHelpersDeneb;

public class BeaconStateAccessorsElectra extends BeaconStateAccessorsDeneb {

private final UInt64 maxEffectiveBalanceElectra;
private final UInt64 minActivationBalance;

protected PredicatesElectra predicatesElectra;

public BeaconStateAccessorsElectra(
SpecConfigDeneb config, PredicatesElectra predicatesElectra, MiscHelpersDeneb miscHelpers) {
rolfyone marked this conversation as resolved.
Show resolved Hide resolved
super(config, predicatesElectra, miscHelpers);
this.maxEffectiveBalanceElectra =
config.toVersionElectra().orElseThrow().getMaxEffectiveBalanceElectra();
this.minActivationBalance = config.toVersionElectra().orElseThrow().getMinActivationBalance();
this.predicatesElectra = predicatesElectra;
}

/**
* implements get_validator_max_effective_balance state accessor
*
* @param validator - a validator from a state.
* @return the max effective balance for the specified validator based on its withdrawal
* credentials.
*/
public UInt64 getValidatorMaxEffectiveBalance(final Validator validator) {
return predicatesElectra.hasCompoundingWithdrawalCredential(validator)
? maxEffectiveBalanceElectra
: minActivationBalance;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright Consensys Software Inc., 2024
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/

package tech.pegasys.teku.spec.logic.versions.electra.helpers;

import static tech.pegasys.teku.spec.constants.WithdrawalPrefixes.COMPOUNDING_WITHDRAWAL_BYTE;

import org.apache.tuweni.bytes.Bytes32;
import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.spec.config.SpecConfig;
import tech.pegasys.teku.spec.config.SpecConfigElectra;
import tech.pegasys.teku.spec.datastructures.state.Validator;
import tech.pegasys.teku.spec.logic.common.helpers.Predicates;

public class PredicatesElectra extends Predicates {
private final SpecConfigElectra specConfigElectra;

public PredicatesElectra(SpecConfig specConfig) {
super(specConfig);
this.specConfigElectra = SpecConfigElectra.required(specConfig);
}

@Override
public boolean isPartiallyWithdrawableValidator(final Validator validator, final UInt64 balance) {
if (hasEth1WithdrawalCredential(validator)) {
return isPartiallyWithdrawableValidatorEth1CredentialsChecked(validator, balance);
}
if (hasCompoundingWithdrawalCredential(validator)) {
return isPartiallyWithdrawableValidatorCompoundingCredentialChecked(validator, balance);
}

return false;
}

private boolean isPartiallyWithdrawableValidatorCompoundingCredentialChecked(
final Validator validator, final UInt64 balance) {
final UInt64 maxEffectiveBalance = specConfigElectra.getMaxEffectiveBalanceElectra();
final boolean hasMaxEffectiveBalance =
validator.getEffectiveBalance().equals(maxEffectiveBalance);
final boolean hasExcessBalance = balance.isGreaterThan(maxEffectiveBalance);

return hasMaxEffectiveBalance && hasExcessBalance;
}

protected boolean hasCompoundingWithdrawalCredential(Validator validator) {
rolfyone marked this conversation as resolved.
Show resolved Hide resolved
return isCompoundingWithdrawalCredential(validator.getWithdrawalCredentials());
}

protected boolean isCompoundingWithdrawalCredential(Bytes32 withdrawalCredentials) {
rolfyone marked this conversation as resolved.
Show resolved Hide resolved
return withdrawalCredentials.get(0) == COMPOUNDING_WITHDRAWAL_BYTE;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright Consensys Software Inc., 2024
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/

package tech.pegasys.teku.spec.logic.versions.electra.statetransition.epoch;

import tech.pegasys.teku.infrastructure.unsigned.UInt64;
import tech.pegasys.teku.spec.config.SpecConfigBellatrix;
import tech.pegasys.teku.spec.logic.common.helpers.BeaconStateMutators;
import tech.pegasys.teku.spec.logic.common.statetransition.epoch.status.ValidatorStatus;
import tech.pegasys.teku.spec.logic.common.statetransition.epoch.status.ValidatorStatusFactory;
import tech.pegasys.teku.spec.logic.common.util.BeaconStateUtil;
import tech.pegasys.teku.spec.logic.common.util.ValidatorsUtil;
import tech.pegasys.teku.spec.logic.versions.altair.helpers.BeaconStateAccessorsAltair;
import tech.pegasys.teku.spec.logic.versions.altair.helpers.MiscHelpersAltair;
import tech.pegasys.teku.spec.logic.versions.bellatrix.statetransition.epoch.EpochProcessorBellatrix;
import tech.pegasys.teku.spec.schemas.SchemaDefinitions;

public class EpochProcessorElectra extends EpochProcessorBellatrix {

private final UInt64 minActivationBalance;

public EpochProcessorElectra(
SpecConfigBellatrix specConfig,
MiscHelpersAltair miscHelpers,
BeaconStateAccessorsAltair beaconStateAccessors,
BeaconStateMutators beaconStateMutators,
ValidatorsUtil validatorsUtil,
BeaconStateUtil beaconStateUtil,
ValidatorStatusFactory validatorStatusFactory,
SchemaDefinitions schemaDefinitions) {
rolfyone marked this conversation as resolved.
Show resolved Hide resolved
super(
specConfig,
miscHelpers,
beaconStateAccessors,
beaconStateMutators,
validatorsUtil,
beaconStateUtil,
validatorStatusFactory,
schemaDefinitions);
this.minActivationBalance =
specConfig.toVersionElectra().orElseThrow().getMinActivationBalance();
}

@Override
protected boolean isEligibleForActivationQueue(final ValidatorStatus status) {
return !status.isActiveInCurrentEpoch()
&& status.getCurrentEpochEffectiveBalance().isGreaterThanOrEqualTo(minActivationBalance);
}
}