diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/ExpectedWithdrawals.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/ExpectedWithdrawals.java index 9d290a8ded7..d839ba747de 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/ExpectedWithdrawals.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/datastructures/execution/ExpectedWithdrawals.java @@ -248,7 +248,7 @@ private static List getExpectedWithdrawals( withdrawalIndex, UInt64.valueOf(validatorIndex), new Bytes20(validator.getWithdrawalCredentials().slice(12)), - balance.minusMinZero(predicates.getValidatorMaxEffectiveBalance(validator)))); + balance.minusMinZero(miscHelpers.getMaxEffectiveBalance(validator)))); withdrawalIndex = withdrawalIndex.increment(); } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/MiscHelpers.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/MiscHelpers.java index 3ba1a0c6355..5fb68722f14 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/MiscHelpers.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/MiscHelpers.java @@ -42,6 +42,7 @@ import tech.pegasys.teku.spec.datastructures.blocks.BeaconBlock; import tech.pegasys.teku.spec.datastructures.state.ForkData; import tech.pegasys.teku.spec.datastructures.state.SigningData; +import tech.pegasys.teku.spec.datastructures.state.Validator; import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconStateCache; import tech.pegasys.teku.spec.logic.versions.deneb.helpers.MiscHelpersDeneb; @@ -386,6 +387,10 @@ public UInt64 getMaxRequestBlocks() { return UInt64.valueOf(specConfig.getNetworkingConfig().getMaxRequestBlocks()); } + public UInt64 getMaxEffectiveBalance(final Validator validator) { + return specConfig.getMaxEffectiveBalance(); + } + public boolean isFormerDepositMechanismDisabled(final BeaconState state) { return false; } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/Predicates.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/Predicates.java index 528564150be..f5007fcb110 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/Predicates.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/common/helpers/Predicates.java @@ -160,7 +160,7 @@ public boolean isPartiallyWithdrawableValidator(final Validator validator, final public boolean isPartiallyWithdrawableValidatorEth1CredentialsChecked( final Validator validator, final UInt64 balance) { - final UInt64 maxEffectiveBalance = getValidatorMaxEffectiveBalance(validator); + final UInt64 maxEffectiveBalance = specConfig.getMaxEffectiveBalance(); final boolean hasMaxEffectiveBalance = validator.getEffectiveBalance().equals(maxEffectiveBalance); final boolean hasExcessBalance = balance.isGreaterThan(maxEffectiveBalance); @@ -168,10 +168,6 @@ public boolean isPartiallyWithdrawableValidatorEth1CredentialsChecked( return hasMaxEffectiveBalance && hasExcessBalance; } - public UInt64 getValidatorMaxEffectiveBalance(final Validator validator) { - return specConfig.getMaxEffectiveBalance(); - } - public Optional toVersionElectra() { return Optional.empty(); } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/block/BlockProcessorElectra.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/block/BlockProcessorElectra.java index 7815a5f46f3..03c9228ec12 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/block/BlockProcessorElectra.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/block/BlockProcessorElectra.java @@ -725,8 +725,7 @@ protected Validator getValidatorFromDeposit( FAR_FUTURE_EPOCH, FAR_FUTURE_EPOCH); - final UInt64 maxEffectiveBalance = - beaconStateAccessorsElectra.getValidatorMaxEffectiveBalance(validator); + final UInt64 maxEffectiveBalance = miscHelpers.getMaxEffectiveBalance(validator); final UInt64 validatorEffectiveBalance = amount .minusMinZero(amount.mod(specConfig.getEffectiveBalanceIncrement())) diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/BeaconStateAccessorsElectra.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/BeaconStateAccessorsElectra.java index 9aa6cc60272..2bc48d0ba4f 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/BeaconStateAccessorsElectra.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/BeaconStateAccessorsElectra.java @@ -60,7 +60,7 @@ public UInt64 getActivationExitChurnLimit(final BeaconStateElectra state) { */ public UInt64 getActiveBalance(final BeaconState state, final int validatorIndex) { final Validator validator = state.getValidators().get(validatorIndex); - final UInt64 maxEffectiveBalance = predicatesElectra.getValidatorMaxEffectiveBalance(validator); + final UInt64 maxEffectiveBalance = miscHelpers.getMaxEffectiveBalance(validator); final UInt64 validatorBalance = state.getBalances().get(validatorIndex).get(); return validatorBalance.min(maxEffectiveBalance); } @@ -115,17 +115,6 @@ public static BeaconStateAccessorsElectra required( return (BeaconStateAccessorsElectra) beaconStateAccessors; } - /** - * 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.getValidatorMaxEffectiveBalance(validator); - } - @Override public IntList getNextSyncCommitteeIndices(final BeaconState state) { return getNextSyncCommitteeIndices(state, configElectra.getMaxEffectiveBalanceElectra()); diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/MiscHelpersElectra.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/MiscHelpersElectra.java index 3d2f1a0ccd7..2c99e2236cf 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/MiscHelpersElectra.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/MiscHelpersElectra.java @@ -16,8 +16,10 @@ import it.unimi.dsi.fastutil.ints.IntList; import java.util.Optional; import org.apache.tuweni.bytes.Bytes32; +import tech.pegasys.teku.infrastructure.unsigned.UInt64; import tech.pegasys.teku.spec.config.SpecConfigDeneb; import tech.pegasys.teku.spec.config.SpecConfigElectra; +import tech.pegasys.teku.spec.datastructures.state.Validator; import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.BeaconStateElectra; import tech.pegasys.teku.spec.logic.common.helpers.MiscHelpers; @@ -27,6 +29,8 @@ import tech.pegasys.teku.spec.schemas.SchemaDefinitionsDeneb; public class MiscHelpersElectra extends MiscHelpersDeneb { + private final SpecConfigElectra specConfigElectra; + private final PredicatesElectra predicatesElectra; public MiscHelpersElectra( final SpecConfigElectra specConfig, @@ -36,6 +40,8 @@ public MiscHelpersElectra( SpecConfigDeneb.required(specConfig), predicates, SchemaDefinitionsDeneb.required(schemaDefinitions)); + this.specConfigElectra = SpecConfigElectra.required(specConfig); + this.predicatesElectra = PredicatesElectra.required(predicates); } public static MiscHelpersElectra required(final MiscHelpers miscHelpers) { @@ -58,6 +64,13 @@ public int computeProposerIndex( SpecConfigElectra.required(specConfig).getMaxEffectiveBalanceElectra()); } + @Override + public UInt64 getMaxEffectiveBalance(final Validator validator) { + return predicatesElectra.hasCompoundingWithdrawalCredential(validator) + ? specConfigElectra.getMaxEffectiveBalanceElectra() + : specConfigElectra.getMinActivationBalance(); + } + @Override public Optional toVersionElectra() { return Optional.of(this); diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/PredicatesElectra.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/PredicatesElectra.java index 0e61afee911..61798e22439 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/PredicatesElectra.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/PredicatesElectra.java @@ -55,12 +55,22 @@ public Optional toVersionElectra() { */ @Override public boolean isPartiallyWithdrawableValidator(final Validator validator, final UInt64 balance) { - if (hasExecutionWithdrawalCredential(validator)) { - final UInt64 maxEffectiveBalance = getValidatorMaxEffectiveBalance(validator); - return (balance.isGreaterThan(maxEffectiveBalance) - && maxEffectiveBalance.equals(validator.getEffectiveBalance())); - } - return false; + return hasExecutionWithdrawalCredential(validator) + && isPartiallyWithdrawableValidatorEth1CredentialsChecked(validator, balance); + } + + @Override + public boolean isPartiallyWithdrawableValidatorEth1CredentialsChecked( + final Validator validator, final UInt64 balance) { + final UInt64 maxEffectiveBalance = + hasCompoundingWithdrawalCredential(validator) + ? configElectra.getMaxEffectiveBalanceElectra() + : configElectra.getMinActivationBalance(); + final boolean hasMaxEffectiveBalance = + validator.getEffectiveBalance().equals(maxEffectiveBalance); + final boolean hasExcessBalance = balance.isGreaterThan(maxEffectiveBalance); + + return hasMaxEffectiveBalance && hasExcessBalance; } /** @@ -108,18 +118,4 @@ public boolean hasCompoundingWithdrawalCredential(final Validator validator) { public boolean isCompoundingWithdrawalCredential(final Bytes32 withdrawalCredentials) { return withdrawalCredentials.get(0) == COMPOUNDING_WITHDRAWAL_BYTE; } - - /** - * 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. - */ - @Override - public UInt64 getValidatorMaxEffectiveBalance(final Validator validator) { - return hasCompoundingWithdrawalCredential(validator) - ? configElectra.getMaxEffectiveBalanceElectra() - : configElectra.getMinActivationBalance(); - } } diff --git a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/statetransition/epoch/EpochProcessorElectra.java b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/statetransition/epoch/EpochProcessorElectra.java index b4d33c0dfb9..2dafe8d7328 100644 --- a/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/statetransition/epoch/EpochProcessorElectra.java +++ b/ethereum/spec/src/main/java/tech/pegasys/teku/spec/logic/versions/electra/statetransition/epoch/EpochProcessorElectra.java @@ -153,7 +153,7 @@ protected boolean isEligibleForActivationQueue(final ValidatorStatus status) { @Override protected UInt64 getEffectiveBalanceLimitForValidator(final Validator validator) { - return stateAccessorsElectra.getValidatorMaxEffectiveBalance(validator); + return miscHelpers.getMaxEffectiveBalance(validator); } // process_effective_balance_updates @@ -266,8 +266,7 @@ private Validator getValidatorFromDeposit( FAR_FUTURE_EPOCH, FAR_FUTURE_EPOCH); - final UInt64 maxEffectiveBalance = - stateAccessorsElectra.getValidatorMaxEffectiveBalance(validator); + final UInt64 maxEffectiveBalance = miscHelpers.getMaxEffectiveBalance(validator); final UInt64 validatorEffectiveBalance = amount .minusMinZero(amount.mod(specConfig.getEffectiveBalanceIncrement())) diff --git a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/MiscHelpersElectraTest.java b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/MiscHelpersElectraTest.java index 9cd9376ecfc..86acdd78d47 100644 --- a/ethereum/spec/src/test/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/MiscHelpersElectraTest.java +++ b/ethereum/spec/src/test/java/tech/pegasys/teku/spec/logic/versions/electra/helpers/MiscHelpersElectraTest.java @@ -34,7 +34,6 @@ import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.BeaconStateElectra; import tech.pegasys.teku.spec.datastructures.state.beaconstate.versions.electra.MutableBeaconStateElectra; -import tech.pegasys.teku.spec.logic.common.helpers.Predicates; import tech.pegasys.teku.spec.schemas.SchemaDefinitionsElectra; import tech.pegasys.teku.spec.util.DataStructureUtil; @@ -42,20 +41,19 @@ public class MiscHelpersElectraTest { private final Spec spec = TestSpecFactory.createMinimalElectra(); private static final int PROPOSER_INDEX = 3; - private final Predicates predicates = new Predicates(spec.getGenesisSpecConfig()); + private final PredicatesElectra predicatesElectra = + new PredicatesElectra(spec.getGenesisSpecConfig()); private final SchemaDefinitionsElectra schemaDefinitionsElectra = SchemaDefinitionsElectra.required(spec.getGenesisSchemaDefinitions()); private final MiscHelpersElectra miscHelpersElectra = new MiscHelpersElectra( spec.getGenesisSpecConfig().toVersionElectra().orElseThrow(), - predicates, + predicatesElectra, schemaDefinitionsElectra); private final DataStructureUtil dataStructureUtil = new DataStructureUtil(spec); final BeaconStateAccessorsElectra beaconStateAccessors = new BeaconStateAccessorsElectra( - spec.getGenesisSpecConfig(), - new PredicatesElectra(spec.getGenesisSpecConfig()), - miscHelpersElectra); + spec.getGenesisSpecConfig(), predicatesElectra, miscHelpersElectra); private final IntList validatorIndices = IntArrayList.of(1, 2, 3, 4, 5, 6, 7, 0); @@ -98,7 +96,7 @@ public void computeProposerIndexShouldUseMaxEffectiveBalanceElectra() { final SpecConfigElectra specConfigElectra = spy(SpecConfigElectra.required(spec.getGenesisSpecConfig())); final MiscHelpersElectra miscHelpersElectra = - new MiscHelpersElectra(specConfigElectra, predicates, schemaDefinitionsElectra); + new MiscHelpersElectra(specConfigElectra, predicatesElectra, schemaDefinitionsElectra); final BeaconState state = new BeaconStateTestBuilder(dataStructureUtil)